MPEG4Extractor.cpp revision cc14a8393b92cd1ed6cba74829396045605ab211
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "MPEG4Extractor"
18#include <utils/Log.h>
19
20#include "include/MPEG4Extractor.h"
21#include "include/SampleTable.h"
22
23#include <arpa/inet.h>
24
25#include <ctype.h>
26#include <stdint.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include <media/stagefright/DataSource.h>
31#include "include/ESDS.h"
32#include <media/stagefright/MediaBuffer.h>
33#include <media/stagefright/MediaBufferGroup.h>
34#include <media/stagefright/MediaDebug.h>
35#include <media/stagefright/MediaDefs.h>
36#include <media/stagefright/MediaSource.h>
37#include <media/stagefright/MetaData.h>
38#include <media/stagefright/Utils.h>
39#include <utils/String8.h>
40
41namespace android {
42
43class MPEG4Source : public MediaSource {
44public:
45    // Caller retains ownership of both "dataSource" and "sampleTable".
46    MPEG4Source(const sp<MetaData> &format,
47                const sp<DataSource> &dataSource,
48                int32_t timeScale,
49                const sp<SampleTable> &sampleTable);
50
51    virtual status_t start(MetaData *params = NULL);
52    virtual status_t stop();
53
54    virtual sp<MetaData> getFormat();
55
56    virtual status_t read(
57            MediaBuffer **buffer, const ReadOptions *options = NULL);
58
59protected:
60    virtual ~MPEG4Source();
61
62private:
63    Mutex mLock;
64
65    sp<MetaData> mFormat;
66    sp<DataSource> mDataSource;
67    int32_t mTimescale;
68    sp<SampleTable> mSampleTable;
69    uint32_t mCurrentSampleIndex;
70
71    bool mIsAVC;
72    size_t mNALLengthSize;
73
74    bool mStarted;
75
76    MediaBufferGroup *mGroup;
77
78    MediaBuffer *mBuffer;
79
80    bool mWantsNALFragments;
81
82    uint8_t *mSrcBuffer;
83
84    size_t parseNALSize(const uint8_t *data) const;
85
86    MPEG4Source(const MPEG4Source &);
87    MPEG4Source &operator=(const MPEG4Source &);
88};
89
90// This custom data source wraps an existing one and satisfies requests
91// falling entirely within a cached range from the cache while forwarding
92// all remaining requests to the wrapped datasource.
93// This is used to cache the full sampletable metadata for a single track,
94// possibly wrapping multiple times to cover all tracks, i.e.
95// Each MPEG4DataSource caches the sampletable metadata for a single track.
96
97struct MPEG4DataSource : public DataSource {
98    MPEG4DataSource(const sp<DataSource> &source);
99
100    virtual status_t initCheck() const;
101    virtual ssize_t readAt(off_t offset, void *data, size_t size);
102    virtual status_t getSize(off_t *size);
103    virtual uint32_t flags();
104
105    status_t setCachedRange(off_t offset, size_t size);
106
107protected:
108    virtual ~MPEG4DataSource();
109
110private:
111    Mutex mLock;
112
113    sp<DataSource> mSource;
114    off_t mCachedOffset;
115    size_t mCachedSize;
116    uint8_t *mCache;
117
118    void clearCache();
119
120    MPEG4DataSource(const MPEG4DataSource &);
121    MPEG4DataSource &operator=(const MPEG4DataSource &);
122};
123
124MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
125    : mSource(source),
126      mCachedOffset(0),
127      mCachedSize(0),
128      mCache(NULL) {
129}
130
131MPEG4DataSource::~MPEG4DataSource() {
132    clearCache();
133}
134
135void MPEG4DataSource::clearCache() {
136    if (mCache) {
137        free(mCache);
138        mCache = NULL;
139    }
140
141    mCachedOffset = 0;
142    mCachedSize = 0;
143}
144
145status_t MPEG4DataSource::initCheck() const {
146    return mSource->initCheck();
147}
148
149ssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) {
150    Mutex::Autolock autoLock(mLock);
151
152    if (offset >= mCachedOffset
153            && offset + size <= mCachedOffset + mCachedSize) {
154        memcpy(data, &mCache[offset - mCachedOffset], size);
155        return size;
156    }
157
158    return mSource->readAt(offset, data, size);
159}
160
161status_t MPEG4DataSource::getSize(off_t *size) {
162    return mSource->getSize(size);
163}
164
165uint32_t MPEG4DataSource::flags() {
166    return mSource->flags();
167}
168
169status_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) {
170    Mutex::Autolock autoLock(mLock);
171
172    clearCache();
173
174    mCache = (uint8_t *)malloc(size);
175
176    if (mCache == NULL) {
177        return -ENOMEM;
178    }
179
180    mCachedOffset = offset;
181    mCachedSize = size;
182
183    ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
184
185    if (err < (ssize_t)size) {
186        clearCache();
187
188        return ERROR_IO;
189    }
190
191    return OK;
192}
193
194////////////////////////////////////////////////////////////////////////////////
195
196static void hexdump(const void *_data, size_t size) {
197    const uint8_t *data = (const uint8_t *)_data;
198    size_t offset = 0;
199    while (offset < size) {
200        printf("0x%04x  ", offset);
201
202        size_t n = size - offset;
203        if (n > 16) {
204            n = 16;
205        }
206
207        for (size_t i = 0; i < 16; ++i) {
208            if (i == 8) {
209                printf(" ");
210            }
211
212            if (offset + i < size) {
213                printf("%02x ", data[offset + i]);
214            } else {
215                printf("   ");
216            }
217        }
218
219        printf(" ");
220
221        for (size_t i = 0; i < n; ++i) {
222            if (isprint(data[offset + i])) {
223                printf("%c", data[offset + i]);
224            } else {
225                printf(".");
226            }
227        }
228
229        printf("\n");
230
231        offset += 16;
232    }
233}
234
235static const char *FourCC2MIME(uint32_t fourcc) {
236    switch (fourcc) {
237        case FOURCC('m', 'p', '4', 'a'):
238            return MEDIA_MIMETYPE_AUDIO_AAC;
239
240        case FOURCC('s', 'a', 'm', 'r'):
241            return MEDIA_MIMETYPE_AUDIO_AMR_NB;
242
243        case FOURCC('s', 'a', 'w', 'b'):
244            return MEDIA_MIMETYPE_AUDIO_AMR_WB;
245
246        case FOURCC('m', 'p', '4', 'v'):
247            return MEDIA_MIMETYPE_VIDEO_MPEG4;
248
249        case FOURCC('s', '2', '6', '3'):
250            return MEDIA_MIMETYPE_VIDEO_H263;
251
252        case FOURCC('a', 'v', 'c', '1'):
253            return MEDIA_MIMETYPE_VIDEO_AVC;
254
255        default:
256            CHECK(!"should not be here.");
257            return NULL;
258    }
259}
260
261MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
262    : mDataSource(source),
263      mHaveMetadata(false),
264      mHasVideo(false),
265      mFirstTrack(NULL),
266      mLastTrack(NULL),
267      mFileMetaData(new MetaData) {
268}
269
270MPEG4Extractor::~MPEG4Extractor() {
271    Track *track = mFirstTrack;
272    while (track) {
273        Track *next = track->next;
274
275        delete track;
276        track = next;
277    }
278    mFirstTrack = mLastTrack = NULL;
279}
280
281sp<MetaData> MPEG4Extractor::getMetaData() {
282    status_t err;
283    if ((err = readMetaData()) != OK) {
284        return new MetaData;
285    }
286
287    return mFileMetaData;
288}
289
290size_t MPEG4Extractor::countTracks() {
291    status_t err;
292    if ((err = readMetaData()) != OK) {
293        return 0;
294    }
295
296    size_t n = 0;
297    Track *track = mFirstTrack;
298    while (track) {
299        ++n;
300        track = track->next;
301    }
302
303    return n;
304}
305
306sp<MetaData> MPEG4Extractor::getTrackMetaData(
307        size_t index, uint32_t flags) {
308    status_t err;
309    if ((err = readMetaData()) != OK) {
310        return NULL;
311    }
312
313    Track *track = mFirstTrack;
314    while (index > 0) {
315        if (track == NULL) {
316            return NULL;
317        }
318
319        track = track->next;
320        --index;
321    }
322
323    if (track == NULL) {
324        return NULL;
325    }
326
327    if ((flags & kIncludeExtensiveMetaData)
328            && !track->includes_expensive_metadata) {
329        track->includes_expensive_metadata = true;
330
331        const char *mime;
332        CHECK(track->meta->findCString(kKeyMIMEType, &mime));
333        if (!strncasecmp("video/", mime, 6)) {
334            uint32_t sampleIndex;
335            uint32_t sampleTime;
336            if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
337                    && track->sampleTable->getMetaDataForSample(
338                        sampleIndex, NULL /* offset */, NULL /* size */,
339                        &sampleTime) == OK) {
340                track->meta->setInt64(
341                        kKeyThumbnailTime,
342                        ((int64_t)sampleTime * 1000000) / track->timescale);
343            }
344        }
345    }
346
347    return track->meta;
348}
349
350status_t MPEG4Extractor::readMetaData() {
351    if (mHaveMetadata) {
352        return OK;
353    }
354
355    off_t offset = 0;
356    status_t err;
357    while ((err = parseChunk(&offset, 0)) == OK) {
358    }
359
360    if (mHaveMetadata) {
361        if (mHasVideo) {
362            mFileMetaData->setCString(kKeyMIMEType, "video/mp4");
363        } else {
364            mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
365        }
366
367        return OK;
368    }
369
370    return err;
371}
372
373static void MakeFourCCString(uint32_t x, char *s) {
374    s[0] = x >> 24;
375    s[1] = (x >> 16) & 0xff;
376    s[2] = (x >> 8) & 0xff;
377    s[3] = x & 0xff;
378    s[4] = '\0';
379}
380
381struct PathAdder {
382    PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
383        : mPath(path) {
384        mPath->push(chunkType);
385    }
386
387    ~PathAdder() {
388        mPath->pop();
389    }
390
391private:
392    Vector<uint32_t> *mPath;
393
394    PathAdder(const PathAdder &);
395    PathAdder &operator=(const PathAdder &);
396};
397
398static bool underMetaDataPath(const Vector<uint32_t> &path) {
399    return path.size() >= 5
400        && path[0] == FOURCC('m', 'o', 'o', 'v')
401        && path[1] == FOURCC('u', 'd', 't', 'a')
402        && path[2] == FOURCC('m', 'e', 't', 'a')
403        && path[3] == FOURCC('i', 'l', 's', 't');
404}
405
406// Given a time in seconds since Jan 1 1904, produce a human-readable string.
407static void convertTimeToDate(int64_t time_1904, String8 *s) {
408    time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
409
410    char tmp[32];
411    strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
412
413    s->setTo(tmp);
414}
415
416status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
417    uint32_t hdr[2];
418    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
419        return ERROR_IO;
420    }
421    uint64_t chunk_size = ntohl(hdr[0]);
422    uint32_t chunk_type = ntohl(hdr[1]);
423    off_t data_offset = *offset + 8;
424
425    if (chunk_size == 1) {
426        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
427            return ERROR_IO;
428        }
429        chunk_size = ntoh64(chunk_size);
430        data_offset += 8;
431
432        if (chunk_size < 16) {
433            // The smallest valid chunk is 16 bytes long in this case.
434            return ERROR_MALFORMED;
435        }
436    } else if (chunk_size < 8) {
437        // The smallest valid chunk is 8 bytes long.
438        return ERROR_MALFORMED;
439    }
440
441    char chunk[5];
442    MakeFourCCString(chunk_type, chunk);
443
444#if 0
445    static const char kWhitespace[] = "                                        ";
446    const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
447    printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
448
449    char buffer[256];
450    size_t n = chunk_size;
451    if (n > sizeof(buffer)) {
452        n = sizeof(buffer);
453    }
454    if (mDataSource->readAt(*offset, buffer, n)
455            < (ssize_t)n) {
456        return ERROR_IO;
457    }
458
459    hexdump(buffer, n);
460#endif
461
462    PathAdder autoAdder(&mPath, chunk_type);
463
464    off_t chunk_data_size = *offset + chunk_size - data_offset;
465
466    if (chunk_type != FOURCC('c', 'p', 'r', 't')
467            && mPath.size() == 5 && underMetaDataPath(mPath)) {
468        off_t stop_offset = *offset + chunk_size;
469        *offset = data_offset;
470        while (*offset < stop_offset) {
471            status_t err = parseChunk(offset, depth + 1);
472            if (err != OK) {
473                return err;
474            }
475        }
476
477        if (*offset != stop_offset) {
478            return ERROR_MALFORMED;
479        }
480
481        return OK;
482    }
483
484    switch(chunk_type) {
485        case FOURCC('m', 'o', 'o', 'v'):
486        case FOURCC('t', 'r', 'a', 'k'):
487        case FOURCC('m', 'd', 'i', 'a'):
488        case FOURCC('m', 'i', 'n', 'f'):
489        case FOURCC('d', 'i', 'n', 'f'):
490        case FOURCC('s', 't', 'b', 'l'):
491        case FOURCC('m', 'v', 'e', 'x'):
492        case FOURCC('m', 'o', 'o', 'f'):
493        case FOURCC('t', 'r', 'a', 'f'):
494        case FOURCC('m', 'f', 'r', 'a'):
495        case FOURCC('s', 'k', 'i' ,'p'):
496        case FOURCC('u', 'd', 't', 'a'):
497        case FOURCC('i', 'l', 's', 't'):
498        {
499            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
500                LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
501
502                if (mDataSource->flags() & DataSource::kWantsPrefetching) {
503                    sp<MPEG4DataSource> cachedSource =
504                        new MPEG4DataSource(mDataSource);
505
506                    if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
507                        mDataSource = cachedSource;
508                    }
509                }
510
511                mLastTrack->sampleTable = new SampleTable(mDataSource);
512            }
513
514            bool isTrack = false;
515            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
516                isTrack = true;
517
518                Track *track = new Track;
519                track->next = NULL;
520                if (mLastTrack) {
521                    mLastTrack->next = track;
522                } else {
523                    mFirstTrack = track;
524                }
525                mLastTrack = track;
526
527                track->meta = new MetaData;
528                track->includes_expensive_metadata = false;
529                track->skipTrack = false;
530                track->timescale = 0;
531                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
532            }
533
534            off_t stop_offset = *offset + chunk_size;
535            *offset = data_offset;
536            while (*offset < stop_offset) {
537                status_t err = parseChunk(offset, depth + 1);
538                if (err != OK) {
539                    return err;
540                }
541            }
542
543            if (*offset != stop_offset) {
544                return ERROR_MALFORMED;
545            }
546
547            if (isTrack) {
548                if (mLastTrack->skipTrack) {
549                    Track *cur = mFirstTrack;
550
551                    if (cur == mLastTrack) {
552                        delete cur;
553                        mFirstTrack = mLastTrack = NULL;
554                    } else {
555                        while (cur && cur->next != mLastTrack) {
556                            cur = cur->next;
557                        }
558                        cur->next = NULL;
559                        delete mLastTrack;
560                        mLastTrack = cur;
561                    }
562
563                    return OK;
564                }
565
566                status_t err = verifyTrack(mLastTrack);
567
568                if (err != OK) {
569                    return err;
570                }
571            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
572                mHaveMetadata = true;
573
574                return UNKNOWN_ERROR;  // Return a dummy error.
575            }
576            break;
577        }
578
579        case FOURCC('t', 'k', 'h', 'd'):
580        {
581            if (chunk_data_size < 4) {
582                return ERROR_MALFORMED;
583            }
584
585            uint8_t version;
586            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
587                return ERROR_IO;
588            }
589
590            uint64_t ctime, mtime, duration;
591            int32_t id;
592            uint32_t width, height;
593
594            if (version == 1) {
595                if (chunk_data_size != 36 + 60) {
596                    return ERROR_MALFORMED;
597                }
598
599                uint8_t buffer[36 + 60];
600                if (mDataSource->readAt(
601                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
602                    return ERROR_IO;
603                }
604
605                ctime = U64_AT(&buffer[4]);
606                mtime = U64_AT(&buffer[12]);
607                id = U32_AT(&buffer[20]);
608                duration = U64_AT(&buffer[28]);
609                width = U32_AT(&buffer[88]);
610                height = U32_AT(&buffer[92]);
611            } else if (version == 0) {
612                if (chunk_data_size != 24 + 60) {
613                    return ERROR_MALFORMED;
614                }
615
616                uint8_t buffer[24 + 60];
617                if (mDataSource->readAt(
618                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
619                    return ERROR_IO;
620                }
621                ctime = U32_AT(&buffer[4]);
622                mtime = U32_AT(&buffer[8]);
623                id = U32_AT(&buffer[12]);
624                duration = U32_AT(&buffer[20]);
625                width = U32_AT(&buffer[76]);
626                height = U32_AT(&buffer[80]);
627            }
628
629            *offset += chunk_size;
630            break;
631        }
632
633        case FOURCC('m', 'd', 'h', 'd'):
634        {
635            if (chunk_data_size < 4) {
636                return ERROR_MALFORMED;
637            }
638
639            uint8_t version;
640            if (mDataSource->readAt(
641                        data_offset, &version, sizeof(version))
642                    < (ssize_t)sizeof(version)) {
643                return ERROR_IO;
644            }
645
646            off_t timescale_offset;
647
648            if (version == 1) {
649                timescale_offset = data_offset + 4 + 16;
650            } else if (version == 0) {
651                timescale_offset = data_offset + 4 + 8;
652            } else {
653                return ERROR_IO;
654            }
655
656            uint32_t timescale;
657            if (mDataSource->readAt(
658                        timescale_offset, &timescale, sizeof(timescale))
659                    < (ssize_t)sizeof(timescale)) {
660                return ERROR_IO;
661            }
662
663            mLastTrack->timescale = ntohl(timescale);
664
665            int64_t duration;
666            if (version == 1) {
667                if (mDataSource->readAt(
668                            timescale_offset + 4, &duration, sizeof(duration))
669                        < (ssize_t)sizeof(duration)) {
670                    return ERROR_IO;
671                }
672                duration = ntoh64(duration);
673            } else {
674                int32_t duration32;
675                if (mDataSource->readAt(
676                            timescale_offset + 4, &duration32, sizeof(duration32))
677                        < (ssize_t)sizeof(duration32)) {
678                    return ERROR_IO;
679                }
680                duration = ntohl(duration32);
681            }
682            mLastTrack->meta->setInt64(
683                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
684
685            *offset += chunk_size;
686            break;
687        }
688
689        case FOURCC('s', 't', 's', 'd'):
690        {
691            if (chunk_data_size < 8) {
692                return ERROR_MALFORMED;
693            }
694
695            uint8_t buffer[8];
696            if (chunk_data_size < (off_t)sizeof(buffer)) {
697                return ERROR_MALFORMED;
698            }
699
700            if (mDataSource->readAt(
701                        data_offset, buffer, 8) < 8) {
702                return ERROR_IO;
703            }
704
705            if (U32_AT(buffer) != 0) {
706                // Should be version 0, flags 0.
707                return ERROR_MALFORMED;
708            }
709
710            uint32_t entry_count = U32_AT(&buffer[4]);
711
712            if (entry_count > 1) {
713                // For now we only support a single type of media per track.
714
715                mLastTrack->skipTrack = true;
716                *offset += chunk_size;
717                break;
718            }
719
720            off_t stop_offset = *offset + chunk_size;
721            *offset = data_offset + 8;
722            for (uint32_t i = 0; i < entry_count; ++i) {
723                status_t err = parseChunk(offset, depth + 1);
724                if (err != OK) {
725                    return err;
726                }
727            }
728
729            if (*offset != stop_offset) {
730                return ERROR_MALFORMED;
731            }
732            break;
733        }
734
735        case FOURCC('m', 'p', '4', 'a'):
736        case FOURCC('s', 'a', 'm', 'r'):
737        case FOURCC('s', 'a', 'w', 'b'):
738        {
739            uint8_t buffer[8 + 20];
740            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
741                // Basic AudioSampleEntry size.
742                return ERROR_MALFORMED;
743            }
744
745            if (mDataSource->readAt(
746                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
747                return ERROR_IO;
748            }
749
750            uint16_t data_ref_index = U16_AT(&buffer[6]);
751            uint16_t num_channels = U16_AT(&buffer[16]);
752
753            uint16_t sample_size = U16_AT(&buffer[18]);
754            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
755
756            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
757                            FourCC2MIME(chunk_type))) {
758                // AMR NB audio is always mono, 8kHz
759                num_channels = 1;
760                sample_rate = 8000;
761            } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
762                               FourCC2MIME(chunk_type))) {
763                // AMR WB audio is always mono, 16kHz
764                num_channels = 1;
765                sample_rate = 16000;
766            }
767
768#if 0
769            printf("*** coding='%s' %d channels, size %d, rate %d\n",
770                   chunk, num_channels, sample_size, sample_rate);
771#endif
772
773            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
774            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
775            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
776
777            off_t stop_offset = *offset + chunk_size;
778            *offset = data_offset + sizeof(buffer);
779            while (*offset < stop_offset) {
780                status_t err = parseChunk(offset, depth + 1);
781                if (err != OK) {
782                    return err;
783                }
784            }
785
786            if (*offset != stop_offset) {
787                return ERROR_MALFORMED;
788            }
789            break;
790        }
791
792        case FOURCC('m', 'p', '4', 'v'):
793        case FOURCC('s', '2', '6', '3'):
794        case FOURCC('a', 'v', 'c', '1'):
795        {
796            mHasVideo = true;
797
798            uint8_t buffer[78];
799            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
800                // Basic VideoSampleEntry size.
801                return ERROR_MALFORMED;
802            }
803
804            if (mDataSource->readAt(
805                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
806                return ERROR_IO;
807            }
808
809            uint16_t data_ref_index = U16_AT(&buffer[6]);
810            uint16_t width = U16_AT(&buffer[6 + 18]);
811            uint16_t height = U16_AT(&buffer[6 + 20]);
812
813            // printf("*** coding='%s' width=%d height=%d\n",
814            //        chunk, width, height);
815
816            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
817            mLastTrack->meta->setInt32(kKeyWidth, width);
818            mLastTrack->meta->setInt32(kKeyHeight, height);
819
820            off_t stop_offset = *offset + chunk_size;
821            *offset = data_offset + sizeof(buffer);
822            while (*offset < stop_offset) {
823                status_t err = parseChunk(offset, depth + 1);
824                if (err != OK) {
825                    return err;
826                }
827            }
828
829            if (*offset != stop_offset) {
830                return ERROR_MALFORMED;
831            }
832            break;
833        }
834
835        case FOURCC('s', 't', 'c', 'o'):
836        case FOURCC('c', 'o', '6', '4'):
837        {
838            status_t err =
839                mLastTrack->sampleTable->setChunkOffsetParams(
840                        chunk_type, data_offset, chunk_data_size);
841
842            if (err != OK) {
843                return err;
844            }
845
846            *offset += chunk_size;
847            break;
848        }
849
850        case FOURCC('s', 't', 's', 'c'):
851        {
852            status_t err =
853                mLastTrack->sampleTable->setSampleToChunkParams(
854                        data_offset, chunk_data_size);
855
856            if (err != OK) {
857                return err;
858            }
859
860            *offset += chunk_size;
861            break;
862        }
863
864        case FOURCC('s', 't', 's', 'z'):
865        case FOURCC('s', 't', 'z', '2'):
866        {
867            status_t err =
868                mLastTrack->sampleTable->setSampleSizeParams(
869                        chunk_type, data_offset, chunk_data_size);
870
871            if (err != OK) {
872                return err;
873            }
874
875            size_t max_size;
876            CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK);
877
878            // Assume that a given buffer only contains at most 10 fragments,
879            // each fragment originally prefixed with a 2 byte length will
880            // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
881            // and thus will grow by 2 bytes per fragment.
882            mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
883
884            *offset += chunk_size;
885            break;
886        }
887
888        case FOURCC('s', 't', 't', 's'):
889        {
890            status_t err =
891                mLastTrack->sampleTable->setTimeToSampleParams(
892                        data_offset, chunk_data_size);
893
894            if (err != OK) {
895                return err;
896            }
897
898            *offset += chunk_size;
899            break;
900        }
901
902        case FOURCC('s', 't', 's', 's'):
903        {
904            status_t err =
905                mLastTrack->sampleTable->setSyncSampleParams(
906                        data_offset, chunk_data_size);
907
908            if (err != OK) {
909                return err;
910            }
911
912            *offset += chunk_size;
913            break;
914        }
915
916        case FOURCC('e', 's', 'd', 's'):
917        {
918            if (chunk_data_size < 4) {
919                return ERROR_MALFORMED;
920            }
921
922            uint8_t buffer[256];
923            if (chunk_data_size > (off_t)sizeof(buffer)) {
924                return ERROR_BUFFER_TOO_SMALL;
925            }
926
927            if (mDataSource->readAt(
928                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
929                return ERROR_IO;
930            }
931
932            if (U32_AT(buffer) != 0) {
933                // Should be version 0, flags 0.
934                return ERROR_MALFORMED;
935            }
936
937            mLastTrack->meta->setData(
938                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
939
940            if (mPath.size() >= 2
941                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
942                // Information from the ESDS must be relied on for proper
943                // setup of sample rate and channel count for MPEG4 Audio.
944                // The generic header appears to only contain generic
945                // information...
946
947                status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
948                        &buffer[4], chunk_data_size - 4);
949
950                if (err != OK) {
951                    return err;
952                }
953            }
954
955            *offset += chunk_size;
956            break;
957        }
958
959        case FOURCC('a', 'v', 'c', 'C'):
960        {
961            char buffer[256];
962            if (chunk_data_size > (off_t)sizeof(buffer)) {
963                return ERROR_BUFFER_TOO_SMALL;
964            }
965
966            if (mDataSource->readAt(
967                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
968                return ERROR_IO;
969            }
970
971            mLastTrack->meta->setData(
972                    kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
973
974            *offset += chunk_size;
975            break;
976        }
977
978        case FOURCC('m', 'e', 't', 'a'):
979        {
980            uint8_t buffer[4];
981            if (chunk_data_size < (off_t)sizeof(buffer)) {
982                return ERROR_MALFORMED;
983            }
984
985            if (mDataSource->readAt(
986                        data_offset, buffer, 4) < 4) {
987                return ERROR_IO;
988            }
989
990            if (U32_AT(buffer) != 0) {
991                // Should be version 0, flags 0.
992
993                // If it's not, let's assume this is one of those
994                // apparently malformed chunks that don't have flags
995                // and completely different semantics than what's
996                // in the MPEG4 specs and skip it.
997                *offset += chunk_size;
998                return OK;
999            }
1000
1001            off_t stop_offset = *offset + chunk_size;
1002            *offset = data_offset + sizeof(buffer);
1003            while (*offset < stop_offset) {
1004                status_t err = parseChunk(offset, depth + 1);
1005                if (err != OK) {
1006                    return err;
1007                }
1008            }
1009
1010            if (*offset != stop_offset) {
1011                return ERROR_MALFORMED;
1012            }
1013            break;
1014        }
1015
1016        case FOURCC('d', 'a', 't', 'a'):
1017        {
1018            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
1019                status_t err = parseMetaData(data_offset, chunk_data_size);
1020
1021                if (err != OK) {
1022                    return err;
1023                }
1024            }
1025
1026            *offset += chunk_size;
1027            break;
1028        }
1029
1030        case FOURCC('m', 'v', 'h', 'd'):
1031        {
1032            if (chunk_data_size < 12) {
1033                return ERROR_MALFORMED;
1034            }
1035
1036            uint8_t header[12];
1037            if (mDataSource->readAt(
1038                        data_offset, header, sizeof(header))
1039                    < (ssize_t)sizeof(header)) {
1040                return ERROR_IO;
1041            }
1042
1043            int64_t creationTime;
1044            if (header[0] == 1) {
1045                creationTime = U64_AT(&header[4]);
1046            } else if (header[0] != 0) {
1047                return ERROR_MALFORMED;
1048            } else {
1049                creationTime = U32_AT(&header[4]);
1050            }
1051
1052            String8 s;
1053            convertTimeToDate(creationTime, &s);
1054
1055            mFileMetaData->setCString(kKeyDate, s.string());
1056
1057            *offset += chunk_size;
1058            break;
1059        }
1060
1061        default:
1062        {
1063            *offset += chunk_size;
1064            break;
1065        }
1066    }
1067
1068    return OK;
1069}
1070
1071status_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) {
1072    if (size < 4) {
1073        return ERROR_MALFORMED;
1074    }
1075
1076    uint8_t *buffer = new uint8_t[size + 1];
1077    if (mDataSource->readAt(
1078                offset, buffer, size) != (ssize_t)size) {
1079        delete[] buffer;
1080        buffer = NULL;
1081
1082        return ERROR_IO;
1083    }
1084
1085    uint32_t flags = U32_AT(buffer);
1086
1087    uint32_t metadataKey = 0;
1088    switch (mPath[4]) {
1089        case FOURCC(0xa9, 'a', 'l', 'b'):
1090        {
1091            metadataKey = kKeyAlbum;
1092            break;
1093        }
1094        case FOURCC(0xa9, 'A', 'R', 'T'):
1095        {
1096            metadataKey = kKeyArtist;
1097            break;
1098        }
1099        case FOURCC('a', 'A', 'R', 'T'):
1100        {
1101            metadataKey = kKeyAlbumArtist;
1102            break;
1103        }
1104        case FOURCC(0xa9, 'd', 'a', 'y'):
1105        {
1106            metadataKey = kKeyYear;
1107            break;
1108        }
1109        case FOURCC(0xa9, 'n', 'a', 'm'):
1110        {
1111            metadataKey = kKeyTitle;
1112            break;
1113        }
1114        case FOURCC(0xa9, 'w', 'r', 't'):
1115        {
1116            metadataKey = kKeyWriter;
1117            break;
1118        }
1119        case FOURCC('c', 'o', 'v', 'r'):
1120        {
1121            metadataKey = kKeyAlbumArt;
1122            break;
1123        }
1124        case FOURCC('g', 'n', 'r', 'e'):
1125        {
1126            metadataKey = kKeyGenre;
1127            break;
1128        }
1129        case FOURCC(0xa9, 'g', 'e', 'n'):
1130        {
1131            metadataKey = kKeyGenre;
1132            break;
1133        }
1134        case FOURCC('t', 'r', 'k', 'n'):
1135        {
1136            if (size == 16 && flags == 0) {
1137                char tmp[16];
1138                sprintf(tmp, "%d/%d",
1139                        (int)buffer[size - 5], (int)buffer[size - 3]);
1140
1141                mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
1142            }
1143            break;
1144        }
1145        case FOURCC('d', 'i', 's', 'k'):
1146        {
1147            if (size == 14 && flags == 0) {
1148                char tmp[16];
1149                sprintf(tmp, "%d/%d",
1150                        (int)buffer[size - 3], (int)buffer[size - 1]);
1151
1152                mFileMetaData->setCString(kKeyDiscNumber, tmp);
1153            }
1154            break;
1155        }
1156
1157        default:
1158            break;
1159    }
1160
1161    if (size >= 8 && metadataKey) {
1162        if (metadataKey == kKeyAlbumArt) {
1163            mFileMetaData->setData(
1164                    kKeyAlbumArt, MetaData::TYPE_NONE,
1165                    buffer + 8, size - 8);
1166        } else if (metadataKey == kKeyGenre) {
1167            if (flags == 0) {
1168                // uint8_t genre code, iTunes genre codes are
1169                // the standard id3 codes, except they start
1170                // at 1 instead of 0 (e.g. Pop is 14, not 13)
1171                // We use standard id3 numbering, so subtract 1.
1172                int genrecode = (int)buffer[size - 1];
1173                genrecode--;
1174                if (genrecode < 0) {
1175                    genrecode = 255; // reserved for 'unknown genre'
1176                }
1177                char genre[10];
1178                sprintf(genre, "%d", genrecode);
1179
1180                mFileMetaData->setCString(metadataKey, genre);
1181            } else if (flags == 1) {
1182                // custom genre string
1183                buffer[size] = '\0';
1184
1185                mFileMetaData->setCString(
1186                        metadataKey, (const char *)buffer + 8);
1187            }
1188        } else {
1189            buffer[size] = '\0';
1190
1191            mFileMetaData->setCString(
1192                    metadataKey, (const char *)buffer + 8);
1193        }
1194    }
1195
1196    delete[] buffer;
1197    buffer = NULL;
1198
1199    return OK;
1200}
1201
1202sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
1203    status_t err;
1204    if ((err = readMetaData()) != OK) {
1205        return NULL;
1206    }
1207
1208    Track *track = mFirstTrack;
1209    while (index > 0) {
1210        if (track == NULL) {
1211            return NULL;
1212        }
1213
1214        track = track->next;
1215        --index;
1216    }
1217
1218    if (track == NULL) {
1219        return NULL;
1220    }
1221
1222    return new MPEG4Source(
1223            track->meta, mDataSource, track->timescale, track->sampleTable);
1224}
1225
1226// static
1227status_t MPEG4Extractor::verifyTrack(Track *track) {
1228    const char *mime;
1229    CHECK(track->meta->findCString(kKeyMIMEType, &mime));
1230
1231    uint32_t type;
1232    const void *data;
1233    size_t size;
1234    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1235        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
1236                || type != kTypeAVCC) {
1237            return ERROR_MALFORMED;
1238        }
1239    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
1240            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1241        if (!track->meta->findData(kKeyESDS, &type, &data, &size)
1242                || type != kTypeESDS) {
1243            return ERROR_MALFORMED;
1244        }
1245    }
1246
1247    return OK;
1248}
1249
1250status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
1251        const void *esds_data, size_t esds_size) {
1252    ESDS esds(esds_data, esds_size);
1253
1254    uint8_t objectTypeIndication;
1255    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
1256        return ERROR_MALFORMED;
1257    }
1258
1259    if (objectTypeIndication == 0xe1) {
1260        // This isn't MPEG4 audio at all, it's QCELP 14k...
1261        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
1262        return OK;
1263    }
1264
1265    const uint8_t *csd;
1266    size_t csd_size;
1267    if (esds.getCodecSpecificInfo(
1268                (const void **)&csd, &csd_size) != OK) {
1269        return ERROR_MALFORMED;
1270    }
1271
1272#if 0
1273    printf("ESD of size %d\n", csd_size);
1274    hexdump(csd, csd_size);
1275#endif
1276
1277    if (csd_size < 2) {
1278        return ERROR_MALFORMED;
1279    }
1280
1281    uint32_t objectType = csd[0] >> 3;
1282
1283    if (objectType == 31) {
1284        return ERROR_UNSUPPORTED;
1285    }
1286
1287    uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7);
1288    int32_t sampleRate = 0;
1289    int32_t numChannels = 0;
1290    if (freqIndex == 15) {
1291        if (csd_size < 5) {
1292            return ERROR_MALFORMED;
1293        }
1294
1295        sampleRate = (csd[1] & 0x7f) << 17
1296                        | csd[2] << 9
1297                        | csd[3] << 1
1298                        | (csd[4] >> 7);
1299
1300        numChannels = (csd[4] >> 3) & 15;
1301    } else {
1302        static uint32_t kSamplingRate[] = {
1303            96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1304            16000, 12000, 11025, 8000, 7350
1305        };
1306
1307        if (freqIndex == 13 || freqIndex == 14) {
1308            return ERROR_MALFORMED;
1309        }
1310
1311        sampleRate = kSamplingRate[freqIndex];
1312        numChannels = (csd[1] >> 3) & 15;
1313    }
1314
1315    if (numChannels == 0) {
1316        return ERROR_UNSUPPORTED;
1317    }
1318
1319    int32_t prevSampleRate;
1320    CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
1321
1322    if (prevSampleRate != sampleRate) {
1323        LOGV("mpeg4 audio sample rate different from previous setting. "
1324             "was: %d, now: %d", prevSampleRate, sampleRate);
1325    }
1326
1327    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
1328
1329    int32_t prevChannelCount;
1330    CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
1331
1332    if (prevChannelCount != numChannels) {
1333        LOGV("mpeg4 audio channel count different from previous setting. "
1334             "was: %d, now: %d", prevChannelCount, numChannels);
1335    }
1336
1337    mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
1338
1339    return OK;
1340}
1341
1342////////////////////////////////////////////////////////////////////////////////
1343
1344MPEG4Source::MPEG4Source(
1345        const sp<MetaData> &format,
1346        const sp<DataSource> &dataSource,
1347        int32_t timeScale,
1348        const sp<SampleTable> &sampleTable)
1349    : mFormat(format),
1350      mDataSource(dataSource),
1351      mTimescale(timeScale),
1352      mSampleTable(sampleTable),
1353      mCurrentSampleIndex(0),
1354      mIsAVC(false),
1355      mNALLengthSize(0),
1356      mStarted(false),
1357      mGroup(NULL),
1358      mBuffer(NULL),
1359      mWantsNALFragments(false),
1360      mSrcBuffer(NULL) {
1361    const char *mime;
1362    bool success = mFormat->findCString(kKeyMIMEType, &mime);
1363    CHECK(success);
1364
1365    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
1366
1367    if (mIsAVC) {
1368        uint32_t type;
1369        const void *data;
1370        size_t size;
1371        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
1372
1373        const uint8_t *ptr = (const uint8_t *)data;
1374
1375        CHECK(size >= 7);
1376        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
1377
1378        // The number of bytes used to encode the length of a NAL unit.
1379        mNALLengthSize = 1 + (ptr[4] & 3);
1380    }
1381}
1382
1383MPEG4Source::~MPEG4Source() {
1384    if (mStarted) {
1385        stop();
1386    }
1387}
1388
1389status_t MPEG4Source::start(MetaData *params) {
1390    Mutex::Autolock autoLock(mLock);
1391
1392    CHECK(!mStarted);
1393
1394    int32_t val;
1395    if (params && params->findInt32(kKeyWantsNALFragments, &val)
1396        && val != 0) {
1397        mWantsNALFragments = true;
1398    } else {
1399        mWantsNALFragments = false;
1400    }
1401
1402    mGroup = new MediaBufferGroup;
1403
1404    int32_t max_size;
1405    CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
1406
1407    mGroup->add_buffer(new MediaBuffer(max_size));
1408
1409    mSrcBuffer = new uint8_t[max_size];
1410
1411    mStarted = true;
1412
1413    return OK;
1414}
1415
1416status_t MPEG4Source::stop() {
1417    Mutex::Autolock autoLock(mLock);
1418
1419    CHECK(mStarted);
1420
1421    if (mBuffer != NULL) {
1422        mBuffer->release();
1423        mBuffer = NULL;
1424    }
1425
1426    delete[] mSrcBuffer;
1427    mSrcBuffer = NULL;
1428
1429    delete mGroup;
1430    mGroup = NULL;
1431
1432    mStarted = false;
1433    mCurrentSampleIndex = 0;
1434
1435    return OK;
1436}
1437
1438sp<MetaData> MPEG4Source::getFormat() {
1439    Mutex::Autolock autoLock(mLock);
1440
1441    return mFormat;
1442}
1443
1444size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
1445    switch (mNALLengthSize) {
1446        case 1:
1447            return *data;
1448        case 2:
1449            return U16_AT(data);
1450        case 3:
1451            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
1452        case 4:
1453            return U32_AT(data);
1454    }
1455
1456    // This cannot happen, mNALLengthSize springs to life by adding 1 to
1457    // a 2-bit integer.
1458    CHECK(!"Should not be here.");
1459
1460    return 0;
1461}
1462
1463status_t MPEG4Source::read(
1464        MediaBuffer **out, const ReadOptions *options) {
1465    Mutex::Autolock autoLock(mLock);
1466
1467    CHECK(mStarted);
1468
1469    *out = NULL;
1470
1471    int64_t seekTimeUs;
1472    if (options && options->getSeekTo(&seekTimeUs)) {
1473        uint32_t sampleIndex;
1474        status_t err = mSampleTable->findClosestSample(
1475                seekTimeUs * mTimescale / 1000000,
1476                &sampleIndex, SampleTable::kSyncSample_Flag);
1477
1478        if (err != OK) {
1479            if (err == ERROR_OUT_OF_RANGE) {
1480                // An attempt to seek past the end of the stream would
1481                // normally cause this ERROR_OUT_OF_RANGE error. Propagating
1482                // this all the way to the MediaPlayer would cause abnormal
1483                // termination. Legacy behaviour appears to be to behave as if
1484                // we had seeked to the end of stream, ending normally.
1485                err = ERROR_END_OF_STREAM;
1486            }
1487            return err;
1488        }
1489
1490        mCurrentSampleIndex = sampleIndex;
1491        if (mBuffer != NULL) {
1492            mBuffer->release();
1493            mBuffer = NULL;
1494        }
1495
1496        // fall through
1497    }
1498
1499    off_t offset;
1500    size_t size;
1501    uint32_t dts;
1502    bool newBuffer = false;
1503    if (mBuffer == NULL) {
1504        newBuffer = true;
1505
1506        status_t err =
1507            mSampleTable->getMetaDataForSample(
1508                    mCurrentSampleIndex, &offset, &size, &dts);
1509
1510        if (err != OK) {
1511            return err;
1512        }
1513
1514        err = mGroup->acquire_buffer(&mBuffer);
1515
1516        if (err != OK) {
1517            CHECK_EQ(mBuffer, NULL);
1518            return err;
1519        }
1520    }
1521
1522    if (!mIsAVC || mWantsNALFragments) {
1523        if (newBuffer) {
1524            ssize_t num_bytes_read =
1525                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
1526
1527            if (num_bytes_read < (ssize_t)size) {
1528                mBuffer->release();
1529                mBuffer = NULL;
1530
1531                return ERROR_IO;
1532            }
1533
1534            CHECK(mBuffer != NULL);
1535            mBuffer->set_range(0, size);
1536            mBuffer->meta_data()->clear();
1537            mBuffer->meta_data()->setInt64(
1538                    kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1539            ++mCurrentSampleIndex;
1540        }
1541
1542        if (!mIsAVC) {
1543            *out = mBuffer;
1544            mBuffer = NULL;
1545
1546            return OK;
1547        }
1548
1549        // Each NAL unit is split up into its constituent fragments and
1550        // each one of them returned in its own buffer.
1551
1552        CHECK(mBuffer->range_length() >= mNALLengthSize);
1553
1554        const uint8_t *src =
1555            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
1556
1557        size_t nal_size = parseNALSize(src);
1558        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
1559            LOGE("incomplete NAL unit.");
1560
1561            mBuffer->release();
1562            mBuffer = NULL;
1563
1564            return ERROR_MALFORMED;
1565        }
1566
1567        MediaBuffer *clone = mBuffer->clone();
1568        CHECK(clone != NULL);
1569        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
1570
1571        CHECK(mBuffer != NULL);
1572        mBuffer->set_range(
1573                mBuffer->range_offset() + mNALLengthSize + nal_size,
1574                mBuffer->range_length() - mNALLengthSize - nal_size);
1575
1576        if (mBuffer->range_length() == 0) {
1577            mBuffer->release();
1578            mBuffer = NULL;
1579        }
1580
1581        *out = clone;
1582
1583        return OK;
1584    } else {
1585        // Whole NAL units are returned but each fragment is prefixed by
1586        // the start code (0x00 00 00 01).
1587
1588        ssize_t num_bytes_read =
1589            mDataSource->readAt(offset, mSrcBuffer, size);
1590
1591        if (num_bytes_read < (ssize_t)size) {
1592            mBuffer->release();
1593            mBuffer = NULL;
1594
1595            return ERROR_IO;
1596        }
1597
1598        uint8_t *dstData = (uint8_t *)mBuffer->data();
1599        size_t srcOffset = 0;
1600        size_t dstOffset = 0;
1601
1602        while (srcOffset < size) {
1603            CHECK(srcOffset + mNALLengthSize <= size);
1604            size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
1605            srcOffset += mNALLengthSize;
1606
1607            if (srcOffset + nalLength > size) {
1608                mBuffer->release();
1609                mBuffer = NULL;
1610
1611                return ERROR_MALFORMED;
1612            }
1613
1614            if (nalLength == 0) {
1615                continue;
1616            }
1617
1618            CHECK(dstOffset + 4 <= mBuffer->size());
1619
1620            dstData[dstOffset++] = 0;
1621            dstData[dstOffset++] = 0;
1622            dstData[dstOffset++] = 0;
1623            dstData[dstOffset++] = 1;
1624            memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
1625            srcOffset += nalLength;
1626            dstOffset += nalLength;
1627        }
1628        CHECK_EQ(srcOffset, size);
1629
1630        CHECK(mBuffer != NULL);
1631        mBuffer->set_range(0, dstOffset);
1632        mBuffer->meta_data()->clear();
1633        mBuffer->meta_data()->setInt64(
1634                kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1635        ++mCurrentSampleIndex;
1636
1637        *out = mBuffer;
1638        mBuffer = NULL;
1639
1640        return OK;
1641    }
1642}
1643
1644static bool LegacySniffMPEG4(
1645        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
1646    uint8_t header[8];
1647
1648    ssize_t n = source->readAt(4, header, sizeof(header));
1649    if (n < (ssize_t)sizeof(header)) {
1650        return false;
1651    }
1652
1653    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
1654        || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
1655        || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
1656        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
1657        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
1658        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
1659        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
1660        *confidence = 0.1;
1661
1662        return true;
1663    }
1664
1665    return false;
1666}
1667
1668static bool isCompatibleBrand(uint32_t fourcc) {
1669    static const uint32_t kCompatibleBrands[] = {
1670        FOURCC('i', 's', 'o', 'm'),
1671        FOURCC('i', 's', 'o', '2'),
1672        FOURCC('a', 'v', 'c', '1'),
1673        FOURCC('3', 'g', 'p', '4'),
1674        FOURCC('m', 'p', '4', '1'),
1675        FOURCC('m', 'p', '4', '2'),
1676    };
1677
1678    for (size_t i = 0;
1679         i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
1680         ++i) {
1681        if (kCompatibleBrands[i] == fourcc) {
1682            return true;
1683        }
1684    }
1685
1686    return false;
1687}
1688
1689// Attempt to actually parse the 'ftyp' atom and determine if a suitable
1690// compatible brand is present.
1691static bool BetterSniffMPEG4(
1692        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
1693    uint8_t header[12];
1694    if (source->readAt(0, header, 12) != 12
1695            || memcmp("ftyp", &header[4], 4)) {
1696        return false;
1697    }
1698
1699    size_t atomSize = U32_AT(&header[0]);
1700    if (atomSize < 16 || (atomSize % 4) != 0) {
1701        return false;
1702    }
1703
1704    bool success = false;
1705    if (isCompatibleBrand(U32_AT(&header[8]))) {
1706        success = true;
1707    } else {
1708        size_t numCompatibleBrands = (atomSize - 16) / 4;
1709        for (size_t i = 0; i < numCompatibleBrands; ++i) {
1710            uint8_t tmp[4];
1711            if (source->readAt(16 + i * 4, tmp, 4) != 4) {
1712                return false;
1713            }
1714
1715            if (isCompatibleBrand(U32_AT(&tmp[0]))) {
1716                success = true;
1717                break;
1718            }
1719        }
1720    }
1721
1722    if (!success) {
1723        return false;
1724    }
1725
1726    *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
1727    *confidence = 0.3f;
1728
1729    return true;
1730}
1731
1732bool SniffMPEG4(
1733        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
1734    if (BetterSniffMPEG4(source, mimeType, confidence)) {
1735        return true;
1736    }
1737
1738    if (LegacySniffMPEG4(source, mimeType, confidence)) {
1739        LOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
1740        return true;
1741    }
1742
1743    return false;
1744}
1745
1746}  // namespace android
1747
1748