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