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