MPEG4Extractor.cpp revision 1cb02bf661807ffc6525dcc13e16d7ce027bef00
1e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber/*
2e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
4e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * you may not use this file except in compliance with the License.
6e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * You may obtain a copy of the License at
7e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
8e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
10e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Unless required by applicable law or agreed to in writing, software
11e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * See the License for the specific language governing permissions and
14e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * limitations under the License.
15e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber */
16e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
17e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#define LOG_TAG "MPEG4Extractor"
18e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/Log.h>
19e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
2057515f334bcc1f66f95e342bfcaa13bf9ca802adAndreas Huber#include "include/MPEG4Extractor.h"
21bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber#include "include/SampleTable.h"
22bd7b43bb02852e51b3000185fa66e10c56b120e0Andreas Huber
23e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <arpa/inet.h>
24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <ctype.h>
26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdint.h>
27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdlib.h>
28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <string.h>
29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/DataSource.h>
31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBuffer.h>
32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber#include <media/stagefright/MediaDebug.h>
34e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber#include <media/stagefright/MediaDefs.h>
35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaSource.h>
36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h>
37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/Utils.h>
38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/String8.h>
39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android {
41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass MPEG4Source : public MediaSource {
43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic:
44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    // Caller retains ownership of both "dataSource" and "sampleTable".
45be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    MPEG4Source(const sp<MetaData> &format,
46be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber                const sp<DataSource> &dataSource,
47fa8de752507feaca695123911915070c1ce463b2Andreas Huber                int32_t timeScale,
48be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber                const sp<SampleTable> &sampleTable);
49e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t start(MetaData *params = NULL);
51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t stop();
52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual sp<MetaData> getFormat();
54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t read(
56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
58be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberprotected:
59be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    virtual ~MPEG4Source();
60be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber
61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate:
62e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    sp<MetaData> mFormat;
63be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    sp<DataSource> mDataSource;
64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int32_t mTimescale;
65be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    sp<SampleTable> mSampleTable;
66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t mCurrentSampleIndex;
67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool mIsAVC;
69db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    size_t mNALLengthSize;
70db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool mStarted;
72e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
73e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBufferGroup *mGroup;
74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBuffer *mBuffer;
76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    bool mWantsNALFragments;
78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
798a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    uint8_t *mSrcBuffer;
808a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber
81db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    size_t parseNALSize(const uint8_t *data) const;
82db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
83e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MPEG4Source(const MPEG4Source &);
84e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MPEG4Source &operator=(const MPEG4Source &);
85e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber};
86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void hexdump(const void *_data, size_t size) {
88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const uint8_t *data = (const uint8_t *)_data;
89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t offset = 0;
90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (offset < size) {
91e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        printf("0x%04x  ", offset);
92e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
93e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size_t n = size - offset;
94e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (n > 16) {
95e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            n = 16;
96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
97e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
98e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        for (size_t i = 0; i < 16; ++i) {
99e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (i == 8) {
100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf(" ");
101e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
103e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (offset + i < size) {
104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf("%02x ", data[offset + i]);
105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf("   ");
107e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        printf(" ");
111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        for (size_t i = 0; i < n; ++i) {
113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (isprint(data[offset + i])) {
114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf("%c", data[offset + i]);
115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf(".");
117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        printf("\n");
121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
122e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        offset += 16;
123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
126e6c409632f773e41f33188272a0072be9fcb783fAndreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) {
127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    switch (fourcc) {
128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
129e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_AUDIO_AAC;
130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
132e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_NB;
133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1342a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber        case FOURCC('s', 'a', 'w', 'b'):
135e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_WB;
1362a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber
137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
138e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_VIDEO_MPEG4;
139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', '2', '6', '3'):
141e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_VIDEO_H263;
142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
144e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_VIDEO_AVC;
145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        default:
1474f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK(!"should not be here.");
148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return NULL;
149e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
150e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
152be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mDataSource(source),
154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mHaveMetadata(false),
1551cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber      mHasVideo(false),
156e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFirstTrack(NULL),
157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mLastTrack(NULL) {
158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
160e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Extractor::~MPEG4Extractor() {
161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    Track *track = mFirstTrack;
162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (track) {
163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        Track *next = track->next;
164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        delete track;
166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        track = next;
167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mFirstTrack = mLastTrack = NULL;
169e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1711cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() {
1721cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    sp<MetaData> meta = new MetaData;
1731cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
1741cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    status_t err;
1751cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    if ((err = readMetaData()) != OK) {
1761cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber        return meta;
1771cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    }
1781cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
1791cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    if (mHasVideo) {
1801cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber        meta->setCString(kKeyMIMEType, "video/mp4");
1811cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    } else {
1821cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber        meta->setCString(kKeyMIMEType, "audio/mp4");
1831cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    }
1841cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
1851cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    return meta;
1861cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber}
1871cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
188be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MPEG4Extractor::countTracks() {
189e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err;
190e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if ((err = readMetaData()) != OK) {
191be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        return 0;
192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
194be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    size_t n = 0;
195e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    Track *track = mFirstTrack;
196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (track) {
197be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        ++n;
198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        track = track->next;
199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
201be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    return n;
202e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
204e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData(
205e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        size_t index, uint32_t flags) {
206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err;
207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if ((err = readMetaData()) != OK) {
208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return NULL;
209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
211e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    Track *track = mFirstTrack;
212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (index > 0) {
213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (track == NULL) {
214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return NULL;
215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        track = track->next;
218e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        --index;
219e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
220e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
2212a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber    if (track == NULL) {
2222a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber        return NULL;
2232a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber    }
2242a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber
225e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber    if ((flags & kIncludeExtensiveMetaData)
226e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            && !track->includes_expensive_metadata) {
227e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        track->includes_expensive_metadata = true;
228e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber
229e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        const char *mime;
230e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        CHECK(track->meta->findCString(kKeyMIMEType, &mime));
231e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        if (!strncasecmp("video/", mime, 6)) {
232e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            uint32_t sampleIndex;
233e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            uint32_t sampleTime;
234e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
235e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber                    && track->sampleTable->getDecodingTime(
236e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber                        sampleIndex, &sampleTime) == OK) {
237e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber                track->meta->setInt64(
238e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber                        kKeyThumbnailTime,
239e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber                        ((int64_t)sampleTime * 1000000) / track->timescale);
240e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            }
241e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        }
242e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber    }
243e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber
244e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return track->meta;
245e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
246e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
247e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::readMetaData() {
248e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mHaveMetadata) {
249e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return OK;
250e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
251e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
252e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t offset = 0;
253e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err;
254e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while ((err = parseChunk(&offset, 0)) == OK) {
255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
2561cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mHaveMetadata) {
258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return OK;
259e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
261e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return err;
262e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
263e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
264e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) {
265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[0] = x >> 24;
266e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[1] = (x >> 16) & 0xff;
267e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[2] = (x >> 8) & 0xff;
268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[3] = x & 0xff;
269e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[4] = '\0';
270e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
272e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t hdr[2];
2749a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
275e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_IO;
276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint64_t chunk_size = ntohl(hdr[0]);
278e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t chunk_type = ntohl(hdr[1]);
279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t data_offset = *offset + 8;
280e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
281e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (chunk_size == 1) {
2829a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
283e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_IO;
284e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
285e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        chunk_size = ntoh64(chunk_size);
286e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        data_offset += 8;
287e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
288e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
289e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    char chunk[5];
290e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MakeFourCCString(chunk_type, chunk);
291e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
292e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#if 0
293e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    static const char kWhitespace[] = "                                        ";
294e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
295e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
296e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
297e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    char buffer[256];
298e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (chunk_size <= sizeof(buffer)) {
2999a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber        if (mDataSource->readAt(*offset, buffer, chunk_size) < chunk_size) {
300e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_IO;
301e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
302e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
303e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        hexdump(buffer, chunk_size);
304e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
305e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#endif
306e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
307e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t chunk_data_size = *offset + chunk_size - data_offset;
308e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    switch(chunk_type) {
310e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'o', 'o', 'v'):
311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('t', 'r', 'a', 'k'):
312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'd', 'i', 'a'):
313e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'i', 'n', 'f'):
314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('d', 'i', 'n', 'f'):
315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 'b', 'l'):
316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'v', 'e', 'x'):
317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'o', 'o', 'f'):
318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('t', 'r', 'a', 'f'):
319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'f', 'r', 'a'):
320e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 'k', 'i' ,'p'):
321e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
322e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t stop_offset = *offset + chunk_size;
323e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset = data_offset;
324e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            while (*offset < stop_offset) {
325e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                status_t err = parseChunk(offset, depth + 1);
326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (err != OK) {
327e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return err;
328e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
329e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
3304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK_EQ(*offset, stop_offset);
331e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
332e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
333e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mHaveMetadata = true;
334e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
335e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return UNKNOWN_ERROR;  // Return a dummy error.
336e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
337e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
338e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
339e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
340e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('t', 'k', 'h', 'd'):
341e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
3424f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK(chunk_data_size >= 4);
343e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
344e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t version;
3459a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
346e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
347e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
348e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
349e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint64_t ctime, mtime, duration;
350e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            int32_t id;
351e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint32_t width, height;
352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (version == 1) {
354e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (chunk_data_size != 36 + 60) {
355e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_MALFORMED;
356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                uint8_t buffer[36 + 60];
3599a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                if (mDataSource->readAt(
360e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
361e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_IO;
362e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
363e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
364e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                ctime = U64_AT(&buffer[4]);
365e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mtime = U64_AT(&buffer[12]);
366e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                id = U32_AT(&buffer[20]);
367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                duration = U64_AT(&buffer[28]);
368e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                width = U32_AT(&buffer[88]);
369e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                height = U32_AT(&buffer[92]);
370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else if (version == 0) {
371e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (chunk_data_size != 24 + 60) {
372e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_MALFORMED;
373e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
374e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
375e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                uint8_t buffer[24 + 60];
3769a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                if (mDataSource->readAt(
377e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
378e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_IO;
379e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
380e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                ctime = U32_AT(&buffer[4]);
381e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mtime = U32_AT(&buffer[8]);
382e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                id = U32_AT(&buffer[12]);
383e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                duration = U32_AT(&buffer[20]);
384e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                width = U32_AT(&buffer[76]);
385e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                height = U32_AT(&buffer[80]);
386e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
387e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
388e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            Track *track = new Track;
389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            track->next = NULL;
390e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (mLastTrack) {
391e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->next = track;
392e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
393e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mFirstTrack = track;
394e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
395e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack = track;
396e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
397e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            track->meta = new MetaData;
398e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            track->includes_expensive_metadata = false;
399e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            track->timescale = 0;
400e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            track->sampleTable = new SampleTable(mDataSource);
401e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            track->meta->setCString(kKeyMIMEType, "application/octet-stream");
402e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
403e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
404e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
405e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
406e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
407e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'd', 'h', 'd'):
408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
409e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < 4) {
410e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
411e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
412e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
413e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t version;
4149a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
415e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, &version, sizeof(version))
416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    < (ssize_t)sizeof(version)) {
417e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
418e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
419e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
420e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t timescale_offset;
421e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (version == 1) {
423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                timescale_offset = data_offset + 4 + 16;
424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else if (version == 0) {
425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                timescale_offset = data_offset + 4 + 8;
426e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
428e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
429e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
430e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint32_t timescale;
4319a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        timescale_offset, &timescale, sizeof(timescale))
433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    < (ssize_t)sizeof(timescale)) {
434e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
435e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->timescale = ntohl(timescale);
438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            int64_t duration;
440e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (version == 1) {
4419a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                if (mDataSource->readAt(
442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                            timescale_offset + 4, &duration, sizeof(duration))
443e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        < (ssize_t)sizeof(duration)) {
444e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_IO;
445e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                duration = ntoh64(duration);
447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                int32_t duration32;
4499a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                if (mDataSource->readAt(
450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                            timescale_offset + 4, &duration32, sizeof(duration32))
451e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        < (ssize_t)sizeof(duration32)) {
452e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_IO;
453e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
454e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                duration = ntohl(duration32);
455e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
456fa8de752507feaca695123911915070c1ce463b2Andreas Huber            mLastTrack->meta->setInt64(
457fa8de752507feaca695123911915070c1ce463b2Andreas Huber                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
458e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
459e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
460e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
461e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
462e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
463e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('h', 'd', 'l', 'r'):
464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
465e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < 25) {
466e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
467e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
468e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
469e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[24];
4709a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(data_offset, buffer, 24) < 24) {
471e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
472e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
473e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
474e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (U32_AT(buffer) != 0) {
475e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Should be version 0, flags 0.
476e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
477e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
478e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
479e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (U32_AT(&buffer[4]) != 0) {
480e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // pre_defined should be 0.
481e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
482e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
483e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
484e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mHandlerType = U32_AT(&buffer[8]);
485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
486e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
487e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
488e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
489e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 's', 'd'):
490e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
491e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < 8) {
492e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
494e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[8];
4964f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK(chunk_data_size >= (off_t)sizeof(buffer));
4979a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
498e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, 8) < 8) {
499e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
500e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
501e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
502e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (U32_AT(buffer) != 0) {
503e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Should be version 0, flags 0.
504e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
505e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
506e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
507e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint32_t entry_count = U32_AT(&buffer[4]);
508e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
509e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (entry_count > 1) {
510e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // For now we only support a single type of media per track.
511e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_UNSUPPORTED;
512e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
513e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
514e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t stop_offset = *offset + chunk_size;
515e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset = data_offset + 8;
516e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            for (uint32_t i = 0; i < entry_count; ++i) {
517e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                status_t err = parseChunk(offset, depth + 1);
518e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (err != OK) {
519e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return err;
520e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
5224f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK_EQ(*offset, stop_offset);
523e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
524e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
525e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
526e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
527e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
5282a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber        case FOURCC('s', 'a', 'w', 'b'):
529e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
530e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) {
531e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
532e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
533e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
534e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[8 + 20];
535e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
536e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Basic AudioSampleEntry size.
537e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
538e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5409a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
541e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
543e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t data_ref_index = U16_AT(&buffer[6]);
546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t num_channels = U16_AT(&buffer[16]);
547e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
548e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
549e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber                            FourCC2MIME(chunk_type))
550e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber                || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
551e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber                               FourCC2MIME(chunk_type))) {
552e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // AMR audio is always mono.
553e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                num_channels = 1;
554e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
555e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
556e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t sample_size = U16_AT(&buffer[18]);
557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5592ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber            // printf("*** coding='%s' %d channels, size %d, rate %d\n",
5602ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber            //        chunk, num_channels, sample_size, sample_rate);
561e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
563e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t stop_offset = *offset + chunk_size;
567e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset = data_offset + sizeof(buffer);
568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            while (*offset < stop_offset) {
569e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                status_t err = parseChunk(offset, depth + 1);
570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (err != OK) {
571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return err;
572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
573e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
5744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK_EQ(*offset, stop_offset);
575e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
577e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
578e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', '2', '6', '3'):
580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
581e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
5821cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber            mHasVideo = true;
5831cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
584e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) {
585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
586e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
587e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
588e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[78];
589e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
590e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Basic VideoSampleEntry size.
591e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5949a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
598e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t data_ref_index = U16_AT(&buffer[6]);
600e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t width = U16_AT(&buffer[6 + 18]);
601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t height = U16_AT(&buffer[6 + 20]);
602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
6032ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber            // printf("*** coding='%s' width=%d height=%d\n",
6042ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber            //        chunk, width, height);
605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setInt32(kKeyWidth, width);
608e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setInt32(kKeyHeight, height);
609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t stop_offset = *offset + chunk_size;
611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset = data_offset + sizeof(buffer);
612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            while (*offset < stop_offset) {
613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                status_t err = parseChunk(offset, depth + 1);
614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (err != OK) {
615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return err;
616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
617e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
6184f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK_EQ(*offset, stop_offset);
619e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
620e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
621e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
622e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 'c', 'o'):
623e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('c', 'o', '6', '4'):
624e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
626e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setChunkOffsetParams(
627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        chunk_type, data_offset, chunk_data_size);
628e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
629e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
630e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
633e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
634e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
635e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
636e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
637e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 's', 'c'):
638e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
639e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
640e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setSampleToChunkParams(
641e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, chunk_data_size);
642e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
643e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
644e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
645e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 's', 'z'):
652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 'z', '2'):
653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
654e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setSampleSizeParams(
656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        chunk_type, data_offset, chunk_data_size);
657e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
659e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
661e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
6621bceff916a72246fa208605d50615823d7f1688bAndreas Huber            size_t max_size;
6631bceff916a72246fa208605d50615823d7f1688bAndreas Huber            CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK);
6641bceff916a72246fa208605d50615823d7f1688bAndreas Huber
6651bceff916a72246fa208605d50615823d7f1688bAndreas Huber            // Assume that a given buffer only contains at most 10 fragments,
6661bceff916a72246fa208605d50615823d7f1688bAndreas Huber            // each fragment originally prefixed with a 2 byte length will
6671bceff916a72246fa208605d50615823d7f1688bAndreas Huber            // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
6681bceff916a72246fa208605d50615823d7f1688bAndreas Huber            // and thus will grow by 2 bytes per fragment.
6691bceff916a72246fa208605d50615823d7f1688bAndreas Huber            mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
6701bceff916a72246fa208605d50615823d7f1688bAndreas Huber
671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
673e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
674e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
675e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 't', 's'):
676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setTimeToSampleParams(
679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, chunk_data_size);
680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
681e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
682e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
683e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
684e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
687e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
689e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 's', 's'):
690e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
692e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setSyncSampleParams(
693e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, chunk_data_size);
694e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
695e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
696e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
697e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
698e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
699e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('e', 's', 'd', 's'):
704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
705e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < 4) {
706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
708e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
709e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[256];
710e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size > (off_t)sizeof(buffer)) {
711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
7149a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
715e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
716e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
717e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
718e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
719e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (U32_AT(buffer) != 0) {
720e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Should be version 0, flags 0.
721e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
724e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setData(
725e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
726e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
727e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
728e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
729e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
730e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
731e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('a', 'v', 'c', 'C'):
732e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
733e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            char buffer[256];
734e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size > (off_t)sizeof(buffer)) {
735e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
736e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
737e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
7389a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
739e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
740e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
741e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
742e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
743e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setData(
744e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
745e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
746e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
747e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
748e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
749e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
750e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        default:
751e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
752e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
753e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
754e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
755e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
756e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
757e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
758e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
759e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
760be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
761e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err;
762e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if ((err = readMetaData()) != OK) {
763be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        return NULL;
764e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
765e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
766e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    Track *track = mFirstTrack;
767e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (index > 0) {
768e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (track == NULL) {
769be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber            return NULL;
770e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
771e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
772e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        track = track->next;
773e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        --index;
774e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
775e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
7762a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber    if (track == NULL) {
7772a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber        return NULL;
7782a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber    }
7792a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber
780be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    return new MPEG4Source(
781fa8de752507feaca695123911915070c1ce463b2Andreas Huber            track->meta, mDataSource, track->timescale, track->sampleTable);
782e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
783e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
784e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber////////////////////////////////////////////////////////////////////////////////
785e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
786e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::MPEG4Source(
787e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        const sp<MetaData> &format,
788be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<DataSource> &dataSource,
789fa8de752507feaca695123911915070c1ce463b2Andreas Huber        int32_t timeScale,
790be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<SampleTable> &sampleTable)
791e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mFormat(format),
792e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mDataSource(dataSource),
793fa8de752507feaca695123911915070c1ce463b2Andreas Huber      mTimescale(timeScale),
794e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mSampleTable(sampleTable),
795e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mCurrentSampleIndex(0),
796e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mIsAVC(false),
797db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber      mNALLengthSize(0),
798e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mStarted(false),
799e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mGroup(NULL),
800e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mBuffer(NULL),
8014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber      mWantsNALFragments(false),
8028a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber      mSrcBuffer(NULL) {
803e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const char *mime;
804e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool success = mFormat->findCString(kKeyMIMEType, &mime);
8054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    CHECK(success);
806e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
807e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
808db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
809db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    if (mIsAVC) {
810db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        uint32_t type;
811db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        const void *data;
812db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        size_t size;
813db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
814db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
815db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
816db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
817db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK(size >= 7);
818db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
819db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
820db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        // The number of bytes used to encode the length of a NAL unit.
821db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        mNALLengthSize = 1 + (ptr[4] & 3);
822db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    }
823e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
824e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
825e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::~MPEG4Source() {
826e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mStarted) {
827e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        stop();
828e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
829e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
830e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
831e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::start(MetaData *params) {
8324f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    CHECK(!mStarted);
833e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
834e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int32_t val;
8354f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    if (params && params->findInt32(kKeyWantsNALFragments, &val)
836e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        && val != 0) {
8374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        mWantsNALFragments = true;
838e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } else {
8394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        mWantsNALFragments = false;
840e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
841e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
842e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = new MediaBufferGroup;
843e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
8441bceff916a72246fa208605d50615823d7f1688bAndreas Huber    int32_t max_size;
8451bceff916a72246fa208605d50615823d7f1688bAndreas Huber    CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
846e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
8471bceff916a72246fa208605d50615823d7f1688bAndreas Huber    mGroup->add_buffer(new MediaBuffer(max_size));
8488a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber
8498a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    mSrcBuffer = new uint8_t[max_size];
850e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
851e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = true;
852e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
853e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
854e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
855e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
856e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::stop() {
8574f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    CHECK(mStarted);
858e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
859e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mBuffer != NULL) {
860e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mBuffer->release();
861e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mBuffer = NULL;
862e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
863e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
8648a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    delete[] mSrcBuffer;
8658a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    mSrcBuffer = NULL;
8668a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber
867e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    delete mGroup;
868e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = NULL;
869e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
870e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = false;
871e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentSampleIndex = 0;
872e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
873e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
874e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
875e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
876e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MPEG4Source::getFormat() {
877e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mFormat;
878e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
879e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
880db5d662254f2ed788d32e2466739adc8d655c732Andreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const {
881db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    switch (mNALLengthSize) {
882db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        case 1:
883db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            return *data;
884db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        case 2:
885db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            return U16_AT(data);
886db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        case 3:
887db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
888db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        case 4:
889db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            return U32_AT(data);
890db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    }
891db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
892db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    // This cannot happen, mNALLengthSize springs to life by adding 1 to
893db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    // a 2-bit integer.
894db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    CHECK(!"Should not be here.");
895db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
896db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    return 0;
897db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber}
898db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
899e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::read(
900e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
9014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    CHECK(mStarted);
902e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
903e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *out = NULL;
904e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
905e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int64_t seekTimeUs;
906e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (options && options->getSeekTo(&seekTimeUs)) {
907e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint32_t sampleIndex;
908e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        status_t err = mSampleTable->findClosestSample(
909e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                seekTimeUs * mTimescale / 1000000,
910e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                &sampleIndex, SampleTable::kSyncSample_Flag);
911e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
912e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (err != OK) {
913e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return err;
914e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
915e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
916e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mCurrentSampleIndex = sampleIndex;
917e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (mBuffer != NULL) {
918e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mBuffer->release();
919e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mBuffer = NULL;
920e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
921e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
922e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // fall through
923e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
924e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
9258a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    off_t offset;
9268a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    size_t size;
9274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    uint32_t dts;
9284f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    bool newBuffer = false;
9294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    if (mBuffer == NULL) {
9304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        newBuffer = true;
931e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
9324f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        status_t err = mSampleTable->getSampleOffsetAndSize(
9334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                mCurrentSampleIndex, &offset, &size);
934e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
9354f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (err != OK) {
9364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return err;
9374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
938e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
9394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts);
940e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
9414f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (err != OK) {
9424f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return err;
9434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
9444f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9454f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        err = mGroup->acquire_buffer(&mBuffer);
9464f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (err != OK) {
9474f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK_EQ(mBuffer, NULL);
9484f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return err;
9494f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
9508a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    }
951e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
9524f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    if (!mIsAVC || mWantsNALFragments) {
9534f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (newBuffer) {
9544f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            ssize_t num_bytes_read =
9559a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
9564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9574f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            if (num_bytes_read < (ssize_t)size) {
9584f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                mBuffer->release();
9594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                mBuffer = NULL;
9604f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9614f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                return ERROR_IO;
9624f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            }
9634f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9644f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer->set_range(0, size);
9654f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer->meta_data()->clear();
966fa8de752507feaca695123911915070c1ce463b2Andreas Huber            mBuffer->meta_data()->setInt64(
967fa8de752507feaca695123911915070c1ce463b2Andreas Huber                    kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
9684f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            ++mCurrentSampleIndex;
9694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
9704f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9714f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (!mIsAVC) {
9724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            *out = mBuffer;
9734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer = NULL;
9744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9754f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return OK;
9764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
9774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        // Each NAL unit is split up into its constituent fragments and
9794f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        // each one of them returned in its own buffer.
9804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
981db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK(mBuffer->range_length() >= mNALLengthSize);
9824f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        const uint8_t *src =
9844f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
9854f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
986db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        size_t nal_size = parseNALSize(src);
987db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK(mBuffer->range_length() >= mNALLengthSize + nal_size);
9884f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9894f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        MediaBuffer *clone = mBuffer->clone();
990db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
9914f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9924f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        mBuffer->set_range(
993db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber                mBuffer->range_offset() + mNALLengthSize + nal_size,
994db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber                mBuffer->range_length() - mNALLengthSize - nal_size);
9954f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
9964f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (mBuffer->range_length() == 0) {
9974f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer->release();
9984f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer = NULL;
9994f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
10004f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
10014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        *out = clone;
10024f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
10034f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        return OK;
10044f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    } else {
10054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        // Whole NAL units are returned but each fragment is prefixed by
10064f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        // the start code (0x00 00 00 01).
10074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
1008e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        ssize_t num_bytes_read =
10099a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            mDataSource->readAt(offset, mSrcBuffer, size);
1010e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1011e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (num_bytes_read < (ssize_t)size) {
1012e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mBuffer->release();
1013e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mBuffer = NULL;
1014e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
10154f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return ERROR_IO;
1016e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
1017e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
10184f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        uint8_t *dstData = (uint8_t *)mBuffer->data();
10194f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        size_t srcOffset = 0;
10204f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        size_t dstOffset = 0;
1021db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
10224f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        while (srcOffset < size) {
1023db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            CHECK(srcOffset + mNALLengthSize <= size);
1024db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
1025db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            srcOffset += mNALLengthSize;
1026db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            CHECK(srcOffset + nalLength <= size);
10274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
10284f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            if (nalLength == 0) {
10294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                continue;
10304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            }
10314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
10324f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK(dstOffset + 4 <= mBuffer->size());
10334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
10344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstData[dstOffset++] = 0;
10354f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstData[dstOffset++] = 0;
10364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstData[dstOffset++] = 0;
10374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstData[dstOffset++] = 1;
10384f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
10394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            srcOffset += nalLength;
10404f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstOffset += nalLength;
10414f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
1042db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK_EQ(srcOffset, size);
10434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
10444f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        mBuffer->set_range(0, dstOffset);
1045e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mBuffer->meta_data()->clear();
1046fa8de752507feaca695123911915070c1ce463b2Andreas Huber        mBuffer->meta_data()->setInt64(
1047fa8de752507feaca695123911915070c1ce463b2Andreas Huber                kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1048e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        ++mCurrentSampleIndex;
1049e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1050e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out = mBuffer;
1051e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mBuffer = NULL;
1052e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1053e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return OK;
1054e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1055e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1056e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1057be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberbool SniffMPEG4(
1058be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
1059e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint8_t header[8];
1060e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
10619a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber    ssize_t n = source->readAt(4, header, sizeof(header));
1062e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (n < (ssize_t)sizeof(header)) {
1063e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
1064e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1065e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1066e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
10676bce6d87b3fd98e68fb54328fb4dc8e40cd2c293Andreas Huber        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
10686bce6d87b3fd98e68fb54328fb4dc8e40cd2c293Andreas Huber        || !memcmp(header, "ftypM4A ", 8)) {
1069e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
1070e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *confidence = 0.1;
1071e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1072e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return true;
1073e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1074e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1075e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return false;
1076e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1077e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1078e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}  // namespace android
1079e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1080