AMPEG4AudioAssembler.cpp revision df64d15042bbd5e0e4933ac49bf3c177dd94752c
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 "AMPEG4AudioAssembler" 19 20#include "AMPEG4AudioAssembler.h" 21 22#include "ARTPSource.h" 23 24#include <media/stagefright/foundation/hexdump.h> 25#include <media/stagefright/foundation/ABitReader.h> 26#include <media/stagefright/foundation/ABuffer.h> 27#include <media/stagefright/foundation/ADebug.h> 28#include <media/stagefright/foundation/AMessage.h> 29#include <media/stagefright/MediaErrors.h> 30 31#include <ctype.h> 32 33namespace android { 34 35static bool GetAttribute(const char *s, const char *key, AString *value) { 36 value->clear(); 37 38 size_t keyLen = strlen(key); 39 40 for (;;) { 41 while (isspace(*s)) { 42 ++s; 43 } 44 45 const char *colonPos = strchr(s, ';'); 46 47 size_t len = 48 (colonPos == NULL) ? strlen(s) : colonPos - s; 49 50 if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) { 51 value->setTo(&s[keyLen + 1], len - keyLen - 1); 52 return true; 53 } 54 55 if (colonPos == NULL) { 56 return false; 57 } 58 59 s = colonPos + 1; 60 } 61} 62 63static sp<ABuffer> decodeHex(const AString &s) { 64 if ((s.size() % 2) != 0) { 65 return NULL; 66 } 67 68 size_t outLen = s.size() / 2; 69 sp<ABuffer> buffer = new ABuffer(outLen); 70 uint8_t *out = buffer->data(); 71 72 uint8_t accum = 0; 73 for (size_t i = 0; i < s.size(); ++i) { 74 char c = s.c_str()[i]; 75 unsigned value; 76 if (c >= '0' && c <= '9') { 77 value = c - '0'; 78 } else if (c >= 'a' && c <= 'f') { 79 value = c - 'a' + 10; 80 } else if (c >= 'A' && c <= 'F') { 81 value = c - 'A' + 10; 82 } else { 83 return NULL; 84 } 85 86 accum = (accum << 4) | value; 87 88 if (i & 1) { 89 *out++ = accum; 90 91 accum = 0; 92 } 93 } 94 95 return buffer; 96} 97 98static status_t parseAudioObjectType( 99 ABitReader *bits, unsigned *audioObjectType) { 100 *audioObjectType = bits->getBits(5); 101 if ((*audioObjectType) == 31) { 102 *audioObjectType = 32 + bits->getBits(6); 103 } 104 105 return OK; 106} 107 108static status_t parseGASpecificConfig( 109 ABitReader *bits, 110 unsigned audioObjectType, unsigned channelConfiguration) { 111 unsigned frameLengthFlag = bits->getBits(1); 112 unsigned dependsOnCoreCoder = bits->getBits(1); 113 if (dependsOnCoreCoder) { 114 /* unsigned coreCoderDelay = */bits->getBits(1); 115 } 116 unsigned extensionFlag = bits->getBits(1); 117 118 if (!channelConfiguration) { 119 // program_config_element 120 return ERROR_UNSUPPORTED; // XXX to be implemented 121 } 122 123 if (audioObjectType == 6 || audioObjectType == 20) { 124 /* unsigned layerNr = */bits->getBits(3); 125 } 126 127 if (extensionFlag) { 128 if (audioObjectType == 22) { 129 /* unsigned numOfSubFrame = */bits->getBits(5); 130 /* unsigned layerLength = */bits->getBits(11); 131 } else if (audioObjectType == 17 || audioObjectType == 19 132 || audioObjectType == 20 || audioObjectType == 23) { 133 /* unsigned aacSectionDataResilienceFlag = */bits->getBits(1); 134 /* unsigned aacScalefactorDataResilienceFlag = */bits->getBits(1); 135 /* unsigned aacSpectralDataResilienceFlag = */bits->getBits(1); 136 } 137 138 unsigned extensionFlag3 = bits->getBits(1); 139 CHECK_EQ(extensionFlag3, 0u); // TBD in version 3 140 } 141 142 return OK; 143} 144 145static status_t parseAudioSpecificConfig(ABitReader *bits, sp<ABuffer> *asc) { 146 const uint8_t *dataStart = bits->data(); 147 size_t totalNumBits = bits->numBitsLeft(); 148 149 unsigned audioObjectType; 150 CHECK_EQ(parseAudioObjectType(bits, &audioObjectType), (status_t)OK); 151 152 unsigned samplingFreqIndex = bits->getBits(4); 153 if (samplingFreqIndex == 0x0f) { 154 /* unsigned samplingFrequency = */bits->getBits(24); 155 } 156 157 unsigned channelConfiguration = bits->getBits(4); 158 159 unsigned extensionAudioObjectType = 0; 160 unsigned sbrPresent = 0; 161 162 if (audioObjectType == 5) { 163 extensionAudioObjectType = audioObjectType; 164 sbrPresent = 1; 165 unsigned extensionSamplingFreqIndex = bits->getBits(4); 166 if (extensionSamplingFreqIndex == 0x0f) { 167 /* unsigned extensionSamplingFrequency = */bits->getBits(24); 168 } 169 CHECK_EQ(parseAudioObjectType(bits, &audioObjectType), (status_t)OK); 170 } 171 172 CHECK((audioObjectType >= 1 && audioObjectType <= 4) 173 || (audioObjectType >= 6 && audioObjectType <= 7) 174 || audioObjectType == 17 175 || (audioObjectType >= 19 && audioObjectType <= 23)); 176 177 CHECK_EQ(parseGASpecificConfig( 178 bits, audioObjectType, channelConfiguration), (status_t)OK); 179 180 if (audioObjectType == 17 181 || (audioObjectType >= 19 && audioObjectType <= 27)) { 182 unsigned epConfig = bits->getBits(2); 183 if (epConfig == 2 || epConfig == 3) { 184 // ErrorProtectionSpecificConfig 185 return ERROR_UNSUPPORTED; // XXX to be implemented 186 187 if (epConfig == 3) { 188 unsigned directMapping = bits->getBits(1); 189 CHECK_EQ(directMapping, 1u); 190 } 191 } 192 } 193 194 if (extensionAudioObjectType != 5 && bits->numBitsLeft() >= 16) { 195 size_t numBitsLeftAtStart = bits->numBitsLeft(); 196 197 unsigned syncExtensionType = bits->getBits(11); 198 if (syncExtensionType == 0x2b7) { 199 ALOGI("found syncExtension"); 200 201 CHECK_EQ(parseAudioObjectType(bits, &extensionAudioObjectType), 202 (status_t)OK); 203 204 sbrPresent = bits->getBits(1); 205 206 if (sbrPresent == 1) { 207 unsigned extensionSamplingFreqIndex = bits->getBits(4); 208 if (extensionSamplingFreqIndex == 0x0f) { 209 /* unsigned extensionSamplingFrequency = */bits->getBits(24); 210 } 211 } 212 213 size_t numBitsInExtension = 214 numBitsLeftAtStart - bits->numBitsLeft(); 215 216 if (numBitsInExtension & 7) { 217 // Apparently an extension is always considered an even 218 // multiple of 8 bits long. 219 220 ALOGI("Skipping %d bits after sync extension", 221 8 - (numBitsInExtension & 7)); 222 223 bits->skipBits(8 - (numBitsInExtension & 7)); 224 } 225 } else { 226 bits->putBits(syncExtensionType, 11); 227 } 228 } 229 230 if (asc != NULL) { 231 size_t bitpos = totalNumBits & 7; 232 233 ABitReader bs(dataStart, (totalNumBits + 7) / 8); 234 235 totalNumBits -= bits->numBitsLeft(); 236 237 size_t numBytes = (totalNumBits + 7) / 8; 238 239 *asc = new ABuffer(numBytes); 240 241 if (bitpos & 7) { 242 bs.skipBits(8 - (bitpos & 7)); 243 } 244 245 uint8_t *dstPtr = (*asc)->data(); 246 while (numBytes > 0) { 247 *dstPtr++ = bs.getBits(8); 248 --numBytes; 249 } 250 } 251 252 return OK; 253} 254 255static status_t parseStreamMuxConfig( 256 ABitReader *bits, 257 unsigned *numSubFrames, 258 unsigned *frameLengthType, 259 ssize_t *fixedFrameLength, 260 bool *otherDataPresent, 261 unsigned *otherDataLenBits) { 262 unsigned audioMuxVersion = bits->getBits(1); 263 264 unsigned audioMuxVersionA = 0; 265 if (audioMuxVersion == 1) { 266 audioMuxVersionA = bits->getBits(1); 267 } 268 269 CHECK_EQ(audioMuxVersionA, 0u); // otherwise future spec 270 271 if (audioMuxVersion != 0) { 272 return ERROR_UNSUPPORTED; // XXX to be implemented; 273 } 274 CHECK_EQ(audioMuxVersion, 0u); // XXX to be implemented 275 276 unsigned allStreamsSameTimeFraming = bits->getBits(1); 277 CHECK_EQ(allStreamsSameTimeFraming, 1u); // There's only one stream. 278 279 *numSubFrames = bits->getBits(6); 280 unsigned numProgram = bits->getBits(4); 281 CHECK_EQ(numProgram, 0u); // disabled in RTP LATM 282 283 unsigned numLayer = bits->getBits(3); 284 CHECK_EQ(numLayer, 0u); // disabled in RTP LATM 285 286 if (audioMuxVersion == 0) { 287 // AudioSpecificConfig 288 CHECK_EQ(parseAudioSpecificConfig(bits, NULL /* asc */), (status_t)OK); 289 } else { 290 TRESPASS(); // XXX to be implemented 291 } 292 293 *frameLengthType = bits->getBits(3); 294 *fixedFrameLength = -1; 295 296 switch (*frameLengthType) { 297 case 0: 298 { 299 /* unsigned bufferFullness = */bits->getBits(8); 300 301 // The "coreFrameOffset" does not apply since there's only 302 // a single layer. 303 break; 304 } 305 306 case 1: 307 { 308 *fixedFrameLength = bits->getBits(9); 309 break; 310 } 311 312 case 2: 313 { 314 // reserved 315 TRESPASS(); 316 break; 317 } 318 319 case 3: 320 case 4: 321 case 5: 322 { 323 /* unsigned CELPframeLengthTableIndex = */bits->getBits(6); 324 break; 325 } 326 327 case 6: 328 case 7: 329 { 330 /* unsigned HVXCframeLengthTableIndex = */bits->getBits(1); 331 break; 332 } 333 334 default: 335 break; 336 } 337 338 *otherDataPresent = bits->getBits(1); 339 *otherDataLenBits = 0; 340 if (*otherDataPresent) { 341 if (audioMuxVersion == 1) { 342 TRESPASS(); // XXX to be implemented 343 } else { 344 *otherDataLenBits = 0; 345 346 unsigned otherDataLenEsc; 347 do { 348 (*otherDataLenBits) <<= 8; 349 otherDataLenEsc = bits->getBits(1); 350 unsigned otherDataLenTmp = bits->getBits(8); 351 (*otherDataLenBits) += otherDataLenTmp; 352 } while (otherDataLenEsc); 353 } 354 } 355 356 unsigned crcCheckPresent = bits->getBits(1); 357 if (crcCheckPresent) { 358 /* unsigned crcCheckSum = */bits->getBits(8); 359 } 360 361 return OK; 362} 363 364sp<ABuffer> AMPEG4AudioAssembler::removeLATMFraming(const sp<ABuffer> &buffer) { 365 CHECK(!mMuxConfigPresent); // XXX to be implemented 366 367 sp<ABuffer> out = new ABuffer(buffer->size()); 368 out->setRange(0, 0); 369 370 size_t offset = 0; 371 uint8_t *ptr = buffer->data(); 372 373 for (size_t i = 0; i <= mNumSubFrames; ++i) { 374 // parse PayloadLengthInfo 375 376 unsigned payloadLength = 0; 377 378 switch (mFrameLengthType) { 379 case 0: 380 { 381 unsigned muxSlotLengthBytes = 0; 382 unsigned tmp; 383 do { 384 CHECK_LT(offset, buffer->size()); 385 tmp = ptr[offset++]; 386 muxSlotLengthBytes += tmp; 387 } while (tmp == 0xff); 388 389 payloadLength = muxSlotLengthBytes; 390 break; 391 } 392 393 case 2: 394 { 395 // reserved 396 397 TRESPASS(); 398 break; 399 } 400 401 default: 402 { 403 CHECK_GE(mFixedFrameLength, 0); 404 405 payloadLength = mFixedFrameLength; 406 break; 407 } 408 } 409 410 CHECK_LE(offset + payloadLength, buffer->size()); 411 412 memcpy(out->data() + out->size(), &ptr[offset], payloadLength); 413 out->setRange(0, out->size() + payloadLength); 414 415 offset += payloadLength; 416 417 if (mOtherDataPresent) { 418 // We want to stay byte-aligned. 419 420 CHECK((mOtherDataLenBits % 8) == 0); 421 CHECK_LE(offset + (mOtherDataLenBits / 8), buffer->size()); 422 offset += mOtherDataLenBits / 8; 423 } 424 } 425 426 if (offset < buffer->size()) { 427 ALOGI("ignoring %d bytes of trailing data", buffer->size() - offset); 428 } 429 CHECK_LE(offset, buffer->size()); 430 431 return out; 432} 433 434AMPEG4AudioAssembler::AMPEG4AudioAssembler( 435 const sp<AMessage> ¬ify, const AString ¶ms) 436 : mNotifyMsg(notify), 437 mMuxConfigPresent(false), 438 mAccessUnitRTPTime(0), 439 mNextExpectedSeqNoValid(false), 440 mNextExpectedSeqNo(0), 441 mAccessUnitDamaged(false) { 442 AString val; 443 if (!GetAttribute(params.c_str(), "cpresent", &val)) { 444 mMuxConfigPresent = true; 445 } else if (val == "0") { 446 mMuxConfigPresent = false; 447 } else { 448 CHECK(val == "1"); 449 mMuxConfigPresent = true; 450 } 451 452 CHECK(GetAttribute(params.c_str(), "config", &val)); 453 454 sp<ABuffer> config = decodeHex(val); 455 CHECK(config != NULL); 456 457 ABitReader bits(config->data(), config->size()); 458 status_t err = parseStreamMuxConfig( 459 &bits, &mNumSubFrames, &mFrameLengthType, 460 &mFixedFrameLength, 461 &mOtherDataPresent, &mOtherDataLenBits); 462 463 CHECK_EQ(err, (status_t)NO_ERROR); 464} 465 466AMPEG4AudioAssembler::~AMPEG4AudioAssembler() { 467} 468 469ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::assembleMore( 470 const sp<ARTPSource> &source) { 471 AssemblyStatus status = addPacket(source); 472 if (status == MALFORMED_PACKET) { 473 mAccessUnitDamaged = true; 474 } 475 return status; 476} 477 478ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::addPacket( 479 const sp<ARTPSource> &source) { 480 List<sp<ABuffer> > *queue = source->queue(); 481 482 if (queue->empty()) { 483 return NOT_ENOUGH_DATA; 484 } 485 486 if (mNextExpectedSeqNoValid) { 487 List<sp<ABuffer> >::iterator it = queue->begin(); 488 while (it != queue->end()) { 489 if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) { 490 break; 491 } 492 493 it = queue->erase(it); 494 } 495 496 if (queue->empty()) { 497 return NOT_ENOUGH_DATA; 498 } 499 } 500 501 sp<ABuffer> buffer = *queue->begin(); 502 503 if (!mNextExpectedSeqNoValid) { 504 mNextExpectedSeqNoValid = true; 505 mNextExpectedSeqNo = (uint32_t)buffer->int32Data(); 506 } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) { 507#if VERBOSE 508 LOG(VERBOSE) << "Not the sequence number I expected"; 509#endif 510 511 return WRONG_SEQUENCE_NUMBER; 512 } 513 514 uint32_t rtpTime; 515 CHECK(buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)); 516 517 if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) { 518 submitAccessUnit(); 519 } 520 mAccessUnitRTPTime = rtpTime; 521 522 mPackets.push_back(buffer); 523 524 queue->erase(queue->begin()); 525 ++mNextExpectedSeqNo; 526 527 return OK; 528} 529 530void AMPEG4AudioAssembler::submitAccessUnit() { 531 CHECK(!mPackets.empty()); 532 533#if VERBOSE 534 LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)"; 535#endif 536 537 size_t totalSize = 0; 538 List<sp<ABuffer> >::iterator it = mPackets.begin(); 539 while (it != mPackets.end()) { 540 const sp<ABuffer> &unit = *it; 541 542 totalSize += unit->size(); 543 ++it; 544 } 545 546 sp<ABuffer> accessUnit = new ABuffer(totalSize); 547 size_t offset = 0; 548 it = mPackets.begin(); 549 while (it != mPackets.end()) { 550 const sp<ABuffer> &unit = *it; 551 552 memcpy((uint8_t *)accessUnit->data() + offset, 553 unit->data(), unit->size()); 554 555 ++it; 556 } 557 558 accessUnit = removeLATMFraming(accessUnit); 559 CopyTimes(accessUnit, *mPackets.begin()); 560 561#if 0 562 printf(mAccessUnitDamaged ? "X" : "."); 563 fflush(stdout); 564#endif 565 566 if (mAccessUnitDamaged) { 567 accessUnit->meta()->setInt32("damaged", true); 568 } 569 570 mPackets.clear(); 571 mAccessUnitDamaged = false; 572 573 sp<AMessage> msg = mNotifyMsg->dup(); 574 msg->setObject("access-unit", accessUnit); 575 msg->post(); 576} 577 578void AMPEG4AudioAssembler::packetLost() { 579 CHECK(mNextExpectedSeqNoValid); 580 ++mNextExpectedSeqNo; 581 582 mAccessUnitDamaged = true; 583} 584 585void AMPEG4AudioAssembler::onByeReceived() { 586 sp<AMessage> msg = mNotifyMsg->dup(); 587 msg->setInt32("eos", true); 588 msg->post(); 589} 590 591} // namespace android 592