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 ALOGV("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 ALOGV("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 if (nalType == 0) { 110 ALOGV("Ignoring undefined nal type."); 111 112 queue->erase(queue->begin()); 113 ++mNextExpectedSeqNo; 114 115 return OK; 116 } else { 117 ALOGV("Ignoring unsupported buffer (nalType=%d)", nalType); 118 119 queue->erase(queue->begin()); 120 ++mNextExpectedSeqNo; 121 122 return MALFORMED_PACKET; 123 } 124 } 125 126 void AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) { 127 ALOGV("addSingleNALUnit of size %d", buffer->size()); 128 #if !LOG_NDEBUG 129 hexdump(buffer->data(), buffer->size()); 130 #endif 131 132 uint32_t rtpTime; 133 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 134 135 if (!mNALUnits.empty() && rtpTime != mAccessUnitRTPTime) { 136 submitAccessUnit(); 137 } 138 mAccessUnitRTPTime = rtpTime; 139 140 mNALUnits.push_back(buffer); 141 } 142 143 bool AAVCAssembler::addSingleTimeAggregationPacket(const sp<ABuffer> &buffer) { 144 const uint8_t *data = buffer->data(); 145 size_t size = buffer->size(); 146 147 if (size < 3) { 148 ALOGV("Discarding too small STAP-A packet."); 149 return false; 150 } 151 152 ++data; 153 --size; 154 while (size >= 2) { 155 size_t nalSize = (data[0] << 8) | data[1]; 156 157 if (size < nalSize + 2) { 158 ALOGV("Discarding malformed STAP-A packet."); 159 return false; 160 } 161 162 sp<ABuffer> unit = new ABuffer(nalSize); 163 memcpy(unit->data(), &data[2], nalSize); 164 165 CopyTimes(unit, buffer); 166 167 addSingleNALUnit(unit); 168 169 data += 2 + nalSize; 170 size -= 2 + nalSize; 171 } 172 173 if (size != 0) { 174 ALOGV("Unexpected padding at end of STAP-A packet."); 175 } 176 177 return true; 178 } 179 180 ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit( 181 List<sp<ABuffer> > *queue) { 182 CHECK(!queue->empty()); 183 184 sp<ABuffer> buffer = *queue->begin(); 185 const uint8_t *data = buffer->data(); 186 size_t size = buffer->size(); 187 188 CHECK(size > 0); 189 unsigned indicator = data[0]; 190 191 CHECK((indicator & 0x1f) == 28); 192 193 if (size < 2) { 194 ALOGV("Ignoring malformed FU buffer (size = %d)", size); 195 196 queue->erase(queue->begin()); 197 ++mNextExpectedSeqNo; 198 return MALFORMED_PACKET; 199 } 200 201 if (!(data[1] & 0x80)) { 202 // Start bit not set on the first buffer. 203 204 ALOGV("Start bit not set on first buffer"); 205 206 queue->erase(queue->begin()); 207 ++mNextExpectedSeqNo; 208 return MALFORMED_PACKET; 209 } 210 211 uint32_t nalType = data[1] & 0x1f; 212 uint32_t nri = (data[0] >> 5) & 3; 213 214 uint32_t expectedSeqNo = (uint32_t)buffer->int32Data() + 1; 215 size_t totalSize = size - 2; 216 size_t totalCount = 1; 217 bool complete = false; 218 219 if (data[1] & 0x40) { 220 // Huh? End bit also set on the first buffer. 221 222 ALOGV("Grrr. This isn't fragmented at all."); 223 224 complete = true; 225 } else { 226 List<sp<ABuffer> >::iterator it = ++queue->begin(); 227 while (it != queue->end()) { 228 ALOGV("sequence length %d", totalCount); 229 230 const sp<ABuffer> &buffer = *it; 231 232 const uint8_t *data = buffer->data(); 233 size_t size = buffer->size(); 234 235 if ((uint32_t)buffer->int32Data() != expectedSeqNo) { 236 ALOGV("sequence not complete, expected seqNo %d, got %d", 237 expectedSeqNo, (uint32_t)buffer->int32Data()); 238 239 return WRONG_SEQUENCE_NUMBER; 240 } 241 242 if (size < 2 243 || data[0] != indicator 244 || (data[1] & 0x1f) != nalType 245 || (data[1] & 0x80)) { 246 ALOGV("Ignoring malformed FU buffer."); 247 248 // Delete the whole start of the FU. 249 250 it = queue->begin(); 251 for (size_t i = 0; i <= totalCount; ++i) { 252 it = queue->erase(it); 253 } 254 255 mNextExpectedSeqNo = expectedSeqNo + 1; 256 257 return MALFORMED_PACKET; 258 } 259 260 totalSize += size - 2; 261 ++totalCount; 262 263 expectedSeqNo = expectedSeqNo + 1; 264 265 if (data[1] & 0x40) { 266 // This is the last fragment. 267 complete = true; 268 break; 269 } 270 271 ++it; 272 } 273 } 274 275 if (!complete) { 276 return NOT_ENOUGH_DATA; 277 } 278 279 mNextExpectedSeqNo = expectedSeqNo; 280 281 // We found all the fragments that make up the complete NAL unit. 282 283 // Leave room for the header. So far totalSize did not include the 284 // header byte. 285 ++totalSize; 286 287 sp<ABuffer> unit = new ABuffer(totalSize); 288 CopyTimes(unit, *queue->begin()); 289 290 unit->data()[0] = (nri << 5) | nalType; 291 292 size_t offset = 1; 293 List<sp<ABuffer> >::iterator it = queue->begin(); 294 for (size_t i = 0; i < totalCount; ++i) { 295 const sp<ABuffer> &buffer = *it; 296 297 ALOGV("piece #%d/%d", i + 1, totalCount); 298 #if !LOG_NDEBUG 299 hexdump(buffer->data(), buffer->size()); 300 #endif 301 302 memcpy(unit->data() + offset, buffer->data() + 2, buffer->size() - 2); 303 offset += buffer->size() - 2; 304 305 it = queue->erase(it); 306 } 307 308 unit->setRange(0, totalSize); 309 310 addSingleNALUnit(unit); 311 312 ALOGV("successfully assembled a NAL unit from fragments."); 313 314 return OK; 315 } 316 317 void AAVCAssembler::submitAccessUnit() { 318 CHECK(!mNALUnits.empty()); 319 320 ALOGV("Access unit complete (%d nal units)", mNALUnits.size()); 321 322 size_t totalSize = 0; 323 for (List<sp<ABuffer> >::iterator it = mNALUnits.begin(); 324 it != mNALUnits.end(); ++it) { 325 totalSize += 4 + (*it)->size(); 326 } 327 328 sp<ABuffer> accessUnit = new ABuffer(totalSize); 329 size_t offset = 0; 330 for (List<sp<ABuffer> >::iterator it = mNALUnits.begin(); 331 it != mNALUnits.end(); ++it) { 332 memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4); 333 offset += 4; 334 335 sp<ABuffer> nal = *it; 336 memcpy(accessUnit->data() + offset, nal->data(), nal->size()); 337 offset += nal->size(); 338 } 339 340 CopyTimes(accessUnit, *mNALUnits.begin()); 341 342 #if 0 343 printf(mAccessUnitDamaged ? "X" : "."); 344 fflush(stdout); 345 #endif 346 347 if (mAccessUnitDamaged) { 348 accessUnit->meta()->setInt32("damaged", true); 349 } 350 351 mNALUnits.clear(); 352 mAccessUnitDamaged = false; 353 354 sp<AMessage> msg = mNotifyMsg->dup(); 355 msg->setBuffer("access-unit", accessUnit); 356 msg->post(); 357 } 358 359 ARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore( 360 const sp<ARTPSource> &source) { 361 AssemblyStatus status = addNALUnit(source); 362 if (status == MALFORMED_PACKET) { 363 mAccessUnitDamaged = true; 364 } 365 return status; 366 } 367 368 void AAVCAssembler::packetLost() { 369 CHECK(mNextExpectedSeqNoValid); 370 ALOGV("packetLost (expected %d)", mNextExpectedSeqNo); 371 372 ++mNextExpectedSeqNo; 373 374 mAccessUnitDamaged = true; 375 } 376 377 void AAVCAssembler::onByeReceived() { 378 sp<AMessage> msg = mNotifyMsg->dup(); 379 msg->setInt32("eos", true); 380 msg->post(); 381 } 382 383 } // namespace android 384