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