MPEG4Extractor.cpp revision affa99c52957685f5a5652ab5254b92e729651c7
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 <media/stagefright/MediaBuffer.h>
32#include <media/stagefright/MediaBufferGroup.h>
33#include <media/stagefright/MediaDebug.h>
34#include <media/stagefright/MediaDefs.h>
35#include <media/stagefright/MediaSource.h>
36#include <media/stagefright/MetaData.h>
37#include <media/stagefright/Utils.h>
38#include <utils/String8.h>
39
40namespace android {
41
42class MPEG4Source : public MediaSource {
43public:
44    // Caller retains ownership of both "dataSource" and "sampleTable".
45    MPEG4Source(const sp<MetaData> &format,
46                const sp<DataSource> &dataSource,
47                int32_t timeScale,
48                const sp<SampleTable> &sampleTable);
49
50    virtual status_t start(MetaData *params = NULL);
51    virtual status_t stop();
52
53    virtual sp<MetaData> getFormat();
54
55    virtual status_t read(
56            MediaBuffer **buffer, const ReadOptions *options = NULL);
57
58protected:
59    virtual ~MPEG4Source();
60
61private:
62    sp<MetaData> mFormat;
63    sp<DataSource> mDataSource;
64    int32_t mTimescale;
65    sp<SampleTable> mSampleTable;
66    uint32_t mCurrentSampleIndex;
67
68    bool mIsAVC;
69    size_t mNALLengthSize;
70
71    bool mStarted;
72
73    MediaBufferGroup *mGroup;
74
75    MediaBuffer *mBuffer;
76
77    bool mWantsNALFragments;
78
79    uint8_t *mSrcBuffer;
80
81    size_t parseNALSize(const uint8_t *data) const;
82
83    MPEG4Source(const MPEG4Source &);
84    MPEG4Source &operator=(const MPEG4Source &);
85};
86
87// This custom data source wraps an existing one and satisfies requests
88// falling entirely within a cached range from the cache while forwarding
89// all remaining requests to the wrapped datasource.
90// This is used to cache the full sampletable metadata for a single track,
91// possibly wrapping multiple times to cover all tracks, i.e.
92// Each MPEG4DataSource caches the sampletable metadata for a single track.
93
94struct MPEG4DataSource : public DataSource {
95    MPEG4DataSource(const sp<DataSource> &source);
96
97    virtual status_t initCheck() const;
98    virtual ssize_t readAt(off_t offset, void *data, size_t size);
99    virtual status_t getSize(off_t *size);
100    virtual uint32_t flags();
101
102    status_t setCachedRange(off_t offset, size_t size);
103
104protected:
105    virtual ~MPEG4DataSource();
106
107private:
108    Mutex mLock;
109
110    sp<DataSource> mSource;
111    off_t mCachedOffset;
112    size_t mCachedSize;
113    uint8_t *mCache;
114
115    void clearCache();
116
117    MPEG4DataSource(const MPEG4DataSource &);
118    MPEG4DataSource &operator=(const MPEG4DataSource &);
119};
120
121MPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
122    : mSource(source),
123      mCachedOffset(0),
124      mCachedSize(0),
125      mCache(NULL) {
126}
127
128MPEG4DataSource::~MPEG4DataSource() {
129    clearCache();
130}
131
132void MPEG4DataSource::clearCache() {
133    if (mCache) {
134        free(mCache);
135        mCache = NULL;
136    }
137
138    mCachedOffset = 0;
139    mCachedSize = 0;
140}
141
142status_t MPEG4DataSource::initCheck() const {
143    return mSource->initCheck();
144}
145
146ssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) {
147    Mutex::Autolock autoLock(mLock);
148
149    if (offset >= mCachedOffset
150            && offset + size <= mCachedOffset + mCachedSize) {
151        memcpy(data, &mCache[offset - mCachedOffset], size);
152        return size;
153    }
154
155    return mSource->readAt(offset, data, size);
156}
157
158status_t MPEG4DataSource::getSize(off_t *size) {
159    return mSource->getSize(size);
160}
161
162uint32_t MPEG4DataSource::flags() {
163    return mSource->flags();
164}
165
166status_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) {
167    Mutex::Autolock autoLock(mLock);
168
169    clearCache();
170
171    mCache = (uint8_t *)malloc(size);
172
173    if (mCache == NULL) {
174        return -ENOMEM;
175    }
176
177    mCachedOffset = offset;
178    mCachedSize = size;
179
180    ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
181
182    if (err < (ssize_t)size) {
183        clearCache();
184
185        return ERROR_IO;
186    }
187
188    return OK;
189}
190
191////////////////////////////////////////////////////////////////////////////////
192
193static void hexdump(const void *_data, size_t size) {
194    const uint8_t *data = (const uint8_t *)_data;
195    size_t offset = 0;
196    while (offset < size) {
197        printf("0x%04x  ", offset);
198
199        size_t n = size - offset;
200        if (n > 16) {
201            n = 16;
202        }
203
204        for (size_t i = 0; i < 16; ++i) {
205            if (i == 8) {
206                printf(" ");
207            }
208
209            if (offset + i < size) {
210                printf("%02x ", data[offset + i]);
211            } else {
212                printf("   ");
213            }
214        }
215
216        printf(" ");
217
218        for (size_t i = 0; i < n; ++i) {
219            if (isprint(data[offset + i])) {
220                printf("%c", data[offset + i]);
221            } else {
222                printf(".");
223            }
224        }
225
226        printf("\n");
227
228        offset += 16;
229    }
230}
231
232static const char *FourCC2MIME(uint32_t fourcc) {
233    switch (fourcc) {
234        case FOURCC('m', 'p', '4', 'a'):
235            return MEDIA_MIMETYPE_AUDIO_AAC;
236
237        case FOURCC('s', 'a', 'm', 'r'):
238            return MEDIA_MIMETYPE_AUDIO_AMR_NB;
239
240        case FOURCC('s', 'a', 'w', 'b'):
241            return MEDIA_MIMETYPE_AUDIO_AMR_WB;
242
243        case FOURCC('m', 'p', '4', 'v'):
244            return MEDIA_MIMETYPE_VIDEO_MPEG4;
245
246        case FOURCC('s', '2', '6', '3'):
247            return MEDIA_MIMETYPE_VIDEO_H263;
248
249        case FOURCC('a', 'v', 'c', '1'):
250            return MEDIA_MIMETYPE_VIDEO_AVC;
251
252        default:
253            CHECK(!"should not be here.");
254            return NULL;
255    }
256}
257
258MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
259    : mDataSource(source),
260      mHaveMetadata(false),
261      mHasVideo(false),
262      mFirstTrack(NULL),
263      mLastTrack(NULL),
264      mFileMetaData(new MetaData) {
265}
266
267MPEG4Extractor::~MPEG4Extractor() {
268    Track *track = mFirstTrack;
269    while (track) {
270        Track *next = track->next;
271
272        delete track;
273        track = next;
274    }
275    mFirstTrack = mLastTrack = NULL;
276}
277
278sp<MetaData> MPEG4Extractor::getMetaData() {
279    status_t err;
280    if ((err = readMetaData()) != OK) {
281        return new MetaData;
282    }
283
284    return mFileMetaData;
285}
286
287size_t MPEG4Extractor::countTracks() {
288    status_t err;
289    if ((err = readMetaData()) != OK) {
290        return 0;
291    }
292
293    size_t n = 0;
294    Track *track = mFirstTrack;
295    while (track) {
296        ++n;
297        track = track->next;
298    }
299
300    return n;
301}
302
303sp<MetaData> MPEG4Extractor::getTrackMetaData(
304        size_t index, uint32_t flags) {
305    status_t err;
306    if ((err = readMetaData()) != OK) {
307        return NULL;
308    }
309
310    Track *track = mFirstTrack;
311    while (index > 0) {
312        if (track == NULL) {
313            return NULL;
314        }
315
316        track = track->next;
317        --index;
318    }
319
320    if (track == NULL) {
321        return NULL;
322    }
323
324    if ((flags & kIncludeExtensiveMetaData)
325            && !track->includes_expensive_metadata) {
326        track->includes_expensive_metadata = true;
327
328        const char *mime;
329        CHECK(track->meta->findCString(kKeyMIMEType, &mime));
330        if (!strncasecmp("video/", mime, 6)) {
331            uint32_t sampleIndex;
332            uint32_t sampleTime;
333            if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
334                    && track->sampleTable->getMetaDataForSample(
335                        sampleIndex, NULL /* offset */, NULL /* size */,
336                        &sampleTime) == OK) {
337                track->meta->setInt64(
338                        kKeyThumbnailTime,
339                        ((int64_t)sampleTime * 1000000) / track->timescale);
340            }
341        }
342    }
343
344    return track->meta;
345}
346
347status_t MPEG4Extractor::readMetaData() {
348    if (mHaveMetadata) {
349        return OK;
350    }
351
352    off_t offset = 0;
353    status_t err;
354    while ((err = parseChunk(&offset, 0)) == OK) {
355    }
356
357    if (mHaveMetadata) {
358        if (mHasVideo) {
359            mFileMetaData->setCString(kKeyMIMEType, "video/mp4");
360        } else {
361            mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
362        }
363
364        return OK;
365    }
366
367    return err;
368}
369
370static void MakeFourCCString(uint32_t x, char *s) {
371    s[0] = x >> 24;
372    s[1] = (x >> 16) & 0xff;
373    s[2] = (x >> 8) & 0xff;
374    s[3] = x & 0xff;
375    s[4] = '\0';
376}
377
378struct PathAdder {
379    PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
380        : mPath(path) {
381        mPath->push(chunkType);
382    }
383
384    ~PathAdder() {
385        mPath->pop();
386    }
387
388private:
389    Vector<uint32_t> *mPath;
390
391    PathAdder(const PathAdder &);
392    PathAdder &operator=(const PathAdder &);
393};
394
395static bool underMetaDataPath(const Vector<uint32_t> &path) {
396    return path.size() >= 5
397        && path[0] == FOURCC('m', 'o', 'o', 'v')
398        && path[1] == FOURCC('u', 'd', 't', 'a')
399        && path[2] == FOURCC('m', 'e', 't', 'a')
400        && path[3] == FOURCC('i', 'l', 's', 't');
401}
402
403// Given a time in seconds since Jan 1 1904, produce a human-readable string.
404static void convertTimeToDate(int64_t time_1904, String8 *s) {
405    time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
406
407    char tmp[32];
408    strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
409
410    s->setTo(tmp);
411}
412
413status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
414    uint32_t hdr[2];
415    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
416        return ERROR_IO;
417    }
418    uint64_t chunk_size = ntohl(hdr[0]);
419    uint32_t chunk_type = ntohl(hdr[1]);
420    off_t data_offset = *offset + 8;
421
422    if (chunk_size == 1) {
423        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
424            return ERROR_IO;
425        }
426        chunk_size = ntoh64(chunk_size);
427        data_offset += 8;
428    }
429
430    char chunk[5];
431    MakeFourCCString(chunk_type, chunk);
432
433#if 0
434    static const char kWhitespace[] = "                                        ";
435    const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
436    printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
437
438    char buffer[256];
439    if (chunk_size <= sizeof(buffer)) {
440        if (mDataSource->readAt(*offset, buffer, chunk_size)
441                < (ssize_t)chunk_size) {
442            return ERROR_IO;
443        }
444
445        hexdump(buffer, chunk_size);
446    }
447#endif
448
449    PathAdder autoAdder(&mPath, chunk_type);
450
451    off_t chunk_data_size = *offset + chunk_size - data_offset;
452
453    if (chunk_type != FOURCC('c', 'p', 'r', 't')
454            && mPath.size() == 5 && underMetaDataPath(mPath)) {
455        off_t stop_offset = *offset + chunk_size;
456        *offset = data_offset;
457        while (*offset < stop_offset) {
458            status_t err = parseChunk(offset, depth + 1);
459            if (err != OK) {
460                return err;
461            }
462        }
463        CHECK_EQ(*offset, stop_offset);
464
465        return OK;
466    }
467
468    switch(chunk_type) {
469        case FOURCC('m', 'o', 'o', 'v'):
470        case FOURCC('t', 'r', 'a', 'k'):
471        case FOURCC('m', 'd', 'i', 'a'):
472        case FOURCC('m', 'i', 'n', 'f'):
473        case FOURCC('d', 'i', 'n', 'f'):
474        case FOURCC('s', 't', 'b', 'l'):
475        case FOURCC('m', 'v', 'e', 'x'):
476        case FOURCC('m', 'o', 'o', 'f'):
477        case FOURCC('t', 'r', 'a', 'f'):
478        case FOURCC('m', 'f', 'r', 'a'):
479        case FOURCC('s', 'k', 'i' ,'p'):
480        case FOURCC('u', 'd', 't', 'a'):
481        case FOURCC('i', 'l', 's', 't'):
482        {
483            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
484                LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
485
486                if (mDataSource->flags() & DataSource::kWantsPrefetching) {
487                    sp<MPEG4DataSource> cachedSource =
488                        new MPEG4DataSource(mDataSource);
489
490                    if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
491                        mDataSource = cachedSource;
492                    }
493                }
494            }
495
496            off_t stop_offset = *offset + chunk_size;
497            *offset = data_offset;
498            while (*offset < stop_offset) {
499                status_t err = parseChunk(offset, depth + 1);
500                if (err != OK) {
501                    return err;
502                }
503            }
504            CHECK_EQ(*offset, stop_offset);
505
506            if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
507                mHaveMetadata = true;
508
509                return UNKNOWN_ERROR;  // Return a dummy error.
510            }
511            break;
512        }
513
514        case FOURCC('t', 'k', 'h', 'd'):
515        {
516            CHECK(chunk_data_size >= 4);
517
518            uint8_t version;
519            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
520                return ERROR_IO;
521            }
522
523            uint64_t ctime, mtime, duration;
524            int32_t id;
525            uint32_t width, height;
526
527            if (version == 1) {
528                if (chunk_data_size != 36 + 60) {
529                    return ERROR_MALFORMED;
530                }
531
532                uint8_t buffer[36 + 60];
533                if (mDataSource->readAt(
534                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
535                    return ERROR_IO;
536                }
537
538                ctime = U64_AT(&buffer[4]);
539                mtime = U64_AT(&buffer[12]);
540                id = U32_AT(&buffer[20]);
541                duration = U64_AT(&buffer[28]);
542                width = U32_AT(&buffer[88]);
543                height = U32_AT(&buffer[92]);
544            } else if (version == 0) {
545                if (chunk_data_size != 24 + 60) {
546                    return ERROR_MALFORMED;
547                }
548
549                uint8_t buffer[24 + 60];
550                if (mDataSource->readAt(
551                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
552                    return ERROR_IO;
553                }
554                ctime = U32_AT(&buffer[4]);
555                mtime = U32_AT(&buffer[8]);
556                id = U32_AT(&buffer[12]);
557                duration = U32_AT(&buffer[20]);
558                width = U32_AT(&buffer[76]);
559                height = U32_AT(&buffer[80]);
560            }
561
562            Track *track = new Track;
563            track->next = NULL;
564            if (mLastTrack) {
565                mLastTrack->next = track;
566            } else {
567                mFirstTrack = track;
568            }
569            mLastTrack = track;
570
571            track->meta = new MetaData;
572            track->includes_expensive_metadata = false;
573            track->timescale = 0;
574            track->sampleTable = new SampleTable(mDataSource);
575            track->meta->setCString(kKeyMIMEType, "application/octet-stream");
576
577            *offset += chunk_size;
578            break;
579        }
580
581        case FOURCC('m', 'd', 'h', 'd'):
582        {
583            if (chunk_data_size < 4) {
584                return ERROR_MALFORMED;
585            }
586
587            uint8_t version;
588            if (mDataSource->readAt(
589                        data_offset, &version, sizeof(version))
590                    < (ssize_t)sizeof(version)) {
591                return ERROR_IO;
592            }
593
594            off_t timescale_offset;
595
596            if (version == 1) {
597                timescale_offset = data_offset + 4 + 16;
598            } else if (version == 0) {
599                timescale_offset = data_offset + 4 + 8;
600            } else {
601                return ERROR_IO;
602            }
603
604            uint32_t timescale;
605            if (mDataSource->readAt(
606                        timescale_offset, &timescale, sizeof(timescale))
607                    < (ssize_t)sizeof(timescale)) {
608                return ERROR_IO;
609            }
610
611            mLastTrack->timescale = ntohl(timescale);
612
613            int64_t duration;
614            if (version == 1) {
615                if (mDataSource->readAt(
616                            timescale_offset + 4, &duration, sizeof(duration))
617                        < (ssize_t)sizeof(duration)) {
618                    return ERROR_IO;
619                }
620                duration = ntoh64(duration);
621            } else {
622                int32_t duration32;
623                if (mDataSource->readAt(
624                            timescale_offset + 4, &duration32, sizeof(duration32))
625                        < (ssize_t)sizeof(duration32)) {
626                    return ERROR_IO;
627                }
628                duration = ntohl(duration32);
629            }
630            mLastTrack->meta->setInt64(
631                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
632
633            *offset += chunk_size;
634            break;
635        }
636
637        case FOURCC('h', 'd', 'l', 'r'):
638        {
639            if (chunk_data_size < 25) {
640                return ERROR_MALFORMED;
641            }
642
643            uint8_t buffer[24];
644            if (mDataSource->readAt(data_offset, buffer, 24) < 24) {
645                return ERROR_IO;
646            }
647
648            if (U32_AT(buffer) != 0) {
649                // Should be version 0, flags 0.
650                return ERROR_MALFORMED;
651            }
652
653            if (U32_AT(&buffer[4]) != 0) {
654                // pre_defined should be 0.
655                return ERROR_MALFORMED;
656            }
657
658            mHandlerType = U32_AT(&buffer[8]);
659            *offset += chunk_size;
660            break;
661        }
662
663        case FOURCC('s', 't', 's', 'd'):
664        {
665            if (chunk_data_size < 8) {
666                return ERROR_MALFORMED;
667            }
668
669            uint8_t buffer[8];
670            CHECK(chunk_data_size >= (off_t)sizeof(buffer));
671            if (mDataSource->readAt(
672                        data_offset, buffer, 8) < 8) {
673                return ERROR_IO;
674            }
675
676            if (U32_AT(buffer) != 0) {
677                // Should be version 0, flags 0.
678                return ERROR_MALFORMED;
679            }
680
681            uint32_t entry_count = U32_AT(&buffer[4]);
682
683            if (entry_count > 1) {
684                // For now we only support a single type of media per track.
685                return ERROR_UNSUPPORTED;
686            }
687
688            off_t stop_offset = *offset + chunk_size;
689            *offset = data_offset + 8;
690            for (uint32_t i = 0; i < entry_count; ++i) {
691                status_t err = parseChunk(offset, depth + 1);
692                if (err != OK) {
693                    return err;
694                }
695            }
696            CHECK_EQ(*offset, stop_offset);
697            break;
698        }
699
700        case FOURCC('m', 'p', '4', 'a'):
701        case FOURCC('s', 'a', 'm', 'r'):
702        case FOURCC('s', 'a', 'w', 'b'):
703        {
704            if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) {
705                return ERROR_MALFORMED;
706            }
707
708            uint8_t buffer[8 + 20];
709            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
710                // Basic AudioSampleEntry size.
711                return ERROR_MALFORMED;
712            }
713
714            if (mDataSource->readAt(
715                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
716                return ERROR_IO;
717            }
718
719            uint16_t data_ref_index = U16_AT(&buffer[6]);
720            uint16_t num_channels = U16_AT(&buffer[16]);
721
722            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
723                            FourCC2MIME(chunk_type))
724                || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
725                               FourCC2MIME(chunk_type))) {
726                // AMR audio is always mono.
727                num_channels = 1;
728            }
729
730            uint16_t sample_size = U16_AT(&buffer[18]);
731            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
732
733            // printf("*** coding='%s' %d channels, size %d, rate %d\n",
734            //        chunk, num_channels, sample_size, sample_rate);
735
736            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
737            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
738            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
739
740            off_t stop_offset = *offset + chunk_size;
741            *offset = data_offset + sizeof(buffer);
742            while (*offset < stop_offset) {
743                status_t err = parseChunk(offset, depth + 1);
744                if (err != OK) {
745                    return err;
746                }
747            }
748            CHECK_EQ(*offset, stop_offset);
749            break;
750        }
751
752        case FOURCC('m', 'p', '4', 'v'):
753        case FOURCC('s', '2', '6', '3'):
754        case FOURCC('a', 'v', 'c', '1'):
755        {
756            mHasVideo = true;
757
758            if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) {
759                return ERROR_MALFORMED;
760            }
761
762            uint8_t buffer[78];
763            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
764                // Basic VideoSampleEntry size.
765                return ERROR_MALFORMED;
766            }
767
768            if (mDataSource->readAt(
769                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
770                return ERROR_IO;
771            }
772
773            uint16_t data_ref_index = U16_AT(&buffer[6]);
774            uint16_t width = U16_AT(&buffer[6 + 18]);
775            uint16_t height = U16_AT(&buffer[6 + 20]);
776
777            // printf("*** coding='%s' width=%d height=%d\n",
778            //        chunk, width, height);
779
780            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
781            mLastTrack->meta->setInt32(kKeyWidth, width);
782            mLastTrack->meta->setInt32(kKeyHeight, height);
783
784            off_t stop_offset = *offset + chunk_size;
785            *offset = data_offset + sizeof(buffer);
786            while (*offset < stop_offset) {
787                status_t err = parseChunk(offset, depth + 1);
788                if (err != OK) {
789                    return err;
790                }
791            }
792            CHECK_EQ(*offset, stop_offset);
793            break;
794        }
795
796        case FOURCC('s', 't', 'c', 'o'):
797        case FOURCC('c', 'o', '6', '4'):
798        {
799            status_t err =
800                mLastTrack->sampleTable->setChunkOffsetParams(
801                        chunk_type, data_offset, chunk_data_size);
802
803            if (err != OK) {
804                return err;
805            }
806
807            *offset += chunk_size;
808            break;
809        }
810
811        case FOURCC('s', 't', 's', 'c'):
812        {
813            status_t err =
814                mLastTrack->sampleTable->setSampleToChunkParams(
815                        data_offset, chunk_data_size);
816
817            if (err != OK) {
818                return err;
819            }
820
821            *offset += chunk_size;
822            break;
823        }
824
825        case FOURCC('s', 't', 's', 'z'):
826        case FOURCC('s', 't', 'z', '2'):
827        {
828            status_t err =
829                mLastTrack->sampleTable->setSampleSizeParams(
830                        chunk_type, data_offset, chunk_data_size);
831
832            if (err != OK) {
833                return err;
834            }
835
836            size_t max_size;
837            CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK);
838
839            // Assume that a given buffer only contains at most 10 fragments,
840            // each fragment originally prefixed with a 2 byte length will
841            // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
842            // and thus will grow by 2 bytes per fragment.
843            mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
844
845            *offset += chunk_size;
846            break;
847        }
848
849        case FOURCC('s', 't', 't', 's'):
850        {
851            status_t err =
852                mLastTrack->sampleTable->setTimeToSampleParams(
853                        data_offset, chunk_data_size);
854
855            if (err != OK) {
856                return err;
857            }
858
859            *offset += chunk_size;
860            break;
861        }
862
863        case FOURCC('s', 't', 's', 's'):
864        {
865            status_t err =
866                mLastTrack->sampleTable->setSyncSampleParams(
867                        data_offset, chunk_data_size);
868
869            if (err != OK) {
870                return err;
871            }
872
873            *offset += chunk_size;
874            break;
875        }
876
877        case FOURCC('e', 's', 'd', 's'):
878        {
879            if (chunk_data_size < 4) {
880                return ERROR_MALFORMED;
881            }
882
883            uint8_t buffer[256];
884            if (chunk_data_size > (off_t)sizeof(buffer)) {
885                return ERROR_BUFFER_TOO_SMALL;
886            }
887
888            if (mDataSource->readAt(
889                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
890                return ERROR_IO;
891            }
892
893            if (U32_AT(buffer) != 0) {
894                // Should be version 0, flags 0.
895                return ERROR_MALFORMED;
896            }
897
898            mLastTrack->meta->setData(
899                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
900
901            *offset += chunk_size;
902            break;
903        }
904
905        case FOURCC('a', 'v', 'c', 'C'):
906        {
907            char buffer[256];
908            if (chunk_data_size > (off_t)sizeof(buffer)) {
909                return ERROR_BUFFER_TOO_SMALL;
910            }
911
912            if (mDataSource->readAt(
913                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
914                return ERROR_IO;
915            }
916
917            mLastTrack->meta->setData(
918                    kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
919
920            *offset += chunk_size;
921            break;
922        }
923
924        case FOURCC('m', 'e', 't', 'a'):
925        {
926            uint8_t buffer[4];
927            CHECK(chunk_data_size >= (off_t)sizeof(buffer));
928            if (mDataSource->readAt(
929                        data_offset, buffer, 4) < 4) {
930                return ERROR_IO;
931            }
932
933            if (U32_AT(buffer) != 0) {
934                // Should be version 0, flags 0.
935                return ERROR_MALFORMED;
936            }
937
938            off_t stop_offset = *offset + chunk_size;
939            *offset = data_offset + sizeof(buffer);
940            while (*offset < stop_offset) {
941                status_t err = parseChunk(offset, depth + 1);
942                if (err != OK) {
943                    return err;
944                }
945            }
946            CHECK_EQ(*offset, stop_offset);
947            break;
948        }
949
950        case FOURCC('d', 'a', 't', 'a'):
951        {
952            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
953                status_t err = parseMetaData(data_offset, chunk_data_size);
954
955                if (err != OK) {
956                    return err;
957                }
958            }
959
960            *offset += chunk_size;
961            break;
962        }
963
964        case FOURCC('m', 'v', 'h', 'd'):
965        {
966            if (chunk_data_size < 12) {
967                return ERROR_MALFORMED;
968            }
969
970            uint8_t header[12];
971            if (mDataSource->readAt(
972                        data_offset, header, sizeof(header))
973                    < (ssize_t)sizeof(header)) {
974                return ERROR_IO;
975            }
976
977            int64_t creationTime;
978            if (header[0] == 1) {
979                creationTime = U64_AT(&header[4]);
980            } else {
981                CHECK_EQ(header[0], 0);
982                creationTime = U32_AT(&header[4]);
983            }
984
985            String8 s;
986            convertTimeToDate(creationTime, &s);
987
988            mFileMetaData->setCString(kKeyDate, s.string());
989
990            *offset += chunk_size;
991            break;
992        }
993
994        default:
995        {
996            *offset += chunk_size;
997            break;
998        }
999    }
1000
1001    return OK;
1002}
1003
1004status_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) {
1005    if (size < 4) {
1006        return ERROR_MALFORMED;
1007    }
1008
1009    uint8_t *buffer = new uint8_t[size + 1];
1010    if (mDataSource->readAt(
1011                offset, buffer, size) != (ssize_t)size) {
1012        delete[] buffer;
1013        buffer = NULL;
1014
1015        return ERROR_IO;
1016    }
1017
1018    uint32_t flags = U32_AT(buffer);
1019
1020    uint32_t metadataKey = 0;
1021    switch (mPath[4]) {
1022        case FOURCC(0xa9, 'a', 'l', 'b'):
1023        {
1024            metadataKey = kKeyAlbum;
1025            break;
1026        }
1027        case FOURCC(0xa9, 'A', 'R', 'T'):
1028        {
1029            metadataKey = kKeyArtist;
1030            break;
1031        }
1032        case FOURCC(0xa9, 'd', 'a', 'y'):
1033        {
1034            metadataKey = kKeyYear;
1035            break;
1036        }
1037        case FOURCC(0xa9, 'n', 'a', 'm'):
1038        {
1039            metadataKey = kKeyTitle;
1040            break;
1041        }
1042        case FOURCC(0xa9, 'w', 'r', 't'):
1043        {
1044            metadataKey = kKeyWriter;
1045            break;
1046        }
1047        case FOURCC('c', 'o', 'v', 'r'):
1048        {
1049            metadataKey = kKeyAlbumArt;
1050            break;
1051        }
1052        case FOURCC('g', 'n', 'r', 'e'):
1053        {
1054            metadataKey = kKeyGenre;
1055            break;
1056        }
1057        case FOURCC('t', 'r', 'k', 'n'):
1058        {
1059            if (size == 16 && flags == 0) {
1060                char tmp[16];
1061                sprintf(tmp, "%d/%d",
1062                        (int)buffer[size - 5], (int)buffer[size - 3]);
1063
1064                printf("track: %s\n", tmp);
1065                mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
1066            }
1067            break;
1068        }
1069        default:
1070            break;
1071    }
1072
1073    if (size >= 8 && metadataKey) {
1074        if (metadataKey == kKeyAlbumArt) {
1075            mFileMetaData->setData(
1076                    kKeyAlbumArt, MetaData::TYPE_NONE,
1077                    buffer + 8, size - 8);
1078        } else if (metadataKey == kKeyGenre) {
1079            if (flags == 0) {
1080                // uint8_t
1081                char genre[10];
1082                sprintf(genre, "%d", (int)buffer[size - 1]);
1083
1084                mFileMetaData->setCString(metadataKey, genre);
1085            }
1086        } else {
1087            buffer[size] = '\0';
1088
1089            mFileMetaData->setCString(
1090                    metadataKey, (const char *)buffer + 8);
1091        }
1092    }
1093
1094    delete[] buffer;
1095    buffer = NULL;
1096
1097    return OK;
1098}
1099
1100sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
1101    status_t err;
1102    if ((err = readMetaData()) != OK) {
1103        return NULL;
1104    }
1105
1106    Track *track = mFirstTrack;
1107    while (index > 0) {
1108        if (track == NULL) {
1109            return NULL;
1110        }
1111
1112        track = track->next;
1113        --index;
1114    }
1115
1116    if (track == NULL) {
1117        return NULL;
1118    }
1119
1120    return new MPEG4Source(
1121            track->meta, mDataSource, track->timescale, track->sampleTable);
1122}
1123
1124////////////////////////////////////////////////////////////////////////////////
1125
1126MPEG4Source::MPEG4Source(
1127        const sp<MetaData> &format,
1128        const sp<DataSource> &dataSource,
1129        int32_t timeScale,
1130        const sp<SampleTable> &sampleTable)
1131    : mFormat(format),
1132      mDataSource(dataSource),
1133      mTimescale(timeScale),
1134      mSampleTable(sampleTable),
1135      mCurrentSampleIndex(0),
1136      mIsAVC(false),
1137      mNALLengthSize(0),
1138      mStarted(false),
1139      mGroup(NULL),
1140      mBuffer(NULL),
1141      mWantsNALFragments(false),
1142      mSrcBuffer(NULL) {
1143    const char *mime;
1144    bool success = mFormat->findCString(kKeyMIMEType, &mime);
1145    CHECK(success);
1146
1147    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
1148
1149    if (mIsAVC) {
1150        uint32_t type;
1151        const void *data;
1152        size_t size;
1153        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
1154
1155        const uint8_t *ptr = (const uint8_t *)data;
1156
1157        CHECK(size >= 7);
1158        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
1159
1160        // The number of bytes used to encode the length of a NAL unit.
1161        mNALLengthSize = 1 + (ptr[4] & 3);
1162    }
1163}
1164
1165MPEG4Source::~MPEG4Source() {
1166    if (mStarted) {
1167        stop();
1168    }
1169}
1170
1171status_t MPEG4Source::start(MetaData *params) {
1172    CHECK(!mStarted);
1173
1174    int32_t val;
1175    if (params && params->findInt32(kKeyWantsNALFragments, &val)
1176        && val != 0) {
1177        mWantsNALFragments = true;
1178    } else {
1179        mWantsNALFragments = false;
1180    }
1181
1182    mGroup = new MediaBufferGroup;
1183
1184    int32_t max_size;
1185    CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
1186
1187    mGroup->add_buffer(new MediaBuffer(max_size));
1188
1189    mSrcBuffer = new uint8_t[max_size];
1190
1191    mStarted = true;
1192
1193    return OK;
1194}
1195
1196status_t MPEG4Source::stop() {
1197    CHECK(mStarted);
1198
1199    if (mBuffer != NULL) {
1200        mBuffer->release();
1201        mBuffer = NULL;
1202    }
1203
1204    delete[] mSrcBuffer;
1205    mSrcBuffer = NULL;
1206
1207    delete mGroup;
1208    mGroup = NULL;
1209
1210    mStarted = false;
1211    mCurrentSampleIndex = 0;
1212
1213    return OK;
1214}
1215
1216sp<MetaData> MPEG4Source::getFormat() {
1217    return mFormat;
1218}
1219
1220size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
1221    switch (mNALLengthSize) {
1222        case 1:
1223            return *data;
1224        case 2:
1225            return U16_AT(data);
1226        case 3:
1227            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
1228        case 4:
1229            return U32_AT(data);
1230    }
1231
1232    // This cannot happen, mNALLengthSize springs to life by adding 1 to
1233    // a 2-bit integer.
1234    CHECK(!"Should not be here.");
1235
1236    return 0;
1237}
1238
1239status_t MPEG4Source::read(
1240        MediaBuffer **out, const ReadOptions *options) {
1241    CHECK(mStarted);
1242
1243    *out = NULL;
1244
1245    int64_t seekTimeUs;
1246    if (options && options->getSeekTo(&seekTimeUs)) {
1247        uint32_t sampleIndex;
1248        status_t err = mSampleTable->findClosestSample(
1249                seekTimeUs * mTimescale / 1000000,
1250                &sampleIndex, SampleTable::kSyncSample_Flag);
1251
1252        if (err != OK) {
1253            return err;
1254        }
1255
1256        mCurrentSampleIndex = sampleIndex;
1257        if (mBuffer != NULL) {
1258            mBuffer->release();
1259            mBuffer = NULL;
1260        }
1261
1262        // fall through
1263    }
1264
1265    off_t offset;
1266    size_t size;
1267    uint32_t dts;
1268    bool newBuffer = false;
1269    if (mBuffer == NULL) {
1270        newBuffer = true;
1271
1272        status_t err =
1273            mSampleTable->getMetaDataForSample(
1274                    mCurrentSampleIndex, &offset, &size, &dts);
1275
1276        if (err != OK) {
1277            return err;
1278        }
1279
1280        err = mGroup->acquire_buffer(&mBuffer);
1281
1282        if (err != OK) {
1283            CHECK_EQ(mBuffer, NULL);
1284            return err;
1285        }
1286    }
1287
1288    if (!mIsAVC || mWantsNALFragments) {
1289        if (newBuffer) {
1290            ssize_t num_bytes_read =
1291                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
1292
1293            if (num_bytes_read < (ssize_t)size) {
1294                mBuffer->release();
1295                mBuffer = NULL;
1296
1297                return ERROR_IO;
1298            }
1299
1300            mBuffer->set_range(0, size);
1301            mBuffer->meta_data()->clear();
1302            mBuffer->meta_data()->setInt64(
1303                    kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1304            ++mCurrentSampleIndex;
1305        }
1306
1307        if (!mIsAVC) {
1308            *out = mBuffer;
1309            mBuffer = NULL;
1310
1311            return OK;
1312        }
1313
1314        // Each NAL unit is split up into its constituent fragments and
1315        // each one of them returned in its own buffer.
1316
1317        CHECK(mBuffer->range_length() >= mNALLengthSize);
1318
1319        const uint8_t *src =
1320            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
1321
1322        size_t nal_size = parseNALSize(src);
1323        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
1324            LOGE("incomplete NAL unit.");
1325
1326            mBuffer->release();
1327            mBuffer = NULL;
1328
1329            return ERROR_MALFORMED;
1330        }
1331
1332        MediaBuffer *clone = mBuffer->clone();
1333        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
1334
1335        mBuffer->set_range(
1336                mBuffer->range_offset() + mNALLengthSize + nal_size,
1337                mBuffer->range_length() - mNALLengthSize - nal_size);
1338
1339        if (mBuffer->range_length() == 0) {
1340            mBuffer->release();
1341            mBuffer = NULL;
1342        }
1343
1344        *out = clone;
1345
1346        return OK;
1347    } else {
1348        // Whole NAL units are returned but each fragment is prefixed by
1349        // the start code (0x00 00 00 01).
1350
1351        ssize_t num_bytes_read =
1352            mDataSource->readAt(offset, mSrcBuffer, size);
1353
1354        if (num_bytes_read < (ssize_t)size) {
1355            mBuffer->release();
1356            mBuffer = NULL;
1357
1358            return ERROR_IO;
1359        }
1360
1361        uint8_t *dstData = (uint8_t *)mBuffer->data();
1362        size_t srcOffset = 0;
1363        size_t dstOffset = 0;
1364
1365        while (srcOffset < size) {
1366            CHECK(srcOffset + mNALLengthSize <= size);
1367            size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
1368            srcOffset += mNALLengthSize;
1369
1370            if (srcOffset + nalLength > size) {
1371                mBuffer->release();
1372                mBuffer = NULL;
1373
1374                return ERROR_MALFORMED;
1375            }
1376
1377            if (nalLength == 0) {
1378                continue;
1379            }
1380
1381            CHECK(dstOffset + 4 <= mBuffer->size());
1382
1383            dstData[dstOffset++] = 0;
1384            dstData[dstOffset++] = 0;
1385            dstData[dstOffset++] = 0;
1386            dstData[dstOffset++] = 1;
1387            memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
1388            srcOffset += nalLength;
1389            dstOffset += nalLength;
1390        }
1391        CHECK_EQ(srcOffset, size);
1392
1393        mBuffer->set_range(0, dstOffset);
1394        mBuffer->meta_data()->clear();
1395        mBuffer->meta_data()->setInt64(
1396                kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1397        ++mCurrentSampleIndex;
1398
1399        *out = mBuffer;
1400        mBuffer = NULL;
1401
1402        return OK;
1403    }
1404}
1405
1406bool SniffMPEG4(
1407        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
1408    uint8_t header[8];
1409
1410    ssize_t n = source->readAt(4, header, sizeof(header));
1411    if (n < (ssize_t)sizeof(header)) {
1412        return false;
1413    }
1414
1415    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
1416        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
1417        || !memcmp(header, "ftypM4A ", 8)) {
1418        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
1419        *confidence = 0.1;
1420
1421        return true;
1422    }
1423
1424    return false;
1425}
1426
1427}  // namespace android
1428
1429