MPEG4Extractor.cpp revision 6655174826330afe66ef766258181ae8c11f3f6c
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
24#include <arpa/inet.h>
25
26#include <ctype.h>
27#include <stdint.h>
28#include <stdlib.h>
29#include <string.h>
30
31#include <media/stagefright/foundation/ADebug.h>
32#include <media/stagefright/foundation/AMessage.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
390char* MPEG4Extractor::getDrmTrackInfo(size_t trackID, int *len) {
391    if (mFirstSINF == NULL) {
392        return NULL;
393    }
394
395    SINF *sinf = mFirstSINF;
396    while (sinf && (trackID != sinf->trackID)) {
397        sinf = sinf->next;
398    }
399
400    if (sinf == NULL) {
401        return NULL;
402    }
403
404    *len = sinf->len;
405    return sinf->IPMPData;
406}
407
408// Reads an encoded integer 7 bits at a time until it encounters the high bit clear.
409int32_t readSize(off64_t offset,
410        const sp<DataSource> DataSource, uint8_t *numOfBytes) {
411    uint32_t size = 0;
412    uint8_t data;
413    bool moreData = true;
414    *numOfBytes = 0;
415
416    while (moreData) {
417        if (DataSource->readAt(offset, &data, 1) < 1) {
418            return -1;
419        }
420        offset ++;
421        moreData = (data >= 128) ? true : false;
422        size = (size << 7) | (data & 0x7f); // Take last 7 bits
423        (*numOfBytes) ++;
424    }
425
426    return size;
427}
428
429status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) {
430    uint8_t updateIdTag;
431    if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
432        return ERROR_IO;
433    }
434    data_offset ++;
435
436    if (0x01/*OBJECT_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
437        return ERROR_MALFORMED;
438    }
439
440    uint8_t numOfBytes;
441    int32_t size = readSize(data_offset, mDataSource, &numOfBytes);
442    if (size < 0) {
443        return ERROR_IO;
444    }
445    int32_t classSize = size;
446    data_offset += numOfBytes;
447
448    while(size >= 11 ) {
449        uint8_t descriptorTag;
450        if (mDataSource->readAt(data_offset, &descriptorTag, 1) < 1) {
451            return ERROR_IO;
452        }
453        data_offset ++;
454
455        if (0x11/*OBJECT_DESCRIPTOR_ID_TAG*/ != descriptorTag) {
456            return ERROR_MALFORMED;
457        }
458
459        uint8_t buffer[8];
460        //ObjectDescriptorID and ObjectDescriptor url flag
461        if (mDataSource->readAt(data_offset, buffer, 2) < 2) {
462            return ERROR_IO;
463        }
464        data_offset += 2;
465
466        if ((buffer[1] >> 5) & 0x0001) { //url flag is set
467            return ERROR_MALFORMED;
468        }
469
470        if (mDataSource->readAt(data_offset, buffer, 8) < 8) {
471            return ERROR_IO;
472        }
473        data_offset += 8;
474
475        if ((0x0F/*ES_ID_REF_TAG*/ != buffer[1])
476                || ( 0x0A/*IPMP_DESCRIPTOR_POINTER_ID_TAG*/ != buffer[5])) {
477            return ERROR_MALFORMED;
478        }
479
480        SINF *sinf = new SINF;
481        sinf->trackID = U16_AT(&buffer[3]);
482        sinf->IPMPDescriptorID = buffer[7];
483        sinf->next = mFirstSINF;
484        mFirstSINF = sinf;
485
486        size -= (8 + 2 + 1);
487    }
488
489    if (size != 0) {
490        return ERROR_MALFORMED;
491    }
492
493    if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
494        return ERROR_IO;
495    }
496    data_offset ++;
497
498    if(0x05/*IPMP_DESCRIPTOR_UPDATE_ID_TAG*/ != updateIdTag) {
499        return ERROR_MALFORMED;
500    }
501
502    size = readSize(data_offset, mDataSource, &numOfBytes);
503    if (size < 0) {
504        return ERROR_IO;
505    }
506    classSize = size;
507    data_offset += numOfBytes;
508
509    while (size > 0) {
510        uint8_t tag;
511        int32_t dataLen;
512        if (mDataSource->readAt(data_offset, &tag, 1) < 1) {
513            return ERROR_IO;
514        }
515        data_offset ++;
516
517        if (0x0B/*IPMP_DESCRIPTOR_ID_TAG*/ == tag) {
518            uint8_t id;
519            dataLen = readSize(data_offset, mDataSource, &numOfBytes);
520            if (dataLen < 0) {
521                return ERROR_IO;
522            } else if (dataLen < 4) {
523                return ERROR_MALFORMED;
524            }
525            data_offset += numOfBytes;
526
527            if (mDataSource->readAt(data_offset, &id, 1) < 1) {
528                return ERROR_IO;
529            }
530            data_offset ++;
531
532            SINF *sinf = mFirstSINF;
533            while (sinf && (sinf->IPMPDescriptorID != id)) {
534                sinf = sinf->next;
535            }
536            if (sinf == NULL) {
537                return ERROR_MALFORMED;
538            }
539            sinf->len = dataLen - 3;
540            sinf->IPMPData = new char[sinf->len];
541
542            if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) {
543                return ERROR_IO;
544            }
545            data_offset += sinf->len;
546
547            size -= (dataLen + numOfBytes + 1);
548        }
549    }
550
551    if (size != 0) {
552        return ERROR_MALFORMED;
553    }
554
555    return UNKNOWN_ERROR;  // Return a dummy error.
556}
557
558static void MakeFourCCString(uint32_t x, char *s) {
559    s[0] = x >> 24;
560    s[1] = (x >> 16) & 0xff;
561    s[2] = (x >> 8) & 0xff;
562    s[3] = x & 0xff;
563    s[4] = '\0';
564}
565
566struct PathAdder {
567    PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
568        : mPath(path) {
569        mPath->push(chunkType);
570    }
571
572    ~PathAdder() {
573        mPath->pop();
574    }
575
576private:
577    Vector<uint32_t> *mPath;
578
579    PathAdder(const PathAdder &);
580    PathAdder &operator=(const PathAdder &);
581};
582
583static bool underMetaDataPath(const Vector<uint32_t> &path) {
584    return path.size() >= 5
585        && path[0] == FOURCC('m', 'o', 'o', 'v')
586        && path[1] == FOURCC('u', 'd', 't', 'a')
587        && path[2] == FOURCC('m', 'e', 't', 'a')
588        && path[3] == FOURCC('i', 'l', 's', 't');
589}
590
591// Given a time in seconds since Jan 1 1904, produce a human-readable string.
592static void convertTimeToDate(int64_t time_1904, String8 *s) {
593    time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
594
595    char tmp[32];
596    strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
597
598    s->setTo(tmp);
599}
600
601status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
602    uint32_t hdr[2];
603    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
604        return ERROR_IO;
605    }
606    uint64_t chunk_size = ntohl(hdr[0]);
607    uint32_t chunk_type = ntohl(hdr[1]);
608    off64_t data_offset = *offset + 8;
609
610    if (chunk_size == 1) {
611        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
612            return ERROR_IO;
613        }
614        chunk_size = ntoh64(chunk_size);
615        data_offset += 8;
616
617        if (chunk_size < 16) {
618            // The smallest valid chunk is 16 bytes long in this case.
619            return ERROR_MALFORMED;
620        }
621    } else if (chunk_size < 8) {
622        // The smallest valid chunk is 8 bytes long.
623        return ERROR_MALFORMED;
624    }
625
626    char chunk[5];
627    MakeFourCCString(chunk_type, chunk);
628
629#if 0
630    static const char kWhitespace[] = "                                        ";
631    const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
632    printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
633
634    char buffer[256];
635    size_t n = chunk_size;
636    if (n > sizeof(buffer)) {
637        n = sizeof(buffer);
638    }
639    if (mDataSource->readAt(*offset, buffer, n)
640            < (ssize_t)n) {
641        return ERROR_IO;
642    }
643
644    hexdump(buffer, n);
645#endif
646
647    PathAdder autoAdder(&mPath, chunk_type);
648
649    off64_t chunk_data_size = *offset + chunk_size - data_offset;
650
651    if (chunk_type != FOURCC('c', 'p', 'r', 't')
652            && chunk_type != FOURCC('c', 'o', 'v', 'r')
653            && mPath.size() == 5 && underMetaDataPath(mPath)) {
654        off64_t stop_offset = *offset + chunk_size;
655        *offset = data_offset;
656        while (*offset < stop_offset) {
657            status_t err = parseChunk(offset, depth + 1);
658            if (err != OK) {
659                return err;
660            }
661        }
662
663        if (*offset != stop_offset) {
664            return ERROR_MALFORMED;
665        }
666
667        return OK;
668    }
669
670    switch(chunk_type) {
671        case FOURCC('m', 'o', 'o', 'v'):
672        case FOURCC('t', 'r', 'a', 'k'):
673        case FOURCC('m', 'd', 'i', 'a'):
674        case FOURCC('m', 'i', 'n', 'f'):
675        case FOURCC('d', 'i', 'n', 'f'):
676        case FOURCC('s', 't', 'b', 'l'):
677        case FOURCC('m', 'v', 'e', 'x'):
678        case FOURCC('m', 'o', 'o', 'f'):
679        case FOURCC('t', 'r', 'a', 'f'):
680        case FOURCC('m', 'f', 'r', 'a'):
681        case FOURCC('u', 'd', 't', 'a'):
682        case FOURCC('i', 'l', 's', 't'):
683        {
684            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
685                ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
686
687                if (mDataSource->flags()
688                        & (DataSource::kWantsPrefetching
689                            | DataSource::kIsCachingDataSource)) {
690                    sp<MPEG4DataSource> cachedSource =
691                        new MPEG4DataSource(mDataSource);
692
693                    if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
694                        mDataSource = cachedSource;
695                    }
696                }
697
698                mLastTrack->sampleTable = new SampleTable(mDataSource);
699            }
700
701            bool isTrack = false;
702            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
703                isTrack = true;
704
705                Track *track = new Track;
706                track->next = NULL;
707                if (mLastTrack) {
708                    mLastTrack->next = track;
709                } else {
710                    mFirstTrack = track;
711                }
712                mLastTrack = track;
713
714                track->meta = new MetaData;
715                track->includes_expensive_metadata = false;
716                track->skipTrack = false;
717                track->timescale = 0;
718                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
719            }
720
721            off64_t stop_offset = *offset + chunk_size;
722            *offset = data_offset;
723            while (*offset < stop_offset) {
724                status_t err = parseChunk(offset, depth + 1);
725                if (err != OK) {
726                    return err;
727                }
728            }
729
730            if (*offset != stop_offset) {
731                return ERROR_MALFORMED;
732            }
733
734            if (isTrack) {
735                if (mLastTrack->skipTrack) {
736                    Track *cur = mFirstTrack;
737
738                    if (cur == mLastTrack) {
739                        delete cur;
740                        mFirstTrack = mLastTrack = NULL;
741                    } else {
742                        while (cur && cur->next != mLastTrack) {
743                            cur = cur->next;
744                        }
745                        cur->next = NULL;
746                        delete mLastTrack;
747                        mLastTrack = cur;
748                    }
749
750                    return OK;
751                }
752
753                status_t err = verifyTrack(mLastTrack);
754
755                if (err != OK) {
756                    return err;
757                }
758            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
759                mInitCheck = OK;
760
761                if (!mIsDrm) {
762                    return UNKNOWN_ERROR;  // Return a dummy error.
763                } else {
764                    return OK;
765                }
766            }
767            break;
768        }
769
770        case FOURCC('t', 'k', 'h', 'd'):
771        {
772            status_t err;
773            if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) {
774                return err;
775            }
776
777            *offset += chunk_size;
778            break;
779        }
780
781        case FOURCC('m', 'd', 'h', 'd'):
782        {
783            if (chunk_data_size < 4) {
784                return ERROR_MALFORMED;
785            }
786
787            uint8_t version;
788            if (mDataSource->readAt(
789                        data_offset, &version, sizeof(version))
790                    < (ssize_t)sizeof(version)) {
791                return ERROR_IO;
792            }
793
794            off64_t timescale_offset;
795
796            if (version == 1) {
797                timescale_offset = data_offset + 4 + 16;
798            } else if (version == 0) {
799                timescale_offset = data_offset + 4 + 8;
800            } else {
801                return ERROR_IO;
802            }
803
804            uint32_t timescale;
805            if (mDataSource->readAt(
806                        timescale_offset, &timescale, sizeof(timescale))
807                    < (ssize_t)sizeof(timescale)) {
808                return ERROR_IO;
809            }
810
811            mLastTrack->timescale = ntohl(timescale);
812
813            int64_t duration;
814            if (version == 1) {
815                if (mDataSource->readAt(
816                            timescale_offset + 4, &duration, sizeof(duration))
817                        < (ssize_t)sizeof(duration)) {
818                    return ERROR_IO;
819                }
820                duration = ntoh64(duration);
821            } else {
822                int32_t duration32;
823                if (mDataSource->readAt(
824                            timescale_offset + 4, &duration32, sizeof(duration32))
825                        < (ssize_t)sizeof(duration32)) {
826                    return ERROR_IO;
827                }
828                duration = ntohl(duration32);
829            }
830            mLastTrack->meta->setInt64(
831                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
832
833            uint8_t lang[2];
834            off64_t lang_offset;
835            if (version == 1) {
836                lang_offset = timescale_offset + 4 + 8;
837            } else if (version == 0) {
838                lang_offset = timescale_offset + 4 + 4;
839            } else {
840                return ERROR_IO;
841            }
842
843            if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
844                    < (ssize_t)sizeof(lang)) {
845                return ERROR_IO;
846            }
847
848            // To get the ISO-639-2/T three character language code
849            // 1 bit pad followed by 3 5-bits characters. Each character
850            // is packed as the difference between its ASCII value and 0x60.
851            char lang_code[4];
852            lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
853            lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
854            lang_code[2] = (lang[1] & 0x1f) + 0x60;
855            lang_code[3] = '\0';
856
857            mLastTrack->meta->setCString(
858                    kKeyMediaLanguage, lang_code);
859
860            *offset += chunk_size;
861            break;
862        }
863
864        case FOURCC('s', 't', 's', 'd'):
865        {
866            if (chunk_data_size < 8) {
867                return ERROR_MALFORMED;
868            }
869
870            uint8_t buffer[8];
871            if (chunk_data_size < (off64_t)sizeof(buffer)) {
872                return ERROR_MALFORMED;
873            }
874
875            if (mDataSource->readAt(
876                        data_offset, buffer, 8) < 8) {
877                return ERROR_IO;
878            }
879
880            if (U32_AT(buffer) != 0) {
881                // Should be version 0, flags 0.
882                return ERROR_MALFORMED;
883            }
884
885            uint32_t entry_count = U32_AT(&buffer[4]);
886
887            if (entry_count > 1) {
888                // For 3GPP timed text, there could be multiple tx3g boxes contain
889                // multiple text display formats. These formats will be used to
890                // display the timed text.
891                const char *mime;
892                CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
893                if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP)) {
894                    // For now we only support a single type of media per track.
895                    mLastTrack->skipTrack = true;
896                    *offset += chunk_size;
897                    break;
898                }
899            }
900
901            off64_t stop_offset = *offset + chunk_size;
902            *offset = data_offset + 8;
903            for (uint32_t i = 0; i < entry_count; ++i) {
904                status_t err = parseChunk(offset, depth + 1);
905                if (err != OK) {
906                    return err;
907                }
908            }
909
910            if (*offset != stop_offset) {
911                return ERROR_MALFORMED;
912            }
913            break;
914        }
915
916        case FOURCC('m', 'p', '4', 'a'):
917        case FOURCC('s', 'a', 'm', 'r'):
918        case FOURCC('s', 'a', 'w', 'b'):
919        {
920            uint8_t buffer[8 + 20];
921            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
922                // Basic AudioSampleEntry size.
923                return ERROR_MALFORMED;
924            }
925
926            if (mDataSource->readAt(
927                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
928                return ERROR_IO;
929            }
930
931            uint16_t data_ref_index = U16_AT(&buffer[6]);
932            uint16_t num_channels = U16_AT(&buffer[16]);
933
934            uint16_t sample_size = U16_AT(&buffer[18]);
935            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
936
937            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
938                            FourCC2MIME(chunk_type))) {
939                // AMR NB audio is always mono, 8kHz
940                num_channels = 1;
941                sample_rate = 8000;
942            } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
943                               FourCC2MIME(chunk_type))) {
944                // AMR WB audio is always mono, 16kHz
945                num_channels = 1;
946                sample_rate = 16000;
947            }
948
949#if 0
950            printf("*** coding='%s' %d channels, size %d, rate %d\n",
951                   chunk, num_channels, sample_size, sample_rate);
952#endif
953
954            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
955            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
956            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
957
958            off64_t stop_offset = *offset + chunk_size;
959            *offset = data_offset + sizeof(buffer);
960            while (*offset < stop_offset) {
961                status_t err = parseChunk(offset, depth + 1);
962                if (err != OK) {
963                    return err;
964                }
965            }
966
967            if (*offset != stop_offset) {
968                return ERROR_MALFORMED;
969            }
970            break;
971        }
972
973        case FOURCC('m', 'p', '4', 'v'):
974        case FOURCC('s', '2', '6', '3'):
975        case FOURCC('H', '2', '6', '3'):
976        case FOURCC('h', '2', '6', '3'):
977        case FOURCC('a', 'v', 'c', '1'):
978        {
979            mHasVideo = true;
980
981            uint8_t buffer[78];
982            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
983                // Basic VideoSampleEntry size.
984                return ERROR_MALFORMED;
985            }
986
987            if (mDataSource->readAt(
988                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
989                return ERROR_IO;
990            }
991
992            uint16_t data_ref_index = U16_AT(&buffer[6]);
993            uint16_t width = U16_AT(&buffer[6 + 18]);
994            uint16_t height = U16_AT(&buffer[6 + 20]);
995
996            // The video sample is not stand-compliant if it has invalid dimension.
997            // Use some default width and height value, and
998            // let the decoder figure out the actual width and height (and thus
999            // be prepared for INFO_FOMRAT_CHANGED event).
1000            if (width == 0)  width  = 352;
1001            if (height == 0) height = 288;
1002
1003            // printf("*** coding='%s' width=%d height=%d\n",
1004            //        chunk, width, height);
1005
1006            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
1007            mLastTrack->meta->setInt32(kKeyWidth, width);
1008            mLastTrack->meta->setInt32(kKeyHeight, height);
1009
1010            off64_t stop_offset = *offset + chunk_size;
1011            *offset = data_offset + sizeof(buffer);
1012            while (*offset < stop_offset) {
1013                status_t err = parseChunk(offset, depth + 1);
1014                if (err != OK) {
1015                    return err;
1016                }
1017            }
1018
1019            if (*offset != stop_offset) {
1020                return ERROR_MALFORMED;
1021            }
1022            break;
1023        }
1024
1025        case FOURCC('s', 't', 'c', 'o'):
1026        case FOURCC('c', 'o', '6', '4'):
1027        {
1028            status_t err =
1029                mLastTrack->sampleTable->setChunkOffsetParams(
1030                        chunk_type, data_offset, chunk_data_size);
1031
1032            if (err != OK) {
1033                return err;
1034            }
1035
1036            *offset += chunk_size;
1037            break;
1038        }
1039
1040        case FOURCC('s', 't', 's', 'c'):
1041        {
1042            status_t err =
1043                mLastTrack->sampleTable->setSampleToChunkParams(
1044                        data_offset, chunk_data_size);
1045
1046            if (err != OK) {
1047                return err;
1048            }
1049
1050            *offset += chunk_size;
1051            break;
1052        }
1053
1054        case FOURCC('s', 't', 's', 'z'):
1055        case FOURCC('s', 't', 'z', '2'):
1056        {
1057            status_t err =
1058                mLastTrack->sampleTable->setSampleSizeParams(
1059                        chunk_type, data_offset, chunk_data_size);
1060
1061            if (err != OK) {
1062                return err;
1063            }
1064
1065            size_t max_size;
1066            err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
1067
1068            if (err != OK) {
1069                return err;
1070            }
1071
1072            // Assume that a given buffer only contains at most 10 fragments,
1073            // each fragment originally prefixed with a 2 byte length will
1074            // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
1075            // and thus will grow by 2 bytes per fragment.
1076            mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
1077            *offset += chunk_size;
1078
1079            // Calculate average frame rate.
1080            const char *mime;
1081            CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
1082            if (!strncasecmp("video/", mime, 6)) {
1083                size_t nSamples = mLastTrack->sampleTable->countSamples();
1084                int64_t durationUs;
1085                if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
1086                    if (durationUs > 0) {
1087                        int32_t frameRate = (nSamples * 1000000LL +
1088                                    (durationUs >> 1)) / durationUs;
1089                        mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
1090                    }
1091                }
1092            }
1093
1094            break;
1095        }
1096
1097        case FOURCC('s', 't', 't', 's'):
1098        {
1099            status_t err =
1100                mLastTrack->sampleTable->setTimeToSampleParams(
1101                        data_offset, chunk_data_size);
1102
1103            if (err != OK) {
1104                return err;
1105            }
1106
1107            *offset += chunk_size;
1108            break;
1109        }
1110
1111        case FOURCC('c', 't', 't', 's'):
1112        {
1113            status_t err =
1114                mLastTrack->sampleTable->setCompositionTimeToSampleParams(
1115                        data_offset, chunk_data_size);
1116
1117            if (err != OK) {
1118                return err;
1119            }
1120
1121            *offset += chunk_size;
1122            break;
1123        }
1124
1125        case FOURCC('s', 't', 's', 's'):
1126        {
1127            status_t err =
1128                mLastTrack->sampleTable->setSyncSampleParams(
1129                        data_offset, chunk_data_size);
1130
1131            if (err != OK) {
1132                return err;
1133            }
1134
1135            *offset += chunk_size;
1136            break;
1137        }
1138
1139        // @xyz
1140        case FOURCC('\xA9', 'x', 'y', 'z'):
1141        {
1142            // Best case the total data length inside "@xyz" box
1143            // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/",
1144            // where "\x00\x04" is the text string length with value = 4,
1145            // "\0x15\xc7" is the language code = en, and "0+0" is a
1146            // location (string) value with longitude = 0 and latitude = 0.
1147            if (chunk_data_size < 8) {
1148                return ERROR_MALFORMED;
1149            }
1150
1151            // Worst case the location string length would be 18,
1152            // for instance +90.0000-180.0000, without the trailing "/" and
1153            // the string length + language code.
1154            char buffer[18];
1155
1156            // Substracting 5 from the data size is because the text string length +
1157            // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
1158            off64_t location_length = chunk_data_size - 5;
1159            if (location_length >= (off64_t) sizeof(buffer)) {
1160                return ERROR_MALFORMED;
1161            }
1162
1163            if (mDataSource->readAt(
1164                        data_offset + 4, buffer, location_length) < location_length) {
1165                return ERROR_IO;
1166            }
1167
1168            buffer[location_length] = '\0';
1169            mFileMetaData->setCString(kKeyLocation, buffer);
1170            *offset += chunk_size;
1171            break;
1172        }
1173
1174        case FOURCC('e', 's', 'd', 's'):
1175        {
1176            if (chunk_data_size < 4) {
1177                return ERROR_MALFORMED;
1178            }
1179
1180            uint8_t buffer[256];
1181            if (chunk_data_size > (off64_t)sizeof(buffer)) {
1182                return ERROR_BUFFER_TOO_SMALL;
1183            }
1184
1185            if (mDataSource->readAt(
1186                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
1187                return ERROR_IO;
1188            }
1189
1190            if (U32_AT(buffer) != 0) {
1191                // Should be version 0, flags 0.
1192                return ERROR_MALFORMED;
1193            }
1194
1195            mLastTrack->meta->setData(
1196                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
1197
1198            if (mPath.size() >= 2
1199                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
1200                // Information from the ESDS must be relied on for proper
1201                // setup of sample rate and channel count for MPEG4 Audio.
1202                // The generic header appears to only contain generic
1203                // information...
1204
1205                status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
1206                        &buffer[4], chunk_data_size - 4);
1207
1208                if (err != OK) {
1209                    return err;
1210                }
1211            }
1212
1213            *offset += chunk_size;
1214            break;
1215        }
1216
1217        case FOURCC('a', 'v', 'c', 'C'):
1218        {
1219            char buffer[256];
1220            if (chunk_data_size > (off64_t)sizeof(buffer)) {
1221                return ERROR_BUFFER_TOO_SMALL;
1222            }
1223
1224            if (mDataSource->readAt(
1225                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
1226                return ERROR_IO;
1227            }
1228
1229            mLastTrack->meta->setData(
1230                    kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
1231
1232            *offset += chunk_size;
1233            break;
1234        }
1235
1236        case FOURCC('d', '2', '6', '3'):
1237        {
1238            /*
1239             * d263 contains a fixed 7 bytes part:
1240             *   vendor - 4 bytes
1241             *   version - 1 byte
1242             *   level - 1 byte
1243             *   profile - 1 byte
1244             * optionally, "d263" box itself may contain a 16-byte
1245             * bit rate box (bitr)
1246             *   average bit rate - 4 bytes
1247             *   max bit rate - 4 bytes
1248             */
1249            char buffer[23];
1250            if (chunk_data_size != 7 &&
1251                chunk_data_size != 23) {
1252                ALOGE("Incorrect D263 box size %lld", chunk_data_size);
1253                return ERROR_MALFORMED;
1254            }
1255
1256            if (mDataSource->readAt(
1257                    data_offset, buffer, chunk_data_size) < chunk_data_size) {
1258                return ERROR_IO;
1259            }
1260
1261            mLastTrack->meta->setData(kKeyD263, kTypeD263, buffer, chunk_data_size);
1262
1263            *offset += chunk_size;
1264            break;
1265        }
1266
1267        case FOURCC('m', 'e', 't', 'a'):
1268        {
1269            uint8_t buffer[4];
1270            if (chunk_data_size < (off64_t)sizeof(buffer)) {
1271                return ERROR_MALFORMED;
1272            }
1273
1274            if (mDataSource->readAt(
1275                        data_offset, buffer, 4) < 4) {
1276                return ERROR_IO;
1277            }
1278
1279            if (U32_AT(buffer) != 0) {
1280                // Should be version 0, flags 0.
1281
1282                // If it's not, let's assume this is one of those
1283                // apparently malformed chunks that don't have flags
1284                // and completely different semantics than what's
1285                // in the MPEG4 specs and skip it.
1286                *offset += chunk_size;
1287                return OK;
1288            }
1289
1290            off64_t stop_offset = *offset + chunk_size;
1291            *offset = data_offset + sizeof(buffer);
1292            while (*offset < stop_offset) {
1293                status_t err = parseChunk(offset, depth + 1);
1294                if (err != OK) {
1295                    return err;
1296                }
1297            }
1298
1299            if (*offset != stop_offset) {
1300                return ERROR_MALFORMED;
1301            }
1302            break;
1303        }
1304
1305        case FOURCC('d', 'a', 't', 'a'):
1306        {
1307            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
1308                status_t err = parseMetaData(data_offset, chunk_data_size);
1309
1310                if (err != OK) {
1311                    return err;
1312                }
1313            }
1314
1315            *offset += chunk_size;
1316            break;
1317        }
1318
1319        case FOURCC('m', 'v', 'h', 'd'):
1320        {
1321            if (chunk_data_size < 12) {
1322                return ERROR_MALFORMED;
1323            }
1324
1325            uint8_t header[12];
1326            if (mDataSource->readAt(
1327                        data_offset, header, sizeof(header))
1328                    < (ssize_t)sizeof(header)) {
1329                return ERROR_IO;
1330            }
1331
1332            int64_t creationTime;
1333            if (header[0] == 1) {
1334                creationTime = U64_AT(&header[4]);
1335            } else if (header[0] != 0) {
1336                return ERROR_MALFORMED;
1337            } else {
1338                creationTime = U32_AT(&header[4]);
1339            }
1340
1341            String8 s;
1342            convertTimeToDate(creationTime, &s);
1343
1344            mFileMetaData->setCString(kKeyDate, s.string());
1345
1346            *offset += chunk_size;
1347            break;
1348        }
1349
1350        case FOURCC('m', 'd', 'a', 't'):
1351        {
1352            if (!mIsDrm) {
1353                *offset += chunk_size;
1354                break;
1355            }
1356
1357            if (chunk_size < 8) {
1358                return ERROR_MALFORMED;
1359            }
1360
1361            return parseDrmSINF(offset, data_offset);
1362        }
1363
1364        case FOURCC('h', 'd', 'l', 'r'):
1365        {
1366            uint32_t buffer;
1367            if (mDataSource->readAt(
1368                        data_offset + 8, &buffer, 4) < 4) {
1369                return ERROR_IO;
1370            }
1371
1372            uint32_t type = ntohl(buffer);
1373            // For the 3GPP file format, the handler-type within the 'hdlr' box
1374            // shall be 'text'. We also want to support 'sbtl' handler type
1375            // for a practical reason as various MPEG4 containers use it.
1376            if (type == FOURCC('t', 'e', 'x', 't') || type == FOURCC('s', 'b', 't', 'l')) {
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                ALOGV("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    ALOGI("x' = %.2f * x + %.2f * y + %.2f",
1503         a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
1504    ALOGI("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        ALOGW("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        ALOGE("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        ALOGV("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        ALOGV("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        ALOGI("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            ALOGE("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                    ALOGE("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        ALOGV("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        ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
2425        return true;
2426    }
2427
2428    return false;
2429}
2430
2431}  // namespace android
2432