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 */
16a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger//#define LOG_NDEBUG 0
17a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger#define LOG_TAG "AH263Assembler"
18a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger#include <utils/Log.h>
1939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "AH263Assembler.h"
2139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include "ARTPSource.h"
2339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
2439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
2539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/AMessage.h>
2739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/foundation/hexdump.h>
2839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#include <media/stagefright/Utils.h>
2939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
3039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubernamespace android {
3139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
3239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberAH263Assembler::AH263Assembler(const sp<AMessage> &notify)
3339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    : mNotifyMsg(notify),
3439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mAccessUnitRTPTime(0),
3539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mNextExpectedSeqNoValid(false),
3639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mNextExpectedSeqNo(0),
3739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber      mAccessUnitDamaged(false) {
3839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
3939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
4039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberAH263Assembler::~AH263Assembler() {
4139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
4239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
4339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberARTPAssembler::AssemblyStatus AH263Assembler::assembleMore(
4439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        const sp<ARTPSource> &source) {
4539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    AssemblyStatus status = addPacket(source);
4639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (status == MALFORMED_PACKET) {
4739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mAccessUnitDamaged = true;
4839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
4939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return status;
5039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
5139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
5239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas HuberARTPAssembler::AssemblyStatus AH263Assembler::addPacket(
5339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        const sp<ARTPSource> &source) {
5439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    List<sp<ABuffer> > *queue = source->queue();
5539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
5639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (queue->empty()) {
5739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return NOT_ENOUGH_DATA;
5839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
5939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
6039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mNextExpectedSeqNoValid) {
6139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        List<sp<ABuffer> >::iterator it = queue->begin();
6239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        while (it != queue->end()) {
6339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
6439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber                break;
6539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            }
6639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
6739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            it = queue->erase(it);
6839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
6939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
7039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        if (queue->empty()) {
7139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber            return NOT_ENOUGH_DATA;
7239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        }
7339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
7439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
7539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<ABuffer> buffer = *queue->begin();
7639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
7739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (!mNextExpectedSeqNoValid) {
7839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mNextExpectedSeqNoValid = true;
7939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
8039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
8139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if VERBOSE
8239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        LOG(VERBOSE) << "Not the sequence number I expected";
8339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif
8439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
8539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return WRONG_SEQUENCE_NUMBER;
8639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
8739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
8839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    uint32_t rtpTime;
8939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime));
9039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
9139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
9239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        submitAccessUnit();
9339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
9439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mAccessUnitRTPTime = rtpTime;
9539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
9639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    // hexdump(buffer->data(), buffer->size());
9739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
9839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (buffer->size() < 2) {
9939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        queue->erase(queue->begin());
10039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ++mNextExpectedSeqNo;
10139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
10239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        return MALFORMED_PACKET;
10339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
10439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
10539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    unsigned payloadHeader = U16_AT(buffer->data());
10639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    unsigned P = (payloadHeader >> 10) & 1;
107f95439afa8eb2484969d4a928b0fdd6a4d3a38d7Andreas Huber    unsigned V = (payloadHeader >> 9) & 1;
108f95439afa8eb2484969d4a928b0fdd6a4d3a38d7Andreas Huber    unsigned PLEN = (payloadHeader >> 3) & 0x3f;
109a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    unsigned PEBIT = payloadHeader & 7;
110a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger
111a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    // V=0
112a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    if (V != 0u) {
113a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        queue->erase(queue->begin());
114a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        ++mNextExpectedSeqNo;
115a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        ALOGW("Packet discarded due to VRC (V != 0)");
116a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        return MALFORMED_PACKET;
117a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    }
118a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger
119a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    // PLEN=0
120a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    if (PLEN != 0u) {
121a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        queue->erase(queue->begin());
122a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        ++mNextExpectedSeqNo;
123a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        ALOGW("Packet discarded (PLEN != 0)");
124a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        return MALFORMED_PACKET;
125a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    }
126a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger
127a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    // PEBIT=0
128a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    if (PEBIT != 0u) {
129a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        queue->erase(queue->begin());
130a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        ++mNextExpectedSeqNo;
131a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        ALOGW("Packet discarded (PEBIT != 0)");
132a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger        return MALFORMED_PACKET;
133a1ca351f98e2e9c3d03654fb9794a7bf7d8f9617Roger    }
134f95439afa8eb2484969d4a928b0fdd6a4d3a38d7Andreas Huber
135f95439afa8eb2484969d4a928b0fdd6a4d3a38d7Andreas Huber    size_t skip = V + PLEN + (P ? 0 : 2);
136f95439afa8eb2484969d4a928b0fdd6a4d3a38d7Andreas Huber
137f95439afa8eb2484969d4a928b0fdd6a4d3a38d7Andreas Huber    buffer->setRange(buffer->offset() + skip, buffer->size() - skip);
13839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
13939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (P) {
14039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        buffer->data()[0] = 0x00;
14139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        buffer->data()[1] = 0x00;
14239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
14339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mPackets.push_back(buffer);
14539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    queue->erase(queue->begin());
14739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    ++mNextExpectedSeqNo;
14839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
14939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    return OK;
15039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
15139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
15239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid AH263Assembler::submitAccessUnit() {
15339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(!mPackets.empty());
15439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
15539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if VERBOSE
15639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
15739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif
15839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
15939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    size_t totalSize = 0;
16039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    List<sp<ABuffer> >::iterator it = mPackets.begin();
16139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    while (it != mPackets.end()) {
16239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        const sp<ABuffer> &unit = *it;
16339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
16439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        totalSize += unit->size();
16539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ++it;
16639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
16739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
16839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<ABuffer> accessUnit = new ABuffer(totalSize);
16939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    size_t offset = 0;
17039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    it = mPackets.begin();
17139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    while (it != mPackets.end()) {
17239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        const sp<ABuffer> &unit = *it;
17339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
17439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        memcpy((uint8_t *)accessUnit->data() + offset,
17539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber               unit->data(), unit->size());
17639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
17739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        offset += unit->size();
17839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
17939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        ++it;
18039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
18139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
1828d342970108926c4ea355c90d26a2a353ec0fd47Andreas Huber    CopyTimes(accessUnit, *mPackets.begin());
18339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
18439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#if 0
18539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    printf(mAccessUnitDamaged ? "X" : ".");
18639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    fflush(stdout);
18739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber#endif
18839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
18939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    if (mAccessUnitDamaged) {
19039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber        accessUnit->meta()->setInt32("damaged", true);
19139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    }
19239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
19339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mPackets.clear();
19439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mAccessUnitDamaged = false;
19539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
19639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<AMessage> msg = mNotifyMsg->dup();
1972d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    msg->setBuffer("access-unit", accessUnit);
19839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    msg->post();
19939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
20039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
20139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid AH263Assembler::packetLost() {
20239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    CHECK(mNextExpectedSeqNoValid);
20339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    ++mNextExpectedSeqNo;
20439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
20539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    mAccessUnitDamaged = true;
20639ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
20739ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
20839ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Hubervoid AH263Assembler::onByeReceived() {
20939ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    sp<AMessage> msg = mNotifyMsg->dup();
21039ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    msg->setInt32("eos", true);
21139ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber    msg->post();
21239ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}
21339ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
21439ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber}  // namespace android
21539ddf8e0f18766f7ba1e3246b774aa6ebd93eea8Andreas Huber
216