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 "ESQueue" 19 #include <media/stagefright/foundation/ADebug.h> 20 21 #include "ESQueue.h" 22 23 #include <media/stagefright/foundation/hexdump.h> 24 #include <media/stagefright/foundation/ABitReader.h> 25 #include <media/stagefright/foundation/ABuffer.h> 26 #include <media/stagefright/foundation/AMessage.h> 27 #include <media/stagefright/MediaErrors.h> 28 #include <media/stagefright/MediaDefs.h> 29 #include <media/stagefright/MetaData.h> 30 #include <media/stagefright/Utils.h> 31 32 #include "include/avc_utils.h" 33 34 #include <netinet/in.h> 35 36 namespace android { 37 38 ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags) 39 : mMode(mode), 40 mFlags(flags) { 41 } 42 43 sp<MetaData> ElementaryStreamQueue::getFormat() { 44 return mFormat; 45 } 46 47 void ElementaryStreamQueue::clear(bool clearFormat) { 48 if (mBuffer != NULL) { 49 mBuffer->setRange(0, 0); 50 } 51 52 mRangeInfos.clear(); 53 54 if (clearFormat) { 55 mFormat.clear(); 56 } 57 } 58 59 static bool IsSeeminglyValidADTSHeader(const uint8_t *ptr, size_t size) { 60 if (size < 3) { 61 // Not enough data to verify header. 62 return false; 63 } 64 65 if (ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) { 66 return false; 67 } 68 69 unsigned layer = (ptr[1] >> 1) & 3; 70 71 if (layer != 0) { 72 return false; 73 } 74 75 unsigned ID = (ptr[1] >> 3) & 1; 76 unsigned profile_ObjectType = ptr[2] >> 6; 77 78 if (ID == 1 && profile_ObjectType == 3) { 79 // MPEG-2 profile 3 is reserved. 80 return false; 81 } 82 83 return true; 84 } 85 86 static bool IsSeeminglyValidMPEGAudioHeader(const uint8_t *ptr, size_t size) { 87 if (size < 3) { 88 // Not enough data to verify header. 89 return false; 90 } 91 92 if (ptr[0] != 0xff || (ptr[1] >> 5) != 0x07) { 93 return false; 94 } 95 96 unsigned ID = (ptr[1] >> 3) & 3; 97 98 if (ID == 1) { 99 return false; // reserved 100 } 101 102 unsigned layer = (ptr[1] >> 1) & 3; 103 104 if (layer == 0) { 105 return false; // reserved 106 } 107 108 unsigned bitrateIndex = (ptr[2] >> 4); 109 110 if (bitrateIndex == 0x0f) { 111 return false; // reserved 112 } 113 114 unsigned samplingRateIndex = (ptr[2] >> 2) & 3; 115 116 if (samplingRateIndex == 3) { 117 return false; // reserved 118 } 119 120 return true; 121 } 122 123 status_t ElementaryStreamQueue::appendData( 124 const void *data, size_t size, int64_t timeUs) { 125 if (mBuffer == NULL || mBuffer->size() == 0) { 126 switch (mMode) { 127 case H264: 128 case MPEG_VIDEO: 129 { 130 #if 0 131 if (size < 4 || memcmp("\x00\x00\x00\x01", data, 4)) { 132 return ERROR_MALFORMED; 133 } 134 #else 135 uint8_t *ptr = (uint8_t *)data; 136 137 ssize_t startOffset = -1; 138 for (size_t i = 0; i + 3 < size; ++i) { 139 if (!memcmp("\x00\x00\x00\x01", &ptr[i], 4)) { 140 startOffset = i; 141 break; 142 } 143 } 144 145 if (startOffset < 0) { 146 return ERROR_MALFORMED; 147 } 148 149 if (startOffset > 0) { 150 ALOGI("found something resembling an H.264/MPEG syncword " 151 "at offset %d", 152 startOffset); 153 } 154 155 data = &ptr[startOffset]; 156 size -= startOffset; 157 #endif 158 break; 159 } 160 161 case MPEG4_VIDEO: 162 { 163 #if 0 164 if (size < 3 || memcmp("\x00\x00\x01", data, 3)) { 165 return ERROR_MALFORMED; 166 } 167 #else 168 uint8_t *ptr = (uint8_t *)data; 169 170 ssize_t startOffset = -1; 171 for (size_t i = 0; i + 2 < size; ++i) { 172 if (!memcmp("\x00\x00\x01", &ptr[i], 3)) { 173 startOffset = i; 174 break; 175 } 176 } 177 178 if (startOffset < 0) { 179 return ERROR_MALFORMED; 180 } 181 182 if (startOffset > 0) { 183 ALOGI("found something resembling an H.264/MPEG syncword " 184 "at offset %d", 185 startOffset); 186 } 187 188 data = &ptr[startOffset]; 189 size -= startOffset; 190 #endif 191 break; 192 } 193 194 case AAC: 195 { 196 uint8_t *ptr = (uint8_t *)data; 197 198 #if 0 199 if (size < 2 || ptr[0] != 0xff || (ptr[1] >> 4) != 0x0f) { 200 return ERROR_MALFORMED; 201 } 202 #else 203 ssize_t startOffset = -1; 204 for (size_t i = 0; i < size; ++i) { 205 if (IsSeeminglyValidADTSHeader(&ptr[i], size - i)) { 206 startOffset = i; 207 break; 208 } 209 } 210 211 if (startOffset < 0) { 212 return ERROR_MALFORMED; 213 } 214 215 if (startOffset > 0) { 216 ALOGI("found something resembling an AAC syncword at " 217 "offset %d", 218 startOffset); 219 } 220 221 data = &ptr[startOffset]; 222 size -= startOffset; 223 #endif 224 break; 225 } 226 227 case MPEG_AUDIO: 228 { 229 uint8_t *ptr = (uint8_t *)data; 230 231 ssize_t startOffset = -1; 232 for (size_t i = 0; i < size; ++i) { 233 if (IsSeeminglyValidMPEGAudioHeader(&ptr[i], size - i)) { 234 startOffset = i; 235 break; 236 } 237 } 238 239 if (startOffset < 0) { 240 return ERROR_MALFORMED; 241 } 242 243 if (startOffset > 0) { 244 ALOGI("found something resembling an MPEG audio " 245 "syncword at offset %d", 246 startOffset); 247 } 248 249 data = &ptr[startOffset]; 250 size -= startOffset; 251 break; 252 } 253 254 case PCM_AUDIO: 255 { 256 break; 257 } 258 259 default: 260 TRESPASS(); 261 break; 262 } 263 } 264 265 size_t neededSize = (mBuffer == NULL ? 0 : mBuffer->size()) + size; 266 if (mBuffer == NULL || neededSize > mBuffer->capacity()) { 267 neededSize = (neededSize + 65535) & ~65535; 268 269 ALOGV("resizing buffer to size %d", neededSize); 270 271 sp<ABuffer> buffer = new ABuffer(neededSize); 272 if (mBuffer != NULL) { 273 memcpy(buffer->data(), mBuffer->data(), mBuffer->size()); 274 buffer->setRange(0, mBuffer->size()); 275 } else { 276 buffer->setRange(0, 0); 277 } 278 279 mBuffer = buffer; 280 } 281 282 memcpy(mBuffer->data() + mBuffer->size(), data, size); 283 mBuffer->setRange(0, mBuffer->size() + size); 284 285 RangeInfo info; 286 info.mLength = size; 287 info.mTimestampUs = timeUs; 288 mRangeInfos.push_back(info); 289 290 #if 0 291 if (mMode == AAC) { 292 ALOGI("size = %d, timeUs = %.2f secs", size, timeUs / 1E6); 293 hexdump(data, size); 294 } 295 #endif 296 297 return OK; 298 } 299 300 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnit() { 301 if ((mFlags & kFlag_AlignedData) && mMode == H264) { 302 if (mRangeInfos.empty()) { 303 return NULL; 304 } 305 306 RangeInfo info = *mRangeInfos.begin(); 307 mRangeInfos.erase(mRangeInfos.begin()); 308 309 sp<ABuffer> accessUnit = new ABuffer(info.mLength); 310 memcpy(accessUnit->data(), mBuffer->data(), info.mLength); 311 accessUnit->meta()->setInt64("timeUs", info.mTimestampUs); 312 313 memmove(mBuffer->data(), 314 mBuffer->data() + info.mLength, 315 mBuffer->size() - info.mLength); 316 317 mBuffer->setRange(0, mBuffer->size() - info.mLength); 318 319 if (mFormat == NULL) { 320 mFormat = MakeAVCCodecSpecificData(accessUnit); 321 } 322 323 return accessUnit; 324 } 325 326 switch (mMode) { 327 case H264: 328 return dequeueAccessUnitH264(); 329 case AAC: 330 return dequeueAccessUnitAAC(); 331 case MPEG_VIDEO: 332 return dequeueAccessUnitMPEGVideo(); 333 case MPEG4_VIDEO: 334 return dequeueAccessUnitMPEG4Video(); 335 case PCM_AUDIO: 336 return dequeueAccessUnitPCMAudio(); 337 default: 338 CHECK_EQ((unsigned)mMode, (unsigned)MPEG_AUDIO); 339 return dequeueAccessUnitMPEGAudio(); 340 } 341 } 342 343 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitPCMAudio() { 344 if (mBuffer->size() < 4) { 345 return NULL; 346 } 347 348 ABitReader bits(mBuffer->data(), 4); 349 CHECK_EQ(bits.getBits(8), 0xa0); 350 unsigned numAUs = bits.getBits(8); 351 bits.skipBits(8); 352 unsigned quantization_word_length = bits.getBits(2); 353 unsigned audio_sampling_frequency = bits.getBits(3); 354 unsigned num_channels = bits.getBits(3); 355 356 CHECK_EQ(audio_sampling_frequency, 2); // 48kHz 357 CHECK_EQ(num_channels, 1u); // stereo! 358 359 if (mFormat == NULL) { 360 mFormat = new MetaData; 361 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); 362 mFormat->setInt32(kKeyChannelCount, 2); 363 mFormat->setInt32(kKeySampleRate, 48000); 364 } 365 366 static const size_t kFramesPerAU = 80; 367 size_t frameSize = 2 /* numChannels */ * sizeof(int16_t); 368 369 size_t payloadSize = numAUs * frameSize * kFramesPerAU; 370 371 if (mBuffer->size() < 4 + payloadSize) { 372 return NULL; 373 } 374 375 sp<ABuffer> accessUnit = new ABuffer(payloadSize); 376 memcpy(accessUnit->data(), mBuffer->data() + 4, payloadSize); 377 378 int64_t timeUs = fetchTimestamp(payloadSize + 4); 379 CHECK_GE(timeUs, 0ll); 380 accessUnit->meta()->setInt64("timeUs", timeUs); 381 382 int16_t *ptr = (int16_t *)accessUnit->data(); 383 for (size_t i = 0; i < payloadSize / sizeof(int16_t); ++i) { 384 ptr[i] = ntohs(ptr[i]); 385 } 386 387 memmove( 388 mBuffer->data(), 389 mBuffer->data() + 4 + payloadSize, 390 mBuffer->size() - 4 - payloadSize); 391 392 mBuffer->setRange(0, mBuffer->size() - 4 - payloadSize); 393 394 return accessUnit; 395 } 396 397 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitAAC() { 398 if (mBuffer->size() == 0) { 399 return NULL; 400 } 401 402 CHECK(!mRangeInfos.empty()); 403 404 const RangeInfo &info = *mRangeInfos.begin(); 405 if (mBuffer->size() < info.mLength) { 406 return NULL; 407 } 408 409 CHECK_GE(info.mTimestampUs, 0ll); 410 411 // The idea here is consume all AAC frames starting at offsets before 412 // info.mLength so we can assign a meaningful timestamp without 413 // having to interpolate. 414 // The final AAC frame may well extend into the next RangeInfo but 415 // that's ok. 416 size_t offset = 0; 417 while (offset < info.mLength) { 418 if (offset + 7 > mBuffer->size()) { 419 return NULL; 420 } 421 422 ABitReader bits(mBuffer->data() + offset, mBuffer->size() - offset); 423 424 // adts_fixed_header 425 426 CHECK_EQ(bits.getBits(12), 0xfffu); 427 bits.skipBits(3); // ID, layer 428 bool protection_absent = bits.getBits(1) != 0; 429 430 if (mFormat == NULL) { 431 unsigned profile = bits.getBits(2); 432 CHECK_NE(profile, 3u); 433 unsigned sampling_freq_index = bits.getBits(4); 434 bits.getBits(1); // private_bit 435 unsigned channel_configuration = bits.getBits(3); 436 CHECK_NE(channel_configuration, 0u); 437 bits.skipBits(2); // original_copy, home 438 439 mFormat = MakeAACCodecSpecificData( 440 profile, sampling_freq_index, channel_configuration); 441 442 mFormat->setInt32(kKeyIsADTS, true); 443 444 int32_t sampleRate; 445 int32_t numChannels; 446 CHECK(mFormat->findInt32(kKeySampleRate, &sampleRate)); 447 CHECK(mFormat->findInt32(kKeyChannelCount, &numChannels)); 448 449 ALOGI("found AAC codec config (%d Hz, %d channels)", 450 sampleRate, numChannels); 451 } else { 452 // profile_ObjectType, sampling_frequency_index, private_bits, 453 // channel_configuration, original_copy, home 454 bits.skipBits(12); 455 } 456 457 // adts_variable_header 458 459 // copyright_identification_bit, copyright_identification_start 460 bits.skipBits(2); 461 462 unsigned aac_frame_length = bits.getBits(13); 463 464 bits.skipBits(11); // adts_buffer_fullness 465 466 unsigned number_of_raw_data_blocks_in_frame = bits.getBits(2); 467 468 if (number_of_raw_data_blocks_in_frame != 0) { 469 // To be implemented. 470 TRESPASS(); 471 } 472 473 if (offset + aac_frame_length > mBuffer->size()) { 474 return NULL; 475 } 476 477 size_t headerSize = protection_absent ? 7 : 9; 478 479 offset += aac_frame_length; 480 } 481 482 int64_t timeUs = fetchTimestamp(offset); 483 484 sp<ABuffer> accessUnit = new ABuffer(offset); 485 memcpy(accessUnit->data(), mBuffer->data(), offset); 486 487 memmove(mBuffer->data(), mBuffer->data() + offset, 488 mBuffer->size() - offset); 489 mBuffer->setRange(0, mBuffer->size() - offset); 490 491 accessUnit->meta()->setInt64("timeUs", timeUs); 492 493 return accessUnit; 494 } 495 496 int64_t ElementaryStreamQueue::fetchTimestamp(size_t size) { 497 int64_t timeUs = -1; 498 bool first = true; 499 500 while (size > 0) { 501 CHECK(!mRangeInfos.empty()); 502 503 RangeInfo *info = &*mRangeInfos.begin(); 504 505 if (first) { 506 timeUs = info->mTimestampUs; 507 first = false; 508 } 509 510 if (info->mLength > size) { 511 info->mLength -= size; 512 size = 0; 513 } else { 514 size -= info->mLength; 515 516 mRangeInfos.erase(mRangeInfos.begin()); 517 info = NULL; 518 } 519 520 } 521 522 if (timeUs == 0ll) { 523 ALOGV("Returning 0 timestamp"); 524 } 525 526 return timeUs; 527 } 528 529 struct NALPosition { 530 size_t nalOffset; 531 size_t nalSize; 532 }; 533 534 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() { 535 const uint8_t *data = mBuffer->data(); 536 537 size_t size = mBuffer->size(); 538 Vector<NALPosition> nals; 539 540 size_t totalSize = 0; 541 542 status_t err; 543 const uint8_t *nalStart; 544 size_t nalSize; 545 bool foundSlice = false; 546 while ((err = getNextNALUnit(&data, &size, &nalStart, &nalSize)) == OK) { 547 if (nalSize == 0) continue; 548 549 unsigned nalType = nalStart[0] & 0x1f; 550 bool flush = false; 551 552 if (nalType == 1 || nalType == 5) { 553 if (foundSlice) { 554 ABitReader br(nalStart + 1, nalSize); 555 unsigned first_mb_in_slice = parseUE(&br); 556 557 if (first_mb_in_slice == 0) { 558 // This slice starts a new frame. 559 560 flush = true; 561 } 562 } 563 564 foundSlice = true; 565 } else if ((nalType == 9 || nalType == 7) && foundSlice) { 566 // Access unit delimiter and SPS will be associated with the 567 // next frame. 568 569 flush = true; 570 } 571 572 if (flush) { 573 // The access unit will contain all nal units up to, but excluding 574 // the current one, separated by 0x00 0x00 0x00 0x01 startcodes. 575 576 size_t auSize = 4 * nals.size() + totalSize; 577 sp<ABuffer> accessUnit = new ABuffer(auSize); 578 579 #if !LOG_NDEBUG 580 AString out; 581 #endif 582 583 size_t dstOffset = 0; 584 for (size_t i = 0; i < nals.size(); ++i) { 585 const NALPosition &pos = nals.itemAt(i); 586 587 unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f; 588 589 #if !LOG_NDEBUG 590 char tmp[128]; 591 sprintf(tmp, "0x%02x", nalType); 592 if (i > 0) { 593 out.append(", "); 594 } 595 out.append(tmp); 596 #endif 597 598 memcpy(accessUnit->data() + dstOffset, "\x00\x00\x00\x01", 4); 599 600 memcpy(accessUnit->data() + dstOffset + 4, 601 mBuffer->data() + pos.nalOffset, 602 pos.nalSize); 603 604 dstOffset += pos.nalSize + 4; 605 } 606 607 ALOGV("accessUnit contains nal types %s", out.c_str()); 608 609 const NALPosition &pos = nals.itemAt(nals.size() - 1); 610 size_t nextScan = pos.nalOffset + pos.nalSize; 611 612 memmove(mBuffer->data(), 613 mBuffer->data() + nextScan, 614 mBuffer->size() - nextScan); 615 616 mBuffer->setRange(0, mBuffer->size() - nextScan); 617 618 int64_t timeUs = fetchTimestamp(nextScan); 619 CHECK_GE(timeUs, 0ll); 620 621 accessUnit->meta()->setInt64("timeUs", timeUs); 622 623 if (mFormat == NULL) { 624 mFormat = MakeAVCCodecSpecificData(accessUnit); 625 } 626 627 return accessUnit; 628 } 629 630 NALPosition pos; 631 pos.nalOffset = nalStart - mBuffer->data(); 632 pos.nalSize = nalSize; 633 634 nals.push(pos); 635 636 totalSize += nalSize; 637 } 638 CHECK_EQ(err, (status_t)-EAGAIN); 639 640 return NULL; 641 } 642 643 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() { 644 const uint8_t *data = mBuffer->data(); 645 size_t size = mBuffer->size(); 646 647 if (size < 4) { 648 return NULL; 649 } 650 651 uint32_t header = U32_AT(data); 652 653 size_t frameSize; 654 int samplingRate, numChannels, bitrate, numSamples; 655 CHECK(GetMPEGAudioFrameSize( 656 header, &frameSize, &samplingRate, &numChannels, 657 &bitrate, &numSamples)); 658 659 if (size < frameSize) { 660 return NULL; 661 } 662 663 unsigned layer = 4 - ((header >> 17) & 3); 664 665 sp<ABuffer> accessUnit = new ABuffer(frameSize); 666 memcpy(accessUnit->data(), data, frameSize); 667 668 memmove(mBuffer->data(), 669 mBuffer->data() + frameSize, 670 mBuffer->size() - frameSize); 671 672 mBuffer->setRange(0, mBuffer->size() - frameSize); 673 674 int64_t timeUs = fetchTimestamp(frameSize); 675 CHECK_GE(timeUs, 0ll); 676 677 accessUnit->meta()->setInt64("timeUs", timeUs); 678 679 if (mFormat == NULL) { 680 mFormat = new MetaData; 681 682 switch (layer) { 683 case 1: 684 mFormat->setCString( 685 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I); 686 break; 687 case 2: 688 mFormat->setCString( 689 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II); 690 break; 691 case 3: 692 mFormat->setCString( 693 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 694 break; 695 default: 696 TRESPASS(); 697 } 698 699 mFormat->setInt32(kKeySampleRate, samplingRate); 700 mFormat->setInt32(kKeyChannelCount, numChannels); 701 } 702 703 return accessUnit; 704 } 705 706 static void EncodeSize14(uint8_t **_ptr, size_t size) { 707 CHECK_LE(size, 0x3fff); 708 709 uint8_t *ptr = *_ptr; 710 711 *ptr++ = 0x80 | (size >> 7); 712 *ptr++ = size & 0x7f; 713 714 *_ptr = ptr; 715 } 716 717 static sp<ABuffer> MakeMPEGVideoESDS(const sp<ABuffer> &csd) { 718 sp<ABuffer> esds = new ABuffer(csd->size() + 25); 719 720 uint8_t *ptr = esds->data(); 721 *ptr++ = 0x03; 722 EncodeSize14(&ptr, 22 + csd->size()); 723 724 *ptr++ = 0x00; // ES_ID 725 *ptr++ = 0x00; 726 727 *ptr++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 728 729 *ptr++ = 0x04; 730 EncodeSize14(&ptr, 16 + csd->size()); 731 732 *ptr++ = 0x40; // Audio ISO/IEC 14496-3 733 734 for (size_t i = 0; i < 12; ++i) { 735 *ptr++ = 0x00; 736 } 737 738 *ptr++ = 0x05; 739 EncodeSize14(&ptr, csd->size()); 740 741 memcpy(ptr, csd->data(), csd->size()); 742 743 return esds; 744 } 745 746 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() { 747 const uint8_t *data = mBuffer->data(); 748 size_t size = mBuffer->size(); 749 750 bool sawPictureStart = false; 751 int pprevStartCode = -1; 752 int prevStartCode = -1; 753 int currentStartCode = -1; 754 755 size_t offset = 0; 756 while (offset + 3 < size) { 757 if (memcmp(&data[offset], "\x00\x00\x01", 3)) { 758 ++offset; 759 continue; 760 } 761 762 pprevStartCode = prevStartCode; 763 prevStartCode = currentStartCode; 764 currentStartCode = data[offset + 3]; 765 766 if (currentStartCode == 0xb3 && mFormat == NULL) { 767 memmove(mBuffer->data(), mBuffer->data() + offset, size - offset); 768 size -= offset; 769 (void)fetchTimestamp(offset); 770 offset = 0; 771 mBuffer->setRange(0, size); 772 } 773 774 if ((prevStartCode == 0xb3 && currentStartCode != 0xb5) 775 || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) { 776 // seqHeader without/with extension 777 778 if (mFormat == NULL) { 779 CHECK_GE(size, 7u); 780 781 unsigned width = 782 (data[4] << 4) | data[5] >> 4; 783 784 unsigned height = 785 ((data[5] & 0x0f) << 8) | data[6]; 786 787 mFormat = new MetaData; 788 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); 789 mFormat->setInt32(kKeyWidth, width); 790 mFormat->setInt32(kKeyHeight, height); 791 792 ALOGI("found MPEG2 video codec config (%d x %d)", width, height); 793 794 sp<ABuffer> csd = new ABuffer(offset); 795 memcpy(csd->data(), data, offset); 796 797 memmove(mBuffer->data(), 798 mBuffer->data() + offset, 799 mBuffer->size() - offset); 800 801 mBuffer->setRange(0, mBuffer->size() - offset); 802 size -= offset; 803 (void)fetchTimestamp(offset); 804 offset = 0; 805 806 // hexdump(csd->data(), csd->size()); 807 808 sp<ABuffer> esds = MakeMPEGVideoESDS(csd); 809 mFormat->setData( 810 kKeyESDS, kTypeESDS, esds->data(), esds->size()); 811 812 return NULL; 813 } 814 } 815 816 if (mFormat != NULL && currentStartCode == 0x00) { 817 // Picture start 818 819 if (!sawPictureStart) { 820 sawPictureStart = true; 821 } else { 822 sp<ABuffer> accessUnit = new ABuffer(offset); 823 memcpy(accessUnit->data(), data, offset); 824 825 memmove(mBuffer->data(), 826 mBuffer->data() + offset, 827 mBuffer->size() - offset); 828 829 mBuffer->setRange(0, mBuffer->size() - offset); 830 831 int64_t timeUs = fetchTimestamp(offset); 832 CHECK_GE(timeUs, 0ll); 833 834 offset = 0; 835 836 accessUnit->meta()->setInt64("timeUs", timeUs); 837 838 ALOGV("returning MPEG video access unit at time %lld us", 839 timeUs); 840 841 // hexdump(accessUnit->data(), accessUnit->size()); 842 843 return accessUnit; 844 } 845 } 846 847 ++offset; 848 } 849 850 return NULL; 851 } 852 853 static ssize_t getNextChunkSize( 854 const uint8_t *data, size_t size) { 855 static const char kStartCode[] = "\x00\x00\x01"; 856 857 if (size < 3) { 858 return -EAGAIN; 859 } 860 861 if (memcmp(kStartCode, data, 3)) { 862 TRESPASS(); 863 } 864 865 size_t offset = 3; 866 while (offset + 2 < size) { 867 if (!memcmp(&data[offset], kStartCode, 3)) { 868 return offset; 869 } 870 871 ++offset; 872 } 873 874 return -EAGAIN; 875 } 876 877 sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() { 878 uint8_t *data = mBuffer->data(); 879 size_t size = mBuffer->size(); 880 881 enum { 882 SKIP_TO_VISUAL_OBJECT_SEQ_START, 883 EXPECT_VISUAL_OBJECT_START, 884 EXPECT_VO_START, 885 EXPECT_VOL_START, 886 WAIT_FOR_VOP_START, 887 SKIP_TO_VOP_START, 888 889 } state; 890 891 if (mFormat == NULL) { 892 state = SKIP_TO_VISUAL_OBJECT_SEQ_START; 893 } else { 894 state = SKIP_TO_VOP_START; 895 } 896 897 int32_t width = -1, height = -1; 898 899 size_t offset = 0; 900 ssize_t chunkSize; 901 while ((chunkSize = getNextChunkSize( 902 &data[offset], size - offset)) > 0) { 903 bool discard = false; 904 905 unsigned chunkType = data[offset + 3]; 906 907 switch (state) { 908 case SKIP_TO_VISUAL_OBJECT_SEQ_START: 909 { 910 if (chunkType == 0xb0) { 911 // Discard anything before this marker. 912 913 state = EXPECT_VISUAL_OBJECT_START; 914 } else { 915 discard = true; 916 } 917 break; 918 } 919 920 case EXPECT_VISUAL_OBJECT_START: 921 { 922 CHECK_EQ(chunkType, 0xb5); 923 state = EXPECT_VO_START; 924 break; 925 } 926 927 case EXPECT_VO_START: 928 { 929 CHECK_LE(chunkType, 0x1f); 930 state = EXPECT_VOL_START; 931 break; 932 } 933 934 case EXPECT_VOL_START: 935 { 936 CHECK((chunkType & 0xf0) == 0x20); 937 938 CHECK(ExtractDimensionsFromVOLHeader( 939 &data[offset], chunkSize, 940 &width, &height)); 941 942 state = WAIT_FOR_VOP_START; 943 break; 944 } 945 946 case WAIT_FOR_VOP_START: 947 { 948 if (chunkType == 0xb3 || chunkType == 0xb6) { 949 // group of VOP or VOP start. 950 951 mFormat = new MetaData; 952 mFormat->setCString( 953 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 954 955 mFormat->setInt32(kKeyWidth, width); 956 mFormat->setInt32(kKeyHeight, height); 957 958 ALOGI("found MPEG4 video codec config (%d x %d)", 959 width, height); 960 961 sp<ABuffer> csd = new ABuffer(offset); 962 memcpy(csd->data(), data, offset); 963 964 // hexdump(csd->data(), csd->size()); 965 966 sp<ABuffer> esds = MakeMPEGVideoESDS(csd); 967 mFormat->setData( 968 kKeyESDS, kTypeESDS, 969 esds->data(), esds->size()); 970 971 discard = true; 972 state = SKIP_TO_VOP_START; 973 } 974 975 break; 976 } 977 978 case SKIP_TO_VOP_START: 979 { 980 if (chunkType == 0xb6) { 981 offset += chunkSize; 982 983 sp<ABuffer> accessUnit = new ABuffer(offset); 984 memcpy(accessUnit->data(), data, offset); 985 986 memmove(data, &data[offset], size - offset); 987 size -= offset; 988 mBuffer->setRange(0, size); 989 990 int64_t timeUs = fetchTimestamp(offset); 991 CHECK_GE(timeUs, 0ll); 992 993 offset = 0; 994 995 accessUnit->meta()->setInt64("timeUs", timeUs); 996 997 ALOGV("returning MPEG4 video access unit at time %lld us", 998 timeUs); 999 1000 // hexdump(accessUnit->data(), accessUnit->size()); 1001 1002 return accessUnit; 1003 } else if (chunkType != 0xb3) { 1004 offset += chunkSize; 1005 discard = true; 1006 } 1007 1008 break; 1009 } 1010 1011 default: 1012 TRESPASS(); 1013 } 1014 1015 if (discard) { 1016 (void)fetchTimestamp(offset); 1017 memmove(data, &data[offset], size - offset); 1018 size -= offset; 1019 offset = 0; 1020 mBuffer->setRange(0, size); 1021 } else { 1022 offset += chunkSize; 1023 } 1024 } 1025 1026 return NULL; 1027 } 1028 1029 } // namespace android 1030