MPEG4Extractor.cpp revision 1edbcb2bb9988cc7cb54a865aaea4613bdd53a9d
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
433    char chunk[5];
434    MakeFourCCString(chunk_type, chunk);
435
436#if 0
437    static const char kWhitespace[] = "                                        ";
438    const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
439    printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
440
441    char buffer[256];
442    size_t n = chunk_size;
443    if (n > sizeof(buffer)) {
444        n = sizeof(buffer);
445    }
446    if (mDataSource->readAt(*offset, buffer, n)
447            < (ssize_t)n) {
448        return ERROR_IO;
449    }
450
451    hexdump(buffer, n);
452#endif
453
454    PathAdder autoAdder(&mPath, chunk_type);
455
456    off_t chunk_data_size = *offset + chunk_size - data_offset;
457
458    if (chunk_type != FOURCC('c', 'p', 'r', 't')
459            && mPath.size() == 5 && underMetaDataPath(mPath)) {
460        off_t stop_offset = *offset + chunk_size;
461        *offset = data_offset;
462        while (*offset < stop_offset) {
463            status_t err = parseChunk(offset, depth + 1);
464            if (err != OK) {
465                return err;
466            }
467        }
468
469        if (*offset != stop_offset) {
470            return ERROR_MALFORMED;
471        }
472
473        return OK;
474    }
475
476    switch(chunk_type) {
477        case FOURCC('m', 'o', 'o', 'v'):
478        case FOURCC('t', 'r', 'a', 'k'):
479        case FOURCC('m', 'd', 'i', 'a'):
480        case FOURCC('m', 'i', 'n', 'f'):
481        case FOURCC('d', 'i', 'n', 'f'):
482        case FOURCC('s', 't', 'b', 'l'):
483        case FOURCC('m', 'v', 'e', 'x'):
484        case FOURCC('m', 'o', 'o', 'f'):
485        case FOURCC('t', 'r', 'a', 'f'):
486        case FOURCC('m', 'f', 'r', 'a'):
487        case FOURCC('s', 'k', 'i' ,'p'):
488        case FOURCC('u', 'd', 't', 'a'):
489        case FOURCC('i', 'l', 's', 't'):
490        {
491            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
492                LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
493
494                if (mDataSource->flags() & DataSource::kWantsPrefetching) {
495                    sp<MPEG4DataSource> cachedSource =
496                        new MPEG4DataSource(mDataSource);
497
498                    if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
499                        mDataSource = cachedSource;
500                    }
501                }
502
503                mLastTrack->sampleTable = new SampleTable(mDataSource);
504            }
505
506            bool isTrack = false;
507            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
508                isTrack = true;
509
510                Track *track = new Track;
511                track->next = NULL;
512                if (mLastTrack) {
513                    mLastTrack->next = track;
514                } else {
515                    mFirstTrack = track;
516                }
517                mLastTrack = track;
518
519                track->meta = new MetaData;
520                track->includes_expensive_metadata = false;
521                track->skipTrack = false;
522                track->timescale = 0;
523                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
524            }
525
526            off_t stop_offset = *offset + chunk_size;
527            *offset = data_offset;
528            while (*offset < stop_offset) {
529                status_t err = parseChunk(offset, depth + 1);
530                if (err != OK) {
531                    return err;
532                }
533            }
534
535            if (*offset != stop_offset) {
536                return ERROR_MALFORMED;
537            }
538
539            if (isTrack) {
540                if (mLastTrack->skipTrack) {
541                    Track *cur = mFirstTrack;
542
543                    if (cur == mLastTrack) {
544                        delete cur;
545                        mFirstTrack = mLastTrack = NULL;
546                    } else {
547                        while (cur && cur->next != mLastTrack) {
548                            cur = cur->next;
549                        }
550                        cur->next = NULL;
551                        delete mLastTrack;
552                        mLastTrack = cur;
553                    }
554
555                    return OK;
556                }
557
558                status_t err = verifyTrack(mLastTrack);
559
560                if (err != OK) {
561                    return err;
562                }
563            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
564                mHaveMetadata = true;
565
566                return UNKNOWN_ERROR;  // Return a dummy error.
567            }
568            break;
569        }
570
571        case FOURCC('t', 'k', 'h', 'd'):
572        {
573            if (chunk_data_size < 4) {
574                return ERROR_MALFORMED;
575            }
576
577            uint8_t version;
578            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
579                return ERROR_IO;
580            }
581
582            uint64_t ctime, mtime, duration;
583            int32_t id;
584            uint32_t width, height;
585
586            if (version == 1) {
587                if (chunk_data_size != 36 + 60) {
588                    return ERROR_MALFORMED;
589                }
590
591                uint8_t buffer[36 + 60];
592                if (mDataSource->readAt(
593                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
594                    return ERROR_IO;
595                }
596
597                ctime = U64_AT(&buffer[4]);
598                mtime = U64_AT(&buffer[12]);
599                id = U32_AT(&buffer[20]);
600                duration = U64_AT(&buffer[28]);
601                width = U32_AT(&buffer[88]);
602                height = U32_AT(&buffer[92]);
603            } else if (version == 0) {
604                if (chunk_data_size != 24 + 60) {
605                    return ERROR_MALFORMED;
606                }
607
608                uint8_t buffer[24 + 60];
609                if (mDataSource->readAt(
610                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
611                    return ERROR_IO;
612                }
613                ctime = U32_AT(&buffer[4]);
614                mtime = U32_AT(&buffer[8]);
615                id = U32_AT(&buffer[12]);
616                duration = U32_AT(&buffer[20]);
617                width = U32_AT(&buffer[76]);
618                height = U32_AT(&buffer[80]);
619            }
620
621            *offset += chunk_size;
622            break;
623        }
624
625        case FOURCC('m', 'd', 'h', 'd'):
626        {
627            if (chunk_data_size < 4) {
628                return ERROR_MALFORMED;
629            }
630
631            uint8_t version;
632            if (mDataSource->readAt(
633                        data_offset, &version, sizeof(version))
634                    < (ssize_t)sizeof(version)) {
635                return ERROR_IO;
636            }
637
638            off_t timescale_offset;
639
640            if (version == 1) {
641                timescale_offset = data_offset + 4 + 16;
642            } else if (version == 0) {
643                timescale_offset = data_offset + 4 + 8;
644            } else {
645                return ERROR_IO;
646            }
647
648            uint32_t timescale;
649            if (mDataSource->readAt(
650                        timescale_offset, &timescale, sizeof(timescale))
651                    < (ssize_t)sizeof(timescale)) {
652                return ERROR_IO;
653            }
654
655            mLastTrack->timescale = ntohl(timescale);
656
657            int64_t duration;
658            if (version == 1) {
659                if (mDataSource->readAt(
660                            timescale_offset + 4, &duration, sizeof(duration))
661                        < (ssize_t)sizeof(duration)) {
662                    return ERROR_IO;
663                }
664                duration = ntoh64(duration);
665            } else {
666                int32_t duration32;
667                if (mDataSource->readAt(
668                            timescale_offset + 4, &duration32, sizeof(duration32))
669                        < (ssize_t)sizeof(duration32)) {
670                    return ERROR_IO;
671                }
672                duration = ntohl(duration32);
673            }
674            mLastTrack->meta->setInt64(
675                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
676
677            *offset += chunk_size;
678            break;
679        }
680
681        case FOURCC('s', 't', 's', 'd'):
682        {
683            if (chunk_data_size < 8) {
684                return ERROR_MALFORMED;
685            }
686
687            uint8_t buffer[8];
688            if (chunk_data_size < (off_t)sizeof(buffer)) {
689                return ERROR_MALFORMED;
690            }
691
692            if (mDataSource->readAt(
693                        data_offset, buffer, 8) < 8) {
694                return ERROR_IO;
695            }
696
697            if (U32_AT(buffer) != 0) {
698                // Should be version 0, flags 0.
699                return ERROR_MALFORMED;
700            }
701
702            uint32_t entry_count = U32_AT(&buffer[4]);
703
704            if (entry_count > 1) {
705                // For now we only support a single type of media per track.
706
707                mLastTrack->skipTrack = true;
708                *offset += chunk_size;
709                break;
710            }
711
712            off_t stop_offset = *offset + chunk_size;
713            *offset = data_offset + 8;
714            for (uint32_t i = 0; i < entry_count; ++i) {
715                status_t err = parseChunk(offset, depth + 1);
716                if (err != OK) {
717                    return err;
718                }
719            }
720
721            if (*offset != stop_offset) {
722                return ERROR_MALFORMED;
723            }
724            break;
725        }
726
727        case FOURCC('m', 'p', '4', 'a'):
728        case FOURCC('s', 'a', 'm', 'r'):
729        case FOURCC('s', 'a', 'w', 'b'):
730        {
731            uint8_t buffer[8 + 20];
732            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
733                // Basic AudioSampleEntry size.
734                return ERROR_MALFORMED;
735            }
736
737            if (mDataSource->readAt(
738                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
739                return ERROR_IO;
740            }
741
742            uint16_t data_ref_index = U16_AT(&buffer[6]);
743            uint16_t num_channels = U16_AT(&buffer[16]);
744
745            uint16_t sample_size = U16_AT(&buffer[18]);
746            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
747
748            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
749                            FourCC2MIME(chunk_type))) {
750                // AMR NB audio is always mono, 8kHz
751                num_channels = 1;
752                sample_rate = 8000;
753            } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
754                               FourCC2MIME(chunk_type))) {
755                // AMR WB audio is always mono, 16kHz
756                num_channels = 1;
757                sample_rate = 16000;
758            }
759
760#if 0
761            printf("*** coding='%s' %d channels, size %d, rate %d\n",
762                   chunk, num_channels, sample_size, sample_rate);
763#endif
764
765            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
766            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
767            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
768
769            off_t stop_offset = *offset + chunk_size;
770            *offset = data_offset + sizeof(buffer);
771            while (*offset < stop_offset) {
772                status_t err = parseChunk(offset, depth + 1);
773                if (err != OK) {
774                    return err;
775                }
776            }
777
778            if (*offset != stop_offset) {
779                return ERROR_MALFORMED;
780            }
781            break;
782        }
783
784        case FOURCC('m', 'p', '4', 'v'):
785        case FOURCC('s', '2', '6', '3'):
786        case FOURCC('a', 'v', 'c', '1'):
787        {
788            mHasVideo = true;
789
790            uint8_t buffer[78];
791            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
792                // Basic VideoSampleEntry size.
793                return ERROR_MALFORMED;
794            }
795
796            if (mDataSource->readAt(
797                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
798                return ERROR_IO;
799            }
800
801            uint16_t data_ref_index = U16_AT(&buffer[6]);
802            uint16_t width = U16_AT(&buffer[6 + 18]);
803            uint16_t height = U16_AT(&buffer[6 + 20]);
804
805            // printf("*** coding='%s' width=%d height=%d\n",
806            //        chunk, width, height);
807
808            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
809            mLastTrack->meta->setInt32(kKeyWidth, width);
810            mLastTrack->meta->setInt32(kKeyHeight, height);
811
812            off_t stop_offset = *offset + chunk_size;
813            *offset = data_offset + sizeof(buffer);
814            while (*offset < stop_offset) {
815                status_t err = parseChunk(offset, depth + 1);
816                if (err != OK) {
817                    return err;
818                }
819            }
820
821            if (*offset != stop_offset) {
822                return ERROR_MALFORMED;
823            }
824            break;
825        }
826
827        case FOURCC('s', 't', 'c', 'o'):
828        case FOURCC('c', 'o', '6', '4'):
829        {
830            status_t err =
831                mLastTrack->sampleTable->setChunkOffsetParams(
832                        chunk_type, data_offset, chunk_data_size);
833
834            if (err != OK) {
835                return err;
836            }
837
838            *offset += chunk_size;
839            break;
840        }
841
842        case FOURCC('s', 't', 's', 'c'):
843        {
844            status_t err =
845                mLastTrack->sampleTable->setSampleToChunkParams(
846                        data_offset, chunk_data_size);
847
848            if (err != OK) {
849                return err;
850            }
851
852            *offset += chunk_size;
853            break;
854        }
855
856        case FOURCC('s', 't', 's', 'z'):
857        case FOURCC('s', 't', 'z', '2'):
858        {
859            status_t err =
860                mLastTrack->sampleTable->setSampleSizeParams(
861                        chunk_type, data_offset, chunk_data_size);
862
863            if (err != OK) {
864                return err;
865            }
866
867            size_t max_size;
868            CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK);
869
870            // Assume that a given buffer only contains at most 10 fragments,
871            // each fragment originally prefixed with a 2 byte length will
872            // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
873            // and thus will grow by 2 bytes per fragment.
874            mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
875
876            *offset += chunk_size;
877            break;
878        }
879
880        case FOURCC('s', 't', 't', 's'):
881        {
882            status_t err =
883                mLastTrack->sampleTable->setTimeToSampleParams(
884                        data_offset, chunk_data_size);
885
886            if (err != OK) {
887                return err;
888            }
889
890            *offset += chunk_size;
891            break;
892        }
893
894        case FOURCC('s', 't', 's', 's'):
895        {
896            status_t err =
897                mLastTrack->sampleTable->setSyncSampleParams(
898                        data_offset, chunk_data_size);
899
900            if (err != OK) {
901                return err;
902            }
903
904            *offset += chunk_size;
905            break;
906        }
907
908        case FOURCC('e', 's', 'd', 's'):
909        {
910            if (chunk_data_size < 4) {
911                return ERROR_MALFORMED;
912            }
913
914            uint8_t buffer[256];
915            if (chunk_data_size > (off_t)sizeof(buffer)) {
916                return ERROR_BUFFER_TOO_SMALL;
917            }
918
919            if (mDataSource->readAt(
920                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
921                return ERROR_IO;
922            }
923
924            if (U32_AT(buffer) != 0) {
925                // Should be version 0, flags 0.
926                return ERROR_MALFORMED;
927            }
928
929            mLastTrack->meta->setData(
930                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
931
932            if (mPath.size() >= 2
933                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
934                // Information from the ESDS must be relied on for proper
935                // setup of sample rate and channel count for MPEG4 Audio.
936                // The generic header appears to only contain generic
937                // information...
938
939                status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
940                        &buffer[4], chunk_data_size - 4);
941
942                if (err != OK) {
943                    return err;
944                }
945            }
946
947            *offset += chunk_size;
948            break;
949        }
950
951        case FOURCC('a', 'v', 'c', 'C'):
952        {
953            char buffer[256];
954            if (chunk_data_size > (off_t)sizeof(buffer)) {
955                return ERROR_BUFFER_TOO_SMALL;
956            }
957
958            if (mDataSource->readAt(
959                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
960                return ERROR_IO;
961            }
962
963            mLastTrack->meta->setData(
964                    kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
965
966            *offset += chunk_size;
967            break;
968        }
969
970        case FOURCC('m', 'e', 't', 'a'):
971        {
972            uint8_t buffer[4];
973            if (chunk_data_size < (off_t)sizeof(buffer)) {
974                return ERROR_MALFORMED;
975            }
976
977            if (mDataSource->readAt(
978                        data_offset, buffer, 4) < 4) {
979                return ERROR_IO;
980            }
981
982            if (U32_AT(buffer) != 0) {
983                // Should be version 0, flags 0.
984
985                // If it's not, let's assume this is one of those
986                // apparently malformed chunks that don't have flags
987                // and completely different semantics than what's
988                // in the MPEG4 specs and skip it.
989                *offset += chunk_size;
990                return OK;
991            }
992
993            off_t stop_offset = *offset + chunk_size;
994            *offset = data_offset + sizeof(buffer);
995            while (*offset < stop_offset) {
996                status_t err = parseChunk(offset, depth + 1);
997                if (err != OK) {
998                    return err;
999                }
1000            }
1001
1002            if (*offset != stop_offset) {
1003                return ERROR_MALFORMED;
1004            }
1005            break;
1006        }
1007
1008        case FOURCC('d', 'a', 't', 'a'):
1009        {
1010            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
1011                status_t err = parseMetaData(data_offset, chunk_data_size);
1012
1013                if (err != OK) {
1014                    return err;
1015                }
1016            }
1017
1018            *offset += chunk_size;
1019            break;
1020        }
1021
1022        case FOURCC('m', 'v', 'h', 'd'):
1023        {
1024            if (chunk_data_size < 12) {
1025                return ERROR_MALFORMED;
1026            }
1027
1028            uint8_t header[12];
1029            if (mDataSource->readAt(
1030                        data_offset, header, sizeof(header))
1031                    < (ssize_t)sizeof(header)) {
1032                return ERROR_IO;
1033            }
1034
1035            int64_t creationTime;
1036            if (header[0] == 1) {
1037                creationTime = U64_AT(&header[4]);
1038            } else if (header[0] != 0) {
1039                return ERROR_MALFORMED;
1040            } else {
1041                creationTime = U32_AT(&header[4]);
1042            }
1043
1044            String8 s;
1045            convertTimeToDate(creationTime, &s);
1046
1047            mFileMetaData->setCString(kKeyDate, s.string());
1048
1049            *offset += chunk_size;
1050            break;
1051        }
1052
1053        default:
1054        {
1055            *offset += chunk_size;
1056            break;
1057        }
1058    }
1059
1060    return OK;
1061}
1062
1063status_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) {
1064    if (size < 4) {
1065        return ERROR_MALFORMED;
1066    }
1067
1068    uint8_t *buffer = new uint8_t[size + 1];
1069    if (mDataSource->readAt(
1070                offset, buffer, size) != (ssize_t)size) {
1071        delete[] buffer;
1072        buffer = NULL;
1073
1074        return ERROR_IO;
1075    }
1076
1077    uint32_t flags = U32_AT(buffer);
1078
1079    uint32_t metadataKey = 0;
1080    switch (mPath[4]) {
1081        case FOURCC(0xa9, 'a', 'l', 'b'):
1082        {
1083            metadataKey = kKeyAlbum;
1084            break;
1085        }
1086        case FOURCC(0xa9, 'A', 'R', 'T'):
1087        {
1088            metadataKey = kKeyArtist;
1089            break;
1090        }
1091        case FOURCC('a', 'A', 'R', 'T'):
1092        {
1093            metadataKey = kKeyAlbumArtist;
1094            break;
1095        }
1096        case FOURCC(0xa9, 'd', 'a', 'y'):
1097        {
1098            metadataKey = kKeyYear;
1099            break;
1100        }
1101        case FOURCC(0xa9, 'n', 'a', 'm'):
1102        {
1103            metadataKey = kKeyTitle;
1104            break;
1105        }
1106        case FOURCC(0xa9, 'w', 'r', 't'):
1107        {
1108            metadataKey = kKeyWriter;
1109            break;
1110        }
1111        case FOURCC('c', 'o', 'v', 'r'):
1112        {
1113            metadataKey = kKeyAlbumArt;
1114            break;
1115        }
1116        case FOURCC('g', 'n', 'r', 'e'):
1117        {
1118            metadataKey = kKeyGenre;
1119            break;
1120        }
1121        case FOURCC(0xa9, 'g', 'e', 'n'):
1122        {
1123            metadataKey = kKeyGenre;
1124            break;
1125        }
1126        case FOURCC('t', 'r', 'k', 'n'):
1127        {
1128            if (size == 16 && flags == 0) {
1129                char tmp[16];
1130                sprintf(tmp, "%d/%d",
1131                        (int)buffer[size - 5], (int)buffer[size - 3]);
1132
1133                mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
1134            }
1135            break;
1136        }
1137        case FOURCC('d', 'i', 's', 'k'):
1138        {
1139            if (size == 14 && flags == 0) {
1140                char tmp[16];
1141                sprintf(tmp, "%d/%d",
1142                        (int)buffer[size - 3], (int)buffer[size - 1]);
1143
1144                mFileMetaData->setCString(kKeyDiscNumber, tmp);
1145            }
1146            break;
1147        }
1148
1149        default:
1150            break;
1151    }
1152
1153    if (size >= 8 && metadataKey) {
1154        if (metadataKey == kKeyAlbumArt) {
1155            mFileMetaData->setData(
1156                    kKeyAlbumArt, MetaData::TYPE_NONE,
1157                    buffer + 8, size - 8);
1158        } else if (metadataKey == kKeyGenre) {
1159            if (flags == 0) {
1160                // uint8_t genre code, iTunes genre codes are
1161                // the standard id3 codes, except they start
1162                // at 1 instead of 0 (e.g. Pop is 14, not 13)
1163                // We use standard id3 numbering, so subtract 1.
1164                int genrecode = (int)buffer[size - 1];
1165                genrecode--;
1166                if (genrecode < 0) {
1167                    genrecode = 255; // reserved for 'unknown genre'
1168                }
1169                char genre[10];
1170                sprintf(genre, "%d", genrecode);
1171
1172                mFileMetaData->setCString(metadataKey, genre);
1173            } else if (flags == 1) {
1174                // custom genre string
1175                buffer[size] = '\0';
1176
1177                mFileMetaData->setCString(
1178                        metadataKey, (const char *)buffer + 8);
1179            }
1180        } else {
1181            buffer[size] = '\0';
1182
1183            mFileMetaData->setCString(
1184                    metadataKey, (const char *)buffer + 8);
1185        }
1186    }
1187
1188    delete[] buffer;
1189    buffer = NULL;
1190
1191    return OK;
1192}
1193
1194sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
1195    status_t err;
1196    if ((err = readMetaData()) != OK) {
1197        return NULL;
1198    }
1199
1200    Track *track = mFirstTrack;
1201    while (index > 0) {
1202        if (track == NULL) {
1203            return NULL;
1204        }
1205
1206        track = track->next;
1207        --index;
1208    }
1209
1210    if (track == NULL) {
1211        return NULL;
1212    }
1213
1214    return new MPEG4Source(
1215            track->meta, mDataSource, track->timescale, track->sampleTable);
1216}
1217
1218// static
1219status_t MPEG4Extractor::verifyTrack(Track *track) {
1220    const char *mime;
1221    CHECK(track->meta->findCString(kKeyMIMEType, &mime));
1222
1223    uint32_t type;
1224    const void *data;
1225    size_t size;
1226    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1227        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
1228                || type != kTypeAVCC) {
1229            return ERROR_MALFORMED;
1230        }
1231    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
1232            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1233        if (!track->meta->findData(kKeyESDS, &type, &data, &size)
1234                || type != kTypeESDS) {
1235            return ERROR_MALFORMED;
1236        }
1237    }
1238
1239    return OK;
1240}
1241
1242status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
1243        const void *esds_data, size_t esds_size) {
1244    ESDS esds(esds_data, esds_size);
1245
1246    uint8_t objectTypeIndication;
1247    if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
1248        return ERROR_MALFORMED;
1249    }
1250
1251    if (objectTypeIndication == 0xe1) {
1252        // This isn't MPEG4 audio at all, it's QCELP 14k...
1253        mLastTrack->meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_QCELP);
1254        return OK;
1255    }
1256
1257    const uint8_t *csd;
1258    size_t csd_size;
1259    if (esds.getCodecSpecificInfo(
1260                (const void **)&csd, &csd_size) != OK) {
1261        return ERROR_MALFORMED;
1262    }
1263
1264#if 0
1265    printf("ESD of size %d\n", csd_size);
1266    hexdump(csd, csd_size);
1267#endif
1268
1269    if (csd_size < 2) {
1270        return ERROR_MALFORMED;
1271    }
1272
1273    uint32_t objectType = csd[0] >> 3;
1274
1275    if (objectType == 31) {
1276        return ERROR_UNSUPPORTED;
1277    }
1278
1279    uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7);
1280    int32_t sampleRate = 0;
1281    int32_t numChannels = 0;
1282    if (freqIndex == 15) {
1283        if (csd_size < 5) {
1284            return ERROR_MALFORMED;
1285        }
1286
1287        sampleRate = (csd[1] & 0x7f) << 17
1288                        | csd[2] << 9
1289                        | csd[3] << 1
1290                        | (csd[4] >> 7);
1291
1292        numChannels = (csd[4] >> 3) & 15;
1293    } else {
1294        static uint32_t kSamplingRate[] = {
1295            96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1296            16000, 12000, 11025, 8000, 7350
1297        };
1298
1299        if (freqIndex == 13 || freqIndex == 14) {
1300            return ERROR_MALFORMED;
1301        }
1302
1303        sampleRate = kSamplingRate[freqIndex];
1304        numChannels = (csd[1] >> 3) & 15;
1305    }
1306
1307    if (numChannels == 0) {
1308        return ERROR_UNSUPPORTED;
1309    }
1310
1311    int32_t prevSampleRate;
1312    CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
1313
1314    if (prevSampleRate != sampleRate) {
1315        LOGV("mpeg4 audio sample rate different from previous setting. "
1316             "was: %d, now: %d", prevSampleRate, sampleRate);
1317    }
1318
1319    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
1320
1321    int32_t prevChannelCount;
1322    CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
1323
1324    if (prevChannelCount != numChannels) {
1325        LOGV("mpeg4 audio channel count different from previous setting. "
1326             "was: %d, now: %d", prevChannelCount, numChannels);
1327    }
1328
1329    mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
1330
1331    return OK;
1332}
1333
1334////////////////////////////////////////////////////////////////////////////////
1335
1336MPEG4Source::MPEG4Source(
1337        const sp<MetaData> &format,
1338        const sp<DataSource> &dataSource,
1339        int32_t timeScale,
1340        const sp<SampleTable> &sampleTable)
1341    : mFormat(format),
1342      mDataSource(dataSource),
1343      mTimescale(timeScale),
1344      mSampleTable(sampleTable),
1345      mCurrentSampleIndex(0),
1346      mIsAVC(false),
1347      mNALLengthSize(0),
1348      mStarted(false),
1349      mGroup(NULL),
1350      mBuffer(NULL),
1351      mWantsNALFragments(false),
1352      mSrcBuffer(NULL) {
1353    const char *mime;
1354    bool success = mFormat->findCString(kKeyMIMEType, &mime);
1355    CHECK(success);
1356
1357    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
1358
1359    if (mIsAVC) {
1360        uint32_t type;
1361        const void *data;
1362        size_t size;
1363        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
1364
1365        const uint8_t *ptr = (const uint8_t *)data;
1366
1367        CHECK(size >= 7);
1368        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
1369
1370        // The number of bytes used to encode the length of a NAL unit.
1371        mNALLengthSize = 1 + (ptr[4] & 3);
1372    }
1373}
1374
1375MPEG4Source::~MPEG4Source() {
1376    if (mStarted) {
1377        stop();
1378    }
1379}
1380
1381status_t MPEG4Source::start(MetaData *params) {
1382    Mutex::Autolock autoLock(mLock);
1383
1384    CHECK(!mStarted);
1385
1386    int32_t val;
1387    if (params && params->findInt32(kKeyWantsNALFragments, &val)
1388        && val != 0) {
1389        mWantsNALFragments = true;
1390    } else {
1391        mWantsNALFragments = false;
1392    }
1393
1394    mGroup = new MediaBufferGroup;
1395
1396    int32_t max_size;
1397    CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
1398
1399    mGroup->add_buffer(new MediaBuffer(max_size));
1400
1401    mSrcBuffer = new uint8_t[max_size];
1402
1403    mStarted = true;
1404
1405    return OK;
1406}
1407
1408status_t MPEG4Source::stop() {
1409    Mutex::Autolock autoLock(mLock);
1410
1411    CHECK(mStarted);
1412
1413    if (mBuffer != NULL) {
1414        mBuffer->release();
1415        mBuffer = NULL;
1416    }
1417
1418    delete[] mSrcBuffer;
1419    mSrcBuffer = NULL;
1420
1421    delete mGroup;
1422    mGroup = NULL;
1423
1424    mStarted = false;
1425    mCurrentSampleIndex = 0;
1426
1427    return OK;
1428}
1429
1430sp<MetaData> MPEG4Source::getFormat() {
1431    Mutex::Autolock autoLock(mLock);
1432
1433    return mFormat;
1434}
1435
1436size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
1437    switch (mNALLengthSize) {
1438        case 1:
1439            return *data;
1440        case 2:
1441            return U16_AT(data);
1442        case 3:
1443            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
1444        case 4:
1445            return U32_AT(data);
1446    }
1447
1448    // This cannot happen, mNALLengthSize springs to life by adding 1 to
1449    // a 2-bit integer.
1450    CHECK(!"Should not be here.");
1451
1452    return 0;
1453}
1454
1455status_t MPEG4Source::read(
1456        MediaBuffer **out, const ReadOptions *options) {
1457    Mutex::Autolock autoLock(mLock);
1458
1459    CHECK(mStarted);
1460
1461    *out = NULL;
1462
1463    int64_t seekTimeUs;
1464    if (options && options->getSeekTo(&seekTimeUs)) {
1465        uint32_t sampleIndex;
1466        status_t err = mSampleTable->findClosestSample(
1467                seekTimeUs * mTimescale / 1000000,
1468                &sampleIndex, SampleTable::kSyncSample_Flag);
1469
1470        if (err != OK) {
1471            if (err == ERROR_OUT_OF_RANGE) {
1472                // An attempt to seek past the end of the stream would
1473                // normally cause this ERROR_OUT_OF_RANGE error. Propagating
1474                // this all the way to the MediaPlayer would cause abnormal
1475                // termination. Legacy behaviour appears to be to behave as if
1476                // we had seeked to the end of stream, ending normally.
1477                err = ERROR_END_OF_STREAM;
1478            }
1479            return err;
1480        }
1481
1482        mCurrentSampleIndex = sampleIndex;
1483        if (mBuffer != NULL) {
1484            mBuffer->release();
1485            mBuffer = NULL;
1486        }
1487
1488        // fall through
1489    }
1490
1491    off_t offset;
1492    size_t size;
1493    uint32_t dts;
1494    bool newBuffer = false;
1495    if (mBuffer == NULL) {
1496        newBuffer = true;
1497
1498        status_t err =
1499            mSampleTable->getMetaDataForSample(
1500                    mCurrentSampleIndex, &offset, &size, &dts);
1501
1502        if (err != OK) {
1503            return err;
1504        }
1505
1506        err = mGroup->acquire_buffer(&mBuffer);
1507
1508        if (err != OK) {
1509            CHECK_EQ(mBuffer, NULL);
1510            return err;
1511        }
1512    }
1513
1514    if (!mIsAVC || mWantsNALFragments) {
1515        if (newBuffer) {
1516            ssize_t num_bytes_read =
1517                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
1518
1519            if (num_bytes_read < (ssize_t)size) {
1520                mBuffer->release();
1521                mBuffer = NULL;
1522
1523                return ERROR_IO;
1524            }
1525
1526            CHECK(mBuffer != NULL);
1527            mBuffer->set_range(0, size);
1528            mBuffer->meta_data()->clear();
1529            mBuffer->meta_data()->setInt64(
1530                    kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1531            ++mCurrentSampleIndex;
1532        }
1533
1534        if (!mIsAVC) {
1535            *out = mBuffer;
1536            mBuffer = NULL;
1537
1538            return OK;
1539        }
1540
1541        // Each NAL unit is split up into its constituent fragments and
1542        // each one of them returned in its own buffer.
1543
1544        CHECK(mBuffer->range_length() >= mNALLengthSize);
1545
1546        const uint8_t *src =
1547            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
1548
1549        size_t nal_size = parseNALSize(src);
1550        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
1551            LOGE("incomplete NAL unit.");
1552
1553            mBuffer->release();
1554            mBuffer = NULL;
1555
1556            return ERROR_MALFORMED;
1557        }
1558
1559        MediaBuffer *clone = mBuffer->clone();
1560        CHECK(clone != NULL);
1561        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
1562
1563        CHECK(mBuffer != NULL);
1564        mBuffer->set_range(
1565                mBuffer->range_offset() + mNALLengthSize + nal_size,
1566                mBuffer->range_length() - mNALLengthSize - nal_size);
1567
1568        if (mBuffer->range_length() == 0) {
1569            mBuffer->release();
1570            mBuffer = NULL;
1571        }
1572
1573        *out = clone;
1574
1575        return OK;
1576    } else {
1577        // Whole NAL units are returned but each fragment is prefixed by
1578        // the start code (0x00 00 00 01).
1579
1580        ssize_t num_bytes_read =
1581            mDataSource->readAt(offset, mSrcBuffer, size);
1582
1583        if (num_bytes_read < (ssize_t)size) {
1584            mBuffer->release();
1585            mBuffer = NULL;
1586
1587            return ERROR_IO;
1588        }
1589
1590        uint8_t *dstData = (uint8_t *)mBuffer->data();
1591        size_t srcOffset = 0;
1592        size_t dstOffset = 0;
1593
1594        while (srcOffset < size) {
1595            CHECK(srcOffset + mNALLengthSize <= size);
1596            size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
1597            srcOffset += mNALLengthSize;
1598
1599            if (srcOffset + nalLength > size) {
1600                mBuffer->release();
1601                mBuffer = NULL;
1602
1603                return ERROR_MALFORMED;
1604            }
1605
1606            if (nalLength == 0) {
1607                continue;
1608            }
1609
1610            CHECK(dstOffset + 4 <= mBuffer->size());
1611
1612            dstData[dstOffset++] = 0;
1613            dstData[dstOffset++] = 0;
1614            dstData[dstOffset++] = 0;
1615            dstData[dstOffset++] = 1;
1616            memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
1617            srcOffset += nalLength;
1618            dstOffset += nalLength;
1619        }
1620        CHECK_EQ(srcOffset, size);
1621
1622        CHECK(mBuffer != NULL);
1623        mBuffer->set_range(0, dstOffset);
1624        mBuffer->meta_data()->clear();
1625        mBuffer->meta_data()->setInt64(
1626                kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1627        ++mCurrentSampleIndex;
1628
1629        *out = mBuffer;
1630        mBuffer = NULL;
1631
1632        return OK;
1633    }
1634}
1635
1636bool SniffMPEG4(
1637        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
1638    uint8_t header[8];
1639
1640    ssize_t n = source->readAt(4, header, sizeof(header));
1641    if (n < (ssize_t)sizeof(header)) {
1642        return false;
1643    }
1644
1645    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
1646        || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
1647        || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
1648        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
1649        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
1650        || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)) {
1651        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
1652        *confidence = 0.1;
1653
1654        return true;
1655    }
1656
1657    return false;
1658}
1659
1660}  // namespace android
1661
1662