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         ALOGV("%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         ALOGV("%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('H', '2', '6', '4'):
    581         case FOURCC('v', 's', 's', 'h'):
    582             return MEDIA_MIMETYPE_VIDEO_AVC;
    583 
    584         default:
    585             return NULL;
    586     }
    587 }
    588 
    589 status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
    590     if (size != 56) {
    591         return ERROR_MALFORMED;
    592     }
    593 
    594     if (mTracks.size() > 99) {
    595         return -ERANGE;
    596     }
    597 
    598     sp<ABuffer> buffer = new ABuffer(size);
    599     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
    600 
    601     if (n < (ssize_t)size) {
    602         return n < 0 ? (status_t)n : ERROR_MALFORMED;
    603     }
    604 
    605     const uint8_t *data = buffer->data();
    606 
    607     uint32_t type = U32_AT(data);
    608     uint32_t handler = U32_AT(&data[4]);
    609     uint32_t flags = U32LE_AT(&data[8]);
    610 
    611     sp<MetaData> meta = new MetaData;
    612 
    613     uint32_t rate = U32LE_AT(&data[20]);
    614     uint32_t scale = U32LE_AT(&data[24]);
    615 
    616     uint32_t sampleSize = U32LE_AT(&data[44]);
    617 
    618     const char *mime = NULL;
    619     Track::Kind kind = Track::OTHER;
    620 
    621     if (type == FOURCC('v', 'i', 'd', 's')) {
    622         mime = GetMIMETypeForHandler(handler);
    623 
    624         if (mime && strncasecmp(mime, "video/", 6)) {
    625             return ERROR_MALFORMED;
    626         }
    627 
    628         if (mime == NULL) {
    629             ALOGW("Unsupported video format '%c%c%c%c'",
    630                  (char)(handler >> 24),
    631                  (char)((handler >> 16) & 0xff),
    632                  (char)((handler >> 8) & 0xff),
    633                  (char)(handler & 0xff));
    634         }
    635 
    636         kind = Track::VIDEO;
    637     } else if (type == FOURCC('a', 'u', 'd', 's')) {
    638         if (mime && strncasecmp(mime, "audio/", 6)) {
    639             return ERROR_MALFORMED;
    640         }
    641 
    642         kind = Track::AUDIO;
    643     }
    644 
    645     if (!mime) {
    646         mime = "application/octet-stream";
    647     }
    648 
    649     meta->setCString(kKeyMIMEType, mime);
    650 
    651     mTracks.push();
    652     Track *track = &mTracks.editItemAt(mTracks.size() - 1);
    653 
    654     track->mMeta = meta;
    655     track->mRate = rate;
    656     track->mScale = scale;
    657     track->mBytesPerSample = sampleSize;
    658     track->mKind = kind;
    659     track->mNumSyncSamples = 0;
    660     track->mThumbnailSampleSize = 0;
    661     track->mThumbnailSampleIndex = -1;
    662     track->mMaxSampleSize = 0;
    663     track->mAvgChunkSize = 1.0;
    664     track->mFirstChunkSize = 0;
    665 
    666     return OK;
    667 }
    668 
    669 status_t AVIExtractor::parseStreamFormat(off64_t offset, size_t size) {
    670     if (mTracks.isEmpty()) {
    671         return ERROR_MALFORMED;
    672     }
    673 
    674     Track *track = &mTracks.editItemAt(mTracks.size() - 1);
    675 
    676     if (track->mKind == Track::OTHER) {
    677         // We don't support this content, but that's not a parsing error.
    678         return OK;
    679     }
    680 
    681     bool isVideo = (track->mKind == Track::VIDEO);
    682 
    683     if ((isVideo && size < 40) || (!isVideo && size < 16)) {
    684         // Expected a BITMAPINFO or WAVEFORMAT(EX) structure, respectively.
    685         return ERROR_MALFORMED;
    686     }
    687 
    688     sp<ABuffer> buffer = new ABuffer(size);
    689     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
    690 
    691     if (n < (ssize_t)size) {
    692         return n < 0 ? (status_t)n : ERROR_MALFORMED;
    693     }
    694 
    695     const uint8_t *data = buffer->data();
    696 
    697     if (isVideo) {
    698         uint32_t width = U32LE_AT(&data[4]);
    699         uint32_t height = U32LE_AT(&data[8]);
    700 
    701         track->mMeta->setInt32(kKeyWidth, width);
    702         track->mMeta->setInt32(kKeyHeight, height);
    703     } else {
    704         uint32_t format = U16LE_AT(data);
    705 
    706         if (format == 0x55) {
    707             track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
    708         } else {
    709             ALOGW("Unsupported audio format = 0x%04x", format);
    710         }
    711 
    712         uint32_t numChannels = U16LE_AT(&data[2]);
    713         uint32_t sampleRate = U32LE_AT(&data[4]);
    714 
    715         track->mMeta->setInt32(kKeyChannelCount, numChannels);
    716         track->mMeta->setInt32(kKeySampleRate, sampleRate);
    717     }
    718 
    719     return OK;
    720 }
    721 
    722 // static
    723 bool AVIExtractor::IsCorrectChunkType(
    724         ssize_t trackIndex, Track::Kind kind, uint32_t chunkType) {
    725     uint32_t chunkBase = chunkType & 0xffff;
    726 
    727     switch (kind) {
    728         case Track::VIDEO:
    729         {
    730             if (chunkBase != FOURCC(0, 0, 'd', 'c')
    731                     && chunkBase != FOURCC(0, 0, 'd', 'b')) {
    732                 return false;
    733             }
    734             break;
    735         }
    736 
    737         case Track::AUDIO:
    738         {
    739             if (chunkBase != FOURCC(0, 0, 'w', 'b')) {
    740                 return false;
    741             }
    742             break;
    743         }
    744 
    745         default:
    746             break;
    747     }
    748 
    749     if (trackIndex < 0) {
    750         return true;
    751     }
    752 
    753     uint8_t hi = chunkType >> 24;
    754     uint8_t lo = (chunkType >> 16) & 0xff;
    755 
    756     if (hi < '0' || hi > '9' || lo < '0' || lo > '9') {
    757         return false;
    758     }
    759 
    760     if (trackIndex != (10 * (hi - '0') + (lo - '0'))) {
    761         return false;
    762     }
    763 
    764     return true;
    765 }
    766 
    767 status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
    768     if ((size % 16) != 0) {
    769         return ERROR_MALFORMED;
    770     }
    771 
    772     sp<ABuffer> buffer = new ABuffer(size);
    773     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
    774 
    775     if (n < (ssize_t)size) {
    776         return n < 0 ? (status_t)n : ERROR_MALFORMED;
    777     }
    778 
    779     const uint8_t *data = buffer->data();
    780 
    781     while (size > 0) {
    782         uint32_t chunkType = U32_AT(data);
    783 
    784         uint8_t hi = chunkType >> 24;
    785         uint8_t lo = (chunkType >> 16) & 0xff;
    786 
    787         if (hi < '0' || hi > '9' || lo < '0' || lo > '9') {
    788             return ERROR_MALFORMED;
    789         }
    790 
    791         size_t trackIndex = 10 * (hi - '0') + (lo - '0');
    792 
    793         if (trackIndex >= mTracks.size()) {
    794             return ERROR_MALFORMED;
    795         }
    796 
    797         Track *track = &mTracks.editItemAt(trackIndex);
    798 
    799         if (!IsCorrectChunkType(-1, track->mKind, chunkType)) {
    800             return ERROR_MALFORMED;
    801         }
    802 
    803         if (track->mKind == Track::OTHER) {
    804             data += 16;
    805             size -= 16;
    806             continue;
    807         }
    808 
    809         uint32_t flags = U32LE_AT(&data[4]);
    810         uint32_t offset = U32LE_AT(&data[8]);
    811         uint32_t chunkSize = U32LE_AT(&data[12]);
    812 
    813         if (chunkSize > track->mMaxSampleSize) {
    814             track->mMaxSampleSize = chunkSize;
    815         }
    816 
    817         track->mSamples.push();
    818 
    819         SampleInfo *info =
    820             &track->mSamples.editItemAt(track->mSamples.size() - 1);
    821 
    822         info->mOffset = offset;
    823         info->mIsKey = (flags & 0x10) != 0;
    824 
    825         if (info->mIsKey) {
    826             static const size_t kMaxNumSyncSamplesToScan = 20;
    827 
    828             if (track->mNumSyncSamples < kMaxNumSyncSamplesToScan) {
    829                 if (chunkSize > track->mThumbnailSampleSize) {
    830                     track->mThumbnailSampleSize = chunkSize;
    831 
    832                     track->mThumbnailSampleIndex =
    833                         track->mSamples.size() - 1;
    834                 }
    835             }
    836 
    837             ++track->mNumSyncSamples;
    838         }
    839 
    840         data += 16;
    841         size -= 16;
    842     }
    843 
    844     if (!mTracks.isEmpty()) {
    845         off64_t offset;
    846         size_t size;
    847         bool isKey;
    848         int64_t timeUs;
    849         status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
    850 
    851         if (err != OK) {
    852             mOffsetsAreAbsolute = !mOffsetsAreAbsolute;
    853             err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
    854 
    855             if (err != OK) {
    856                 return err;
    857             }
    858         }
    859 
    860         ALOGV("Chunk offsets are %s",
    861              mOffsetsAreAbsolute ? "absolute" : "movie-chunk relative");
    862     }
    863 
    864     for (size_t i = 0; i < mTracks.size(); ++i) {
    865         Track *track = &mTracks.editItemAt(i);
    866 
    867         if (track->mBytesPerSample > 0) {
    868             // Assume all chunks are roughly the same size for now.
    869 
    870             // Compute the avg. size of the first 128 chunks (if there are
    871             // that many), but exclude the size of the first one, since
    872             // it may be an outlier.
    873             size_t numSamplesToAverage = track->mSamples.size();
    874             if (numSamplesToAverage > 256) {
    875                 numSamplesToAverage = 256;
    876             }
    877 
    878             double avgChunkSize = 0;
    879             size_t j;
    880             for (j = 0; j <= numSamplesToAverage; ++j) {
    881                 off64_t offset;
    882                 size_t size;
    883                 bool isKey;
    884                 int64_t dummy;
    885 
    886                 status_t err =
    887                     getSampleInfo(
    888                             i, j,
    889                             &offset, &size, &isKey, &dummy);
    890 
    891                 if (err != OK) {
    892                     return err;
    893                 }
    894 
    895                 if (j == 0) {
    896                     track->mFirstChunkSize = size;
    897                     continue;
    898                 }
    899 
    900                 avgChunkSize += size;
    901             }
    902 
    903             avgChunkSize /= numSamplesToAverage;
    904 
    905             track->mAvgChunkSize = avgChunkSize;
    906         }
    907 
    908         int64_t durationUs;
    909         CHECK_EQ((status_t)OK,
    910                  getSampleTime(i, track->mSamples.size() - 1, &durationUs));
    911 
    912         ALOGV("track %d duration = %.2f secs", i, durationUs / 1E6);
    913 
    914         track->mMeta->setInt64(kKeyDuration, durationUs);
    915         track->mMeta->setInt32(kKeyMaxInputSize, track->mMaxSampleSize);
    916 
    917         const char *tmp;
    918         CHECK(track->mMeta->findCString(kKeyMIMEType, &tmp));
    919 
    920         AString mime = tmp;
    921 
    922         if (!strncasecmp("video/", mime.c_str(), 6)) {
    923             if (track->mThumbnailSampleIndex >= 0) {
    924                 int64_t thumbnailTimeUs;
    925                 CHECK_EQ((status_t)OK,
    926                          getSampleTime(i, track->mThumbnailSampleIndex,
    927                                        &thumbnailTimeUs));
    928 
    929                 track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
    930             }
    931 
    932             status_t err = OK;
    933 
    934             if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
    935                 err = addMPEG4CodecSpecificData(i);
    936             } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
    937                 err = addH264CodecSpecificData(i);
    938             }
    939 
    940             if (err != OK) {
    941                 return err;
    942             }
    943         }
    944     }
    945 
    946     mFoundIndex = true;
    947 
    948     return OK;
    949 }
    950 
    951 static size_t GetSizeWidth(size_t x) {
    952     size_t n = 1;
    953     while (x > 127) {
    954         ++n;
    955         x >>= 7;
    956     }
    957     return n;
    958 }
    959 
    960 static uint8_t *EncodeSize(uint8_t *dst, size_t x) {
    961     while (x > 127) {
    962         *dst++ = (x & 0x7f) | 0x80;
    963         x >>= 7;
    964     }
    965     *dst++ = x;
    966     return dst;
    967 }
    968 
    969 sp<ABuffer> MakeMPEG4VideoCodecSpecificData(const sp<ABuffer> &config) {
    970     size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
    971     size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
    972     size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
    973 
    974     sp<ABuffer> csd = new ABuffer(len3);
    975     uint8_t *dst = csd->data();
    976     *dst++ = 0x03;
    977     dst = EncodeSize(dst, len2 + 3);
    978     *dst++ = 0x00;  // ES_ID
    979     *dst++ = 0x00;
    980     *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
    981 
    982     *dst++ = 0x04;
    983     dst = EncodeSize(dst, len1 + 13);
    984     *dst++ = 0x01;  // Video ISO/IEC 14496-2 Simple Profile
    985     for (size_t i = 0; i < 12; ++i) {
    986         *dst++ = 0x00;
    987     }
    988 
    989     *dst++ = 0x05;
    990     dst = EncodeSize(dst, config->size());
    991     memcpy(dst, config->data(), config->size());
    992     dst += config->size();
    993 
    994     // hexdump(csd->data(), csd->size());
    995 
    996     return csd;
    997 }
    998 
    999 status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
   1000     Track *track = &mTracks.editItemAt(trackIndex);
   1001 
   1002     off64_t offset;
   1003     size_t size;
   1004     bool isKey;
   1005     int64_t timeUs;
   1006     status_t err =
   1007         getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs);
   1008 
   1009     if (err != OK) {
   1010         return err;
   1011     }
   1012 
   1013     sp<ABuffer> buffer = new ABuffer(size);
   1014     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
   1015 
   1016     if (n < (ssize_t)size) {
   1017         return n < 0 ? (status_t)n : ERROR_MALFORMED;
   1018     }
   1019 
   1020     // Extract everything up to the first VOP start code from the first
   1021     // frame's encoded data and use it to construct an ESDS with the
   1022     // codec specific data.
   1023 
   1024     size_t i = 0;
   1025     bool found = false;
   1026     while (i + 3 < buffer->size()) {
   1027         if (!memcmp("\x00\x00\x01\xb6", &buffer->data()[i], 4)) {
   1028             found = true;
   1029             break;
   1030         }
   1031 
   1032         ++i;
   1033     }
   1034 
   1035     if (!found) {
   1036         return ERROR_MALFORMED;
   1037     }
   1038 
   1039     buffer->setRange(0, i);
   1040 
   1041     sp<ABuffer> csd = MakeMPEG4VideoCodecSpecificData(buffer);
   1042     track->mMeta->setData(kKeyESDS, kTypeESDS, csd->data(), csd->size());
   1043 
   1044     return OK;
   1045 }
   1046 
   1047 status_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) {
   1048     Track *track = &mTracks.editItemAt(trackIndex);
   1049 
   1050     off64_t offset;
   1051     size_t size;
   1052     bool isKey;
   1053     int64_t timeUs;
   1054 
   1055     // Extract codec specific data from the first non-empty sample.
   1056 
   1057     size_t sampleIndex = 0;
   1058     for (;;) {
   1059         status_t err =
   1060             getSampleInfo(
   1061                     trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs);
   1062 
   1063         if (err != OK) {
   1064             return err;
   1065         }
   1066 
   1067         if (size > 0) {
   1068             break;
   1069         }
   1070 
   1071         ++sampleIndex;
   1072     }
   1073 
   1074     sp<ABuffer> buffer = new ABuffer(size);
   1075     ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
   1076 
   1077     if (n < (ssize_t)size) {
   1078         return n < 0 ? (status_t)n : ERROR_MALFORMED;
   1079     }
   1080 
   1081     sp<MetaData> meta = MakeAVCCodecSpecificData(buffer);
   1082 
   1083     if (meta == NULL) {
   1084         ALOGE("Unable to extract AVC codec specific data");
   1085         return ERROR_MALFORMED;
   1086     }
   1087 
   1088     int32_t width, height;
   1089     CHECK(meta->findInt32(kKeyWidth, &width));
   1090     CHECK(meta->findInt32(kKeyHeight, &height));
   1091 
   1092     uint32_t type;
   1093     const void *csd;
   1094     size_t csdSize;
   1095     CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize));
   1096 
   1097     track->mMeta->setInt32(kKeyWidth, width);
   1098     track->mMeta->setInt32(kKeyHeight, height);
   1099     track->mMeta->setData(kKeyAVCC, type, csd, csdSize);
   1100 
   1101     return OK;
   1102 }
   1103 
   1104 status_t AVIExtractor::getSampleInfo(
   1105         size_t trackIndex, size_t sampleIndex,
   1106         off64_t *offset, size_t *size, bool *isKey,
   1107         int64_t *sampleTimeUs) {
   1108     if (trackIndex >= mTracks.size()) {
   1109         return -ERANGE;
   1110     }
   1111 
   1112     const Track &track = mTracks.itemAt(trackIndex);
   1113 
   1114     if (sampleIndex >= track.mSamples.size()) {
   1115         return -ERANGE;
   1116     }
   1117 
   1118     const SampleInfo &info = track.mSamples.itemAt(sampleIndex);
   1119 
   1120     if (!mOffsetsAreAbsolute) {
   1121         *offset = info.mOffset + mMovieOffset + 8;
   1122     } else {
   1123         *offset = info.mOffset;
   1124     }
   1125 
   1126     *size = 0;
   1127 
   1128     uint8_t tmp[8];
   1129     ssize_t n = mDataSource->readAt(*offset, tmp, 8);
   1130 
   1131     if (n < 8) {
   1132         return n < 0 ? (status_t)n : (status_t)ERROR_MALFORMED;
   1133     }
   1134 
   1135     uint32_t chunkType = U32_AT(tmp);
   1136 
   1137     if (!IsCorrectChunkType(trackIndex, track.mKind, chunkType)) {
   1138         return ERROR_MALFORMED;
   1139     }
   1140 
   1141     *offset += 8;
   1142     *size = U32LE_AT(&tmp[4]);
   1143 
   1144     *isKey = info.mIsKey;
   1145 
   1146     if (track.mBytesPerSample > 0) {
   1147         size_t sampleStartInBytes;
   1148         if (sampleIndex == 0) {
   1149             sampleStartInBytes = 0;
   1150         } else {
   1151             sampleStartInBytes =
   1152                 track.mFirstChunkSize + track.mAvgChunkSize * (sampleIndex - 1);
   1153         }
   1154 
   1155         sampleIndex = sampleStartInBytes / track.mBytesPerSample;
   1156     }
   1157 
   1158     *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale;
   1159 
   1160     return OK;
   1161 }
   1162 
   1163 status_t AVIExtractor::getSampleTime(
   1164         size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) {
   1165     off64_t offset;
   1166     size_t size;
   1167     bool isKey;
   1168     return getSampleInfo(
   1169             trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs);
   1170 }
   1171 
   1172 status_t AVIExtractor::getSampleIndexAtTime(
   1173         size_t trackIndex,
   1174         int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
   1175         size_t *sampleIndex) const {
   1176     if (trackIndex >= mTracks.size()) {
   1177         return -ERANGE;
   1178     }
   1179 
   1180     const Track &track = mTracks.itemAt(trackIndex);
   1181 
   1182     ssize_t closestSampleIndex;
   1183 
   1184     if (track.mBytesPerSample > 0) {
   1185         size_t closestByteOffset =
   1186             (timeUs * track.mBytesPerSample)
   1187                 / track.mRate * track.mScale / 1000000ll;
   1188 
   1189         if (closestByteOffset <= track.mFirstChunkSize) {
   1190             closestSampleIndex = 0;
   1191         } else {
   1192             closestSampleIndex =
   1193                 (closestByteOffset - track.mFirstChunkSize)
   1194                     / track.mAvgChunkSize;
   1195         }
   1196     } else {
   1197         // Each chunk contains a single sample.
   1198         closestSampleIndex = timeUs / track.mRate * track.mScale / 1000000ll;
   1199     }
   1200 
   1201     ssize_t numSamples = track.mSamples.size();
   1202 
   1203     if (closestSampleIndex < 0) {
   1204         closestSampleIndex = 0;
   1205     } else if (closestSampleIndex >= numSamples) {
   1206         closestSampleIndex = numSamples - 1;
   1207     }
   1208 
   1209     if (mode == MediaSource::ReadOptions::SEEK_CLOSEST) {
   1210         *sampleIndex = closestSampleIndex;
   1211 
   1212         return OK;
   1213     }
   1214 
   1215     ssize_t prevSyncSampleIndex = closestSampleIndex;
   1216     while (prevSyncSampleIndex >= 0) {
   1217         const SampleInfo &info =
   1218             track.mSamples.itemAt(prevSyncSampleIndex);
   1219 
   1220         if (info.mIsKey) {
   1221             break;
   1222         }
   1223 
   1224         --prevSyncSampleIndex;
   1225     }
   1226 
   1227     ssize_t nextSyncSampleIndex = closestSampleIndex;
   1228     while (nextSyncSampleIndex < numSamples) {
   1229         const SampleInfo &info =
   1230             track.mSamples.itemAt(nextSyncSampleIndex);
   1231 
   1232         if (info.mIsKey) {
   1233             break;
   1234         }
   1235 
   1236         ++nextSyncSampleIndex;
   1237     }
   1238 
   1239     switch (mode) {
   1240         case MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC:
   1241         {
   1242             *sampleIndex = prevSyncSampleIndex;
   1243 
   1244             return prevSyncSampleIndex >= 0 ? OK : UNKNOWN_ERROR;
   1245         }
   1246 
   1247         case MediaSource::ReadOptions::SEEK_NEXT_SYNC:
   1248         {
   1249             *sampleIndex = nextSyncSampleIndex;
   1250 
   1251             return nextSyncSampleIndex < numSamples ? OK : UNKNOWN_ERROR;
   1252         }
   1253 
   1254         case MediaSource::ReadOptions::SEEK_CLOSEST_SYNC:
   1255         {
   1256             if (prevSyncSampleIndex < 0 && nextSyncSampleIndex >= numSamples) {
   1257                 return UNKNOWN_ERROR;
   1258             }
   1259 
   1260             if (prevSyncSampleIndex < 0) {
   1261                 *sampleIndex = nextSyncSampleIndex;
   1262                 return OK;
   1263             }
   1264 
   1265             if (nextSyncSampleIndex >= numSamples) {
   1266                 *sampleIndex = prevSyncSampleIndex;
   1267                 return OK;
   1268             }
   1269 
   1270             size_t dist1 = closestSampleIndex - prevSyncSampleIndex;
   1271             size_t dist2 = nextSyncSampleIndex - closestSampleIndex;
   1272 
   1273             *sampleIndex =
   1274                 (dist1 < dist2) ? prevSyncSampleIndex : nextSyncSampleIndex;
   1275 
   1276             return OK;
   1277         }
   1278 
   1279         default:
   1280             TRESPASS();
   1281             break;
   1282     }
   1283 }
   1284 
   1285 bool SniffAVI(
   1286         const sp<DataSource> &source, String8 *mimeType, float *confidence,
   1287         sp<AMessage> *) {
   1288     char tmp[12];
   1289     if (source->readAt(0, tmp, 12) < 12) {
   1290         return false;
   1291     }
   1292 
   1293     if (!memcmp(tmp, "RIFF", 4) && !memcmp(&tmp[8], "AVI ", 4)) {
   1294         mimeType->setTo(MEDIA_MIMETYPE_CONTAINER_AVI);
   1295 
   1296         // Just a tad over the mp3 extractor's confidence, since
   1297         // these .avi files may contain .mp3 content that otherwise would
   1298         // mistakenly lead to us identifying the entire file as a .mp3 file.
   1299         *confidence = 0.21;
   1300 
   1301         return true;
   1302     }
   1303 
   1304     return false;
   1305 }
   1306 
   1307 }  // namespace android
   1308