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