Home | History | Annotate | Download | only in mpeg2ts
      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