Home | History | Annotate | Download | only in libstagefright
      1 /*
      2  * Copyright (C) 2009 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 "MPEG4Extractor"
     19 #include <utils/Log.h>
     20 
     21 #include "include/MPEG4Extractor.h"
     22 #include "include/SampleTable.h"
     23 #include "include/ESDS.h"
     24 
     25 #include <arpa/inet.h>
     26 
     27 #include <ctype.h>
     28 #include <stdint.h>
     29 #include <stdlib.h>
     30 #include <string.h>
     31 
     32 #include <media/stagefright/foundation/ABitReader.h>
     33 #include <media/stagefright/foundation/ADebug.h>
     34 #include <media/stagefright/foundation/AMessage.h>
     35 #include <media/stagefright/DataSource.h>
     36 #include <media/stagefright/MediaBuffer.h>
     37 #include <media/stagefright/MediaBufferGroup.h>
     38 #include <media/stagefright/MediaDefs.h>
     39 #include <media/stagefright/MediaSource.h>
     40 #include <media/stagefright/MetaData.h>
     41 #include <media/stagefright/Utils.h>
     42 #include <utils/String8.h>
     43 
     44 namespace android {
     45 
     46 class MPEG4Source : public MediaSource {
     47 public:
     48     // Caller retains ownership of both "dataSource" and "sampleTable".
     49     MPEG4Source(const sp<MetaData> &format,
     50                 const sp<DataSource> &dataSource,
     51                 int32_t timeScale,
     52                 const sp<SampleTable> &sampleTable);
     53 
     54     virtual status_t start(MetaData *params = NULL);
     55     virtual status_t stop();
     56 
     57     virtual sp<MetaData> getFormat();
     58 
     59     virtual status_t read(
     60             MediaBuffer **buffer, const ReadOptions *options = NULL);
     61 
     62 protected:
     63     virtual ~MPEG4Source();
     64 
     65 private:
     66     Mutex mLock;
     67 
     68     sp<MetaData> mFormat;
     69     sp<DataSource> mDataSource;
     70     int32_t mTimescale;
     71     sp<SampleTable> mSampleTable;
     72     uint32_t mCurrentSampleIndex;
     73 
     74     bool mIsAVC;
     75     size_t mNALLengthSize;
     76 
     77     bool mStarted;
     78 
     79     MediaBufferGroup *mGroup;
     80 
     81     MediaBuffer *mBuffer;
     82 
     83     bool mWantsNALFragments;
     84 
     85     uint8_t *mSrcBuffer;
     86 
     87     size_t parseNALSize(const uint8_t *data) const;
     88 
     89     MPEG4Source(const MPEG4Source &);
     90     MPEG4Source &operator=(const MPEG4Source &);
     91 };
     92 
     93 // This custom data source wraps an existing one and satisfies requests
     94 // falling entirely within a cached range from the cache while forwarding
     95 // all remaining requests to the wrapped datasource.
     96 // This is used to cache the full sampletable metadata for a single track,
     97 // possibly wrapping multiple times to cover all tracks, i.e.
     98 // Each MPEG4DataSource caches the sampletable metadata for a single track.
     99 
    100 struct MPEG4DataSource : public DataSource {
    101     MPEG4DataSource(const sp<DataSource> &source);
    102 
    103     virtual status_t initCheck() const;
    104     virtual ssize_t readAt(off64_t offset, void *data, size_t size);
    105     virtual status_t getSize(off64_t *size);
    106     virtual uint32_t flags();
    107 
    108     status_t setCachedRange(off64_t offset, size_t size);
    109 
    110 protected:
    111     virtual ~MPEG4DataSource();
    112 
    113 private:
    114     Mutex mLock;
    115 
    116     sp<DataSource> mSource;
    117     off64_t mCachedOffset;
    118     size_t mCachedSize;
    119     uint8_t *mCache;
    120 
    121     void clearCache();
    122 
    123     MPEG4DataSource(const MPEG4DataSource &);
    124     MPEG4DataSource &operator=(const MPEG4DataSource &);
    125 };
    126 
    127 MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
    128     : mSource(source),
    129       mCachedOffset(0),
    130       mCachedSize(0),
    131       mCache(NULL) {
    132 }
    133 
    134 MPEG4DataSource::~MPEG4DataSource() {
    135     clearCache();
    136 }
    137 
    138 void MPEG4DataSource::clearCache() {
    139     if (mCache) {
    140         free(mCache);
    141         mCache = NULL;
    142     }
    143 
    144     mCachedOffset = 0;
    145     mCachedSize = 0;
    146 }
    147 
    148 status_t MPEG4DataSource::initCheck() const {
    149     return mSource->initCheck();
    150 }
    151 
    152 ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) {
    153     Mutex::Autolock autoLock(mLock);
    154 
    155     if (offset >= mCachedOffset
    156             && offset + size <= mCachedOffset + mCachedSize) {
    157         memcpy(data, &mCache[offset - mCachedOffset], size);
    158         return size;
    159     }
    160 
    161     return mSource->readAt(offset, data, size);
    162 }
    163 
    164 status_t MPEG4DataSource::getSize(off64_t *size) {
    165     return mSource->getSize(size);
    166 }
    167 
    168 uint32_t MPEG4DataSource::flags() {
    169     return mSource->flags();
    170 }
    171 
    172 status_t MPEG4DataSource::setCachedRange(off64_t offset, size_t size) {
    173     Mutex::Autolock autoLock(mLock);
    174 
    175     clearCache();
    176 
    177     mCache = (uint8_t *)malloc(size);
    178 
    179     if (mCache == NULL) {
    180         return -ENOMEM;
    181     }
    182 
    183     mCachedOffset = offset;
    184     mCachedSize = size;
    185 
    186     ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
    187 
    188     if (err < (ssize_t)size) {
    189         clearCache();
    190 
    191         return ERROR_IO;
    192     }
    193 
    194     return OK;
    195 }
    196 
    197 ////////////////////////////////////////////////////////////////////////////////
    198 
    199 static void hexdump(const void *_data, size_t size) {
    200     const uint8_t *data = (const uint8_t *)_data;
    201     size_t offset = 0;
    202     while (offset < size) {
    203         printf("0x%04x  ", offset);
    204 
    205         size_t n = size - offset;
    206         if (n > 16) {
    207             n = 16;
    208         }
    209 
    210         for (size_t i = 0; i < 16; ++i) {
    211             if (i == 8) {
    212                 printf(" ");
    213             }
    214 
    215             if (offset + i < size) {
    216                 printf("%02x ", data[offset + i]);
    217             } else {
    218                 printf("   ");
    219             }
    220         }
    221 
    222         printf(" ");
    223 
    224         for (size_t i = 0; i < n; ++i) {
    225             if (isprint(data[offset + i])) {
    226                 printf("%c", data[offset + i]);
    227             } else {
    228                 printf(".");
    229             }
    230         }
    231 
    232         printf("\n");
    233 
    234         offset += 16;
    235     }
    236 }
    237 
    238 static const char *FourCC2MIME(uint32_t fourcc) {
    239     switch (fourcc) {
    240         case FOURCC('m', 'p', '4', 'a'):
    241             return MEDIA_MIMETYPE_AUDIO_AAC;
    242 
    243         case FOURCC('s', 'a', 'm', 'r'):
    244             return MEDIA_MIMETYPE_AUDIO_AMR_NB;
    245 
    246         case FOURCC('s', 'a', 'w', 'b'):
    247             return MEDIA_MIMETYPE_AUDIO_AMR_WB;
    248 
    249         case FOURCC('m', 'p', '4', 'v'):
    250             return MEDIA_MIMETYPE_VIDEO_MPEG4;
    251 
    252         case FOURCC('s', '2', '6', '3'):
    253         case FOURCC('h', '2', '6', '3'):
    254         case FOURCC('H', '2', '6', '3'):
    255             return MEDIA_MIMETYPE_VIDEO_H263;
    256 
    257         case FOURCC('a', 'v', 'c', '1'):
    258             return MEDIA_MIMETYPE_VIDEO_AVC;
    259 
    260         default:
    261             CHECK(!"should not be here.");
    262             return NULL;
    263     }
    264 }
    265 
    266 MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
    267     : mDataSource(source),
    268       mInitCheck(NO_INIT),
    269       mHasVideo(false),
    270       mFirstTrack(NULL),
    271       mLastTrack(NULL),
    272       mFileMetaData(new MetaData),
    273       mFirstSINF(NULL),
    274       mIsDrm(false) {
    275 }
    276 
    277 MPEG4Extractor::~MPEG4Extractor() {
    278     Track *track = mFirstTrack;
    279     while (track) {
    280         Track *next = track->next;
    281 
    282         delete track;
    283         track = next;
    284     }
    285     mFirstTrack = mLastTrack = NULL;
    286 
    287     SINF *sinf = mFirstSINF;
    288     while (sinf) {
    289         SINF *next = sinf->next;
    290         delete sinf->IPMPData;
    291         delete sinf;
    292         sinf = next;
    293     }
    294     mFirstSINF = NULL;
    295 }
    296 
    297 sp<MetaData> MPEG4Extractor::getMetaData() {
    298     status_t err;
    299     if ((err = readMetaData()) != OK) {
    300         return new MetaData;
    301     }
    302 
    303     return mFileMetaData;
    304 }
    305 
    306 size_t MPEG4Extractor::countTracks() {
    307     status_t err;
    308     if ((err = readMetaData()) != OK) {
    309         return 0;
    310     }
    311 
    312     size_t n = 0;
    313     Track *track = mFirstTrack;
    314     while (track) {
    315         ++n;
    316         track = track->next;
    317     }
    318 
    319     return n;
    320 }
    321 
    322 sp<MetaData> MPEG4Extractor::getTrackMetaData(
    323         size_t index, uint32_t flags) {
    324     status_t err;
    325     if ((err = readMetaData()) != OK) {
    326         return NULL;
    327     }
    328 
    329     Track *track = mFirstTrack;
    330     while (index > 0) {
    331         if (track == NULL) {
    332             return NULL;
    333         }
    334 
    335         track = track->next;
    336         --index;
    337     }
    338 
    339     if (track == NULL) {
    340         return NULL;
    341     }
    342 
    343     if ((flags & kIncludeExtensiveMetaData)
    344             && !track->includes_expensive_metadata) {
    345         track->includes_expensive_metadata = true;
    346 
    347         const char *mime;
    348         CHECK(track->meta->findCString(kKeyMIMEType, &mime));
    349         if (!strncasecmp("video/", mime, 6)) {
    350             uint32_t sampleIndex;
    351             uint32_t sampleTime;
    352             if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
    353                     && track->sampleTable->getMetaDataForSample(
    354                         sampleIndex, NULL /* offset */, NULL /* size */,
    355                         &sampleTime) == OK) {
    356                 track->meta->setInt64(
    357                         kKeyThumbnailTime,
    358                         ((int64_t)sampleTime * 1000000) / track->timescale);
    359             }
    360         }
    361     }
    362 
    363     return track->meta;
    364 }
    365 
    366 status_t MPEG4Extractor::readMetaData() {
    367     if (mInitCheck != NO_INIT) {
    368         return mInitCheck;
    369     }
    370 
    371     off64_t offset = 0;
    372     status_t err;
    373     while ((err = parseChunk(&offset, 0)) == OK) {
    374     }
    375 
    376     if (mInitCheck == OK) {
    377         if (mHasVideo) {
    378             mFileMetaData->setCString(
    379                     kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG4);
    380         } else {
    381             mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
    382         }
    383 
    384         mInitCheck = OK;
    385     } else {
    386         mInitCheck = err;
    387     }
    388 
    389     CHECK_NE(err, (status_t)NO_INIT);
    390     return mInitCheck;
    391 }
    392 
    393 char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
    394     if (mFirstSINF == NULL) {
    395         return NULL;
    396     }
    397 
    398     SINF *sinf = mFirstSINF;
    399     while (sinf && (trackID != sinf->trackID)) {
    400         sinf = sinf->next;
    401     }
    402 
    403     if (sinf == NULL) {
    404         return NULL;
    405     }
    406 
    407     *len = sinf->len;
    408     return sinf->IPMPData;
    409 }
    410 
    411 // Reads an encoded integer 7 bits at a time until it encounters the high bit clear.
    412 static int32_t readSize(off64_t offset,
    413         const sp<DataSource> DataSource, uint8_t *numOfBytes) {
    414     uint32_t size = 0;
    415     uint8_t data;
    416     bool moreData = true;
    417     *numOfBytes = 0;
    418 
    419     while (moreData) {
    420         if (DataSource->readAt(offset, &data, 1) < 1) {
    421             return -1;
    422         }
    423         offset ++;
    424         moreData = (data >= 128) ? true : false;
    425         size = (size << 7) | (data & 0x7f); // Take last 7 bits
    426         (*numOfBytes) ++;
    427     }
    428 
    429     return size;
    430 }
    431 
    432 status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) {
    433     uint8_t updateIdTag;
    434     if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
    435         return ERROR_IO;
    436     }
    437     data_offset ++;
    438 
    439     if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
    440         return ERROR_MALFORMED;
    441     }
    442 
    443     uint8_t numOfBytes;
    444     int32_t size = readSize(data_offset, mDataSource, &numOfBytes);
    445     if (size < 0) {
    446         return ERROR_IO;
    447     }
    448     int32_t classSize = size;
    449     data_offset += numOfBytes;
    450 
    451     while(size >= 11 ) {
    452         uint8_t descriptorTag;
    453         if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) {
    454             return ERROR_IO;
    455         }
    456         data_offset ++;
    457 
    458         if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) {
    459             return ERROR_MALFORMED;
    460         }
    461 
    462         uint8_t buffer[8];
    463         //ObjectDescriptorID and ObjectDescriptor url flag
    464         if (mDataSource->readAt(data_offset, buffer, 2) < 2) {
    465             return ERROR_IO;
    466         }
    467         data_offset += 2;
    468 
    469         if ((buffer[1] >> 5) & 0x0001) { //url flag is set
    470             return ERROR_MALFORMED;
    471         }
    472 
    473         if (mDataSource->readAt(data_offset, buffer, 8) < 8) {
    474             return ERROR_IO;
    475         }
    476         data_offset += 8;
    477 
    478         if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1])
    479                 || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) {
    480             return ERROR_MALFORMED;
    481         }
    482 
    483         SINF *sinf = new SINF;
    484         sinf->trackID = U16_AT(&buffer[3]);
    485         sinf->IPMPDescriptorID = buffer[7];
    486         sinf->next = mFirstSINF;
    487         mFirstSINF = sinf;
    488 
    489         size -= (8 + 2 + 1);
    490     }
    491 
    492     if (size != 0) {
    493         return ERROR_MALFORMED;
    494     }
    495 
    496     if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
    497         return ERROR_IO;
    498     }
    499     data_offset ++;
    500 
    501     if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
    502         return ERROR_MALFORMED;
    503     }
    504 
    505     size = readSize(data_offset, mDataSource, &numOfBytes);
    506     if (size < 0) {
    507         return ERROR_IO;
    508     }
    509     classSize = size;
    510     data_offset += numOfBytes;
    511 
    512     while (size > 0) {
    513         uint8_t tag;
    514         int32_t dataLen;
    515         if (mDataSource->readAt(data_offset, &tag, 1) < 1) {
    516             return ERROR_IO;
    517         }
    518         data_offset ++;
    519 
    520         if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) {
    521             uint8_t id;
    522             dataLen = readSize(data_offset, mDataSource, &numOfBytes);
    523             if (dataLen < 0) {
    524                 return ERROR_IO;
    525             } else if (dataLen < 4) {
    526                 return ERROR_MALFORMED;
    527             }
    528             data_offset += numOfBytes;
    529 
    530             if (mDataSource->readAt(data_offset, &id, 1) < 1) {
    531                 return ERROR_IO;
    532             }
    533             data_offset ++;
    534 
    535             SINF *sinf = mFirstSINF;
    536             while (sinf && (sinf->IPMPDescriptorID != id)) {
    537                 sinf = sinf->next;
    538             }
    539             if (sinf == NULL) {
    540                 return ERROR_MALFORMED;
    541             }
    542             sinf->len = dataLen - 3;
    543             sinf->IPMPData = new char[sinf->len];
    544 
    545             if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) {
    546                 return ERROR_IO;
    547             }
    548             data_offset += sinf->len;
    549 
    550             size -= (dataLen + numOfBytes + 1);
    551         }
    552     }
    553 
    554     if (size != 0) {
    555         return ERROR_MALFORMED;
    556     }
    557 
    558     return UNKNOWN_ERROR;  // Return a dummy error.
    559 }
    560 
    561 static void MakeFourCCString(uint32_t x, char *s) {
    562     s[0] = x >> 24;
    563     s[1] = (x >> 16) & 0xff;
    564     s[2] = (x >> 8) & 0xff;
    565     s[3] = x & 0xff;
    566     s[4] = '\0';
    567 }
    568 
    569 struct PathAdder {
    570     PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
    571         : mPath(path) {
    572         mPath->push(chunkType);
    573     }
    574 
    575     ~PathAdder() {
    576         mPath->pop();
    577     }
    578 
    579 private:
    580     Vector<uint32_t> *mPath;
    581 
    582     PathAdder(const PathAdder &);
    583     PathAdder &operator=(const PathAdder &);
    584 };
    585 
    586 static bool underMetaDataPath(const Vector<uint32_t> &path) {
    587     return path.size() >= 5
    588         && path[0] == FOURCC('m', 'o', 'o', 'v')
    589         && path[1] == FOURCC('u', 'd', 't', 'a')
    590         && path[2] == FOURCC('m', 'e', 't', 'a')
    591         && path[3] == FOURCC('i', 'l', 's', 't');
    592 }
    593 
    594 // Given a time in seconds since Jan 1 1904, produce a human-readable string.
    595 static void convertTimeToDate(int64_t time_1904, String8 *s) {
    596     time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
    597 
    598     char tmp[32];
    599     strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
    600 
    601     s->setTo(tmp);
    602 }
    603 
    604 status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
    605     ALOGV("entering parseChunk %lld/%d", *offset, depth);
    606     uint32_t hdr[2];
    607     if (mDataSource->readAt(*offset, hdr, 8) < 8) {
    608         return ERROR_IO;
    609     }
    610     uint64_t chunk_size = ntohl(hdr[0]);
    611     uint32_t chunk_type = ntohl(hdr[1]);
    612     off64_t data_offset = *offset + 8;
    613 
    614     if (chunk_size == 1) {
    615         if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
    616             return ERROR_IO;
    617         }
    618         chunk_size = ntoh64(chunk_size);
    619         data_offset += 8;
    620 
    621         if (chunk_size < 16) {
    622             // The smallest valid chunk is 16 bytes long in this case.
    623             return ERROR_MALFORMED;
    624         }
    625     } else if (chunk_size < 8) {
    626         // The smallest valid chunk is 8 bytes long.
    627         return ERROR_MALFORMED;
    628     }
    629 
    630     char chunk[5];
    631     MakeFourCCString(chunk_type, chunk);
    632     ALOGV("chunk: %s @ %lld", chunk, *offset);
    633 
    634 #if 0
    635     static const char kWhitespace[] = "                                        ";
    636     const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
    637     printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
    638 
    639     char buffer[256];
    640     size_t n = chunk_size;
    641     if (n > sizeof(buffer)) {
    642         n = sizeof(buffer);
    643     }
    644     if (mDataSource->readAt(*offset, buffer, n)
    645             < (ssize_t)n) {
    646         return ERROR_IO;
    647     }
    648 
    649     hexdump(buffer, n);
    650 #endif
    651 
    652     PathAdder autoAdder(&mPath, chunk_type);
    653 
    654     off64_t chunk_data_size = *offset + chunk_size - data_offset;
    655 
    656     if (chunk_type != FOURCC('c', 'p', 'r', 't')
    657             && chunk_type != FOURCC('c', 'o', 'v', 'r')
    658             && mPath.size() == 5 && underMetaDataPath(mPath)) {
    659         off64_t stop_offset = *offset + chunk_size;
    660         *offset = data_offset;
    661         while (*offset < stop_offset) {
    662             status_t err = parseChunk(offset, depth + 1);
    663             if (err != OK) {
    664                 return err;
    665             }
    666         }
    667 
    668         if (*offset != stop_offset) {
    669             return ERROR_MALFORMED;
    670         }
    671 
    672         return OK;
    673     }
    674 
    675     switch(chunk_type) {
    676         case FOURCC('m', 'o', 'o', 'v'):
    677         case FOURCC('t', 'r', 'a', 'k'):
    678         case FOURCC('m', 'd', 'i', 'a'):
    679         case FOURCC('m', 'i', 'n', 'f'):
    680         case FOURCC('d', 'i', 'n', 'f'):
    681         case FOURCC('s', 't', 'b', 'l'):
    682         case FOURCC('m', 'v', 'e', 'x'):
    683         case FOURCC('m', 'o', 'o', 'f'):
    684         case FOURCC('t', 'r', 'a', 'f'):
    685         case FOURCC('m', 'f', 'r', 'a'):
    686         case FOURCC('u', 'd', 't', 'a'):
    687         case FOURCC('i', 'l', 's', 't'):
    688         {
    689             if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
    690                 ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
    691 
    692                 if (mDataSource->flags()
    693                         & (DataSource::kWantsPrefetching
    694                             | DataSource::kIsCachingDataSource)) {
    695                     sp<MPEG4DataSource> cachedSource =
    696                         new MPEG4DataSource(mDataSource);
    697 
    698                     if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
    699                         mDataSource = cachedSource;
    700                     }
    701                 }
    702 
    703                 mLastTrack->sampleTable = new SampleTable(mDataSource);
    704             }
    705 
    706             bool isTrack = false;
    707             if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
    708                 isTrack = true;
    709 
    710                 Track *track = new Track;
    711                 track->next = NULL;
    712                 if (mLastTrack) {
    713                     mLastTrack->next = track;
    714                 } else {
    715                     mFirstTrack = track;
    716                 }
    717                 mLastTrack = track;
    718 
    719                 track->meta = new MetaData;
    720                 track->includes_expensive_metadata = false;
    721                 track->skipTrack = false;
    722                 track->timescale = 0;
    723                 track->meta->setCString(kKeyMIMEType, "application/octet-stream");
    724             }
    725 
    726             off64_t stop_offset = *offset + chunk_size;
    727             *offset = data_offset;
    728             while (*offset < stop_offset) {
    729                 status_t err = parseChunk(offset, depth + 1);
    730                 if (err != OK) {
    731                     return err;
    732                 }
    733             }
    734 
    735             if (*offset != stop_offset) {
    736                 return ERROR_MALFORMED;
    737             }
    738 
    739             if (isTrack) {
    740                 if (mLastTrack->skipTrack) {
    741                     Track *cur = mFirstTrack;
    742 
    743                     if (cur == mLastTrack) {
    744                         delete cur;
    745                         mFirstTrack = mLastTrack = NULL;
    746                     } else {
    747                         while (cur && cur->next != mLastTrack) {
    748                             cur = cur->next;
    749                         }
    750                         cur->next = NULL;
    751                         delete mLastTrack;
    752                         mLastTrack = cur;
    753                     }
    754 
    755                     return OK;
    756                 }
    757 
    758                 status_t err = verifyTrack(mLastTrack);
    759 
    760                 if (err != OK) {
    761                     return err;
    762                 }
    763             } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
    764                 mInitCheck = OK;
    765 
    766                 if (!mIsDrm) {
    767                     return UNKNOWN_ERROR;  // Return a dummy error.
    768                 } else {
    769                     return OK;
    770                 }
    771             }
    772             break;
    773         }
    774 
    775         case FOURCC('t', 'k', 'h', 'd'):
    776         {
    777             status_t err;
    778             if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) {
    779                 return err;
    780             }
    781 
    782             *offset += chunk_size;
    783             break;
    784         }
    785 
    786         case FOURCC('m', 'd', 'h', 'd'):
    787         {
    788             if (chunk_data_size < 4) {
    789                 return ERROR_MALFORMED;
    790             }
    791 
    792             uint8_t version;
    793             if (mDataSource->readAt(
    794                         data_offset, &version, sizeof(version))
    795                     < (ssize_t)sizeof(version)) {
    796                 return ERROR_IO;
    797             }
    798 
    799             off64_t timescale_offset;
    800 
    801             if (version == 1) {
    802                 timescale_offset = data_offset + 4 + 16;
    803             } else if (version == 0) {
    804                 timescale_offset = data_offset + 4 + 8;
    805             } else {
    806                 return ERROR_IO;
    807             }
    808 
    809             uint32_t timescale;
    810             if (mDataSource->readAt(
    811                         timescale_offset, &timescale, sizeof(timescale))
    812                     < (ssize_t)sizeof(timescale)) {
    813                 return ERROR_IO;
    814             }
    815 
    816             mLastTrack->timescale = ntohl(timescale);
    817 
    818             int64_t duration;
    819             if (version == 1) {
    820                 if (mDataSource->readAt(
    821                             timescale_offset + 4, &duration, sizeof(duration))
    822                         < (ssize_t)sizeof(duration)) {
    823                     return ERROR_IO;
    824                 }
    825                 duration = ntoh64(duration);
    826             } else {
    827                 int32_t duration32;
    828                 if (mDataSource->readAt(
    829                             timescale_offset + 4, &duration32, sizeof(duration32))
    830                         < (ssize_t)sizeof(duration32)) {
    831                     return ERROR_IO;
    832                 }
    833                 duration = ntohl(duration32);
    834             }
    835             mLastTrack->meta->setInt64(
    836                     kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
    837 
    838             uint8_t lang[2];
    839             off64_t lang_offset;
    840             if (version == 1) {
    841                 lang_offset = timescale_offset + 4 + 8;
    842             } else if (version == 0) {
    843                 lang_offset = timescale_offset + 4 + 4;
    844             } else {
    845                 return ERROR_IO;
    846             }
    847 
    848             if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
    849                     < (ssize_t)sizeof(lang)) {
    850                 return ERROR_IO;
    851             }
    852 
    853             // To get the ISO-639-2/T three character language code
    854             // 1 bit pad followed by 3 5-bits characters. Each character
    855             // is packed as the difference between its ASCII value and 0x60.
    856             char lang_code[4];
    857             lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
    858             lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
    859             lang_code[2] = (lang[1] & 0x1f) + 0x60;
    860             lang_code[3] = '\0';
    861 
    862             mLastTrack->meta->setCString(
    863                     kKeyMediaLanguage, lang_code);
    864 
    865             *offset += chunk_size;
    866             break;
    867         }
    868 
    869         case FOURCC('s', 't', 's', 'd'):
    870         {
    871             if (chunk_data_size < 8) {
    872                 return ERROR_MALFORMED;
    873             }
    874 
    875             uint8_t buffer[8];
    876             if (chunk_data_size < (off64_t)sizeof(buffer)) {
    877                 return ERROR_MALFORMED;
    878             }
    879 
    880             if (mDataSource->readAt(
    881                         data_offset, buffer, 8) < 8) {
    882                 return ERROR_IO;
    883             }
    884 
    885             if (U32_AT(buffer) != 0) {
    886                 // Should be version 0, flags 0.
    887                 return ERROR_MALFORMED;
    888             }
    889 
    890             uint32_t entry_count = U32_AT(&buffer[4]);
    891 
    892             if (entry_count > 1) {
    893                 // For 3GPP timed text, there could be multiple tx3g boxes contain
    894                 // multiple text display formats. These formats will be used to
    895                 // display the timed text.
    896                 const char *mime;
    897                 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
    898                 if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
    899                     // For now we only support a single type of media per track.
    900                     mLastTrack->skipTrack = true;
    901                     *offset += chunk_size;
    902                     break;
    903                 }
    904             }
    905 
    906             off64_t stop_offset = *offset + chunk_size;
    907             *offset = data_offset + 8;
    908             for (uint32_t i = 0; i < entry_count; ++i) {
    909                 status_t err = parseChunk(offset, depth + 1);
    910                 if (err != OK) {
    911                     return err;
    912                 }
    913             }
    914 
    915             if (*offset != stop_offset) {
    916                 return ERROR_MALFORMED;
    917             }
    918             break;
    919         }
    920 
    921         case FOURCC('m', 'p', '4', 'a'):
    922         case FOURCC('s', 'a', 'm', 'r'):
    923         case FOURCC('s', 'a', 'w', 'b'):
    924         {
    925             uint8_t buffer[8 + 20];
    926             if (chunk_data_size < (ssize_t)sizeof(buffer)) {
    927                 // Basic AudioSampleEntry size.
    928                 return ERROR_MALFORMED;
    929             }
    930 
    931             if (mDataSource->readAt(
    932                         data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
    933                 return ERROR_IO;
    934             }
    935 
    936             uint16_t data_ref_index = U16_AT(&buffer[6]);
    937             uint16_t num_channels = U16_AT(&buffer[16]);
    938 
    939             uint16_t sample_size = U16_AT(&buffer[18]);
    940             uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
    941 
    942             if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
    943                             FourCC2MIME(chunk_type))) {
    944                 // AMR NB audio is always mono, 8kHz
    945                 num_channels = 1;
    946                 sample_rate = 8000;
    947             } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
    948                                FourCC2MIME(chunk_type))) {
    949                 // AMR WB audio is always mono, 16kHz
    950                 num_channels = 1;
    951                 sample_rate = 16000;
    952             }
    953 
    954 #if 0
    955             printf("*** coding='%s' %d channels, size %d, rate %d\n",
    956                    chunk, num_channels, sample_size, sample_rate);
    957 #endif
    958 
    959             mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
    960             mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
    961             mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
    962 
    963             off64_t stop_offset = *offset + chunk_size;
    964             *offset = data_offset + sizeof(buffer);
    965             while (*offset < stop_offset) {
    966                 status_t err = parseChunk(offset, depth + 1);
    967                 if (err != OK) {
    968                     return err;
    969                 }
    970             }
    971 
    972             if (*offset != stop_offset) {
    973                 return ERROR_MALFORMED;
    974             }
    975             break;
    976         }
    977 
    978         case FOURCC('m', 'p', '4', 'v'):
    979         case FOURCC('s', '2', '6', '3'):
    980         case FOURCC('H', '2', '6', '3'):
    981         case FOURCC('h', '2', '6', '3'):
    982         case FOURCC('a', 'v', 'c', '1'):
    983         {
    984             mHasVideo = true;
    985 
    986             uint8_t buffer[78];
    987             if (chunk_data_size < (ssize_t)sizeof(buffer)) {
    988                 // Basic VideoSampleEntry size.
    989                 return ERROR_MALFORMED;
    990             }
    991 
    992             if (mDataSource->readAt(
    993                         data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
    994                 return ERROR_IO;
    995             }
    996 
    997             uint16_t data_ref_index = U16_AT(&buffer[6]);
    998             uint16_t width = U16_AT(&buffer[6 + 18]);
    999             uint16_t height = U16_AT(&buffer[6 + 20]);
   1000 
   1001             // The video sample is not stand-compliant if it has invalid dimension.
   1002             // Use some default width and height value, and
   1003             // let the decoder figure out the actual width and height (and thus
   1004             // be prepared for INFO_FOMRAT_CHANGED event).
   1005             if (width == 0)  width  = 352;
   1006             if (height == 0) height = 288;
   1007 
   1008             // printf("*** coding='%s' width=%d height=%d\n",
   1009             //        chunk, width, height);
   1010 
   1011             mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
   1012             mLastTrack->meta->setInt32(kKeyWidth, width);
   1013             mLastTrack->meta->setInt32(kKeyHeight, height);
   1014 
   1015             off64_t stop_offset = *offset + chunk_size;
   1016             *offset = data_offset + sizeof(buffer);
   1017             while (*offset < stop_offset) {
   1018                 status_t err = parseChunk(offset, depth + 1);
   1019                 if (err != OK) {
   1020                     return err;
   1021                 }
   1022             }
   1023 
   1024             if (*offset != stop_offset) {
   1025                 return ERROR_MALFORMED;
   1026             }
   1027             break;
   1028         }
   1029 
   1030         case FOURCC('s', 't', 'c', 'o'):
   1031         case FOURCC('c', 'o', '6', '4'):
   1032         {
   1033             status_t err =
   1034                 mLastTrack->sampleTable->setChunkOffsetParams(
   1035                         chunk_type, data_offset, chunk_data_size);
   1036 
   1037             if (err != OK) {
   1038                 return err;
   1039             }
   1040 
   1041             *offset += chunk_size;
   1042             break;
   1043         }
   1044 
   1045         case FOURCC('s', 't', 's', 'c'):
   1046         {
   1047             status_t err =
   1048                 mLastTrack->sampleTable->setSampleToChunkParams(
   1049                         data_offset, chunk_data_size);
   1050 
   1051             if (err != OK) {
   1052                 return err;
   1053             }
   1054 
   1055             *offset += chunk_size;
   1056             break;
   1057         }
   1058 
   1059         case FOURCC('s', 't', 's', 'z'):
   1060         case FOURCC('s', 't', 'z', '2'):
   1061         {
   1062             status_t err =
   1063                 mLastTrack->sampleTable->setSampleSizeParams(
   1064                         chunk_type, data_offset, chunk_data_size);
   1065 
   1066             if (err != OK) {
   1067                 return err;
   1068             }
   1069 
   1070             size_t max_size;
   1071             err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
   1072 
   1073             if (err != OK) {
   1074                 return err;
   1075             }
   1076 
   1077             // Assume that a given buffer only contains at most 10 fragments,
   1078             // each fragment originally prefixed with a 2 byte length will
   1079             // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
   1080             // and thus will grow by 2 bytes per fragment.
   1081             mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
   1082             *offset += chunk_size;
   1083 
   1084             // Calculate average frame rate.
   1085             const char *mime;
   1086             CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
   1087             if (!strncasecmp("video/", mime, 6)) {
   1088                 size_t nSamples = mLastTrack->sampleTable->countSamples();
   1089                 int64_t durationUs;
   1090                 if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
   1091                     if (durationUs > 0) {
   1092                         int32_t frameRate = (nSamples * 1000000LL +
   1093                                     (durationUs >> 1)) / durationUs;
   1094                         mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
   1095                     }
   1096                 }
   1097             }
   1098 
   1099             break;
   1100         }
   1101 
   1102         case FOURCC('s', 't', 't', 's'):
   1103         {
   1104             status_t err =
   1105                 mLastTrack->sampleTable->setTimeToSampleParams(
   1106                         data_offset, chunk_data_size);
   1107 
   1108             if (err != OK) {
   1109                 return err;
   1110             }
   1111 
   1112             *offset += chunk_size;
   1113             break;
   1114         }
   1115 
   1116         case FOURCC('c', 't', 't', 's'):
   1117         {
   1118             status_t err =
   1119                 mLastTrack->sampleTable->setCompositionTimeToSampleParams(
   1120                         data_offset, chunk_data_size);
   1121 
   1122             if (err != OK) {
   1123                 return err;
   1124             }
   1125 
   1126             *offset += chunk_size;
   1127             break;
   1128         }
   1129 
   1130         case FOURCC('s', 't', 's', 's'):
   1131         {
   1132             status_t err =
   1133                 mLastTrack->sampleTable->setSyncSampleParams(
   1134                         data_offset, chunk_data_size);
   1135 
   1136             if (err != OK) {
   1137                 return err;
   1138             }
   1139 
   1140             *offset += chunk_size;
   1141             break;
   1142         }
   1143 
   1144         // @xyz
   1145         case FOURCC('\xA9', 'x', 'y', 'z'):
   1146         {
   1147             // Best case the total data length inside "@xyz" box
   1148             // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/",
   1149             // where "\x00\x04" is the text string length with value = 4,
   1150             // "\0x15\xc7" is the language code = en, and "0+0" is a
   1151             // location (string) value with longitude = 0 and latitude = 0.
   1152             if (chunk_data_size < 8) {
   1153                 return ERROR_MALFORMED;
   1154             }
   1155 
   1156             // Worst case the location string length would be 18,
   1157             // for instance +90.0000-180.0000, without the trailing "/" and
   1158             // the string length + language code.
   1159             char buffer[18];
   1160 
   1161             // Substracting 5 from the data size is because the text string length +
   1162             // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
   1163             off64_t location_length = chunk_data_size - 5;
   1164             if (location_length >= (off64_t) sizeof(buffer)) {
   1165                 return ERROR_MALFORMED;
   1166             }
   1167 
   1168             if (mDataSource->readAt(
   1169                         data_offset + 4, buffer, location_length) < location_length) {
   1170                 return ERROR_IO;
   1171             }
   1172 
   1173             buffer[location_length] = '\0';
   1174             mFileMetaData->setCString(kKeyLocation, buffer);
   1175             *offset += chunk_size;
   1176             break;
   1177         }
   1178 
   1179         case FOURCC('e', 's', 'd', 's'):
   1180         {
   1181             if (chunk_data_size < 4) {
   1182                 return ERROR_MALFORMED;
   1183             }
   1184 
   1185             uint8_t buffer[256];
   1186             if (chunk_data_size > (off64_t)sizeof(buffer)) {
   1187                 return ERROR_BUFFER_TOO_SMALL;
   1188             }
   1189 
   1190             if (mDataSource->readAt(
   1191                         data_offset, buffer, chunk_data_size) < chunk_data_size) {
   1192                 return ERROR_IO;
   1193             }
   1194 
   1195             if (U32_AT(buffer) != 0) {
   1196                 // Should be version 0, flags 0.
   1197                 return ERROR_MALFORMED;
   1198             }
   1199 
   1200             mLastTrack->meta->setData(
   1201                     kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
   1202 
   1203             if (mPath.size() >= 2
   1204                     && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
   1205                 // Information from the ESDS must be relied on for proper
   1206                 // setup of sample rate and channel count for MPEG4 Audio.
   1207                 // The generic header appears to only contain generic
   1208                 // information...
   1209 
   1210                 status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
   1211                         &buffer[4], chunk_data_size - 4);
   1212 
   1213                 if (err != OK) {
   1214                     return err;
   1215                 }
   1216             }
   1217 
   1218             *offset += chunk_size;
   1219             break;
   1220         }
   1221 
   1222         case FOURCC('a', 'v', 'c', 'C'):
   1223         {
   1224             char buffer[256];
   1225             if (chunk_data_size > (off64_t)sizeof(buffer)) {
   1226                 return ERROR_BUFFER_TOO_SMALL;
   1227             }
   1228 
   1229             if (mDataSource->readAt(
   1230                         data_offset, buffer, chunk_data_size) < chunk_data_size) {
   1231                 return ERROR_IO;
   1232             }
   1233 
   1234             mLastTrack->meta->setData(
   1235                     kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
   1236 
   1237             *offset += chunk_size;
   1238             break;
   1239         }
   1240 
   1241         case FOURCC('d', '2', '6', '3'):
   1242         {
   1243             /*
   1244              * d263 contains a fixed 7 bytes part:
   1245              *   vendor - 4 bytes
   1246              *   version - 1 byte
   1247              *   level - 1 byte
   1248              *   profile - 1 byte
   1249              * optionally, "d263" box itself may contain a 16-byte
   1250              * bit rate box (bitr)
   1251              *   average bit rate - 4 bytes
   1252              *   max bit rate - 4 bytes
   1253              */
   1254             char buffer[23];
   1255             if (chunk_data_size != 7 &&
   1256                 chunk_data_size != 23) {
   1257                 ALOGE("Incorrect D263 box size %lld", chunk_data_size);
   1258                 return ERROR_MALFORMED;
   1259             }
   1260 
   1261             if (mDataSource->readAt(
   1262                     data_offset, buffer, chunk_data_size) < chunk_data_size) {
   1263                 return ERROR_IO;
   1264             }
   1265 
   1266             mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size);
   1267 
   1268             *offset += chunk_size;
   1269             break;
   1270         }
   1271 
   1272         case FOURCC('m', 'e', 't', 'a'):
   1273         {
   1274             uint8_t buffer[4];
   1275             if (chunk_data_size < (off64_t)sizeof(buffer)) {
   1276                 return ERROR_MALFORMED;
   1277             }
   1278 
   1279             if (mDataSource->readAt(
   1280                         data_offset, buffer, 4) < 4) {
   1281                 return ERROR_IO;
   1282             }
   1283 
   1284             if (U32_AT(buffer) != 0) {
   1285                 // Should be version 0, flags 0.
   1286 
   1287                 // If it's not, let's assume this is one of those
   1288                 // apparently malformed chunks that don't have flags
   1289                 // and completely different semantics than what's
   1290                 // in the MPEG4 specs and skip it.
   1291                 *offset += chunk_size;
   1292                 return OK;
   1293             }
   1294 
   1295             off64_t stop_offset = *offset + chunk_size;
   1296             *offset = data_offset + sizeof(buffer);
   1297             while (*offset < stop_offset) {
   1298                 status_t err = parseChunk(offset, depth + 1);
   1299                 if (err != OK) {
   1300                     return err;
   1301                 }
   1302             }
   1303 
   1304             if (*offset != stop_offset) {
   1305                 return ERROR_MALFORMED;
   1306             }
   1307             break;
   1308         }
   1309 
   1310         case FOURCC('m', 'e', 'a', 'n'):
   1311         case FOURCC('n', 'a', 'm', 'e'):
   1312         case FOURCC('d', 'a', 't', 'a'):
   1313         {
   1314             if (mPath.size() == 6 && underMetaDataPath(mPath)) {
   1315                 status_t err = parseMetaData(data_offset, chunk_data_size);
   1316 
   1317                 if (err != OK) {
   1318                     return err;
   1319                 }
   1320             }
   1321 
   1322             *offset += chunk_size;
   1323             break;
   1324         }
   1325 
   1326         case FOURCC('m', 'v', 'h', 'd'):
   1327         {
   1328             if (chunk_data_size < 12) {
   1329                 return ERROR_MALFORMED;
   1330             }
   1331 
   1332             uint8_t header[12];
   1333             if (mDataSource->readAt(
   1334                         data_offset, header, sizeof(header))
   1335                     < (ssize_t)sizeof(header)) {
   1336                 return ERROR_IO;
   1337             }
   1338 
   1339             int64_t creationTime;
   1340             if (header[0] == 1) {
   1341                 creationTime = U64_AT(&header[4]);
   1342             } else if (header[0] != 0) {
   1343                 return ERROR_MALFORMED;
   1344             } else {
   1345                 creationTime = U32_AT(&header[4]);
   1346             }
   1347 
   1348             String8 s;
   1349             convertTimeToDate(creationTime, &s);
   1350 
   1351             mFileMetaData->setCString(kKeyDate, s.string());
   1352 
   1353             *offset += chunk_size;
   1354             break;
   1355         }
   1356 
   1357         case FOURCC('m', 'd', 'a', 't'):
   1358         {
   1359             if (!mIsDrm) {
   1360                 *offset += chunk_size;
   1361                 break;
   1362             }
   1363 
   1364             if (chunk_size < 8) {
   1365                 return ERROR_MALFORMED;
   1366             }
   1367 
   1368             return parseDrmSINF(offset, data_offset);
   1369         }
   1370 
   1371         case FOURCC('h', 'd', 'l', 'r'):
   1372         {
   1373             uint32_t buffer;
   1374             if (mDataSource->readAt(
   1375                         data_offset + 8, &buffer, 4) < 4) {
   1376                 return ERROR_IO;
   1377             }
   1378 
   1379             uint32_t type = ntohl(buffer);
   1380             // For the 3GPP file format, the handler-type within the 'hdlr' box
   1381             // shall be 'text'. We also want to support 'sbtl' handler type
   1382             // for a practical reason as various MPEG4 containers use it.
   1383             if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) {
   1384                 mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_TEXT_3GPP);
   1385             }
   1386 
   1387             *offset += chunk_size;
   1388             break;
   1389         }
   1390 
   1391         case FOURCC('t', 'x', '3', 'g'):
   1392         {
   1393             uint32_t type;
   1394             const void *data;
   1395             size_t size = 0;
   1396             if (!mLastTrack->meta->findData(
   1397                     kKeyTextFormatData, &type, &data, &size)) {
   1398                 size = 0;
   1399             }
   1400 
   1401             uint8_t *buffer = new uint8_t[size + chunk_size];
   1402 
   1403             if (size > 0) {
   1404                 memcpy(buffer, data, size);
   1405             }
   1406 
   1407             if ((size_t)(mDataSource->readAt(*offset, buffer + size, chunk_size))
   1408                     < chunk_size) {
   1409                 delete[] buffer;
   1410                 buffer = NULL;
   1411 
   1412                 return ERROR_IO;
   1413             }
   1414 
   1415             mLastTrack->meta->setData(
   1416                     kKeyTextFormatData, 0, buffer, size + chunk_size);
   1417 
   1418             delete[] buffer;
   1419 
   1420             *offset += chunk_size;
   1421             break;
   1422         }
   1423 
   1424         case FOURCC('c', 'o', 'v', 'r'):
   1425         {
   1426             if (mFileMetaData != NULL) {
   1427                 ALOGV("chunk_data_size = %lld and data_offset = %lld",
   1428                         chunk_data_size, data_offset);
   1429                 uint8_t *buffer = new uint8_t[chunk_data_size + 1];
   1430                 if (mDataSource->readAt(
   1431                     data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) {
   1432                     delete[] buffer;
   1433                     buffer = NULL;
   1434 
   1435                     return ERROR_IO;
   1436                 }
   1437                 const int kSkipBytesOfDataBox = 16;
   1438                 mFileMetaData->setData(
   1439                     kKeyAlbumArt, MetaData::TYPE_NONE,
   1440                     buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
   1441             }
   1442 
   1443             *offset += chunk_size;
   1444             break;
   1445         }
   1446 
   1447         case FOURCC('-', '-', '-', '-'):
   1448         {
   1449             mLastCommentMean.clear();
   1450             mLastCommentName.clear();
   1451             mLastCommentData.clear();
   1452             *offset += chunk_size;
   1453             break;
   1454         }
   1455 
   1456         default:
   1457         {
   1458             *offset += chunk_size;
   1459             break;
   1460         }
   1461     }
   1462 
   1463     return OK;
   1464 }
   1465 
   1466 status_t MPEG4Extractor::parseTrackHeader(
   1467         off64_t data_offset, off64_t data_size) {
   1468     if (data_size < 4) {
   1469         return ERROR_MALFORMED;
   1470     }
   1471 
   1472     uint8_t version;
   1473     if (mDataSource->readAt(data_offset, &version, 1) < 1) {
   1474         return ERROR_IO;
   1475     }
   1476 
   1477     size_t dynSize = (version == 1) ? 36 : 24;
   1478 
   1479     uint8_t buffer[36 + 60];
   1480 
   1481     if (data_size != (off64_t)dynSize + 60) {
   1482         return ERROR_MALFORMED;
   1483     }
   1484 
   1485     if (mDataSource->readAt(
   1486                 data_offset, buffer, data_size) < (ssize_t)data_size) {
   1487         return ERROR_IO;
   1488     }
   1489 
   1490     uint64_t ctime, mtime, duration;
   1491     int32_t id;
   1492 
   1493     if (version == 1) {
   1494         ctime = U64_AT(&buffer[4]);
   1495         mtime = U64_AT(&buffer[12]);
   1496         id = U32_AT(&buffer[20]);
   1497         duration = U64_AT(&buffer[28]);
   1498     } else {
   1499         CHECK_EQ((unsigned)version, 0u);
   1500 
   1501         ctime = U32_AT(&buffer[4]);
   1502         mtime = U32_AT(&buffer[8]);
   1503         id = U32_AT(&buffer[12]);
   1504         duration = U32_AT(&buffer[20]);
   1505     }
   1506 
   1507     mLastTrack->meta->setInt32(kKeyTrackID, id);
   1508 
   1509     size_t matrixOffset = dynSize + 16;
   1510     int32_t a00 = U32_AT(&buffer[matrixOffset]);
   1511     int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
   1512     int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
   1513     int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
   1514     int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
   1515     int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
   1516 
   1517 #if 0
   1518     ALOGI("x' = %.2f * x + %.2f * y + %.2f",
   1519          a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
   1520     ALOGI("y' = %.2f * x + %.2f * y + %.2f",
   1521          a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
   1522 #endif
   1523 
   1524     uint32_t rotationDegrees;
   1525 
   1526     static const int32_t kFixedOne = 0x10000;
   1527     if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
   1528         // Identity, no rotation
   1529         rotationDegrees = 0;
   1530     } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
   1531         rotationDegrees = 90;
   1532     } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
   1533         rotationDegrees = 270;
   1534     } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
   1535         rotationDegrees = 180;
   1536     } else {
   1537         ALOGW("We only support 0,90,180,270 degree rotation matrices");
   1538         rotationDegrees = 0;
   1539     }
   1540 
   1541     if (rotationDegrees != 0) {
   1542         mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
   1543     }
   1544 
   1545     // Handle presentation display size, which could be different
   1546     // from the image size indicated by kKeyWidth and kKeyHeight.
   1547     uint32_t width = U32_AT(&buffer[dynSize + 52]);
   1548     uint32_t height = U32_AT(&buffer[dynSize + 56]);
   1549     mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16);
   1550     mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16);
   1551 
   1552     return OK;
   1553 }
   1554 
   1555 status_t MPEG4Extractor::parseMetaData(off64_t offset, size_t size) {
   1556     if (size < 4) {
   1557         return ERROR_MALFORMED;
   1558     }
   1559 
   1560     uint8_t *buffer = new uint8_t[size + 1];
   1561     if (mDataSource->readAt(
   1562                 offset, buffer, size) != (ssize_t)size) {
   1563         delete[] buffer;
   1564         buffer = NULL;
   1565 
   1566         return ERROR_IO;
   1567     }
   1568 
   1569     uint32_t flags = U32_AT(buffer);
   1570 
   1571     uint32_t metadataKey = 0;
   1572     char chunk[5];
   1573     MakeFourCCString(mPath[4], chunk);
   1574     ALOGV("meta: %s @ %lld", chunk, offset);
   1575     switch (mPath[4]) {
   1576         case FOURCC(0xa9, 'a', 'l', 'b'):
   1577         {
   1578             metadataKey = kKeyAlbum;
   1579             break;
   1580         }
   1581         case FOURCC(0xa9, 'A', 'R', 'T'):
   1582         {
   1583             metadataKey = kKeyArtist;
   1584             break;
   1585         }
   1586         case FOURCC('a', 'A', 'R', 'T'):
   1587         {
   1588             metadataKey = kKeyAlbumArtist;
   1589             break;
   1590         }
   1591         case FOURCC(0xa9, 'd', 'a', 'y'):
   1592         {
   1593             metadataKey = kKeyYear;
   1594             break;
   1595         }
   1596         case FOURCC(0xa9, 'n', 'a', 'm'):
   1597         {
   1598             metadataKey = kKeyTitle;
   1599             break;
   1600         }
   1601         case FOURCC(0xa9, 'w', 'r', 't'):
   1602         {
   1603             metadataKey = kKeyWriter;
   1604             break;
   1605         }
   1606         case FOURCC('c', 'o', 'v', 'r'):
   1607         {
   1608             metadataKey = kKeyAlbumArt;
   1609             break;
   1610         }
   1611         case FOURCC('g', 'n', 'r', 'e'):
   1612         {
   1613             metadataKey = kKeyGenre;
   1614             break;
   1615         }
   1616         case FOURCC(0xa9, 'g', 'e', 'n'):
   1617         {
   1618             metadataKey = kKeyGenre;
   1619             break;
   1620         }
   1621         case FOURCC('c', 'p', 'i', 'l'):
   1622         {
   1623             if (size == 9 && flags == 21) {
   1624                 char tmp[16];
   1625                 sprintf(tmp, "%d",
   1626                         (int)buffer[size - 1]);
   1627 
   1628                 mFileMetaData->setCString(kKeyCompilation, tmp);
   1629             }
   1630             break;
   1631         }
   1632         case FOURCC('t', 'r', 'k', 'n'):
   1633         {
   1634             if (size == 16 && flags == 0) {
   1635                 char tmp[16];
   1636                 sprintf(tmp, "%d/%d",
   1637                         (int)buffer[size - 5], (int)buffer[size - 3]);
   1638 
   1639                 mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
   1640             }
   1641             break;
   1642         }
   1643         case FOURCC('d', 'i', 's', 'k'):
   1644         {
   1645             if (size == 14 && flags == 0) {
   1646                 char tmp[16];
   1647                 sprintf(tmp, "%d/%d",
   1648                         (int)buffer[size - 3], (int)buffer[size - 1]);
   1649 
   1650                 mFileMetaData->setCString(kKeyDiscNumber, tmp);
   1651             }
   1652             break;
   1653         }
   1654         case FOURCC('-', '-', '-', '-'):
   1655         {
   1656             buffer[size] = '\0';
   1657             switch (mPath[5]) {
   1658                 case FOURCC('m', 'e', 'a', 'n'):
   1659                     mLastCommentMean.setTo((const char *)buffer + 4);
   1660                     break;
   1661                 case FOURCC('n', 'a', 'm', 'e'):
   1662                     mLastCommentName.setTo((const char *)buffer + 4);
   1663                     break;
   1664                 case FOURCC('d', 'a', 't', 'a'):
   1665                     mLastCommentData.setTo((const char *)buffer + 8);
   1666                     break;
   1667             }
   1668 
   1669             // Once we have a set of mean/name/data info, go ahead and process
   1670             // it to see if its something we are interested in.  Whether or not
   1671             // were are interested in the specific tag, make sure to clear out
   1672             // the set so we can be ready to process another tuple should one
   1673             // show up later in the file.
   1674             if ((mLastCommentMean.length() != 0) &&
   1675                 (mLastCommentName.length() != 0) &&
   1676                 (mLastCommentData.length() != 0)) {
   1677 
   1678                 if (mLastCommentMean == "com.apple.iTunes"
   1679                         && mLastCommentName == "iTunSMPB") {
   1680                     int32_t delay, padding;
   1681                     if (sscanf(mLastCommentData,
   1682                                " %*x %x %x %*x", &delay, &padding) == 2) {
   1683                         mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
   1684                         mLastTrack->meta->setInt32(kKeyEncoderPadding, padding);
   1685                     }
   1686                 }
   1687 
   1688                 mLastCommentMean.clear();
   1689                 mLastCommentName.clear();
   1690                 mLastCommentData.clear();
   1691             }
   1692             break;
   1693         }
   1694 
   1695         default:
   1696             break;
   1697     }
   1698 
   1699     if (size >= 8 && metadataKey) {
   1700         if (metadataKey == kKeyAlbumArt) {
   1701             mFileMetaData->setData(
   1702                     kKeyAlbumArt, MetaData::TYPE_NONE,
   1703                     buffer + 8, size - 8);
   1704         } else if (metadataKey == kKeyGenre) {
   1705             if (flags == 0) {
   1706                 // uint8_t genre code, iTunes genre codes are
   1707                 // the standard id3 codes, except they start
   1708                 // at 1 instead of 0 (e.g. Pop is 14, not 13)
   1709                 // We use standard id3 numbering, so subtract 1.
   1710                 int genrecode = (int)buffer[size - 1];
   1711                 genrecode--;
   1712                 if (genrecode < 0) {
   1713                     genrecode = 255; // reserved for 'unknown genre'
   1714                 }
   1715                 char genre[10];
   1716                 sprintf(genre, "%d", genrecode);
   1717 
   1718                 mFileMetaData->setCString(metadataKey, genre);
   1719             } else if (flags == 1) {
   1720                 // custom genre string
   1721                 buffer[size] = '\0';
   1722 
   1723                 mFileMetaData->setCString(
   1724                         metadataKey, (const char *)buffer + 8);
   1725             }
   1726         } else {
   1727             buffer[size] = '\0';
   1728 
   1729             mFileMetaData->setCString(
   1730                     metadataKey, (const char *)buffer + 8);
   1731         }
   1732     }
   1733 
   1734     delete[] buffer;
   1735     buffer = NULL;
   1736 
   1737     return OK;
   1738 }
   1739 
   1740 sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
   1741     status_t err;
   1742     if ((err = readMetaData()) != OK) {
   1743         return NULL;
   1744     }
   1745 
   1746     Track *track = mFirstTrack;
   1747     while (index > 0) {
   1748         if (track == NULL) {
   1749             return NULL;
   1750         }
   1751 
   1752         track = track->next;
   1753         --index;
   1754     }
   1755 
   1756     if (track == NULL) {
   1757         return NULL;
   1758     }
   1759 
   1760     return new MPEG4Source(
   1761             track->meta, mDataSource, track->timescale, track->sampleTable);
   1762 }
   1763 
   1764 // static
   1765 status_t MPEG4Extractor::verifyTrack(Track *track) {
   1766     const char *mime;
   1767     CHECK(track->meta->findCString(kKeyMIMEType, &mime));
   1768 
   1769     uint32_t type;
   1770     const void *data;
   1771     size_t size;
   1772     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
   1773         if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
   1774                 || type != kTypeAVCC) {
   1775             return ERROR_MALFORMED;
   1776         }
   1777     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
   1778             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
   1779         if (!track->meta->findData(kKeyESDS, &type, &data, &size)
   1780                 || type != kTypeESDS) {
   1781             return ERROR_MALFORMED;
   1782         }
   1783     }
   1784 
   1785     if (!track->sampleTable->isValid()) {
   1786         // Make sure we have all the metadata we need.
   1787         return ERROR_MALFORMED;
   1788     }
   1789 
   1790     return OK;
   1791 }
   1792 
   1793 status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
   1794         const void *esds_data, size_t esds_size) {
   1795     ESDS esds(esds_data, esds_size);
   1796 
   1797     uint8_t objectTypeIndication;
   1798     if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
   1799         return ERROR_MALFORMED;
   1800     }
   1801 
   1802     if (objectTypeIndication == 0xe1) {
   1803         // This isn't MPEG4 audio at all, it's QCELP 14k...
   1804         mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
   1805         return OK;
   1806     }
   1807 
   1808     if (objectTypeIndication  == 0x6b) {
   1809         // The media subtype is MP3 audio
   1810         // Our software MP3 audio decoder may not be able to handle
   1811         // packetized MP3 audio; for now, lets just return ERROR_UNSUPPORTED
   1812         ALOGE("MP3 track in MP4/3GPP file is not supported");
   1813         return ERROR_UNSUPPORTED;
   1814     }
   1815 
   1816     const uint8_t *csd;
   1817     size_t csd_size;
   1818     if (esds.getCodecSpecificInfo(
   1819                 (const void **)&csd, &csd_size) != OK) {
   1820         return ERROR_MALFORMED;
   1821     }
   1822 
   1823 #if 0
   1824     printf("ESD of size %d\n", csd_size);
   1825     hexdump(csd, csd_size);
   1826 #endif
   1827 
   1828     if (csd_size == 0) {
   1829         // There's no further information, i.e. no codec specific data
   1830         // Let's assume that the information provided in the mpeg4 headers
   1831         // is accurate and hope for the best.
   1832 
   1833         return OK;
   1834     }
   1835 
   1836     if (csd_size < 2) {
   1837         return ERROR_MALFORMED;
   1838     }
   1839 
   1840     ABitReader br(csd, csd_size);
   1841     uint32_t objectType = br.getBits(5);
   1842 
   1843     if (objectType == 31) {  // AAC-ELD => additional 6 bits
   1844         objectType = 32 + br.getBits(6);
   1845     }
   1846 
   1847     uint32_t freqIndex = br.getBits(4);
   1848 
   1849     int32_t sampleRate = 0;
   1850     int32_t numChannels = 0;
   1851     if (freqIndex == 15) {
   1852         if (csd_size < 5) {
   1853             return ERROR_MALFORMED;
   1854         }
   1855         sampleRate = br.getBits(24);
   1856         numChannels = br.getBits(4);
   1857     } else {
   1858         static uint32_t kSamplingRate[] = {
   1859             96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
   1860             16000, 12000, 11025, 8000, 7350
   1861         };
   1862 
   1863         if (freqIndex == 13 || freqIndex == 14) {
   1864             return ERROR_MALFORMED;
   1865         }
   1866 
   1867         sampleRate = kSamplingRate[freqIndex];
   1868         numChannels = br.getBits(4);
   1869     }
   1870 
   1871     if (numChannels == 0) {
   1872         return ERROR_UNSUPPORTED;
   1873     }
   1874 
   1875     int32_t prevSampleRate;
   1876     CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
   1877 
   1878     if (prevSampleRate != sampleRate) {
   1879         ALOGV("mpeg4 audio sample rate different from previous setting. "
   1880              "was: %d, now: %d", prevSampleRate, sampleRate);
   1881     }
   1882 
   1883     mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
   1884 
   1885     int32_t prevChannelCount;
   1886     CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
   1887 
   1888     if (prevChannelCount != numChannels) {
   1889         ALOGV("mpeg4 audio channel count different from previous setting. "
   1890              "was: %d, now: %d", prevChannelCount, numChannels);
   1891     }
   1892 
   1893     mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
   1894 
   1895     return OK;
   1896 }
   1897 
   1898 ////////////////////////////////////////////////////////////////////////////////
   1899 
   1900 MPEG4Source::MPEG4Source(
   1901         const sp<MetaData> &format,
   1902         const sp<DataSource> &dataSource,
   1903         int32_t timeScale,
   1904         const sp<SampleTable> &sampleTable)
   1905     : mFormat(format),
   1906       mDataSource(dataSource),
   1907       mTimescale(timeScale),
   1908       mSampleTable(sampleTable),
   1909       mCurrentSampleIndex(0),
   1910       mIsAVC(false),
   1911       mNALLengthSize(0),
   1912       mStarted(false),
   1913       mGroup(NULL),
   1914       mBuffer(NULL),
   1915       mWantsNALFragments(false),
   1916       mSrcBuffer(NULL) {
   1917     const char *mime;
   1918     bool success = mFormat->findCString(kKeyMIMEType, &mime);
   1919     CHECK(success);
   1920 
   1921     mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
   1922 
   1923     if (mIsAVC) {
   1924         uint32_t type;
   1925         const void *data;
   1926         size_t size;
   1927         CHECK(format->findData(kKeyAVCC, &type, &data, &size));
   1928 
   1929         const uint8_t *ptr = (const uint8_t *)data;
   1930 
   1931         CHECK(size >= 7);
   1932         CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
   1933 
   1934         // The number of bytes used to encode the length of a NAL unit.
   1935         mNALLengthSize = 1 + (ptr[4] & 3);
   1936     }
   1937 }
   1938 
   1939 MPEG4Source::~MPEG4Source() {
   1940     if (mStarted) {
   1941         stop();
   1942     }
   1943 }
   1944 
   1945 status_t MPEG4Source::start(MetaData *params) {
   1946     Mutex::Autolock autoLock(mLock);
   1947 
   1948     CHECK(!mStarted);
   1949 
   1950     int32_t val;
   1951     if (params && params->findInt32(kKeyWantsNALFragments, &val)
   1952         && val != 0) {
   1953         mWantsNALFragments = true;
   1954     } else {
   1955         mWantsNALFragments = false;
   1956     }
   1957 
   1958     mGroup = new MediaBufferGroup;
   1959 
   1960     int32_t max_size;
   1961     CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
   1962 
   1963     mGroup->add_buffer(new MediaBuffer(max_size));
   1964 
   1965     mSrcBuffer = new uint8_t[max_size];
   1966 
   1967     mStarted = true;
   1968 
   1969     return OK;
   1970 }
   1971 
   1972 status_t MPEG4Source::stop() {
   1973     Mutex::Autolock autoLock(mLock);
   1974 
   1975     CHECK(mStarted);
   1976 
   1977     if (mBuffer != NULL) {
   1978         mBuffer->release();
   1979         mBuffer = NULL;
   1980     }
   1981 
   1982     delete[] mSrcBuffer;
   1983     mSrcBuffer = NULL;
   1984 
   1985     delete mGroup;
   1986     mGroup = NULL;
   1987 
   1988     mStarted = false;
   1989     mCurrentSampleIndex = 0;
   1990 
   1991     return OK;
   1992 }
   1993 
   1994 sp<MetaData> MPEG4Source::getFormat() {
   1995     Mutex::Autolock autoLock(mLock);
   1996 
   1997     return mFormat;
   1998 }
   1999 
   2000 size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
   2001     switch (mNALLengthSize) {
   2002         case 1:
   2003             return *data;
   2004         case 2:
   2005             return U16_AT(data);
   2006         case 3:
   2007             return ((size_t)data[0] << 16) | U16_AT(&data[1]);
   2008         case 4:
   2009             return U32_AT(data);
   2010     }
   2011 
   2012     // This cannot happen, mNALLengthSize springs to life by adding 1 to
   2013     // a 2-bit integer.
   2014     CHECK(!"Should not be here.");
   2015 
   2016     return 0;
   2017 }
   2018 
   2019 status_t MPEG4Source::read(
   2020         MediaBuffer **out, const ReadOptions *options) {
   2021     Mutex::Autolock autoLock(mLock);
   2022 
   2023     CHECK(mStarted);
   2024 
   2025     *out = NULL;
   2026 
   2027     int64_t targetSampleTimeUs = -1;
   2028 
   2029     int64_t seekTimeUs;
   2030     ReadOptions::SeekMode mode;
   2031     if (options && options->getSeekTo(&seekTimeUs, &mode)) {
   2032         uint32_t findFlags = 0;
   2033         switch (mode) {
   2034             case ReadOptions::SEEK_PREVIOUS_SYNC:
   2035                 findFlags = SampleTable::kFlagBefore;
   2036                 break;
   2037             case ReadOptions::SEEK_NEXT_SYNC:
   2038                 findFlags = SampleTable::kFlagAfter;
   2039                 break;
   2040             case ReadOptions::SEEK_CLOSEST_SYNC:
   2041             case ReadOptions::SEEK_CLOSEST:
   2042                 findFlags = SampleTable::kFlagClosest;
   2043                 break;
   2044             default:
   2045                 CHECK(!"Should not be here.");
   2046                 break;
   2047         }
   2048 
   2049         uint32_t sampleIndex;
   2050         status_t err = mSampleTable->findSampleAtTime(
   2051                 seekTimeUs * mTimescale / 1000000,
   2052                 &sampleIndex, findFlags);
   2053 
   2054         if (mode == ReadOptions::SEEK_CLOSEST) {
   2055             // We found the closest sample already, now we want the sync
   2056             // sample preceding it (or the sample itself of course), even
   2057             // if the subsequent sync sample is closer.
   2058             findFlags = SampleTable::kFlagBefore;
   2059         }
   2060 
   2061         uint32_t syncSampleIndex;
   2062         if (err == OK) {
   2063             err = mSampleTable->findSyncSampleNear(
   2064                     sampleIndex, &syncSampleIndex, findFlags);
   2065         }
   2066 
   2067         uint32_t sampleTime;
   2068         if (err == OK) {
   2069             err = mSampleTable->getMetaDataForSample(
   2070                     sampleIndex, NULL, NULL, &sampleTime);
   2071         }
   2072 
   2073         if (err != OK) {
   2074             if (err == ERROR_OUT_OF_RANGE) {
   2075                 // An attempt to seek past the end of the stream would
   2076                 // normally cause this ERROR_OUT_OF_RANGE error. Propagating
   2077                 // this all the way to the MediaPlayer would cause abnormal
   2078                 // termination. Legacy behaviour appears to be to behave as if
   2079                 // we had seeked to the end of stream, ending normally.
   2080                 err = ERROR_END_OF_STREAM;
   2081             }
   2082             return err;
   2083         }
   2084 
   2085         if (mode == ReadOptions::SEEK_CLOSEST) {
   2086             targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
   2087         }
   2088 
   2089 #if 0
   2090         uint32_t syncSampleTime;
   2091         CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
   2092                     syncSampleIndex, NULL, NULL, &syncSampleTime));
   2093 
   2094         ALOGI("seek to time %lld us => sample at time %lld us, "
   2095              "sync sample at time %lld us",
   2096              seekTimeUs,
   2097              sampleTime * 1000000ll / mTimescale,
   2098              syncSampleTime * 1000000ll / mTimescale);
   2099 #endif
   2100 
   2101         mCurrentSampleIndex = syncSampleIndex;
   2102         if (mBuffer != NULL) {
   2103             mBuffer->release();
   2104             mBuffer = NULL;
   2105         }
   2106 
   2107         // fall through
   2108     }
   2109 
   2110     off64_t offset;
   2111     size_t size;
   2112     uint32_t cts;
   2113     bool isSyncSample;
   2114     bool newBuffer = false;
   2115     if (mBuffer == NULL) {
   2116         newBuffer = true;
   2117 
   2118         status_t err =
   2119             mSampleTable->getMetaDataForSample(
   2120                     mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample);
   2121 
   2122         if (err != OK) {
   2123             return err;
   2124         }
   2125 
   2126         err = mGroup->acquire_buffer(&mBuffer);
   2127 
   2128         if (err != OK) {
   2129             CHECK(mBuffer == NULL);
   2130             return err;
   2131         }
   2132     }
   2133 
   2134     if (!mIsAVC || mWantsNALFragments) {
   2135         if (newBuffer) {
   2136             ssize_t num_bytes_read =
   2137                 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
   2138 
   2139             if (num_bytes_read < (ssize_t)size) {
   2140                 mBuffer->release();
   2141                 mBuffer = NULL;
   2142 
   2143                 return ERROR_IO;
   2144             }
   2145 
   2146             CHECK(mBuffer != NULL);
   2147             mBuffer->set_range(0, size);
   2148             mBuffer->meta_data()->clear();
   2149             mBuffer->meta_data()->setInt64(
   2150                     kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
   2151 
   2152             if (targetSampleTimeUs >= 0) {
   2153                 mBuffer->meta_data()->setInt64(
   2154                         kKeyTargetTime, targetSampleTimeUs);
   2155             }
   2156 
   2157             if (isSyncSample) {
   2158                 mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
   2159             }
   2160 
   2161             ++mCurrentSampleIndex;
   2162         }
   2163 
   2164         if (!mIsAVC) {
   2165             *out = mBuffer;
   2166             mBuffer = NULL;
   2167 
   2168             return OK;
   2169         }
   2170 
   2171         // Each NAL unit is split up into its constituent fragments and
   2172         // each one of them returned in its own buffer.
   2173 
   2174         CHECK(mBuffer->range_length() >= mNALLengthSize);
   2175 
   2176         const uint8_t *src =
   2177             (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
   2178 
   2179         size_t nal_size = parseNALSize(src);
   2180         if (mBuffer->range_length() < mNALLengthSize + nal_size) {
   2181             ALOGE("incomplete NAL unit.");
   2182 
   2183             mBuffer->release();
   2184             mBuffer = NULL;
   2185 
   2186             return ERROR_MALFORMED;
   2187         }
   2188 
   2189         MediaBuffer *clone = mBuffer->clone();
   2190         CHECK(clone != NULL);
   2191         clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
   2192 
   2193         CHECK(mBuffer != NULL);
   2194         mBuffer->set_range(
   2195                 mBuffer->range_offset() + mNALLengthSize + nal_size,
   2196                 mBuffer->range_length() - mNALLengthSize - nal_size);
   2197 
   2198         if (mBuffer->range_length() == 0) {
   2199             mBuffer->release();
   2200             mBuffer = NULL;
   2201         }
   2202 
   2203         *out = clone;
   2204 
   2205         return OK;
   2206     } else {
   2207         // Whole NAL units are returned but each fragment is prefixed by
   2208         // the start code (0x00 00 00 01).
   2209         ssize_t num_bytes_read = 0;
   2210         int32_t drm = 0;
   2211         bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
   2212         if (usesDRM) {
   2213             num_bytes_read =
   2214                 mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
   2215         } else {
   2216             num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
   2217         }
   2218 
   2219         if (num_bytes_read < (ssize_t)size) {
   2220             mBuffer->release();
   2221             mBuffer = NULL;
   2222 
   2223             return ERROR_IO;
   2224         }
   2225 
   2226         if (usesDRM) {
   2227             CHECK(mBuffer != NULL);
   2228             mBuffer->set_range(0, size);
   2229 
   2230         } else {
   2231             uint8_t *dstData = (uint8_t *)mBuffer->data();
   2232             size_t srcOffset = 0;
   2233             size_t dstOffset = 0;
   2234 
   2235             while (srcOffset < size) {
   2236                 bool isMalFormed = (srcOffset + mNALLengthSize > size);
   2237                 size_t nalLength = 0;
   2238                 if (!isMalFormed) {
   2239                     nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
   2240                     srcOffset += mNALLengthSize;
   2241                     isMalFormed = srcOffset + nalLength > size;
   2242                 }
   2243 
   2244                 if (isMalFormed) {
   2245                     ALOGE("Video is malformed");
   2246                     mBuffer->release();
   2247                     mBuffer = NULL;
   2248                     return ERROR_MALFORMED;
   2249                 }
   2250 
   2251                 if (nalLength == 0) {
   2252                     continue;
   2253                 }
   2254 
   2255                 CHECK(dstOffset + 4 <= mBuffer->size());
   2256 
   2257                 dstData[dstOffset++] = 0;
   2258                 dstData[dstOffset++] = 0;
   2259                 dstData[dstOffset++] = 0;
   2260                 dstData[dstOffset++] = 1;
   2261                 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
   2262                 srcOffset += nalLength;
   2263                 dstOffset += nalLength;
   2264             }
   2265             CHECK_EQ(srcOffset, size);
   2266             CHECK(mBuffer != NULL);
   2267             mBuffer->set_range(0, dstOffset);
   2268         }
   2269 
   2270         mBuffer->meta_data()->clear();
   2271         mBuffer->meta_data()->setInt64(
   2272                 kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
   2273 
   2274         if (targetSampleTimeUs >= 0) {
   2275             mBuffer->meta_data()->setInt64(
   2276                     kKeyTargetTime, targetSampleTimeUs);
   2277         }
   2278 
   2279         if (isSyncSample) {
   2280             mBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
   2281         }
   2282 
   2283         ++mCurrentSampleIndex;
   2284 
   2285         *out = mBuffer;
   2286         mBuffer = NULL;
   2287 
   2288         return OK;
   2289     }
   2290 }
   2291 
   2292 MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
   2293         const char *mimePrefix) {
   2294     for (Track *track = mFirstTrack; track != NULL; track = track->next) {
   2295         const char *mime;
   2296         if (track->meta != NULL
   2297                 && track->meta->findCString(kKeyMIMEType, &mime)
   2298                 && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
   2299             return track;
   2300         }
   2301     }
   2302 
   2303     return NULL;
   2304 }
   2305 
   2306 static bool LegacySniffMPEG4(
   2307         const sp<DataSource> &source, String8 *mimeType, float *confidence) {
   2308     uint8_t header[8];
   2309 
   2310     ssize_t n = source->readAt(4, header, sizeof(header));
   2311     if (n < (ssize_t)sizeof(header)) {
   2312         return false;
   2313     }
   2314 
   2315     if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
   2316         || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
   2317         || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
   2318         || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
   2319         || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
   2320         || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
   2321         *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
   2322         *confidence = 0.4;
   2323 
   2324         return true;
   2325     }
   2326 
   2327     return false;
   2328 }
   2329 
   2330 static bool isCompatibleBrand(uint32_t fourcc) {
   2331     static const uint32_t kCompatibleBrands[] = {
   2332         FOURCC('i', 's', 'o', 'm'),
   2333         FOURCC('i', 's', 'o', '2'),
   2334         FOURCC('a', 'v', 'c', '1'),
   2335         FOURCC('3', 'g', 'p', '4'),
   2336         FOURCC('m', 'p', '4', '1'),
   2337         FOURCC('m', 'p', '4', '2'),
   2338 
   2339         // Won't promise that the following file types can be played.
   2340         // Just give these file types a chance.
   2341         FOURCC('q', 't', ' ', ' '),  // Apple's QuickTime
   2342         FOURCC('M', 'S', 'N', 'V'),  // Sony's PSP
   2343 
   2344         FOURCC('3', 'g', '2', 'a'),  // 3GPP2
   2345         FOURCC('3', 'g', '2', 'b'),
   2346     };
   2347 
   2348     for (size_t i = 0;
   2349          i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
   2350          ++i) {
   2351         if (kCompatibleBrands[i] == fourcc) {
   2352             return true;
   2353         }
   2354     }
   2355 
   2356     return false;
   2357 }
   2358 
   2359 // Attempt to actually parse the 'ftyp' atom and determine if a suitable
   2360 // compatible brand is present.
   2361 // Also try to identify where this file's metadata ends
   2362 // (end of the 'moov' atom) and report it to the caller as part of
   2363 // the metadata.
   2364 static bool BetterSniffMPEG4(
   2365         const sp<DataSource> &source, String8 *mimeType, float *confidence,
   2366         sp<AMessage> *meta) {
   2367     // We scan up to 128 bytes to identify this file as an MP4.
   2368     static const off64_t kMaxScanOffset = 128ll;
   2369 
   2370     off64_t offset = 0ll;
   2371     bool foundGoodFileType = false;
   2372     off64_t moovAtomEndOffset = -1ll;
   2373     bool done = false;
   2374 
   2375     while (!done && offset < kMaxScanOffset) {
   2376         uint32_t hdr[2];
   2377         if (source->readAt(offset, hdr, 8) < 8) {
   2378             return false;
   2379         }
   2380 
   2381         uint64_t chunkSize = ntohl(hdr[0]);
   2382         uint32_t chunkType = ntohl(hdr[1]);
   2383         off64_t chunkDataOffset = offset + 8;
   2384 
   2385         if (chunkSize == 1) {
   2386             if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
   2387                 return false;
   2388             }
   2389 
   2390             chunkSize = ntoh64(chunkSize);
   2391             chunkDataOffset += 8;
   2392 
   2393             if (chunkSize < 16) {
   2394                 // The smallest valid chunk is 16 bytes long in this case.
   2395                 return false;
   2396             }
   2397         } else if (chunkSize < 8) {
   2398             // The smallest valid chunk is 8 bytes long.
   2399             return false;
   2400         }
   2401 
   2402         off64_t chunkDataSize = offset + chunkSize - chunkDataOffset;
   2403 
   2404         switch (chunkType) {
   2405             case FOURCC('f', 't', 'y', 'p'):
   2406             {
   2407                 if (chunkDataSize < 8) {
   2408                     return false;
   2409                 }
   2410 
   2411                 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
   2412                 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
   2413                     if (i == 1) {
   2414                         // Skip this index, it refers to the minorVersion,
   2415                         // not a brand.
   2416                         continue;
   2417                     }
   2418 
   2419                     uint32_t brand;
   2420                     if (source->readAt(
   2421                                 chunkDataOffset + 4 * i, &brand, 4) < 4) {
   2422                         return false;
   2423                     }
   2424 
   2425                     brand = ntohl(brand);
   2426 
   2427                     if (isCompatibleBrand(brand)) {
   2428                         foundGoodFileType = true;
   2429                         break;
   2430                     }
   2431                 }
   2432 
   2433                 if (!foundGoodFileType) {
   2434                     return false;
   2435                 }
   2436 
   2437                 break;
   2438             }
   2439 
   2440             case FOURCC('m', 'o', 'o', 'v'):
   2441             {
   2442                 moovAtomEndOffset = offset + chunkSize;
   2443 
   2444                 done = true;
   2445                 break;
   2446             }
   2447 
   2448             default:
   2449                 break;
   2450         }
   2451 
   2452         offset += chunkSize;
   2453     }
   2454 
   2455     if (!foundGoodFileType) {
   2456         return false;
   2457     }
   2458 
   2459     *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
   2460     *confidence = 0.4f;
   2461 
   2462     if (moovAtomEndOffset >= 0) {
   2463         *meta = new AMessage;
   2464         (*meta)->setInt64("meta-data-size", moovAtomEndOffset);
   2465 
   2466         ALOGV("found metadata size: %lld", moovAtomEndOffset);
   2467     }
   2468 
   2469     return true;
   2470 }
   2471 
   2472 bool SniffMPEG4(
   2473         const sp<DataSource> &source, String8 *mimeType, float *confidence,
   2474         sp<AMessage> *meta) {
   2475     if (BetterSniffMPEG4(source, mimeType, confidence, meta)) {
   2476         return true;
   2477     }
   2478 
   2479     if (LegacySniffMPEG4(source, mimeType, confidence)) {
   2480         ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
   2481         return true;
   2482     }
   2483 
   2484     return false;
   2485 }
   2486 
   2487 }  // namespace android
   2488