AMPEG4AudioAssembler.cpp revision 39ddf8e0f18766f7ba1e3246b774aa6ebd93eea8
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "AMPEG4AudioAssembler.h" 18 19#include "ARTPSource.h" 20 21#include <media/stagefright/foundation/ABuffer.h> 22#include <media/stagefright/foundation/ADebug.h> 23#include <media/stagefright/foundation/AMessage.h> 24 25namespace android { 26 27AMPEG4AudioAssembler::AMPEG4AudioAssembler(const sp<AMessage> ¬ify) 28 : mNotifyMsg(notify), 29 mAccessUnitRTPTime(0), 30 mNextExpectedSeqNoValid(false), 31 mNextExpectedSeqNo(0), 32 mAccessUnitDamaged(false) { 33} 34 35AMPEG4AudioAssembler::~AMPEG4AudioAssembler() { 36} 37 38ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::assembleMore( 39 const sp<ARTPSource> &source) { 40 AssemblyStatus status = addPacket(source); 41 if (status == MALFORMED_PACKET) { 42 mAccessUnitDamaged = true; 43 } 44 return status; 45} 46 47ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::addPacket( 48 const sp<ARTPSource> &source) { 49 List<sp<ABuffer> > *queue = source->queue(); 50 51 if (queue->empty()) { 52 return NOT_ENOUGH_DATA; 53 } 54 55 if (mNextExpectedSeqNoValid) { 56 List<sp<ABuffer> >::iterator it = queue->begin(); 57 while (it != queue->end()) { 58 if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) { 59 break; 60 } 61 62 it = queue->erase(it); 63 } 64 65 if (queue->empty()) { 66 return NOT_ENOUGH_DATA; 67 } 68 } 69 70 sp<ABuffer> buffer = *queue->begin(); 71 72 if (!mNextExpectedSeqNoValid) { 73 mNextExpectedSeqNoValid = true; 74 mNextExpectedSeqNo = (uint32_t)buffer->int32Data(); 75 } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) { 76#if VERBOSE 77 LOG(VERBOSE) << "Not the sequence number I expected"; 78#endif 79 80 return WRONG_SEQUENCE_NUMBER; 81 } 82 83 uint32_t rtpTime; 84 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 85 86 if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) { 87 submitAccessUnit(); 88 } 89 mAccessUnitRTPTime = rtpTime; 90 91 mPackets.push_back(buffer); 92 93 queue->erase(queue->begin()); 94 ++mNextExpectedSeqNo; 95 96 return OK; 97} 98 99void AMPEG4AudioAssembler::submitAccessUnit() { 100 CHECK(!mPackets.empty()); 101 102#if VERBOSE 103 LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)"; 104#endif 105 106 uint64_t ntpTime; 107 CHECK((*mPackets.begin())->meta()->findInt64( 108 "ntp-time", (int64_t *)&ntpTime)); 109 110 size_t totalSize = 0; 111 List<sp<ABuffer> >::iterator it = mPackets.begin(); 112 while (it != mPackets.end()) { 113 const sp<ABuffer> &unit = *it; 114 115 size_t n = 0; 116 while (unit->data()[n] == 0xff) { 117 ++n; 118 } 119 ++n; 120 121 totalSize += unit->size() - n; 122 ++it; 123 } 124 125 sp<ABuffer> accessUnit = new ABuffer(totalSize); 126 size_t offset = 0; 127 it = mPackets.begin(); 128 while (it != mPackets.end()) { 129 const sp<ABuffer> &unit = *it; 130 131 size_t n = 0; 132 while (unit->data()[n] == 0xff) { 133 ++n; 134 } 135 ++n; 136 137 memcpy((uint8_t *)accessUnit->data() + offset, 138 unit->data() + n, unit->size() - n); 139 140 offset += unit->size() - n; 141 142 ++it; 143 } 144 145 accessUnit->meta()->setInt64("ntp-time", ntpTime); 146 147#if 0 148 printf(mAccessUnitDamaged ? "X" : "."); 149 fflush(stdout); 150#endif 151 152 if (mAccessUnitDamaged) { 153 accessUnit->meta()->setInt32("damaged", true); 154 } 155 156 mPackets.clear(); 157 mAccessUnitDamaged = false; 158 159 sp<AMessage> msg = mNotifyMsg->dup(); 160 msg->setObject("access-unit", accessUnit); 161 msg->post(); 162} 163 164void AMPEG4AudioAssembler::packetLost() { 165 CHECK(mNextExpectedSeqNoValid); 166 ++mNextExpectedSeqNo; 167 168 mAccessUnitDamaged = true; 169} 170 171void AMPEG4AudioAssembler::onByeReceived() { 172 sp<AMessage> msg = mNotifyMsg->dup(); 173 msg->setInt32("eos", true); 174 msg->post(); 175} 176 177} // namespace android 178