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