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