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> ¬ify) 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