AH263Assembler.cpp revision f95439afa8eb2484969d4a928b0fdd6a4d3a38d7
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 "AH263Assembler.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#include <media/stagefright/foundation/hexdump.h> 25#include <media/stagefright/Utils.h> 26 27namespace android { 28 29AH263Assembler::AH263Assembler(const sp<AMessage> ¬ify) 30 : mNotifyMsg(notify), 31 mAccessUnitRTPTime(0), 32 mNextExpectedSeqNoValid(false), 33 mNextExpectedSeqNo(0), 34 mAccessUnitDamaged(false) { 35} 36 37AH263Assembler::~AH263Assembler() { 38} 39 40ARTPAssembler::AssemblyStatus AH263Assembler::assembleMore( 41 const sp<ARTPSource> &source) { 42 AssemblyStatus status = addPacket(source); 43 if (status == MALFORMED_PACKET) { 44 mAccessUnitDamaged = true; 45 } 46 return status; 47} 48 49ARTPAssembler::AssemblyStatus AH263Assembler::addPacket( 50 const sp<ARTPSource> &source) { 51 List<sp<ABuffer> > *queue = source->queue(); 52 53 if (queue->empty()) { 54 return NOT_ENOUGH_DATA; 55 } 56 57 if (mNextExpectedSeqNoValid) { 58 List<sp<ABuffer> >::iterator it = queue->begin(); 59 while (it != queue->end()) { 60 if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) { 61 break; 62 } 63 64 it = queue->erase(it); 65 } 66 67 if (queue->empty()) { 68 return NOT_ENOUGH_DATA; 69 } 70 } 71 72 sp<ABuffer> buffer = *queue->begin(); 73 74 if (!mNextExpectedSeqNoValid) { 75 mNextExpectedSeqNoValid = true; 76 mNextExpectedSeqNo = (uint32_t)buffer->int32Data(); 77 } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) { 78#if VERBOSE 79 LOG(VERBOSE) << "Not the sequence number I expected"; 80#endif 81 82 return WRONG_SEQUENCE_NUMBER; 83 } 84 85 uint32_t rtpTime; 86 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 87 88 if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) { 89 submitAccessUnit(); 90 } 91 mAccessUnitRTPTime = rtpTime; 92 93 // hexdump(buffer->data(), buffer->size()); 94 95 if (buffer->size() < 2) { 96 queue->erase(queue->begin()); 97 ++mNextExpectedSeqNo; 98 99 return MALFORMED_PACKET; 100 } 101 102 unsigned payloadHeader = U16_AT(buffer->data()); 103 CHECK_EQ(payloadHeader >> 11, 0u); // RR=0 104 unsigned P = (payloadHeader >> 10) & 1; 105 unsigned V = (payloadHeader >> 9) & 1; 106 unsigned PLEN = (payloadHeader >> 3) & 0x3f; 107 // unsigned PEBIT = payloadHeader & 7; 108 109 size_t skip = V + PLEN + (P ? 0 : 2); 110 111 buffer->setRange(buffer->offset() + skip, buffer->size() - skip); 112 113 if (P) { 114 buffer->data()[0] = 0x00; 115 buffer->data()[1] = 0x00; 116 } 117 118 mPackets.push_back(buffer); 119 120 queue->erase(queue->begin()); 121 ++mNextExpectedSeqNo; 122 123 return OK; 124} 125 126void AH263Assembler::submitAccessUnit() { 127 CHECK(!mPackets.empty()); 128 129#if VERBOSE 130 LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)"; 131#endif 132 133 size_t totalSize = 0; 134 List<sp<ABuffer> >::iterator it = mPackets.begin(); 135 while (it != mPackets.end()) { 136 const sp<ABuffer> &unit = *it; 137 138 totalSize += unit->size(); 139 ++it; 140 } 141 142 sp<ABuffer> accessUnit = new ABuffer(totalSize); 143 size_t offset = 0; 144 it = mPackets.begin(); 145 while (it != mPackets.end()) { 146 const sp<ABuffer> &unit = *it; 147 148 memcpy((uint8_t *)accessUnit->data() + offset, 149 unit->data(), unit->size()); 150 151 offset += unit->size(); 152 153 ++it; 154 } 155 156 CopyTimes(accessUnit, *mPackets.begin()); 157 158#if 0 159 printf(mAccessUnitDamaged ? "X" : "."); 160 fflush(stdout); 161#endif 162 163 if (mAccessUnitDamaged) { 164 accessUnit->meta()->setInt32("damaged", true); 165 } 166 167 mPackets.clear(); 168 mAccessUnitDamaged = false; 169 170 sp<AMessage> msg = mNotifyMsg->dup(); 171 msg->setBuffer("access-unit", accessUnit); 172 msg->post(); 173} 174 175void AH263Assembler::packetLost() { 176 CHECK(mNextExpectedSeqNoValid); 177 ++mNextExpectedSeqNo; 178 179 mAccessUnitDamaged = true; 180} 181 182void AH263Assembler::onByeReceived() { 183 sp<AMessage> msg = mNotifyMsg->dup(); 184 msg->setInt32("eos", true); 185 msg->post(); 186} 187 188} // namespace android 189 190