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