139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber/*
239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * Copyright (C) 2010 The Android Open Source Project
339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *
439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * you may not use this file except in compliance with the License.
639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * You may obtain a copy of the License at
739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *
839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber *
1039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * Unless required by applicable law or agreed to in writing, software
1139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * See the License for the specific language governing permissions and
1439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber * limitations under the License.
1539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber */
1639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
176e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber//#define LOG_NDEBUG 0
186e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#define LOG_TAG "AAMRAssembler"
196e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber#include <utils/Log.h>
206e4c5c499999c04c2477b987f9e64f3ff2bf1a06Andreas Huber
2139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "AAMRAssembler.h"
2239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "ARTPSource.h"
2439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
2639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/AMessage.h>
2839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/hexdump.h>
2939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/Utils.h>
3039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
3139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubernamespace android {
3239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
3339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic bool GetAttribute(const char *s, const char *key, AString *value) {
3439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    value->clear();
3539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
3639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    size_t keyLen = strlen(key);
3739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
3839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    for (;;) {
3939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        const char *colonPos = strchr(s, ';');
4039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
4139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        size_t len =
4239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            (colonPos == NULL) ? strlen(s) : colonPos - s;
4339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
4439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
4539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            value->setTo(&s[keyLen + 1], len - keyLen - 1);
4639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return true;
4739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
4839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (len == keyLen && !strncmp(s, key, keyLen)) {
4939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            value->setTo("1");
5039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return true;
5139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
5239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
5339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (colonPos == NULL) {
5439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return false;
5539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
5639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
5739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        s = colonPos + 1;
5839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
5939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
6039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
6139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberAAMRAssembler::AAMRAssembler(
6239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        const sp<AMessage> &notify, bool isWide, const AString &params)
6339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    : mIsWide(isWide),
6439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mNotifyMsg(notify),
6539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mNextExpectedSeqNoValid(false),
6639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mNextExpectedSeqNo(0) {
6739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    AString value;
6839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(GetAttribute(params.c_str(), "octet-align", &value) && value == "1");
6939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(!GetAttribute(params.c_str(), "crc", &value) || value == "0");
7039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(!GetAttribute(params.c_str(), "interleaving", &value));
7139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
7239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
7339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberAAMRAssembler::~AAMRAssembler() {
7439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
7539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
7639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberARTPAssembler::AssemblyStatus AAMRAssembler::assembleMore(
7739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        const sp<ARTPSource> &source) {
7839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return addPacket(source);
7939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
8039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
8139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huberstatic size_t getFrameSize(bool isWide, unsigned FT) {
824aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber    static const size_t kFrameSizeNB[9] = {
834aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber        95, 103, 118, 134, 148, 159, 204, 244, 39
8439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    };
854aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber    static const size_t kFrameSizeWB[10] = {
864aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber        132, 177, 253, 285, 317, 365, 397, 461, 477, 40
8739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    };
8839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
894aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber    if (FT == 15) {
904aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber        return 1;
914aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber    }
924aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber
9339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];
9439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
9539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    // Round up bits to bytes and add 1 for the header byte.
9639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    frameSize = (frameSize + 7) / 8 + 1;
9739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
9839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return frameSize;
9939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
10039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
10139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberARTPAssembler::AssemblyStatus AAMRAssembler::addPacket(
10239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        const sp<ARTPSource> &source) {
10339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    List<sp<ABuffer> > *queue = source->queue();
10439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
10539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (queue->empty()) {
10639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return NOT_ENOUGH_DATA;
10739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
10839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
10939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mNextExpectedSeqNoValid) {
11039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        List<sp<ABuffer> >::iterator it = queue->begin();
11139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        while (it != queue->end()) {
11239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
11339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                break;
11439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            }
11539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
11639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            it = queue->erase(it);
11739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
11839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
11939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (queue->empty()) {
12039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return NOT_ENOUGH_DATA;
12139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
12239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
12339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
12439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<ABuffer> buffer = *queue->begin();
12539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
12639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (!mNextExpectedSeqNoValid) {
12739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mNextExpectedSeqNoValid = true;
12839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
12939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
1303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Not the sequence number I expected");
13139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
13239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return WRONG_SEQUENCE_NUMBER;
13339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
13439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
13539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    // hexdump(buffer->data(), buffer->size());
13639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
13739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (buffer->size() < 1) {
13839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        queue->erase(queue->begin());
13939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ++mNextExpectedSeqNo;
14039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
1413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("AMR packet too short.");
14239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return MALFORMED_PACKET;
14439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
14539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    unsigned payloadHeader = buffer->data()[0];
14739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    unsigned CMR = payloadHeader >> 4;
14839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK_EQ(payloadHeader & 0x0f, 0u);  // RR
14939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
15039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    Vector<uint8_t> tableOfContents;
15139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
15239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    size_t offset = 1;
15339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    size_t totalSize = 0;
15439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    for (;;) {
15539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (offset >= buffer->size()) {
15639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            queue->erase(queue->begin());
15739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            ++mNextExpectedSeqNo;
15839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
1593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Unable to parse TOC.");
16039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
16139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return MALFORMED_PACKET;
16239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
16339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
16439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        uint8_t toc = buffer->data()[offset++];
16539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
16639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        unsigned FT = (toc >> 3) & 0x0f;
16739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if ((toc & 3) != 0
1684aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber                || (mIsWide && FT > 9 && FT != 15)
1694aae77cbe1bf4369910314a55c2bc2349af10d3cAndreas Huber                || (!mIsWide && FT > 8 && FT != 15)) {
17039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            queue->erase(queue->begin());
17139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            ++mNextExpectedSeqNo;
17239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
1733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Illegal TOC entry.");
17439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
17539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return MALFORMED_PACKET;
17639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
17739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
17839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        totalSize += getFrameSize(mIsWide, (toc >> 3) & 0x0f);
17939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
18039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        tableOfContents.push(toc);
18139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
18239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (0 == (toc & 0x80)) {
18339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            break;
18439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
18539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
18639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
18739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<ABuffer> accessUnit = new ABuffer(totalSize);
1888d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CopyTimes(accessUnit, buffer);
18939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
19039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    size_t dstOffset = 0;
19139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    for (size_t i = 0; i < tableOfContents.size(); ++i) {
19239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        uint8_t toc = tableOfContents[i];
19339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
19439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        size_t frameSize = getFrameSize(mIsWide, (toc >> 3) & 0x0f);
19539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
19639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (offset + frameSize - 1 > buffer->size()) {
19739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            queue->erase(queue->begin());
19839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            ++mNextExpectedSeqNo;
19939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("AMR packet too short.");
20139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
20239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return MALFORMED_PACKET;
20339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
20439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
20539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        accessUnit->data()[dstOffset++] = toc;
20639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        memcpy(accessUnit->data() + dstOffset,
20739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber               buffer->data() + offset, frameSize - 1);
20839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
20939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        offset += frameSize - 1;
21039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        dstOffset += frameSize - 1;
21139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
21239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
21339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<AMessage> msg = mNotifyMsg->dup();
2142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    msg->setBuffer("access-unit", accessUnit);
21539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    msg->post();
21639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
21739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    queue->erase(queue->begin());
21839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    ++mNextExpectedSeqNo;
21939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
22039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return OK;
22139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
22239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
22339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid AAMRAssembler::packetLost() {
22439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(mNextExpectedSeqNoValid);
22539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    ++mNextExpectedSeqNo;
22639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
22739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
22839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid AAMRAssembler::onByeReceived() {
22939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<AMessage> msg = mNotifyMsg->dup();
23039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    msg->setInt32("eos", true);
23139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    msg->post();
23239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
23339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
23439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}  // namespace android
235