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