Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2011 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 "AVIExtractor"
     19 #include <utils/Log.h>
     20 
     21 #include "include/avc_utils.h"
     22 #include "include/AVIExtractor.h"
     23 
     24 #include <binder/ProcessState.h>
     25 #include <media/stagefright/foundation/hexdump.h>
     26 #include <media/stagefright/foundation/ABuffer.h>
     27 #include <media/stagefright/foundation/ADebug.h>
     28 #include <media/stagefright/DataSource.h>
     29 #include <media/stagefright/MediaBuffer.h>
     30 #include <media/stagefright/MediaBufferGroup.h>
     31 #include <media/stagefright/MediaDefs.h>
     32 #include <media/stagefright/MediaErrors.h>
     33 #include <media/stagefright/MetaData.h>
     34 #include <media/stagefright/Utils.h>
     35 
     36 namespace android {
     37 
     38 struct AVIExtractor::AVISource : public MediaSource {
     39     AVISource(const sp<AVIExtractor> &extractor, size_t trackIndex);
     40 
     41     virtual status_t start(MetaData *params);
     42     virtual status_t stop();
     43 
     44     virtual sp<MetaData> getFormat();
     45 
     46     virtual status_t read(
     47             MediaBuffer **buffer, const ReadOptions *options);
     48 
     49 protected:
     50     virtual ~AVISource();
     51 
     52 private:
     53     sp<AVIExtractor> mExtractor;
     54     size_t mTrackIndex;
     55     const AVIExtractor::Track &mTrack;
     56     MediaBufferGroup *mBufferGroup;
     57     size_t mSampleIndex;
     58 
     59     sp<MP3Splitter> mSplitter;
     60 
     61     DISALLOW_EVIL_CONSTRUCTORS(AVISource);
     62 };
     63 
     64 ////////////////////////////////////////////////////////////////////////////////
     65 
     66 struct AVIExtractor::MP3Splitter : public RefBase {
     67     MP3Splitter();
     68 
     69     void clear();
     70     void append(MediaBuffer *buffer);
     71     status_t read(MediaBuffer **buffer);
     72 
     73 protected:
     74     virtual ~MP3Splitter();
     75 
     76 private:
     77     bool mFindSync;
     78     int64_t mBaseTimeUs;
     79     int64_t mNumSamplesRead;
     80     sp<ABuffer> mBuffer;
     81 
     82     bool resync();
     83 
     84     DISALLOW_EVIL_CONSTRUCTORS(MP3Splitter);
     85 };
     86 
     87 ////////////////////////////////////////////////////////////////////////////////
     88 
     89 AVIExtractor::AVISource::AVISource(
     90         const sp<AVIExtractor> &extractor, size_t trackIndex)
     91     : mExtractor(extractor),
     92       mTrackIndex(trackIndex),
     93       mTrack(mExtractor->mTracks.itemAt(trackIndex)),
     94       mBufferGroup(NULL) {
     95 }
     96 
     97 AVIExtractor::AVISource::~AVISource() {
     98     if (mBufferGroup) {
     99         stop();
    100     }
    101 }
    102 
    103 status_t AVIExtractor::AVISource::start(MetaData *params) {
    104     CHECK(!mBufferGroup);
    105 
    106     mBufferGroup = new MediaBufferGroup;
    107 
    108     mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize));
    109     mBufferGroup->add_buffer(new MediaBuffer(mTrack.mMaxSampleSize));
    110     mSampleIndex = 0;
    111 
    112     const char *mime;
    113     CHECK(mTrack.mMeta->findCString(kKeyMIMEType, &mime));
    114 
    115     if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
    116         mSplitter = new MP3Splitter;
    117     } else {
    118         mSplitter.clear();
    119     }
    120 
    121     return OK;
    122 }
    123 
    124 status_t AVIExtractor::AVISource::stop() {
    125     CHECK(mBufferGroup);
    126 
    127     delete mBufferGroup;
    128     mBufferGroup = NULL;
    129 
    130     mSplitter.clear();
    131 
    132     return OK;
    133 }
    134 
    135 sp<MetaData> AVIExtractor::AVISource::getFormat() {
    136     return mTrack.mMeta;
    137 }
    138 
    139 status_t AVIExtractor::AVISource::read(
    140         MediaBuffer **buffer, const ReadOptions *options) {
    141     CHECK(mBufferGroup);
    142 
    143     *buffer = NULL;
    144 
    145     int64_t seekTimeUs;
    146     ReadOptions::SeekMode seekMode;
    147     if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
    148         status_t err =
    149             mExtractor->getSampleIndexAtTime(
    150                     mTrackIndex, seekTimeUs, seekMode, &mSampleIndex);
    151 
    152         if (err != OK) {
    153             return ERROR_END_OF_STREAM;
    154         }
    155 
    156         if (mSplitter != NULL) {
    157             mSplitter->clear();
    158         }
    159     }
    160 
    161     for (;;) {
    162         if (mSplitter != NULL) {
    163             status_t err = mSplitter->read(buffer);
    164 
    165             if (err == OK) {
    166                 break;
    167             } else if (err != -EAGAIN) {
    168                 return err;
    169             }
    170         }
    171 
    172         off64_t offset;
    173         size_t size;
    174         bool isKey;
    175         int64_t timeUs;
    176         status_t err = mExtractor->getSampleInfo(
    177                 mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs);
    178 
    179         ++mSampleIndex;
    180 
    181         if (err != OK) {
    182             return ERROR_END_OF_STREAM;
    183         }
    184 
    185         MediaBuffer *out;
    186         CHECK_EQ(mBufferGroup->acquire_buffer(&out), (status_t)OK);
    187 
    188         ssize_t n = mExtractor->mDataSource->readAt(offset, out->data(), size);
    189 
    190         if (n < (ssize_t)size) {
    191             return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
    192         }
    193 
    194         out->set_range(0, size);
    195 
    196         out->meta_data()->setInt64(kKeyTime, timeUs);
    197 
    198         if (isKey) {
    199             out->meta_data()->setInt32(kKeyIsSyncFrame, 1);
    200         }
    201 
    202         if (mSplitter == NULL) {
    203             *buffer = out;
    204             break;
    205         }
    206 
    207         mSplitter->append(out);
    208         out->release();
    209         out = NULL;
    210     }
    211 
    212     return OK;
    213 }
    214 
    215 ////////////////////////////////////////////////////////////////////////////////
    216 
    217 AVIExtractor::MP3Splitter::MP3Splitter()
    218     : mFindSync(true),
    219       mBaseTimeUs(-1ll),
    220       mNumSamplesRead(0) {
    221 }
    222 
    223 AVIExtractor::MP3Splitter::~MP3Splitter() {
    224 }
    225 
    226 void AVIExtractor::MP3Splitter::clear() {
    227     mFindSync = true;
    228     mBaseTimeUs = -1ll;
    229     mNumSamplesRead = 0;
    230 
    231     if (mBuffer != NULL) {
    232         mBuffer->setRange(0, 0);
    233     }
    234 }
    235 
    236 void AVIExtractor::MP3Splitter::append(MediaBuffer *buffer) {
    237     size_t prevCapacity = (mBuffer != NULL) ? mBuffer->capacity() : 0;
    238 
    239     if (mBaseTimeUs < 0) {
    240         CHECK(mBuffer == NULL || mBuffer->size() == 0);
    241         CHECK(buffer->meta_data()->findInt64(kKeyTime, &mBaseTimeUs));
    242         mNumSamplesRead = 0;
    243     }
    244 
    245     if (mBuffer != NULL && mBuffer->offset() > 0) {
    246         memmove(mBuffer->base(), mBuffer->data(), mBuffer->size());
    247         mBuffer->setRange(0, mBuffer->size());
    248     }
    249 
    250     if (mBuffer == NULL
    251             || mBuffer->size() + buffer->range_length() > prevCapacity) {
    252         size_t newCapacity =
    253             (prevCapacity + buffer->range_length() + 1023) & ~1023;
    254 
    255         sp<ABuffer> newBuffer = new ABuffer(newCapacity);
    256         if (mBuffer != NULL) {
    257             memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
    258             newBuffer->setRange(0, mBuffer->size());
    259         } else {
    260             newBuffer->setRange(0, 0);
    261         }
    262         mBuffer = newBuffer;
    263     }
    264 
    265     memcpy(mBuffer->data() + mBuffer->size(),
    266            (const uint8_t *)buffer->data() + buffer->range_offset(),
    267            buffer->range_length());
    268 
    269     mBuffer->setRange(0, mBuffer->size() + buffer->range_length());
    270 }
    271 
    272 bool AVIExtractor::MP3Splitter::resync() {
    273     if (mBuffer == NULL) {
    274         return false;
    275     }
    276 
    277     bool foundSync = false;
    278     for (size_t offset = 0; offset + 3 < mBuffer->size(); ++offset) {
    279         uint32_t firstHeader = U32_AT(mBuffer->data() + offset);
    280 
    281         size_t frameSize;
    282         if (!GetMPEGAudioFrameSize(firstHeader, &frameSize)) {
    283             continue;
    284         }
    285 
    286         size_t subsequentOffset = offset + frameSize;
    287         size_t i = 3;
    288         while (i > 0) {
    289             if (subsequentOffset + 3 >= mBuffer->size()) {
    290                 break;
    291             }
    292 
    293             static const uint32_t kMask = 0xfffe0c00;
    294 
    295             uint32_t header = U32_AT(mBuffer->data() + subsequentOffset);
    296             if ((header & kMask) != (firstHeader & kMask)) {
    297                 break;
    298             }
    299 
    300             if (!GetMPEGAudioFrameSize(header, &frameSize)) {
    301                 break;
    302             }
    303 
    304             subsequentOffset += frameSize;
    305             --i;
    306         }
    307 
    308         if (i == 0) {
    309             foundSync = true;
    310             memmove(mBuffer->data(),
    311                     mBuffer->data() + offset,
    312                     mBuffer->size() - offset);
    313 
    314             mBuffer->setRange(0, mBuffer->size() - offset);
    315             break;
    316         }
    317     }
    318 
    319     return foundSync;
    320 }
    321 
    322 status_t AVIExtractor::MP3Splitter::read(MediaBuffer **out) {
    323     *out = NULL;
    324 
    325     if (mFindSync) {
    326         if (!resync()) {
    327             return -EAGAIN;
    328         }
    329 
    330         mFindSync = false;
    331     }
    332 
    333     if (mBuffer->size() < 4) {
    334         return -EAGAIN;
    335     }
    336 
    337     uint32_t header = U32_AT(mBuffer->data());
    338     size_t frameSize;
    339     int sampleRate;
    340     int numSamples;
    341     if (!GetMPEGAudioFrameSize(
    342                 header, &frameSize, &sampleRate, NULL, NULL, &numSamples)) {
    343         return ERROR_MALFORMED;
    344     }
    345 
    346     if (mBuffer->size() < frameSize) {
    347         return -EAGAIN;
    348     }
    349 
    350     MediaBuffer *mbuf = new MediaBuffer(frameSize);
    351     memcpy(mbuf->data(), mBuffer->data(), frameSize);
    352 
    353     int64_t timeUs = mBaseTimeUs + (mNumSamplesRead * 1000000ll) / sampleRate;
    354     mNumSamplesRead += numSamples;
    355 
    356     mbuf->meta_data()->setInt64(kKeyTime, timeUs);
    357 
    358     mBuffer->setRange(
    359             mBuffer->offset() + frameSize, mBuffer->size() - frameSize);
    360 
    361     *out = mbuf;
    362 
    363     return OK;
    364 }
    365 
    366 ////////////////////////////////////////////////////////////////////////////////
    367 
    368 AVIExtractor::AVIExtractor(const sp<DataSource> &dataSource)
    369     : mDataSource(dataSource) {
    370     mInitCheck = parseHeaders();
    371 
    372     if (mInitCheck != OK) {
    373         mTracks.clear();
    374     }
    375 }
    376 
    377 AVIExtractor::~AVIExtractor() {
    378 }
    379 
    380 size_t AVIExtractor::countTracks() {
    381     return mTracks.size();
    382 }
    383 
    384 sp<MediaSource> AVIExtractor::getTrack(size_t index) {
    385     return index < mTracks.size() ? new AVISource(this, index) : NULL;
    386 }
    387 
    388 sp<MetaData> AVIExtractor::getTrackMetaData(
    389         size_t index, uint32_t flags) {
    390     return index < mTracks.size() ? mTracks.editItemAt(index).mMeta : NULL;
    391 }
    392 
    393 sp<MetaData> AVIExtractor::getMetaData() {
    394     sp<MetaData> meta = new MetaData;
    395 
    396     if (mInitCheck == OK) {
    397         meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_AVI);
    398     }
    399 
    400     return meta;
    401 }
    402 
    403 status_t AVIExtractor::parseHeaders() {
    404     mTracks.clear();
    405     mMovieOffset = 0;
    406     mFoundIndex = false;
    407     mOffsetsAreAbsolute = false;
    408 
    409     ssize_t res = parseChunk(0ll, -1ll);
    410 
    411     if (res < 0) {
    412         return (status_t)res;
    413     }
    414 
    415     if (mMovieOffset == 0ll || !mFoundIndex) {
    416         return ERROR_MALFORMED;
    417     }
    418 
    419     return OK;
    420 }
    421 
    422 ssize_t AVIExtractor::parseChunk(off64_t offset, off64_t size, int depth) {
    423     if (size >= 0 && size < 8) {
    424         return ERROR_MALFORMED;
    425     }
    426 
    427     uint8_t tmp[12];
    428     ssize_t n = mDataSource->readAt(offset, tmp, 8);
    429 
    430     if (n < 8) {
    431         return (n < 0) ? n : (ssize_t)ERROR_MALFORMED;
    432     }
    433 
    434     uint32_t fourcc = U32_AT(tmp);
    435     uint32_t chunkSize = U32LE_AT(&tmp[4]);
    436 
    437     if (size >= 0 && chunkSize + 8 > size) {
    438         return ERROR_MALFORMED;
    439     }
    440 
    441     static const char kPrefix[] = "                              ";
    442     const char *prefix = &kPrefix[strlen(kPrefix) - 2 * depth];
    443 
    444     if (fourcc == FOURCC('L', 'I', 'S', 'T')
    445             || fourcc == FOURCC('R', 'I', 'F', 'F')) {
    446         // It's a list of chunks
    447 
    448         if (size >= 0 && size < 12) {
    449             return ERROR_MALFORMED;
    450         }
    451 
    452         n = mDataSource->readAt(offset + 8, &tmp[8], 4);
    453 
    454         if (n < 4) {
    455             return (n < 0) ? n : (ssize_t)ERROR_MALFORMED;
    456         }
    457 
    458         uint32_t subFourcc = U32_AT(&tmp[8]);
    459 
    460         LOGV("%s offset 0x%08llx LIST of '%c%c%c%c', size %d",
    461              prefix,
    462              offset,
    463              (char)(subFourcc >> 24),
    464              (char)((subFourcc >> 16) & 0xff),
    465              (char)((subFourcc >> 8) & 0xff),
    466              (char)(subFourcc & 0xff),
    467              chunkSize - 4);
    468 
    469         if (subFourcc == FOURCC('m', 'o', 'v', 'i')) {
    470             // We're not going to parse this, but will take note of the
    471             // offset.
    472 
    473             mMovieOffset = offset;
    474         } else {
    475             off64_t subOffset = offset + 12;
    476             off64_t subOffsetLimit = subOffset + chunkSize - 4;
    477             while (subOffset < subOffsetLimit) {
    478                 ssize_t res =
    479                     parseChunk(subOffset, subOffsetLimit - subOffset, depth + 1);
    480 
    481                 if (res < 0) {
    482                     return res;
    483                 }
    484 
    485                 subOffset += res;
    486             }
    487         }
    488     } else {
    489         LOGV("%s offset 0x%08llx CHUNK '%c%c%c%c'",
    490              prefix,
    491              offset,
    492              (char)(fourcc >> 24),
    493              (char)((fourcc >> 16) & 0xff),
    494              (char)((fourcc >> 8) & 0xff),
    495              (char)(fourcc & 0xff));
    496 
    497         status_t err = OK;
    498 
    499         switch (fourcc) {
    500             case FOURCC('s', 't', 'r', 'h'):
    501             {
    502                 err = parseStreamHeader(offset + 8, chunkSize);
    503                 break;
    504             }
    505 
    506             case FOURCC('s', 't', 'r', 'f'):
    507             {
    508                 err = parseStreamFormat(offset + 8, chunkSize);
    509                 break;
    510             }
    511 
    512             case FOURCC('i', 'd', 'x', '1'):
    513             {
    514                 err = parseIndex(offset + 8, chunkSize);
    515                 break;
    516             }
    517 
    518             default:
    519                 break;
    520         }
    521 
    522         if (err != OK) {
    523             return err;
    524         }
    525     }
    526 
    527     if (chunkSize & 1) {
    528         ++chunkSize;
    529     }
    530 
    531     return chunkSize + 8;
    532 }
    533 
    534 static const char *GetMIMETypeForHandler(uint32_t handler) {
    535     switch (handler) {
    536         // Wow... shamelessly copied from
    537         // http://wiki.multimedia.cx/index.php?title=ISO_MPEG-4
    538 
    539         case FOURCC('3', 'I', 'V', '2'):
    540         case FOURCC('3', 'i', 'v', '2'):
    541         case FOURCC('B', 'L', 'Z', '0'):
    542         case FOURCC('D', 'I', 'G', 'I'):
    543         case FOURCC('D', 'I', 'V', '1'):
    544         case FOURCC('d', 'i', 'v', '1'):
    545         case FOURCC('D', 'I', 'V', 'X'):
    546         case FOURCC('d', 'i', 'v', 'x'):
    547         case FOURCC('D', 'X', '5', '0'):
    548         case FOURCC('d', 'x', '5', '0'):
    549         case FOURCC('D', 'X', 'G', 'M'):
    550         case FOURCC('E', 'M', '4', 'A'):
    551         case FOURCC('E', 'P', 'H', 'V'):
    552         case FOURCC('F', 'M', 'P', '4'):
    553         case FOURCC('f', 'm', 'p', '4'):
    554         case FOURCC('F', 'V', 'F', 'W'):
    555         case FOURCC('H', 'D', 'X', '4'):
    556         case FOURCC('h', 'd', 'x', '4'):
    557         case FOURCC('M', '4', 'C', 'C'):
    558         case FOURCC('M', '4', 'S', '2'):
    559         case FOURCC('m', '4', 's', '2'):
    560         case FOURCC('M', 'P', '4', 'S'):
    561         case FOURCC('m', 'p', '4', 's'):
    562         case FOURCC('M', 'P', '4', 'V'):
    563         case FOURCC('m', 'p', '4', 'v'):
    564         case FOURCC('M', 'V', 'X', 'M'):
    565         case FOURCC('R', 'M', 'P', '4'):
    566         case FOURCC('S', 'E', 'D', 'G'):
    567         case FOURCC('S', 'M', 'P', '4'):
    568         case FOURCC('U', 'M', 'P', '4'):
    569         case FOURCC('W', 'V', '1', 'F'):
    570         case FOURCC('X', 'V', 'I', 'D'):
    571         case FOURCC('X', 'v', 'i', 'D'):
    572         case FOURCC('x', 'v', 'i', 'd'):
    573         case FOURCC('X', 'V', 'I', 'X'):
    574             return MEDIA_MIMETYPE_VIDEO_MPEG4;
    575 
    576         // from http://wiki.multimedia.cx/index.php?title=H264
    577         case FOURCC('a', 'v', 'c', '1'):
    578         case FOURCC('d', 'a', 'v', 'c'):
    579         case FOURCC('x', '2', '6', '4'):
    580         case FOURCC('v', 's', 's', 'h'):
    581             return MEDIA_MIMETYPE_VIDEO_AVC;
    582 
    583         default:
    584             return NULL;
    585     }
    586 }
    587 
    588 status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
    589     if (size != 56) {
    590         return ERROR_MALFORMED;
    591     }
    592 
    593     if (mTracks.size() > 99) {
    594         return -ERANGE;
    595     }
    596 
    597     sp<ABuffer> buffer = new ABuffer(size);
    598     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
    599 
    600     if (n < (ssize_t)size) {
    601         return n < 0 ? (status_t)n : ERROR_MALFORMED;
    602     }
    603 
    604     const uint8_t *data = buffer->data();
    605 
    606     uint32_t type = U32_AT(data);
    607     uint32_t handler = U32_AT(&data[4]);
    608     uint32_t flags = U32LE_AT(&data[8]);
    609 
    610     sp<MetaData> meta = new MetaData;
    611 
    612     uint32_t rate = U32LE_AT(&data[20]);
    613     uint32_t scale = U32LE_AT(&data[24]);
    614 
    615     uint32_t sampleSize = U32LE_AT(&data[44]);
    616 
    617     const char *mime = NULL;
    618     Track::Kind kind = Track::OTHER;
    619 
    620     if (type == FOURCC('v', 'i', 'd', 's')) {
    621         mime = GetMIMETypeForHandler(handler);
    622 
    623         if (mime && strncasecmp(mime, "video/", 6)) {
    624             return ERROR_MALFORMED;
    625         }
    626 
    627         if (mime == NULL) {
    628             LOGW("Unsupported video format '%c%c%c%c'",
    629                  (char)(handler >> 24),
    630                  (char)((handler >> 16) & 0xff),
    631                  (char)((handler >> 8) & 0xff),
    632                  (char)(handler & 0xff));
    633         }
    634 
    635         kind = Track::VIDEO;
    636     } else if (type == FOURCC('a', 'u', 'd', 's')) {
    637         if (mime && strncasecmp(mime, "audio/", 6)) {
    638             return ERROR_MALFORMED;
    639         }
    640 
    641         kind = Track::AUDIO;
    642     }
    643 
    644     if (!mime) {
    645         mime = "application/octet-stream";
    646     }
    647 
    648     meta->setCString(kKeyMIMEType, mime);
    649 
    650     mTracks.push();
    651     Track *track = &mTracks.editItemAt(mTracks.size() - 1);
    652 
    653     track->mMeta = meta;
    654     track->mRate = rate;
    655     track->mScale = scale;
    656     track->mBytesPerSample = sampleSize;
    657     track->mKind = kind;
    658     track->mNumSyncSamples = 0;
    659     track->mThumbnailSampleSize = 0;
    660     track->mThumbnailSampleIndex = -1;
    661     track->mMaxSampleSize = 0;
    662     track->mAvgChunkSize = 1.0;
    663     track->mFirstChunkSize = 0;
    664 
    665     return OK;
    666 }
    667 
    668 status_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) {
    669     if (mTracks.isEmpty()) {
    670         return ERROR_MALFORMED;
    671     }
    672 
    673     Track *track = &mTracks.editItemAt(mTracks.size() - 1);
    674 
    675     if (track->mKind == Track::OTHER) {
    676         // We don't support this content, but that's not a parsing error.
    677         return OK;
    678     }
    679 
    680     bool isVideo = (track->mKind == Track::VIDEO);
    681 
    682     if ((isVideo && size < 40) || (!isVideo && size < 16)) {
    683         // Expected a BITMAPINFO or WAVEFORMAT(EX) structure, respectively.
    684         return ERROR_MALFORMED;
    685     }
    686 
    687     sp<ABuffer> buffer = new ABuffer(size);
    688     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
    689 
    690     if (n < (ssize_t)size) {
    691         return n < 0 ? (status_t)n : ERROR_MALFORMED;
    692     }
    693 
    694     const uint8_t *data = buffer->data();
    695 
    696     if (isVideo) {
    697         uint32_t width = U32LE_AT(&data[4]);
    698         uint32_t height = U32LE_AT(&data[8]);
    699 
    700         track->mMeta->setInt32(kKeyWidth, width);
    701         track->mMeta->setInt32(kKeyHeight, height);
    702     } else {
    703         uint32_t format = U16LE_AT(data);
    704 
    705         if (format == 0x55) {
    706             track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
    707         } else {
    708             LOGW("Unsupported audio format = 0x%04x", format);
    709         }
    710 
    711         uint32_t numChannels = U16LE_AT(&data[2]);
    712         uint32_t sampleRate = U32LE_AT(&data[4]);
    713 
    714         track->mMeta->setInt32(kKeyChannelCount, numChannels);
    715         track->mMeta->setInt32(kKeySampleRate, sampleRate);
    716     }
    717 
    718     return OK;
    719 }
    720 
    721 // static
    722 bool AVIExtractor::IsCorrectChunkType(
    723         ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) {
    724     uint32_t chunkBase = chunkType & 0xffff;
    725 
    726     switch (kind) {
    727         case Track::VIDEO:
    728         {
    729             if (chunkBase != FOURCC(0, 0, 'd', 'c')
    730                     && chunkBase != FOURCC(0, 0, 'd', 'b')) {
    731                 return false;
    732             }
    733             break;
    734         }
    735 
    736         case Track::AUDIO:
    737         {
    738             if (chunkBase != FOURCC(0, 0, 'w', 'b')) {
    739                 return false;
    740             }
    741             break;
    742         }
    743 
    744         default:
    745             break;
    746     }
    747 
    748     if (trackIndex < 0) {
    749         return true;
    750     }
    751 
    752     uint8_t hi = chunkType >> 24;
    753     uint8_t lo = (chunkType >> 16) & 0xff;
    754 
    755     if (hi < '0' || hi > '9' || lo < '0' || lo > '9') {
    756         return false;
    757     }
    758 
    759     if (trackIndex != (10 * (hi - '0') + (lo - '0'))) {
    760         return false;
    761     }
    762 
    763     return true;
    764 }
    765 
    766 status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
    767     if ((size % 16) != 0) {
    768         return ERROR_MALFORMED;
    769     }
    770 
    771     sp<ABuffer> buffer = new ABuffer(size);
    772     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
    773 
    774     if (n < (ssize_t)size) {
    775         return n < 0 ? (status_t)n : ERROR_MALFORMED;
    776     }
    777 
    778     const uint8_t *data = buffer->data();
    779 
    780     while (size > 0) {
    781         uint32_t chunkType = U32_AT(data);
    782 
    783         uint8_t hi = chunkType >> 24;
    784         uint8_t lo = (chunkType >> 16) & 0xff;
    785 
    786         if (hi < '0' || hi > '9' || lo < '0' || lo > '9') {
    787             return ERROR_MALFORMED;
    788         }
    789 
    790         size_t trackIndex = 10 * (hi - '0') + (lo - '0');
    791 
    792         if (trackIndex >= mTracks.size()) {
    793             return ERROR_MALFORMED;
    794         }
    795 
    796         Track *track = &mTracks.editItemAt(trackIndex);
    797 
    798         if (!IsCorrectChunkType(-1, track->mKind, chunkType)) {
    799             return ERROR_MALFORMED;
    800         }
    801 
    802         if (track->mKind == Track::OTHER) {
    803             data += 16;
    804             size -= 16;
    805             continue;
    806         }
    807 
    808         uint32_t flags = U32LE_AT(&data[4]);
    809         uint32_t offset = U32LE_AT(&data[8]);
    810         uint32_t chunkSize = U32LE_AT(&data[12]);
    811 
    812         if (chunkSize > track->mMaxSampleSize) {
    813             track->mMaxSampleSize = chunkSize;
    814         }
    815 
    816         track->mSamples.push();
    817 
    818         SampleInfo *info =
    819             &track->mSamples.editItemAt(track->mSamples.size() - 1);
    820 
    821         info->mOffset = offset;
    822         info->mIsKey = (flags & 0x10) != 0;
    823 
    824         if (info->mIsKey) {
    825             static const size_t kMaxNumSyncSamplesToScan = 20;
    826 
    827             if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) {
    828                 if (chunkSize > track->mThumbnailSampleSize) {
    829                     track->mThumbnailSampleSize = chunkSize;
    830 
    831                     track->mThumbnailSampleIndex =
    832                         track->mSamples.size() - 1;
    833                 }
    834             }
    835 
    836             ++track->mNumSyncSamples;
    837         }
    838 
    839         data += 16;
    840         size -= 16;
    841     }
    842 
    843     if (!mTracks.isEmpty()) {
    844         off64_t offset;
    845         size_t size;
    846         bool isKey;
    847         int64_t timeUs;
    848         status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
    849 
    850         if (err != OK) {
    851             mOffsetsAreAbsolute = !mOffsetsAreAbsolute;
    852             err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
    853 
    854             if (err != OK) {
    855                 return err;
    856             }
    857         }
    858 
    859         LOGV("Chunk offsets are %s",
    860              mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative");
    861     }
    862 
    863     for (size_t i = 0; i < mTracks.size(); ++i) {
    864         Track *track = &mTracks.editItemAt(i);
    865 
    866         if (track->mBytesPerSample > 0) {
    867             // Assume all chunks are roughly the same size for now.
    868 
    869             // Compute the avg. size of the first 128 chunks (if there are
    870             // that many), but exclude the size of the first one, since
    871             // it may be an outlier.
    872             size_t numSamplesToAverage = track->mSamples.size();
    873             if (numSamplesToAverage > 256) {
    874                 numSamplesToAverage = 256;
    875             }
    876 
    877             double avgChunkSize = 0;
    878             size_t j;
    879             for (j = 0; j <= numSamplesToAverage; ++j) {
    880                 off64_t offset;
    881                 size_t size;
    882                 bool isKey;
    883                 int64_t dummy;
    884 
    885                 status_t err =
    886                     getSampleInfo(
    887                             i, j,
    888                             &offset, &size, &isKey, &dummy);
    889 
    890                 if (err != OK) {
    891                     return err;
    892                 }
    893 
    894                 if (j == 0) {
    895                     track->mFirstChunkSize = size;
    896                     continue;
    897                 }
    898 
    899                 avgChunkSize += size;
    900             }
    901 
    902             avgChunkSize /= numSamplesToAverage;
    903 
    904             track->mAvgChunkSize = avgChunkSize;
    905         }
    906 
    907         int64_t durationUs;
    908         CHECK_EQ((status_t)OK,
    909                  getSampleTime(i, track->mSamples.size() - 1, &durationUs));
    910 
    911         LOGV("track %d duration = %.2f secs", i, durationUs / 1E6);
    912 
    913         track->mMeta->setInt64(kKeyDuration, durationUs);
    914         track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize);
    915 
    916         const char *tmp;
    917         CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp));
    918 
    919         AString mime = tmp;
    920 
    921         if (!strncasecmp("video/", mime.c_str(), 6)) {
    922             if (track->mThumbnailSampleIndex >= 0) {
    923                 int64_t thumbnailTimeUs;
    924                 CHECK_EQ((status_t)OK,
    925                          getSampleTime(i, track->mThumbnailSampleIndex,
    926                                        &thumbnailTimeUs));
    927 
    928                 track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
    929             }
    930 
    931             status_t err = OK;
    932 
    933             if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
    934                 err = addMPEG4CodecSpecificData(i);
    935             } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
    936                 err = addH264CodecSpecificData(i);
    937             }
    938 
    939             if (err != OK) {
    940                 return err;
    941             }
    942         }
    943     }
    944 
    945     mFoundIndex = true;
    946 
    947     return OK;
    948 }
    949 
    950 static size_t GetSizeWidth(size_t x) {
    951     size_t n = 1;
    952     while (x > 127) {
    953         ++n;
    954         x >>= 7;
    955     }
    956     return n;
    957 }
    958 
    959 static uint8_t *EncodeSize(uint8_t *dst, size_t x) {
    960     while (x > 127) {
    961         *dst++ = (x & 0x7f) | 0x80;
    962         x >>= 7;
    963     }
    964     *dst++ = x;
    965     return dst;
    966 }
    967 
    968 sp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) {
    969     size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
    970     size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
    971     size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
    972 
    973     sp<ABuffer> csd = new ABuffer(len3);
    974     uint8_t *dst = csd->data();
    975     *dst++ = 0x03;
    976     dst = EncodeSize(dst, len2 + 3);
    977     *dst++ = 0x00;  // ES_ID
    978     *dst++ = 0x00;
    979     *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
    980 
    981     *dst++ = 0x04;
    982     dst = EncodeSize(dst, len1 + 13);
    983     *dst++ = 0x01;  // Video ISO/IEC 14496-2 Simple Profile
    984     for (size_t i = 0; i < 12; ++i) {
    985         *dst++ = 0x00;
    986     }
    987 
    988     *dst++ = 0x05;
    989     dst = EncodeSize(dst, config->size());
    990     memcpy(dst, config->data(), config->size());
    991     dst += config->size();
    992 
    993     // hexdump(csd->data(), csd->size());
    994 
    995     return csd;
    996 }
    997 
    998 status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
    999     Track *track = &mTracks.editItemAt(trackIndex);
   1000 
   1001     off64_t offset;
   1002     size_t size;
   1003     bool isKey;
   1004     int64_t timeUs;
   1005     status_t err =
   1006         getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs);
   1007 
   1008     if (err != OK) {
   1009         return err;
   1010     }
   1011 
   1012     sp<ABuffer> buffer = new ABuffer(size);
   1013     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
   1014 
   1015     if (n < (ssize_t)size) {
   1016         return n < 0 ? (status_t)n : ERROR_MALFORMED;
   1017     }
   1018 
   1019     // Extract everything up to the first VOP start code from the first
   1020     // frame's encoded data and use it to construct an ESDS with the
   1021     // codec specific data.
   1022 
   1023     size_t i = 0;
   1024     bool found = false;
   1025     while (i + 3 < buffer->size()) {
   1026         if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) {
   1027             found = true;
   1028             break;
   1029         }
   1030 
   1031         ++i;
   1032     }
   1033 
   1034     if (!found) {
   1035         return ERROR_MALFORMED;
   1036     }
   1037 
   1038     buffer->setRange(0, i);
   1039 
   1040     sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer);
   1041     track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size());
   1042 
   1043     return OK;
   1044 }
   1045 
   1046 status_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) {
   1047     Track *track = &mTracks.editItemAt(trackIndex);
   1048 
   1049     off64_t offset;
   1050     size_t size;
   1051     bool isKey;
   1052     int64_t timeUs;
   1053 
   1054     // Extract codec specific data from the first non-empty sample.
   1055 
   1056     size_t sampleIndex = 0;
   1057     for (;;) {
   1058         status_t err =
   1059             getSampleInfo(
   1060                     trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs);
   1061 
   1062         if (err != OK) {
   1063             return err;
   1064         }
   1065 
   1066         if (size > 0) {
   1067             break;
   1068         }
   1069 
   1070         ++sampleIndex;
   1071     }
   1072 
   1073     sp<ABuffer> buffer = new ABuffer(size);
   1074     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
   1075 
   1076     if (n < (ssize_t)size) {
   1077         return n < 0 ? (status_t)n : ERROR_MALFORMED;
   1078     }
   1079 
   1080     sp<MetaData> meta = MakeAVCCodecSpecificData(buffer);
   1081 
   1082     if (meta == NULL) {
   1083         LOGE("Unable to extract AVC codec specific data");
   1084         return ERROR_MALFORMED;
   1085     }
   1086 
   1087     int32_t width, height;
   1088     CHECK(meta->findInt32(kKeyWidth, &width));
   1089     CHECK(meta->findInt32(kKeyHeight, &height));
   1090 
   1091     uint32_t type;
   1092     const void *csd;
   1093     size_t csdSize;
   1094     CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize));
   1095 
   1096     track->mMeta->setInt32(kKeyWidth, width);
   1097     track->mMeta->setInt32(kKeyHeight, width);
   1098     track->mMeta->setData(kKeyAVCC, type, csd, csdSize);
   1099 
   1100     return OK;
   1101 }
   1102 
   1103 status_t AVIExtractor::getSampleInfo(
   1104         size_t trackIndex, size_t sampleIndex,
   1105         off64_t *offset, size_t *size, bool *isKey,
   1106         int64_t *sampleTimeUs) {
   1107     if (trackIndex >= mTracks.size()) {
   1108         return -ERANGE;
   1109     }
   1110 
   1111     const Track &track = mTracks.itemAt(trackIndex);
   1112 
   1113     if (sampleIndex >= track.mSamples.size()) {
   1114         return -ERANGE;
   1115     }
   1116 
   1117     const SampleInfo &info = track.mSamples.itemAt(sampleIndex);
   1118 
   1119     if (!mOffsetsAreAbsolute) {
   1120         *offset = info.mOffset + mMovieOffset + 8;
   1121     } else {
   1122         *offset = info.mOffset;
   1123     }
   1124 
   1125     *size = 0;
   1126 
   1127     uint8_t tmp[8];
   1128     ssize_t n = mDataSource->readAt(*offset, tmp, 8);
   1129 
   1130     if (n < 8) {
   1131         return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
   1132     }
   1133 
   1134     uint32_t chunkType = U32_AT(tmp);
   1135 
   1136     if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) {
   1137         return ERROR_MALFORMED;
   1138     }
   1139 
   1140     *offset += 8;
   1141     *size = U32LE_AT(&tmp[4]);
   1142 
   1143     *isKey = info.mIsKey;
   1144 
   1145     if (track.mBytesPerSample > 0) {
   1146         size_t sampleStartInBytes;
   1147         if (sampleIndex == 0) {
   1148             sampleStartInBytes = 0;
   1149         } else {
   1150             sampleStartInBytes =
   1151                 track.mFirstChunkSize + track.mAvgChunkSize * (sampleIndex - 1);
   1152         }
   1153 
   1154         sampleIndex = sampleStartInBytes / track.mBytesPerSample;
   1155     }
   1156 
   1157     *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale;
   1158 
   1159     return OK;
   1160 }
   1161 
   1162 status_t AVIExtractor::getSampleTime(
   1163         size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) {
   1164     off64_t offset;
   1165     size_t size;
   1166     bool isKey;
   1167     return getSampleInfo(
   1168             trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs);
   1169 }
   1170 
   1171 status_t AVIExtractor::getSampleIndexAtTime(
   1172         size_t trackIndex,
   1173         int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
   1174         size_t *sampleIndex) const {
   1175     if (trackIndex >= mTracks.size()) {
   1176         return -ERANGE;
   1177     }
   1178 
   1179     const Track &track = mTracks.itemAt(trackIndex);
   1180 
   1181     ssize_t closestSampleIndex;
   1182 
   1183     if (track.mBytesPerSample > 0) {
   1184         size_t closestByteOffset =
   1185             (timeUs * track.mBytesPerSample)
   1186                 / track.mRate * track.mScale / 1000000ll;
   1187 
   1188         if (closestByteOffset <= track.mFirstChunkSize) {
   1189             closestSampleIndex = 0;
   1190         } else {
   1191             closestSampleIndex =
   1192                 (closestByteOffset - track.mFirstChunkSize)
   1193                     / track.mAvgChunkSize;
   1194         }
   1195     } else {
   1196         // Each chunk contains a single sample.
   1197         closestSampleIndex = timeUs / track.mRate * track.mScale / 1000000ll;
   1198     }
   1199 
   1200     ssize_t numSamples = track.mSamples.size();
   1201 
   1202     if (closestSampleIndex < 0) {
   1203         closestSampleIndex = 0;
   1204     } else if (closestSampleIndex >= numSamples) {
   1205         closestSampleIndex = numSamples - 1;
   1206     }
   1207 
   1208     if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) {
   1209         *sampleIndex = closestSampleIndex;
   1210 
   1211         return OK;
   1212     }
   1213 
   1214     ssize_t prevSyncSampleIndex = closestSampleIndex;
   1215     while (prevSyncSampleIndex >= 0) {
   1216         const SampleInfo &info =
   1217             track.mSamples.itemAt(prevSyncSampleIndex);
   1218 
   1219         if (info.mIsKey) {
   1220             break;
   1221         }
   1222 
   1223         --prevSyncSampleIndex;
   1224     }
   1225 
   1226     ssize_t nextSyncSampleIndex = closestSampleIndex;
   1227     while (nextSyncSampleIndex < numSamples) {
   1228         const SampleInfo &info =
   1229             track.mSamples.itemAt(nextSyncSampleIndex);
   1230 
   1231         if (info.mIsKey) {
   1232             break;
   1233         }
   1234 
   1235         ++nextSyncSampleIndex;
   1236     }
   1237 
   1238     switch (mode) {
   1239         case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC:
   1240         {
   1241             *sampleIndex = prevSyncSampleIndex;
   1242 
   1243             return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR;
   1244         }
   1245 
   1246         case MediaSource::ReadOptions::SEEK_NEXT_SYNC:
   1247         {
   1248             *sampleIndex = nextSyncSampleIndex;
   1249 
   1250             return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR;
   1251         }
   1252 
   1253         case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC:
   1254         {
   1255             if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) {
   1256                 return UNKNOWN_ERROR;
   1257             }
   1258 
   1259             if (prevSyncSampleIndex < 0) {
   1260                 *sampleIndex = nextSyncSampleIndex;
   1261                 return OK;
   1262             }
   1263 
   1264             if (nextSyncSampleIndex >= numSamples) {
   1265                 *sampleIndex = prevSyncSampleIndex;
   1266                 return OK;
   1267             }
   1268 
   1269             size_t dist1 = closestSampleIndex - prevSyncSampleIndex;
   1270             size_t dist2 = nextSyncSampleIndex - closestSampleIndex;
   1271 
   1272             *sampleIndex =
   1273                 (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex;
   1274 
   1275             return OK;
   1276         }
   1277 
   1278         default:
   1279             TRESPASS();
   1280             break;
   1281     }
   1282 }
   1283 
   1284 bool SniffAVI(
   1285         const sp<DataSource> &source, String8 *mimeType, float *confidence,
   1286         sp<AMessage> *) {
   1287     char tmp[12];
   1288     if (source->readAt(0, tmp, 12) < 12) {
   1289         return false;
   1290     }
   1291 
   1292     if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) {
   1293         mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI);
   1294 
   1295         // Just a tad over the mp3 extractor's confidence, since
   1296         // these .avi files may contain .mp3 content that otherwise would
   1297         // mistakenly lead to us identifying the entire file as a .mp3 file.
   1298         *confidence = 0.21;
   1299 
   1300         return true;
   1301     }
   1302 
   1303     return false;
   1304 }
   1305 
   1306 }  // namespace android
   1307