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