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 " 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 300sp<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 343sp<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 397sp<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 496int64_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 } 508 509 if (info->mLength > size) { 510 info->mLength -= size; 511 512 if (first) { 513 info->mTimestampUs = -1; 514 } 515 516 size = 0; 517 } else { 518 size -= info->mLength; 519 520 mRangeInfos.erase(mRangeInfos.begin()); 521 info = NULL; 522 } 523 524 first = false; 525 } 526 527 if (timeUs == 0ll) { 528 ALOGV("Returning 0 timestamp"); 529 } 530 531 return timeUs; 532} 533 534struct NALPosition { 535 size_t nalOffset; 536 size_t nalSize; 537}; 538 539sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() { 540 const uint8_t *data = mBuffer->data(); 541 542 size_t size = mBuffer->size(); 543 Vector<NALPosition> nals; 544 545 size_t totalSize = 0; 546 547 status_t err; 548 const uint8_t *nalStart; 549 size_t nalSize; 550 bool foundSlice = false; 551 while ((err = getNextNALUnit(&data, &size, &nalStart, &nalSize)) == OK) { 552 if (nalSize == 0) continue; 553 554 unsigned nalType = nalStart[0] & 0x1f; 555 bool flush = false; 556 557 if (nalType == 1 || nalType == 5) { 558 if (foundSlice) { 559 ABitReader br(nalStart + 1, nalSize); 560 unsigned first_mb_in_slice = parseUE(&br); 561 562 if (first_mb_in_slice == 0) { 563 // This slice starts a new frame. 564 565 flush = true; 566 } 567 } 568 569 foundSlice = true; 570 } else if ((nalType == 9 || nalType == 7) && foundSlice) { 571 // Access unit delimiter and SPS will be associated with the 572 // next frame. 573 574 flush = true; 575 } 576 577 if (flush) { 578 // The access unit will contain all nal units up to, but excluding 579 // the current one, separated by 0x00 0x00 0x00 0x01 startcodes. 580 581 size_t auSize = 4 * nals.size() + totalSize; 582 sp<ABuffer> accessUnit = new ABuffer(auSize); 583 584#if !LOG_NDEBUG 585 AString out; 586#endif 587 588 size_t dstOffset = 0; 589 for (size_t i = 0; i < nals.size(); ++i) { 590 const NALPosition &pos = nals.itemAt(i); 591 592 unsigned nalType = mBuffer->data()[pos.nalOffset] & 0x1f; 593 594#if !LOG_NDEBUG 595 char tmp[128]; 596 sprintf(tmp, "0x%02x", nalType); 597 if (i > 0) { 598 out.append(", "); 599 } 600 out.append(tmp); 601#endif 602 603 memcpy(accessUnit->data() + dstOffset, "\x00\x00\x00\x01", 4); 604 605 memcpy(accessUnit->data() + dstOffset + 4, 606 mBuffer->data() + pos.nalOffset, 607 pos.nalSize); 608 609 dstOffset += pos.nalSize + 4; 610 } 611 612 ALOGV("accessUnit contains nal types %s", out.c_str()); 613 614 const NALPosition &pos = nals.itemAt(nals.size() - 1); 615 size_t nextScan = pos.nalOffset + pos.nalSize; 616 617 memmove(mBuffer->data(), 618 mBuffer->data() + nextScan, 619 mBuffer->size() - nextScan); 620 621 mBuffer->setRange(0, mBuffer->size() - nextScan); 622 623 int64_t timeUs = fetchTimestamp(nextScan); 624 CHECK_GE(timeUs, 0ll); 625 626 accessUnit->meta()->setInt64("timeUs", timeUs); 627 628 if (mFormat == NULL) { 629 mFormat = MakeAVCCodecSpecificData(accessUnit); 630 } 631 632 return accessUnit; 633 } 634 635 NALPosition pos; 636 pos.nalOffset = nalStart - mBuffer->data(); 637 pos.nalSize = nalSize; 638 639 nals.push(pos); 640 641 totalSize += nalSize; 642 } 643 CHECK_EQ(err, (status_t)-EAGAIN); 644 645 return NULL; 646} 647 648sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGAudio() { 649 const uint8_t *data = mBuffer->data(); 650 size_t size = mBuffer->size(); 651 652 if (size < 4) { 653 return NULL; 654 } 655 656 uint32_t header = U32_AT(data); 657 658 size_t frameSize; 659 int samplingRate, numChannels, bitrate, numSamples; 660 CHECK(GetMPEGAudioFrameSize( 661 header, &frameSize, &samplingRate, &numChannels, 662 &bitrate, &numSamples)); 663 664 if (size < frameSize) { 665 return NULL; 666 } 667 668 unsigned layer = 4 - ((header >> 17) & 3); 669 670 sp<ABuffer> accessUnit = new ABuffer(frameSize); 671 memcpy(accessUnit->data(), data, frameSize); 672 673 memmove(mBuffer->data(), 674 mBuffer->data() + frameSize, 675 mBuffer->size() - frameSize); 676 677 mBuffer->setRange(0, mBuffer->size() - frameSize); 678 679 int64_t timeUs = fetchTimestamp(frameSize); 680 CHECK_GE(timeUs, 0ll); 681 682 accessUnit->meta()->setInt64("timeUs", timeUs); 683 684 if (mFormat == NULL) { 685 mFormat = new MetaData; 686 687 switch (layer) { 688 case 1: 689 mFormat->setCString( 690 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I); 691 break; 692 case 2: 693 mFormat->setCString( 694 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II); 695 break; 696 case 3: 697 mFormat->setCString( 698 kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); 699 break; 700 default: 701 TRESPASS(); 702 } 703 704 mFormat->setInt32(kKeySampleRate, samplingRate); 705 mFormat->setInt32(kKeyChannelCount, numChannels); 706 } 707 708 return accessUnit; 709} 710 711static void EncodeSize14(uint8_t **_ptr, size_t size) { 712 CHECK_LE(size, 0x3fff); 713 714 uint8_t *ptr = *_ptr; 715 716 *ptr++ = 0x80 | (size >> 7); 717 *ptr++ = size & 0x7f; 718 719 *_ptr = ptr; 720} 721 722static sp<ABuffer> MakeMPEGVideoESDS(const sp<ABuffer> &csd) { 723 sp<ABuffer> esds = new ABuffer(csd->size() + 25); 724 725 uint8_t *ptr = esds->data(); 726 *ptr++ = 0x03; 727 EncodeSize14(&ptr, 22 + csd->size()); 728 729 *ptr++ = 0x00; // ES_ID 730 *ptr++ = 0x00; 731 732 *ptr++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag 733 734 *ptr++ = 0x04; 735 EncodeSize14(&ptr, 16 + csd->size()); 736 737 *ptr++ = 0x40; // Audio ISO/IEC 14496-3 738 739 for (size_t i = 0; i < 12; ++i) { 740 *ptr++ = 0x00; 741 } 742 743 *ptr++ = 0x05; 744 EncodeSize14(&ptr, csd->size()); 745 746 memcpy(ptr, csd->data(), csd->size()); 747 748 return esds; 749} 750 751sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() { 752 const uint8_t *data = mBuffer->data(); 753 size_t size = mBuffer->size(); 754 755 bool sawPictureStart = false; 756 int pprevStartCode = -1; 757 int prevStartCode = -1; 758 int currentStartCode = -1; 759 760 size_t offset = 0; 761 while (offset + 3 < size) { 762 if (memcmp(&data[offset], "\x00\x00\x01", 3)) { 763 ++offset; 764 continue; 765 } 766 767 pprevStartCode = prevStartCode; 768 prevStartCode = currentStartCode; 769 currentStartCode = data[offset + 3]; 770 771 if (currentStartCode == 0xb3 && mFormat == NULL) { 772 memmove(mBuffer->data(), mBuffer->data() + offset, size - offset); 773 size -= offset; 774 (void)fetchTimestamp(offset); 775 offset = 0; 776 mBuffer->setRange(0, size); 777 } 778 779 if ((prevStartCode == 0xb3 && currentStartCode != 0xb5) 780 || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) { 781 // seqHeader without/with extension 782 783 if (mFormat == NULL) { 784 CHECK_GE(size, 7u); 785 786 unsigned width = 787 (data[4] << 4) | data[5] >> 4; 788 789 unsigned height = 790 ((data[5] & 0x0f) << 8) | data[6]; 791 792 mFormat = new MetaData; 793 mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2); 794 mFormat->setInt32(kKeyWidth, width); 795 mFormat->setInt32(kKeyHeight, height); 796 797 ALOGI("found MPEG2 video codec config (%d x %d)", width, height); 798 799 sp<ABuffer> csd = new ABuffer(offset); 800 memcpy(csd->data(), data, offset); 801 802 memmove(mBuffer->data(), 803 mBuffer->data() + offset, 804 mBuffer->size() - offset); 805 806 mBuffer->setRange(0, mBuffer->size() - offset); 807 size -= offset; 808 (void)fetchTimestamp(offset); 809 offset = 0; 810 811 // hexdump(csd->data(), csd->size()); 812 813 sp<ABuffer> esds = MakeMPEGVideoESDS(csd); 814 mFormat->setData( 815 kKeyESDS, kTypeESDS, esds->data(), esds->size()); 816 817 return NULL; 818 } 819 } 820 821 if (mFormat != NULL && currentStartCode == 0x00) { 822 // Picture start 823 824 if (!sawPictureStart) { 825 sawPictureStart = true; 826 } else { 827 sp<ABuffer> accessUnit = new ABuffer(offset); 828 memcpy(accessUnit->data(), data, offset); 829 830 memmove(mBuffer->data(), 831 mBuffer->data() + offset, 832 mBuffer->size() - offset); 833 834 mBuffer->setRange(0, mBuffer->size() - offset); 835 836 int64_t timeUs = fetchTimestamp(offset); 837 CHECK_GE(timeUs, 0ll); 838 839 offset = 0; 840 841 accessUnit->meta()->setInt64("timeUs", timeUs); 842 843 ALOGV("returning MPEG video access unit at time %lld us", 844 timeUs); 845 846 // hexdump(accessUnit->data(), accessUnit->size()); 847 848 return accessUnit; 849 } 850 } 851 852 ++offset; 853 } 854 855 return NULL; 856} 857 858static ssize_t getNextChunkSize( 859 const uint8_t *data, size_t size) { 860 static const char kStartCode[] = "\x00\x00\x01"; 861 862 if (size < 3) { 863 return -EAGAIN; 864 } 865 866 if (memcmp(kStartCode, data, 3)) { 867 TRESPASS(); 868 } 869 870 size_t offset = 3; 871 while (offset + 2 < size) { 872 if (!memcmp(&data[offset], kStartCode, 3)) { 873 return offset; 874 } 875 876 ++offset; 877 } 878 879 return -EAGAIN; 880} 881 882sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() { 883 uint8_t *data = mBuffer->data(); 884 size_t size = mBuffer->size(); 885 886 enum { 887 SKIP_TO_VISUAL_OBJECT_SEQ_START, 888 EXPECT_VISUAL_OBJECT_START, 889 EXPECT_VO_START, 890 EXPECT_VOL_START, 891 WAIT_FOR_VOP_START, 892 SKIP_TO_VOP_START, 893 894 } state; 895 896 if (mFormat == NULL) { 897 state = SKIP_TO_VISUAL_OBJECT_SEQ_START; 898 } else { 899 state = SKIP_TO_VOP_START; 900 } 901 902 int32_t width = -1, height = -1; 903 904 size_t offset = 0; 905 ssize_t chunkSize; 906 while ((chunkSize = getNextChunkSize( 907 &data[offset], size - offset)) > 0) { 908 bool discard = false; 909 910 unsigned chunkType = data[offset + 3]; 911 912 switch (state) { 913 case SKIP_TO_VISUAL_OBJECT_SEQ_START: 914 { 915 if (chunkType == 0xb0) { 916 // Discard anything before this marker. 917 918 state = EXPECT_VISUAL_OBJECT_START; 919 } else { 920 discard = true; 921 } 922 break; 923 } 924 925 case EXPECT_VISUAL_OBJECT_START: 926 { 927 CHECK_EQ(chunkType, 0xb5); 928 state = EXPECT_VO_START; 929 break; 930 } 931 932 case EXPECT_VO_START: 933 { 934 CHECK_LE(chunkType, 0x1f); 935 state = EXPECT_VOL_START; 936 break; 937 } 938 939 case EXPECT_VOL_START: 940 { 941 CHECK((chunkType & 0xf0) == 0x20); 942 943 CHECK(ExtractDimensionsFromVOLHeader( 944 &data[offset], chunkSize, 945 &width, &height)); 946 947 state = WAIT_FOR_VOP_START; 948 break; 949 } 950 951 case WAIT_FOR_VOP_START: 952 { 953 if (chunkType == 0xb3 || chunkType == 0xb6) { 954 // group of VOP or VOP start. 955 956 mFormat = new MetaData; 957 mFormat->setCString( 958 kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); 959 960 mFormat->setInt32(kKeyWidth, width); 961 mFormat->setInt32(kKeyHeight, height); 962 963 ALOGI("found MPEG4 video codec config (%d x %d)", 964 width, height); 965 966 sp<ABuffer> csd = new ABuffer(offset); 967 memcpy(csd->data(), data, offset); 968 969 // hexdump(csd->data(), csd->size()); 970 971 sp<ABuffer> esds = MakeMPEGVideoESDS(csd); 972 mFormat->setData( 973 kKeyESDS, kTypeESDS, 974 esds->data(), esds->size()); 975 976 discard = true; 977 state = SKIP_TO_VOP_START; 978 } 979 980 break; 981 } 982 983 case SKIP_TO_VOP_START: 984 { 985 if (chunkType == 0xb6) { 986 offset += chunkSize; 987 988 sp<ABuffer> accessUnit = new ABuffer(offset); 989 memcpy(accessUnit->data(), data, offset); 990 991 memmove(data, &data[offset], size - offset); 992 size -= offset; 993 mBuffer->setRange(0, size); 994 995 int64_t timeUs = fetchTimestamp(offset); 996 CHECK_GE(timeUs, 0ll); 997 998 offset = 0; 999 1000 accessUnit->meta()->setInt64("timeUs", timeUs); 1001 1002 ALOGV("returning MPEG4 video access unit at time %lld us", 1003 timeUs); 1004 1005 // hexdump(accessUnit->data(), accessUnit->size()); 1006 1007 return accessUnit; 1008 } else if (chunkType != 0xb3) { 1009 offset += chunkSize; 1010 discard = true; 1011 } 1012 1013 break; 1014 } 1015 1016 default: 1017 TRESPASS(); 1018 } 1019 1020 if (discard) { 1021 (void)fetchTimestamp(offset); 1022 memmove(data, &data[offset], size - offset); 1023 size -= offset; 1024 offset = 0; 1025 mBuffer->setRange(0, size); 1026 } else { 1027 offset += chunkSize; 1028 } 1029 } 1030 1031 return NULL; 1032} 1033 1034} // namespace android 1035