MPEG4Extractor.cpp revision 909255a9cf425534e4a8b582a320686852dc59dc
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}
159
160MPEG4Extractor::~MPEG4Extractor() {
161    Track *track = mFirstTrack;
162    while (track) {
163        Track *next = track->next;
164
165        delete track;
166        track = next;
167    }
168    mFirstTrack = mLastTrack = NULL;
169}
170
171sp<MetaData> MPEG4Extractor::getMetaData() {
172    sp<MetaData> meta = new MetaData;
173
174    status_t err;
175    if ((err = readMetaData()) != OK) {
176        return meta;
177    }
178
179    if (mHasVideo) {
180        meta->setCString(kKeyMIMEType, "video/mp4");
181    } else {
182        meta->setCString(kKeyMIMEType, "audio/mp4");
183    }
184
185    return meta;
186}
187
188size_t MPEG4Extractor::countTracks() {
189    status_t err;
190    if ((err = readMetaData()) != OK) {
191        return 0;
192    }
193
194    size_t n = 0;
195    Track *track = mFirstTrack;
196    while (track) {
197        ++n;
198        track = track->next;
199    }
200
201    return n;
202}
203
204sp<MetaData> MPEG4Extractor::getTrackMetaData(
205        size_t index, uint32_t flags) {
206    status_t err;
207    if ((err = readMetaData()) != OK) {
208        return NULL;
209    }
210
211    Track *track = mFirstTrack;
212    while (index > 0) {
213        if (track == NULL) {
214            return NULL;
215        }
216
217        track = track->next;
218        --index;
219    }
220
221    if (track == NULL) {
222        return NULL;
223    }
224
225    if ((flags & kIncludeExtensiveMetaData)
226            && !track->includes_expensive_metadata) {
227        track->includes_expensive_metadata = true;
228
229        const char *mime;
230        CHECK(track->meta->findCString(kKeyMIMEType, &mime));
231        if (!strncasecmp("video/", mime, 6)) {
232            uint32_t sampleIndex;
233            uint32_t sampleTime;
234            if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
235                    && track->sampleTable->getDecodingTime(
236                        sampleIndex, &sampleTime) == OK) {
237                track->meta->setInt64(
238                        kKeyThumbnailTime,
239                        ((int64_t)sampleTime * 1000000) / track->timescale);
240            }
241        }
242    }
243
244    return track->meta;
245}
246
247status_t MPEG4Extractor::readMetaData() {
248    if (mHaveMetadata) {
249        return OK;
250    }
251
252    off_t offset = 0;
253    status_t err;
254    while ((err = parseChunk(&offset, 0)) == OK) {
255    }
256
257    if (mHaveMetadata) {
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
272status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
273    uint32_t hdr[2];
274    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
275        return ERROR_IO;
276    }
277    uint64_t chunk_size = ntohl(hdr[0]);
278    uint32_t chunk_type = ntohl(hdr[1]);
279    off_t data_offset = *offset + 8;
280
281    if (chunk_size == 1) {
282        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
283            return ERROR_IO;
284        }
285        chunk_size = ntoh64(chunk_size);
286        data_offset += 8;
287    }
288
289    char chunk[5];
290    MakeFourCCString(chunk_type, chunk);
291
292#if 0
293    static const char kWhitespace[] = "                                        ";
294    const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
295    printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
296
297    char buffer[256];
298    if (chunk_size <= sizeof(buffer)) {
299        if (mDataSource->readAt(*offset, buffer, chunk_size) < chunk_size) {
300            return ERROR_IO;
301        }
302
303        hexdump(buffer, chunk_size);
304    }
305#endif
306
307    off_t chunk_data_size = *offset + chunk_size - data_offset;
308
309    switch(chunk_type) {
310        case FOURCC('m', 'o', 'o', 'v'):
311        case FOURCC('t', 'r', 'a', 'k'):
312        case FOURCC('m', 'd', 'i', 'a'):
313        case FOURCC('m', 'i', 'n', 'f'):
314        case FOURCC('d', 'i', 'n', 'f'):
315        case FOURCC('s', 't', 'b', 'l'):
316        case FOURCC('m', 'v', 'e', 'x'):
317        case FOURCC('m', 'o', 'o', 'f'):
318        case FOURCC('t', 'r', 'a', 'f'):
319        case FOURCC('m', 'f', 'r', 'a'):
320        case FOURCC('s', 'k', 'i' ,'p'):
321        {
322            off_t stop_offset = *offset + chunk_size;
323            *offset = data_offset;
324            while (*offset < stop_offset) {
325                status_t err = parseChunk(offset, depth + 1);
326                if (err != OK) {
327                    return err;
328                }
329            }
330            CHECK_EQ(*offset, stop_offset);
331
332            if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
333                mHaveMetadata = true;
334
335                return UNKNOWN_ERROR;  // Return a dummy error.
336            }
337            break;
338        }
339
340        case FOURCC('t', 'k', 'h', 'd'):
341        {
342            CHECK(chunk_data_size >= 4);
343
344            uint8_t version;
345            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
346                return ERROR_IO;
347            }
348
349            uint64_t ctime, mtime, duration;
350            int32_t id;
351            uint32_t width, height;
352
353            if (version == 1) {
354                if (chunk_data_size != 36 + 60) {
355                    return ERROR_MALFORMED;
356                }
357
358                uint8_t buffer[36 + 60];
359                if (mDataSource->readAt(
360                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
361                    return ERROR_IO;
362                }
363
364                ctime = U64_AT(&buffer[4]);
365                mtime = U64_AT(&buffer[12]);
366                id = U32_AT(&buffer[20]);
367                duration = U64_AT(&buffer[28]);
368                width = U32_AT(&buffer[88]);
369                height = U32_AT(&buffer[92]);
370            } else if (version == 0) {
371                if (chunk_data_size != 24 + 60) {
372                    return ERROR_MALFORMED;
373                }
374
375                uint8_t buffer[24 + 60];
376                if (mDataSource->readAt(
377                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
378                    return ERROR_IO;
379                }
380                ctime = U32_AT(&buffer[4]);
381                mtime = U32_AT(&buffer[8]);
382                id = U32_AT(&buffer[12]);
383                duration = U32_AT(&buffer[20]);
384                width = U32_AT(&buffer[76]);
385                height = U32_AT(&buffer[80]);
386            }
387
388            Track *track = new Track;
389            track->next = NULL;
390            if (mLastTrack) {
391                mLastTrack->next = track;
392            } else {
393                mFirstTrack = track;
394            }
395            mLastTrack = track;
396
397            track->meta = new MetaData;
398            track->includes_expensive_metadata = false;
399            track->timescale = 0;
400            track->sampleTable = new SampleTable(mDataSource);
401            track->meta->setCString(kKeyMIMEType, "application/octet-stream");
402
403            *offset += chunk_size;
404            break;
405        }
406
407        case FOURCC('m', 'd', 'h', 'd'):
408        {
409            if (chunk_data_size < 4) {
410                return ERROR_MALFORMED;
411            }
412
413            uint8_t version;
414            if (mDataSource->readAt(
415                        data_offset, &version, sizeof(version))
416                    < (ssize_t)sizeof(version)) {
417                return ERROR_IO;
418            }
419
420            off_t timescale_offset;
421
422            if (version == 1) {
423                timescale_offset = data_offset + 4 + 16;
424            } else if (version == 0) {
425                timescale_offset = data_offset + 4 + 8;
426            } else {
427                return ERROR_IO;
428            }
429
430            uint32_t timescale;
431            if (mDataSource->readAt(
432                        timescale_offset, &timescale, sizeof(timescale))
433                    < (ssize_t)sizeof(timescale)) {
434                return ERROR_IO;
435            }
436
437            mLastTrack->timescale = ntohl(timescale);
438
439            int64_t duration;
440            if (version == 1) {
441                if (mDataSource->readAt(
442                            timescale_offset + 4, &duration, sizeof(duration))
443                        < (ssize_t)sizeof(duration)) {
444                    return ERROR_IO;
445                }
446                duration = ntoh64(duration);
447            } else {
448                int32_t duration32;
449                if (mDataSource->readAt(
450                            timescale_offset + 4, &duration32, sizeof(duration32))
451                        < (ssize_t)sizeof(duration32)) {
452                    return ERROR_IO;
453                }
454                duration = ntohl(duration32);
455            }
456            mLastTrack->meta->setInt64(
457                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
458
459            *offset += chunk_size;
460            break;
461        }
462
463        case FOURCC('h', 'd', 'l', 'r'):
464        {
465            if (chunk_data_size < 25) {
466                return ERROR_MALFORMED;
467            }
468
469            uint8_t buffer[24];
470            if (mDataSource->readAt(data_offset, buffer, 24) < 24) {
471                return ERROR_IO;
472            }
473
474            if (U32_AT(buffer) != 0) {
475                // Should be version 0, flags 0.
476                return ERROR_MALFORMED;
477            }
478
479            if (U32_AT(&buffer[4]) != 0) {
480                // pre_defined should be 0.
481                return ERROR_MALFORMED;
482            }
483
484            mHandlerType = U32_AT(&buffer[8]);
485            *offset += chunk_size;
486            break;
487        }
488
489        case FOURCC('s', 't', 's', 'd'):
490        {
491            if (chunk_data_size < 8) {
492                return ERROR_MALFORMED;
493            }
494
495            uint8_t buffer[8];
496            CHECK(chunk_data_size >= (off_t)sizeof(buffer));
497            if (mDataSource->readAt(
498                        data_offset, buffer, 8) < 8) {
499                return ERROR_IO;
500            }
501
502            if (U32_AT(buffer) != 0) {
503                // Should be version 0, flags 0.
504                return ERROR_MALFORMED;
505            }
506
507            uint32_t entry_count = U32_AT(&buffer[4]);
508
509            if (entry_count > 1) {
510                // For now we only support a single type of media per track.
511                return ERROR_UNSUPPORTED;
512            }
513
514            off_t stop_offset = *offset + chunk_size;
515            *offset = data_offset + 8;
516            for (uint32_t i = 0; i < entry_count; ++i) {
517                status_t err = parseChunk(offset, depth + 1);
518                if (err != OK) {
519                    return err;
520                }
521            }
522            CHECK_EQ(*offset, stop_offset);
523            break;
524        }
525
526        case FOURCC('m', 'p', '4', 'a'):
527        case FOURCC('s', 'a', 'm', 'r'):
528        case FOURCC('s', 'a', 'w', 'b'):
529        {
530            if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) {
531                return ERROR_MALFORMED;
532            }
533
534            uint8_t buffer[8 + 20];
535            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
536                // Basic AudioSampleEntry size.
537                return ERROR_MALFORMED;
538            }
539
540            if (mDataSource->readAt(
541                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
542                return ERROR_IO;
543            }
544
545            uint16_t data_ref_index = U16_AT(&buffer[6]);
546            uint16_t num_channels = U16_AT(&buffer[16]);
547
548            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
549                            FourCC2MIME(chunk_type))
550                || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
551                               FourCC2MIME(chunk_type))) {
552                // AMR audio is always mono.
553                num_channels = 1;
554            }
555
556            uint16_t sample_size = U16_AT(&buffer[18]);
557            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
558
559            // printf("*** coding='%s' %d channels, size %d, rate %d\n",
560            //        chunk, num_channels, sample_size, sample_rate);
561
562            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
563            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
564            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
565
566            off_t stop_offset = *offset + chunk_size;
567            *offset = data_offset + sizeof(buffer);
568            while (*offset < stop_offset) {
569                status_t err = parseChunk(offset, depth + 1);
570                if (err != OK) {
571                    return err;
572                }
573            }
574            CHECK_EQ(*offset, stop_offset);
575            break;
576        }
577
578        case FOURCC('m', 'p', '4', 'v'):
579        case FOURCC('s', '2', '6', '3'):
580        case FOURCC('a', 'v', 'c', '1'):
581        {
582            mHasVideo = true;
583
584            if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) {
585                return ERROR_MALFORMED;
586            }
587
588            uint8_t buffer[78];
589            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
590                // Basic VideoSampleEntry size.
591                return ERROR_MALFORMED;
592            }
593
594            if (mDataSource->readAt(
595                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
596                return ERROR_IO;
597            }
598
599            uint16_t data_ref_index = U16_AT(&buffer[6]);
600            uint16_t width = U16_AT(&buffer[6 + 18]);
601            uint16_t height = U16_AT(&buffer[6 + 20]);
602
603            // printf("*** coding='%s' width=%d height=%d\n",
604            //        chunk, width, height);
605
606            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
607            mLastTrack->meta->setInt32(kKeyWidth, width);
608            mLastTrack->meta->setInt32(kKeyHeight, height);
609
610            off_t stop_offset = *offset + chunk_size;
611            *offset = data_offset + sizeof(buffer);
612            while (*offset < stop_offset) {
613                status_t err = parseChunk(offset, depth + 1);
614                if (err != OK) {
615                    return err;
616                }
617            }
618            CHECK_EQ(*offset, stop_offset);
619            break;
620        }
621
622        case FOURCC('s', 't', 'c', 'o'):
623        case FOURCC('c', 'o', '6', '4'):
624        {
625            status_t err =
626                mLastTrack->sampleTable->setChunkOffsetParams(
627                        chunk_type, data_offset, chunk_data_size);
628
629            if (err != OK) {
630                return err;
631            }
632
633            *offset += chunk_size;
634            break;
635        }
636
637        case FOURCC('s', 't', 's', 'c'):
638        {
639            status_t err =
640                mLastTrack->sampleTable->setSampleToChunkParams(
641                        data_offset, chunk_data_size);
642
643            if (err != OK) {
644                return err;
645            }
646
647            *offset += chunk_size;
648            break;
649        }
650
651        case FOURCC('s', 't', 's', 'z'):
652        case FOURCC('s', 't', 'z', '2'):
653        {
654            status_t err =
655                mLastTrack->sampleTable->setSampleSizeParams(
656                        chunk_type, data_offset, chunk_data_size);
657
658            if (err != OK) {
659                return err;
660            }
661
662            size_t max_size;
663            CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK);
664
665            // Assume that a given buffer only contains at most 10 fragments,
666            // each fragment originally prefixed with a 2 byte length will
667            // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
668            // and thus will grow by 2 bytes per fragment.
669            mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
670
671            *offset += chunk_size;
672            break;
673        }
674
675        case FOURCC('s', 't', 't', 's'):
676        {
677            status_t err =
678                mLastTrack->sampleTable->setTimeToSampleParams(
679                        data_offset, chunk_data_size);
680
681            if (err != OK) {
682                return err;
683            }
684
685            *offset += chunk_size;
686            break;
687        }
688
689        case FOURCC('s', 't', 's', 's'):
690        {
691            status_t err =
692                mLastTrack->sampleTable->setSyncSampleParams(
693                        data_offset, chunk_data_size);
694
695            if (err != OK) {
696                return err;
697            }
698
699            *offset += chunk_size;
700            break;
701        }
702
703        case FOURCC('e', 's', 'd', 's'):
704        {
705            if (chunk_data_size < 4) {
706                return ERROR_MALFORMED;
707            }
708
709            uint8_t buffer[256];
710            if (chunk_data_size > (off_t)sizeof(buffer)) {
711                return ERROR_BUFFER_TOO_SMALL;
712            }
713
714            if (mDataSource->readAt(
715                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
716                return ERROR_IO;
717            }
718
719            if (U32_AT(buffer) != 0) {
720                // Should be version 0, flags 0.
721                return ERROR_MALFORMED;
722            }
723
724            mLastTrack->meta->setData(
725                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
726
727            *offset += chunk_size;
728            break;
729        }
730
731        case FOURCC('a', 'v', 'c', 'C'):
732        {
733            char buffer[256];
734            if (chunk_data_size > (off_t)sizeof(buffer)) {
735                return ERROR_BUFFER_TOO_SMALL;
736            }
737
738            if (mDataSource->readAt(
739                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
740                return ERROR_IO;
741            }
742
743            mLastTrack->meta->setData(
744                    kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
745
746            *offset += chunk_size;
747            break;
748        }
749
750        default:
751        {
752            *offset += chunk_size;
753            break;
754        }
755    }
756
757    return OK;
758}
759
760sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
761    status_t err;
762    if ((err = readMetaData()) != OK) {
763        return NULL;
764    }
765
766    Track *track = mFirstTrack;
767    while (index > 0) {
768        if (track == NULL) {
769            return NULL;
770        }
771
772        track = track->next;
773        --index;
774    }
775
776    if (track == NULL) {
777        return NULL;
778    }
779
780    return new MPEG4Source(
781            track->meta, mDataSource, track->timescale, track->sampleTable);
782}
783
784////////////////////////////////////////////////////////////////////////////////
785
786MPEG4Source::MPEG4Source(
787        const sp<MetaData> &format,
788        const sp<DataSource> &dataSource,
789        int32_t timeScale,
790        const sp<SampleTable> &sampleTable)
791    : mFormat(format),
792      mDataSource(dataSource),
793      mTimescale(timeScale),
794      mSampleTable(sampleTable),
795      mCurrentSampleIndex(0),
796      mIsAVC(false),
797      mNALLengthSize(0),
798      mStarted(false),
799      mGroup(NULL),
800      mBuffer(NULL),
801      mWantsNALFragments(false),
802      mSrcBuffer(NULL) {
803    const char *mime;
804    bool success = mFormat->findCString(kKeyMIMEType, &mime);
805    CHECK(success);
806
807    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
808
809    if (mIsAVC) {
810        uint32_t type;
811        const void *data;
812        size_t size;
813        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
814
815        const uint8_t *ptr = (const uint8_t *)data;
816
817        CHECK(size >= 7);
818        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
819
820        // The number of bytes used to encode the length of a NAL unit.
821        mNALLengthSize = 1 + (ptr[4] & 3);
822    }
823}
824
825MPEG4Source::~MPEG4Source() {
826    if (mStarted) {
827        stop();
828    }
829}
830
831status_t MPEG4Source::start(MetaData *params) {
832    CHECK(!mStarted);
833
834    int32_t val;
835    if (params && params->findInt32(kKeyWantsNALFragments, &val)
836        && val != 0) {
837        mWantsNALFragments = true;
838    } else {
839        mWantsNALFragments = false;
840    }
841
842    mGroup = new MediaBufferGroup;
843
844    int32_t max_size;
845    CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
846
847    mGroup->add_buffer(new MediaBuffer(max_size));
848
849    mSrcBuffer = new uint8_t[max_size];
850
851    mStarted = true;
852
853    return OK;
854}
855
856status_t MPEG4Source::stop() {
857    CHECK(mStarted);
858
859    if (mBuffer != NULL) {
860        mBuffer->release();
861        mBuffer = NULL;
862    }
863
864    delete[] mSrcBuffer;
865    mSrcBuffer = NULL;
866
867    delete mGroup;
868    mGroup = NULL;
869
870    mStarted = false;
871    mCurrentSampleIndex = 0;
872
873    return OK;
874}
875
876sp<MetaData> MPEG4Source::getFormat() {
877    return mFormat;
878}
879
880size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
881    switch (mNALLengthSize) {
882        case 1:
883            return *data;
884        case 2:
885            return U16_AT(data);
886        case 3:
887            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
888        case 4:
889            return U32_AT(data);
890    }
891
892    // This cannot happen, mNALLengthSize springs to life by adding 1 to
893    // a 2-bit integer.
894    CHECK(!"Should not be here.");
895
896    return 0;
897}
898
899status_t MPEG4Source::read(
900        MediaBuffer **out, const ReadOptions *options) {
901    CHECK(mStarted);
902
903    *out = NULL;
904
905    int64_t seekTimeUs;
906    if (options && options->getSeekTo(&seekTimeUs)) {
907        uint32_t sampleIndex;
908        status_t err = mSampleTable->findClosestSample(
909                seekTimeUs * mTimescale / 1000000,
910                &sampleIndex, SampleTable::kSyncSample_Flag);
911
912        if (err != OK) {
913            return err;
914        }
915
916        mCurrentSampleIndex = sampleIndex;
917        if (mBuffer != NULL) {
918            mBuffer->release();
919            mBuffer = NULL;
920        }
921
922        // fall through
923    }
924
925    off_t offset;
926    size_t size;
927    uint32_t dts;
928    bool newBuffer = false;
929    if (mBuffer == NULL) {
930        newBuffer = true;
931
932        status_t err = mSampleTable->getSampleOffsetAndSize(
933                mCurrentSampleIndex, &offset, &size);
934
935        if (err != OK) {
936            return err;
937        }
938
939        err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts);
940
941        if (err != OK) {
942            return err;
943        }
944
945        err = mGroup->acquire_buffer(&mBuffer);
946        if (err != OK) {
947            CHECK_EQ(mBuffer, NULL);
948            return err;
949        }
950    }
951
952    if (!mIsAVC || mWantsNALFragments) {
953        if (newBuffer) {
954            ssize_t num_bytes_read =
955                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
956
957            if (num_bytes_read < (ssize_t)size) {
958                mBuffer->release();
959                mBuffer = NULL;
960
961                return ERROR_IO;
962            }
963
964            mBuffer->set_range(0, size);
965            mBuffer->meta_data()->clear();
966            mBuffer->meta_data()->setInt64(
967                    kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
968            ++mCurrentSampleIndex;
969        }
970
971        if (!mIsAVC) {
972            *out = mBuffer;
973            mBuffer = NULL;
974
975            return OK;
976        }
977
978        // Each NAL unit is split up into its constituent fragments and
979        // each one of them returned in its own buffer.
980
981        CHECK(mBuffer->range_length() >= mNALLengthSize);
982
983        const uint8_t *src =
984            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
985
986        size_t nal_size = parseNALSize(src);
987        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
988            LOGE("incomplete NAL unit.");
989
990            mBuffer->release();
991            mBuffer = NULL;
992
993            return ERROR_MALFORMED;
994        }
995
996        MediaBuffer *clone = mBuffer->clone();
997        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
998
999        mBuffer->set_range(
1000                mBuffer->range_offset() + mNALLengthSize + nal_size,
1001                mBuffer->range_length() - mNALLengthSize - nal_size);
1002
1003        if (mBuffer->range_length() == 0) {
1004            mBuffer->release();
1005            mBuffer = NULL;
1006        }
1007
1008        *out = clone;
1009
1010        return OK;
1011    } else {
1012        // Whole NAL units are returned but each fragment is prefixed by
1013        // the start code (0x00 00 00 01).
1014
1015        ssize_t num_bytes_read =
1016            mDataSource->readAt(offset, mSrcBuffer, size);
1017
1018        if (num_bytes_read < (ssize_t)size) {
1019            mBuffer->release();
1020            mBuffer = NULL;
1021
1022            return ERROR_IO;
1023        }
1024
1025        uint8_t *dstData = (uint8_t *)mBuffer->data();
1026        size_t srcOffset = 0;
1027        size_t dstOffset = 0;
1028
1029        while (srcOffset < size) {
1030            CHECK(srcOffset + mNALLengthSize <= size);
1031            size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
1032            srcOffset += mNALLengthSize;
1033
1034            if (srcOffset + nalLength > size) {
1035                mBuffer->release();
1036                mBuffer = NULL;
1037
1038                return ERROR_MALFORMED;
1039            }
1040
1041            if (nalLength == 0) {
1042                continue;
1043            }
1044
1045            CHECK(dstOffset + 4 <= mBuffer->size());
1046
1047            dstData[dstOffset++] = 0;
1048            dstData[dstOffset++] = 0;
1049            dstData[dstOffset++] = 0;
1050            dstData[dstOffset++] = 1;
1051            memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
1052            srcOffset += nalLength;
1053            dstOffset += nalLength;
1054        }
1055        CHECK_EQ(srcOffset, size);
1056
1057        mBuffer->set_range(0, dstOffset);
1058        mBuffer->meta_data()->clear();
1059        mBuffer->meta_data()->setInt64(
1060                kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1061        ++mCurrentSampleIndex;
1062
1063        *out = mBuffer;
1064        mBuffer = NULL;
1065
1066        return OK;
1067    }
1068}
1069
1070bool SniffMPEG4(
1071        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
1072    uint8_t header[8];
1073
1074    ssize_t n = source->readAt(4, header, sizeof(header));
1075    if (n < (ssize_t)sizeof(header)) {
1076        return false;
1077    }
1078
1079    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
1080        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
1081        || !memcmp(header, "ftypM4A ", 8)) {
1082        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
1083        *confidence = 0.1;
1084
1085        return true;
1086    }
1087
1088    return false;
1089}
1090
1091}  // namespace android
1092
1093