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 //#define LOG_NDEBUG 0 18 #define LOG_TAG "AAVCAssembler" 19 #include <utils/Log.h> 20 21 #include "AAVCAssembler.h" 22 23 #include "ARTPSource.h" 24 25 #include <media/stagefright/foundation/ABuffer.h> 26 #include <media/stagefright/foundation/ADebug.h> 27 #include <media/stagefright/foundation/AMessage.h> 28 #include <media/stagefright/foundation/hexdump.h> 29 30 #include <stdint.h> 31 32 namespace android { 33 34 // static 35 AAVCAssembler::AAVCAssembler(const sp<AMessage> ¬ify) 36 : mNotifyMsg(notify), 37 mAccessUnitRTPTime(0), 38 mNextExpectedSeqNoValid(false), 39 mNextExpectedSeqNo(0), 40 mAccessUnitDamaged(false) { 41 } 42 43 AAVCAssembler::~AAVCAssembler() { 44 } 45 46 ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit( 47 const sp<ARTPSource> &source) { 48 List<sp<ABuffer> > *queue = source->queue(); 49 50 if (queue->empty()) { 51 return NOT_ENOUGH_DATA; 52 } 53 54 if (mNextExpectedSeqNoValid) { 55 List<sp<ABuffer> >::iterator it = queue->begin(); 56 while (it != queue->end()) { 57 if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) { 58 break; 59 } 60 61 it = queue->erase(it); 62 } 63 64 if (queue->empty()) { 65 return NOT_ENOUGH_DATA; 66 } 67 } 68 69 sp<ABuffer> buffer = *queue->begin(); 70 71 if (!mNextExpectedSeqNoValid) { 72 mNextExpectedSeqNoValid = true; 73 mNextExpectedSeqNo = (uint32_t)buffer->int32Data(); 74 } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) { 75 LOGV("Not the sequence number I expected"); 76 77 return WRONG_SEQUENCE_NUMBER; 78 } 79 80 const uint8_t *data = buffer->data(); 81 size_t size = buffer->size(); 82 83 if (size < 1 || (data[0] & 0x80)) { 84 // Corrupt. 85 86 LOGV("Ignoring corrupt buffer."); 87 queue->erase(queue->begin()); 88 89 ++mNextExpectedSeqNo; 90 return MALFORMED_PACKET; 91 } 92 93 unsigned nalType = data[0] & 0x1f; 94 if (nalType >= 1 && nalType <= 23) { 95 addSingleNALUnit(buffer); 96 queue->erase(queue->begin()); 97 ++mNextExpectedSeqNo; 98 return OK; 99 } else if (nalType == 28) { 100 // FU-A 101 return addFragmentedNALUnit(queue); 102 } else if (nalType == 24) { 103 // STAP-A 104 bool success = addSingleTimeAggregationPacket(buffer); 105 queue->erase(queue->begin()); 106 ++mNextExpectedSeqNo; 107 108 return success ? OK : MALFORMED_PACKET; 109 } else { 110 LOGV("Ignoring unsupported buffer (nalType=%d)", nalType); 111 112 queue->erase(queue->begin()); 113 ++mNextExpectedSeqNo; 114 115 return MALFORMED_PACKET; 116 } 117 } 118 119 void AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) { 120 LOGV("addSingleNALUnit of size %d", buffer->size()); 121 #if !LOG_NDEBUG 122 hexdump(buffer->data(), buffer->size()); 123 #endif 124 125 uint32_t rtpTime; 126 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 127 128 if (!mNALUnits.empty() && rtpTime != mAccessUnitRTPTime) { 129 submitAccessUnit(); 130 } 131 mAccessUnitRTPTime = rtpTime; 132 133 mNALUnits.push_back(buffer); 134 } 135 136 bool AAVCAssembler::addSingleTimeAggregationPacket(const sp<ABuffer> &buffer) { 137 const uint8_t *data = buffer->data(); 138 size_t size = buffer->size(); 139 140 if (size < 3) { 141 LOGV("Discarding too small STAP-A packet."); 142 return false; 143 } 144 145 ++data; 146 --size; 147 while (size >= 2) { 148 size_t nalSize = (data[0] << 8) | data[1]; 149 150 if (size < nalSize + 2) { 151 LOGV("Discarding malformed STAP-A packet."); 152 return false; 153 } 154 155 sp<ABuffer> unit = new ABuffer(nalSize); 156 memcpy(unit->data(), &data[2], nalSize); 157 158 CopyTimes(unit, buffer); 159 160 addSingleNALUnit(unit); 161 162 data += 2 + nalSize; 163 size -= 2 + nalSize; 164 } 165 166 if (size != 0) { 167 LOGV("Unexpected padding at end of STAP-A packet."); 168 } 169 170 return true; 171 } 172 173 ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit( 174 List<sp<ABuffer> > *queue) { 175 CHECK(!queue->empty()); 176 177 sp<ABuffer> buffer = *queue->begin(); 178 const uint8_t *data = buffer->data(); 179 size_t size = buffer->size(); 180 181 CHECK(size > 0); 182 unsigned indicator = data[0]; 183 184 CHECK((indicator & 0x1f) == 28); 185 186 if (size < 2) { 187 LOGV("Ignoring malformed FU buffer (size = %d)", size); 188 189 queue->erase(queue->begin()); 190 ++mNextExpectedSeqNo; 191 return MALFORMED_PACKET; 192 } 193 194 if (!(data[1] & 0x80)) { 195 // Start bit not set on the first buffer. 196 197 LOGV("Start bit not set on first buffer"); 198 199 queue->erase(queue->begin()); 200 ++mNextExpectedSeqNo; 201 return MALFORMED_PACKET; 202 } 203 204 uint32_t nalType = data[1] & 0x1f; 205 uint32_t nri = (data[0] >> 5) & 3; 206 207 uint32_t expectedSeqNo = (uint32_t)buffer->int32Data() + 1; 208 size_t totalSize = size - 2; 209 size_t totalCount = 1; 210 bool complete = false; 211 212 if (data[1] & 0x40) { 213 // Huh? End bit also set on the first buffer. 214 215 LOGV("Grrr. This isn't fragmented at all."); 216 217 complete = true; 218 } else { 219 List<sp<ABuffer> >::iterator it = ++queue->begin(); 220 while (it != queue->end()) { 221 LOGV("sequence length %d", totalCount); 222 223 const sp<ABuffer> &buffer = *it; 224 225 const uint8_t *data = buffer->data(); 226 size_t size = buffer->size(); 227 228 if ((uint32_t)buffer->int32Data() != expectedSeqNo) { 229 LOGV("sequence not complete, expected seqNo %d, got %d", 230 expectedSeqNo, (uint32_t)buffer->int32Data()); 231 232 return WRONG_SEQUENCE_NUMBER; 233 } 234 235 if (size < 2 236 || data[0] != indicator 237 || (data[1] & 0x1f) != nalType 238 || (data[1] & 0x80)) { 239 LOGV("Ignoring malformed FU buffer."); 240 241 // Delete the whole start of the FU. 242 243 it = queue->begin(); 244 for (size_t i = 0; i <= totalCount; ++i) { 245 it = queue->erase(it); 246 } 247 248 mNextExpectedSeqNo = expectedSeqNo + 1; 249 250 return MALFORMED_PACKET; 251 } 252 253 totalSize += size - 2; 254 ++totalCount; 255 256 expectedSeqNo = expectedSeqNo + 1; 257 258 if (data[1] & 0x40) { 259 // This is the last fragment. 260 complete = true; 261 break; 262 } 263 264 ++it; 265 } 266 } 267 268 if (!complete) { 269 return NOT_ENOUGH_DATA; 270 } 271 272 mNextExpectedSeqNo = expectedSeqNo; 273 274 // We found all the fragments that make up the complete NAL unit. 275 276 // Leave room for the header. So far totalSize did not include the 277 // header byte. 278 ++totalSize; 279 280 sp<ABuffer> unit = new ABuffer(totalSize); 281 CopyTimes(unit, *queue->begin()); 282 283 unit->data()[0] = (nri << 5) | nalType; 284 285 size_t offset = 1; 286 List<sp<ABuffer> >::iterator it = queue->begin(); 287 for (size_t i = 0; i < totalCount; ++i) { 288 const sp<ABuffer> &buffer = *it; 289 290 LOGV("piece #%d/%d", i + 1, totalCount); 291 #if !LOG_NDEBUG 292 hexdump(buffer->data(), buffer->size()); 293 #endif 294 295 memcpy(unit->data() + offset, buffer->data() + 2, buffer->size() - 2); 296 offset += buffer->size() - 2; 297 298 it = queue->erase(it); 299 } 300 301 unit->setRange(0, totalSize); 302 303 addSingleNALUnit(unit); 304 305 LOGV("successfully assembled a NAL unit from fragments."); 306 307 return OK; 308 } 309 310 void AAVCAssembler::submitAccessUnit() { 311 CHECK(!mNALUnits.empty()); 312 313 LOGV("Access unit complete (%d nal units)", mNALUnits.size()); 314 315 size_t totalSize = 0; 316 for (List<sp<ABuffer> >::iterator it = mNALUnits.begin(); 317 it != mNALUnits.end(); ++it) { 318 totalSize += 4 + (*it)->size(); 319 } 320 321 sp<ABuffer> accessUnit = new ABuffer(totalSize); 322 size_t offset = 0; 323 for (List<sp<ABuffer> >::iterator it = mNALUnits.begin(); 324 it != mNALUnits.end(); ++it) { 325 memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4); 326 offset += 4; 327 328 sp<ABuffer> nal = *it; 329 memcpy(accessUnit->data() + offset, nal->data(), nal->size()); 330 offset += nal->size(); 331 } 332 333 CopyTimes(accessUnit, *mNALUnits.begin()); 334 335 #if 0 336 printf(mAccessUnitDamaged ? "X" : "."); 337 fflush(stdout); 338 #endif 339 340 if (mAccessUnitDamaged) { 341 accessUnit->meta()->setInt32("damaged", true); 342 } 343 344 mNALUnits.clear(); 345 mAccessUnitDamaged = false; 346 347 sp<AMessage> msg = mNotifyMsg->dup(); 348 msg->setObject("access-unit", accessUnit); 349 msg->post(); 350 } 351 352 ARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore( 353 const sp<ARTPSource> &source) { 354 AssemblyStatus status = addNALUnit(source); 355 if (status == MALFORMED_PACKET) { 356 mAccessUnitDamaged = true; 357 } 358 return status; 359 } 360 361 void AAVCAssembler::packetLost() { 362 CHECK(mNextExpectedSeqNoValid); 363 LOGV("packetLost (expected %d)", mNextExpectedSeqNo); 364 365 ++mNextExpectedSeqNo; 366 367 mAccessUnitDamaged = true; 368 } 369 370 void AAVCAssembler::onByeReceived() { 371 sp<AMessage> msg = mNotifyMsg->dup(); 372 msg->setInt32("eos", true); 373 msg->post(); 374 } 375 376 } // namespace android 377