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