MPEG4Extractor.cpp revision d7d22eba3c1bb7212ccc566fedb16dbee44f51a2
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>
31d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#include "include/ESDS.h"
32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBuffer.h>
33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber#include <media/stagefright/MediaDebug.h>
35e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber#include <media/stagefright/MediaDefs.h>
36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaSource.h>
37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h>
38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/Utils.h>
39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/String8.h>
40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android {
42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass MPEG4Source : public MediaSource {
44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic:
45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    // Caller retains ownership of both "dataSource" and "sampleTable".
46be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    MPEG4Source(const sp<MetaData> &format,
47be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber                const sp<DataSource> &dataSource,
48fa8de752507feaca695123911915070c1ce463b2Andreas Huber                int32_t timeScale,
49be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber                const sp<SampleTable> &sampleTable);
50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t start(MetaData *params = NULL);
52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t stop();
53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual sp<MetaData> getFormat();
55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    virtual status_t read(
57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            MediaBuffer **buffer, const ReadOptions *options = NULL);
58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
59be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberprotected:
60be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    virtual ~MPEG4Source();
61be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber
62e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate:
63ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    Mutex mLock;
64ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    sp<MetaData> mFormat;
66be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    sp<DataSource> mDataSource;
67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int32_t mTimescale;
68be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    sp<SampleTable> mSampleTable;
69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t mCurrentSampleIndex;
70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool mIsAVC;
72db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    size_t mNALLengthSize;
73db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool mStarted;
75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBufferGroup *mGroup;
77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBuffer *mBuffer;
79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    bool mWantsNALFragments;
81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
828a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    uint8_t *mSrcBuffer;
838a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber
84db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    size_t parseNALSize(const uint8_t *data) const;
85db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MPEG4Source(const MPEG4Source &);
87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MPEG4Source &operator=(const MPEG4Source &);
88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber};
89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
90affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// This custom data source wraps an existing one and satisfies requests
91affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// falling entirely within a cached range from the cache while forwarding
92affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// all remaining requests to the wrapped datasource.
93affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// This is used to cache the full sampletable metadata for a single track,
94affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// possibly wrapping multiple times to cover all tracks, i.e.
95affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber// Each MPEG4DataSource caches the sampletable metadata for a single track.
96affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
97affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstruct MPEG4DataSource : public DataSource {
98affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    MPEG4DataSource(const sp<DataSource> &source);
99affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
100affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    virtual status_t initCheck() const;
101affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    virtual ssize_t readAt(off_t offset, void *data, size_t size);
102affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    virtual status_t getSize(off_t *size);
103affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    virtual uint32_t flags();
104affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
105affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    status_t setCachedRange(off_t offset, size_t size);
106affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
107affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberprotected:
108affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    virtual ~MPEG4DataSource();
109affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
110affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberprivate:
111affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    Mutex mLock;
112affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
113affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    sp<DataSource> mSource;
114affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    off_t mCachedOffset;
115affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    size_t mCachedSize;
116affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    uint8_t *mCache;
117affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
118affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    void clearCache();
119affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
120affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    MPEG4DataSource(const MPEG4DataSource &);
121affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    MPEG4DataSource &operator=(const MPEG4DataSource &);
122affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber};
123affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
124affa99c52957685f5a5652ab5254b92e729651c7Andreas HuberMPEG4DataSource::MPEG4DataSource(const sp<DataSource> &source)
125affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    : mSource(source),
126affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber      mCachedOffset(0),
127affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber      mCachedSize(0),
128affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber      mCache(NULL) {
129affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}
130affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
131affa99c52957685f5a5652ab5254b92e729651c7Andreas HuberMPEG4DataSource::~MPEG4DataSource() {
132affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    clearCache();
133affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}
134affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
135affa99c52957685f5a5652ab5254b92e729651c7Andreas Hubervoid MPEG4DataSource::clearCache() {
136affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    if (mCache) {
137affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber        free(mCache);
138affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber        mCache = NULL;
139affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    }
140affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
141affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    mCachedOffset = 0;
142affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    mCachedSize = 0;
143affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}
144affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
145affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstatus_t MPEG4DataSource::initCheck() const {
146affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    return mSource->initCheck();
147affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}
148affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
149affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberssize_t MPEG4DataSource::readAt(off_t offset, void *data, size_t size) {
150affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    Mutex::Autolock autoLock(mLock);
151affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
152affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    if (offset >= mCachedOffset
153affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber            && offset + size <= mCachedOffset + mCachedSize) {
154affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber        memcpy(data, &mCache[offset - mCachedOffset], size);
155affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber        return size;
156affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    }
157affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
158affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    return mSource->readAt(offset, data, size);
159affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}
160affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
161affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstatus_t MPEG4DataSource::getSize(off_t *size) {
162affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    return mSource->getSize(size);
163affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}
164affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
165affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberuint32_t MPEG4DataSource::flags() {
166affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    return mSource->flags();
167affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}
168affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
169affa99c52957685f5a5652ab5254b92e729651c7Andreas Huberstatus_t MPEG4DataSource::setCachedRange(off_t offset, size_t size) {
170affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    Mutex::Autolock autoLock(mLock);
171affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
172affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    clearCache();
173affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
174affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    mCache = (uint8_t *)malloc(size);
175affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
176affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    if (mCache == NULL) {
177affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber        return -ENOMEM;
178affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    }
179affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
180affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    mCachedOffset = offset;
181affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    mCachedSize = size;
182affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
183affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
184affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
185affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    if (err < (ssize_t)size) {
186affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber        clearCache();
187affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
188affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber        return ERROR_IO;
189affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    }
190affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
191affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber    return OK;
192affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber}
193affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
194affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber////////////////////////////////////////////////////////////////////////////////
195affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void hexdump(const void *_data, size_t size) {
197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const uint8_t *data = (const uint8_t *)_data;
198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    size_t offset = 0;
199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (offset < size) {
200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        printf("0x%04x  ", offset);
201e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
202e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        size_t n = size - offset;
203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (n > 16) {
204e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            n = 16;
205e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        for (size_t i = 0; i < 16; ++i) {
208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (i == 8) {
209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf(" ");
210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
211e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (offset + i < size) {
213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf("%02x ", data[offset + i]);
214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf("   ");
216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
218e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
219e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        printf(" ");
220e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
221e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        for (size_t i = 0; i < n; ++i) {
222e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (isprint(data[offset + i])) {
223e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf("%c", data[offset + i]);
224e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                printf(".");
226e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
227e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
228e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
229e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        printf("\n");
230e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        offset += 16;
232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
233e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
234e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
235e6c409632f773e41f33188272a0072be9fcb783fAndreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) {
236e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    switch (fourcc) {
237e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
238e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_AUDIO_AAC;
239e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
240e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
241e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_NB;
242e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
2432a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber        case FOURCC('s', 'a', 'w', 'b'):
244e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_AUDIO_AMR_WB;
2452a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber
246e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
247e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_VIDEO_MPEG4;
248e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
249e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', '2', '6', '3'):
250e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_VIDEO_H263;
251e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
252e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
253e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            return MEDIA_MIMETYPE_VIDEO_AVC;
254e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        default:
2564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK(!"should not be here.");
257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return NULL;
258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
259e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
261be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
262e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mDataSource(source),
263e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mHaveMetadata(false),
2641cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber      mHasVideo(false),
265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mFirstTrack(NULL),
266c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber      mLastTrack(NULL),
267c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber      mFileMetaData(new MetaData) {
268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
269e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
270e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Extractor::~MPEG4Extractor() {
271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    Track *track = mFirstTrack;
272e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (track) {
273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        Track *next = track->next;
274e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
275e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        delete track;
276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        track = next;
277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
278e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mFirstTrack = mLastTrack = NULL;
279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
280e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
2811cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() {
2821cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    status_t err;
2831cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    if ((err = readMetaData()) != OK) {
284c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        return new MetaData;
2851cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber    }
2861cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
287c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    return mFileMetaData;
2881cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber}
2891cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
290be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MPEG4Extractor::countTracks() {
291e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err;
292e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if ((err = readMetaData()) != OK) {
293be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        return 0;
294e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
295e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
296be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    size_t n = 0;
297e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    Track *track = mFirstTrack;
298e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (track) {
299be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        ++n;
300e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        track = track->next;
301e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
302e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
303be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    return n;
304e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
305e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
306e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData(
307e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        size_t index, uint32_t flags) {
308e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err;
309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if ((err = readMetaData()) != OK) {
310e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return NULL;
311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
313e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    Track *track = mFirstTrack;
314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (index > 0) {
315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (track == NULL) {
316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return NULL;
317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        track = track->next;
320e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        --index;
321e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
322e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
3232a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber    if (track == NULL) {
3242a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber        return NULL;
3252a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber    }
3262a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber
327e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber    if ((flags & kIncludeExtensiveMetaData)
328e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            && !track->includes_expensive_metadata) {
329e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        track->includes_expensive_metadata = true;
330e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber
331e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        const char *mime;
332e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        CHECK(track->meta->findCString(kKeyMIMEType, &mime));
333e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        if (!strncasecmp("video/", mime, 6)) {
334e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            uint32_t sampleIndex;
335e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            uint32_t sampleTime;
336e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
3371faa92a1e93f311e86dca483ed7702091137de66Andreas Huber                    && track->sampleTable->getMetaDataForSample(
3381faa92a1e93f311e86dca483ed7702091137de66Andreas Huber                        sampleIndex, NULL /* offset */, NULL /* size */,
3391faa92a1e93f311e86dca483ed7702091137de66Andreas Huber                        &sampleTime) == OK) {
340e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber                track->meta->setInt64(
341e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber                        kKeyThumbnailTime,
342e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber                        ((int64_t)sampleTime * 1000000) / track->timescale);
343e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber            }
344e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber        }
345e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber    }
346e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber
347e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return track->meta;
348e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
349e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
350e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::readMetaData() {
351e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mHaveMetadata) {
352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return OK;
353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
354e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
355e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t offset = 0;
356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err;
357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while ((err = parseChunk(&offset, 0)) == OK) {
358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
3591cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
360e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mHaveMetadata) {
361c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        if (mHasVideo) {
362c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            mFileMetaData->setCString(kKeyMIMEType, "video/mp4");
363c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        } else {
364c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
365c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
366c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return OK;
368e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
369e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return err;
371e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
372e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
373e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) {
374e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[0] = x >> 24;
375e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[1] = (x >> 16) & 0xff;
376e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[2] = (x >> 8) & 0xff;
377e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[3] = x & 0xff;
378e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    s[4] = '\0';
379e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
380e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
381c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstruct PathAdder {
382c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
383c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        : mPath(path) {
384c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        mPath->push(chunkType);
385c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    }
386c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
387c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    ~PathAdder() {
388c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        mPath->pop();
389c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    }
390c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
391c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberprivate:
392c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    Vector<uint32_t> *mPath;
393c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
394c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    PathAdder(const PathAdder &);
395c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    PathAdder &operator=(const PathAdder &);
396c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber};
397c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
398c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) {
399c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    return path.size() >= 5
400c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        && path[0] == FOURCC('m', 'o', 'o', 'v')
401c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        && path[1] == FOURCC('u', 'd', 't', 'a')
402c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        && path[2] == FOURCC('m', 'e', 't', 'a')
403c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        && path[3] == FOURCC('i', 'l', 's', 't');
404c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber}
405c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
406c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string.
407c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) {
408c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
409c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
410c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    char tmp[32];
411c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
412c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
413c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    s->setTo(tmp);
414c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber}
415c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
417e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t hdr[2];
4189a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber    if (mDataSource->readAt(*offset, hdr, 8) < 8) {
419e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return ERROR_IO;
420e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
421e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint64_t chunk_size = ntohl(hdr[0]);
422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint32_t chunk_type = ntohl(hdr[1]);
423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t data_offset = *offset + 8;
424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (chunk_size == 1) {
4269a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber        if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_IO;
428e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
429e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        chunk_size = ntoh64(chunk_size);
430e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        data_offset += 8;
431e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    char chunk[5];
434e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MakeFourCCString(chunk_type, chunk);
435e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#if 0
437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    static const char kWhitespace[] = "                                        ";
438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size);
440e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
441e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    char buffer[256];
442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (chunk_size <= sizeof(buffer)) {
443c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        if (mDataSource->readAt(*offset, buffer, chunk_size)
444c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                < (ssize_t)chunk_size) {
445e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return ERROR_IO;
446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        hexdump(buffer, chunk_size);
449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#endif
451e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
452c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    PathAdder autoAdder(&mPath, chunk_type);
453c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
454e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    off_t chunk_data_size = *offset + chunk_size - data_offset;
455e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
456c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    if (chunk_type != FOURCC('c', 'p', 'r', 't')
457c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            && mPath.size() == 5 && underMetaDataPath(mPath)) {
458c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        off_t stop_offset = *offset + chunk_size;
459c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        *offset = data_offset;
460c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        while (*offset < stop_offset) {
461c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            status_t err = parseChunk(offset, depth + 1);
462c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (err != OK) {
463c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                return err;
464c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
465c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
4665ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
4675ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber        if (*offset != stop_offset) {
4685ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            return ERROR_MALFORMED;
4695ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber        }
470c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
471c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        return OK;
472c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    }
473c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
474e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    switch(chunk_type) {
475e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'o', 'o', 'v'):
476e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('t', 'r', 'a', 'k'):
477e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'd', 'i', 'a'):
478e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'i', 'n', 'f'):
479e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('d', 'i', 'n', 'f'):
480e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 'b', 'l'):
481e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'v', 'e', 'x'):
482e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'o', 'o', 'f'):
483e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('t', 'r', 'a', 'f'):
484e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'f', 'r', 'a'):
485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 'k', 'i' ,'p'):
486c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC('u', 'd', 't', 'a'):
487c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC('i', 'l', 's', 't'):
488e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
489affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
490affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber                LOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
491affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
492affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber                if (mDataSource->flags() & DataSource::kWantsPrefetching) {
493affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber                    sp<MPEG4DataSource> cachedSource =
494affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber                        new MPEG4DataSource(mDataSource);
495affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
496affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber                    if (cachedSource->setCachedRange(*offset, chunk_size) == OK) {
497affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber                        mDataSource = cachedSource;
498affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber                    }
499affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber                }
500affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber            }
501affa99c52957685f5a5652ab5254b92e729651c7Andreas Huber
5025ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
5035ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                Track *track = new Track;
5045ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                track->next = NULL;
5055ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                if (mLastTrack) {
5065ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                    mLastTrack->next = track;
5075ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                } else {
5085ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                    mFirstTrack = track;
5095ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                }
5105ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                mLastTrack = track;
5115ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
5125ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                track->meta = new MetaData;
5135ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                track->includes_expensive_metadata = false;
5145ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                track->timescale = 0;
5155ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                track->sampleTable = new SampleTable(mDataSource);
5165ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
5175ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
5185ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
519e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t stop_offset = *offset + chunk_size;
520e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset = data_offset;
521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            while (*offset < stop_offset) {
522e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                status_t err = parseChunk(offset, depth + 1);
523e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (err != OK) {
524e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return err;
525e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
526e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
527e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
5285ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (*offset != stop_offset) {
5295ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
5305ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
5315ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
5325ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
5335ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                status_t err = verifyTrack(mLastTrack);
5345ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
5355ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                if (err != OK) {
5365ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                    return err;
5375ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                }
5385ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mHaveMetadata = true;
540e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
541e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return UNKNOWN_ERROR;  // Return a dummy error.
542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
543e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('t', 'k', 'h', 'd'):
547e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
5485ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (chunk_data_size < 4) {
5495ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
5505ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
551e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
552e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t version;
5539a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
554e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
555e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
556e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint64_t ctime, mtime, duration;
558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            int32_t id;
559e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint32_t width, height;
560e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
561e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (version == 1) {
562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (chunk_data_size != 36 + 60) {
563e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_MALFORMED;
564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                uint8_t buffer[36 + 60];
5679a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                if (mDataSource->readAt(
568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
569e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_IO;
570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                ctime = U64_AT(&buffer[4]);
573e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mtime = U64_AT(&buffer[12]);
574e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                id = U32_AT(&buffer[20]);
575e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                duration = U64_AT(&buffer[28]);
576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                width = U32_AT(&buffer[88]);
577e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                height = U32_AT(&buffer[92]);
578e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else if (version == 0) {
579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (chunk_data_size != 24 + 60) {
580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_MALFORMED;
581e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
582e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
583e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                uint8_t buffer[24 + 60];
5849a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                if (mDataSource->readAt(
585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                            data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
586e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_IO;
587e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
588e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                ctime = U32_AT(&buffer[4]);
589e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mtime = U32_AT(&buffer[8]);
590e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                id = U32_AT(&buffer[12]);
591e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                duration = U32_AT(&buffer[20]);
592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                width = U32_AT(&buffer[76]);
593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                height = U32_AT(&buffer[80]);
594e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
598e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
600e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'd', 'h', 'd'):
601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < 4) {
603e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t version;
6079a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
608e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, &version, sizeof(version))
609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    < (ssize_t)sizeof(version)) {
610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t timescale_offset;
614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (version == 1) {
616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                timescale_offset = data_offset + 4 + 16;
617e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else if (version == 0) {
618e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                timescale_offset = data_offset + 4 + 8;
619e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
620e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
621e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
622e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
623e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint32_t timescale;
6249a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        timescale_offset, &timescale, sizeof(timescale))
626e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    < (ssize_t)sizeof(timescale)) {
627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
628e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
629e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
630e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->timescale = ntohl(timescale);
631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            int64_t duration;
633e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (version == 1) {
6349a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                if (mDataSource->readAt(
635e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                            timescale_offset + 4, &duration, sizeof(duration))
636e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        < (ssize_t)sizeof(duration)) {
637e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_IO;
638e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
639e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                duration = ntoh64(duration);
640e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            } else {
641e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                int32_t duration32;
6429a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                if (mDataSource->readAt(
643e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                            timescale_offset + 4, &duration32, sizeof(duration32))
644e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        < (ssize_t)sizeof(duration32)) {
645e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return ERROR_IO;
646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                duration = ntohl(duration32);
648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
649fa8de752507feaca695123911915070c1ce463b2Andreas Huber            mLastTrack->meta->setInt64(
650fa8de752507feaca695123911915070c1ce463b2Andreas Huber                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
654e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('h', 'd', 'l', 'r'):
657e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < 25) {
659e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
661e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
662e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[24];
6639a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(data_offset, buffer, 24) < 24) {
664e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
665e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
666e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
667e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (U32_AT(buffer) != 0) {
668e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Should be version 0, flags 0.
669e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
670e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (U32_AT(&buffer[4]) != 0) {
673e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // pre_defined should be 0.
674e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
675e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mHandlerType = U32_AT(&buffer[8]);
678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
681e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
682e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 's', 'd'):
683e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
684e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < 8) {
685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
687e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[8];
6895ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (chunk_data_size < (off_t)sizeof(buffer)) {
6905ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
6915ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
6925ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
6939a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
694e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, 8) < 8) {
695e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
696e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
697e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
698e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (U32_AT(buffer) != 0) {
699e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Should be version 0, flags 0.
700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint32_t entry_count = U32_AT(&buffer[4]);
704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
705e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (entry_count > 1) {
706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // For now we only support a single type of media per track.
707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_UNSUPPORTED;
708e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
709e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
710e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t stop_offset = *offset + chunk_size;
711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset = data_offset + 8;
712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            for (uint32_t i = 0; i < entry_count; ++i) {
713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                status_t err = parseChunk(offset, depth + 1);
714e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (err != OK) {
715e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return err;
716e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
717e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
7185ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
7195ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (*offset != stop_offset) {
7205ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
7215ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
724e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
725e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'p', '4', 'a'):
726e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 'a', 'm', 'r'):
7272a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber        case FOURCC('s', 'a', 'w', 'b'):
728e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
729e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) {
730e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
731e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
732e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
733e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[8 + 20];
734e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
735e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Basic AudioSampleEntry size.
736e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
737e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
738e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
7399a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
740e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
741e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
742e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
743e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
744e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t data_ref_index = U16_AT(&buffer[6]);
745e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t num_channels = U16_AT(&buffer[16]);
746e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
747e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
748e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber                            FourCC2MIME(chunk_type))
749e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber                || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
750e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber                               FourCC2MIME(chunk_type))) {
751e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // AMR audio is always mono.
752e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                num_channels = 1;
753e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
754e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
755e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t sample_size = U16_AT(&buffer[18]);
756e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
757e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
7582ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber            // printf("*** coding='%s' %d channels, size %d, rate %d\n",
7592ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber            //        chunk, num_channels, sample_size, sample_rate);
760e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
761e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
762e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setInt32(kKeyChannelCount, num_channels);
763e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setInt32(kKeySampleRate, sample_rate);
764e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
765e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t stop_offset = *offset + chunk_size;
766e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset = data_offset + sizeof(buffer);
767e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            while (*offset < stop_offset) {
768e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                status_t err = parseChunk(offset, depth + 1);
769e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (err != OK) {
770e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return err;
771e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
772e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
7735ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
7745ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (*offset != stop_offset) {
7755ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
7765ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
777e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
778e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
779e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
780e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('m', 'p', '4', 'v'):
781e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', '2', '6', '3'):
782e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('a', 'v', 'c', '1'):
783e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
7841cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber            mHasVideo = true;
7851cb02bf661807ffc6525dcc13e16d7ce027bef00Andreas Huber
786e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) {
787e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
788e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
789e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
790e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[78];
791e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < (ssize_t)sizeof(buffer)) {
792e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Basic VideoSampleEntry size.
793e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
794e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
795e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
7969a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
797e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
798e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
799e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
800e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
801e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t data_ref_index = U16_AT(&buffer[6]);
802e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t width = U16_AT(&buffer[6 + 18]);
803e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint16_t height = U16_AT(&buffer[6 + 20]);
804e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
8052ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber            // printf("*** coding='%s' width=%d height=%d\n",
8062ea14e231945afb6581fa8f54015b33bc74a19e5Andreas Huber            //        chunk, width, height);
807e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
808e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
809e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setInt32(kKeyWidth, width);
810e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setInt32(kKeyHeight, height);
811e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
812e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            off_t stop_offset = *offset + chunk_size;
813e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset = data_offset + sizeof(buffer);
814e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            while (*offset < stop_offset) {
815e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                status_t err = parseChunk(offset, depth + 1);
816e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                if (err != OK) {
817e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    return err;
818e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                }
819e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
8205ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
8215ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (*offset != stop_offset) {
8225ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
8235ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
824e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
825e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
826e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
827e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 'c', 'o'):
828e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('c', 'o', '6', '4'):
829e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
830e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
831e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setChunkOffsetParams(
832e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        chunk_type, data_offset, chunk_data_size);
833e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
834e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
835e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
836e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
837e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
838e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
839e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
840e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
841e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
842e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 's', 'c'):
843e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
844e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
845e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setSampleToChunkParams(
846e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, chunk_data_size);
847e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
848e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
849e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
850e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
851e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
852e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
853e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
854e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
855e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
856e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 's', 'z'):
857e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 'z', '2'):
858e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
859e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
860e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setSampleSizeParams(
861e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        chunk_type, data_offset, chunk_data_size);
862e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
863e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
864e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
865e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
866e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
8671bceff916a72246fa208605d50615823d7f1688bAndreas Huber            size_t max_size;
8681bceff916a72246fa208605d50615823d7f1688bAndreas Huber            CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK);
8691bceff916a72246fa208605d50615823d7f1688bAndreas Huber
8701bceff916a72246fa208605d50615823d7f1688bAndreas Huber            // Assume that a given buffer only contains at most 10 fragments,
8711bceff916a72246fa208605d50615823d7f1688bAndreas Huber            // each fragment originally prefixed with a 2 byte length will
8721bceff916a72246fa208605d50615823d7f1688bAndreas Huber            // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
8731bceff916a72246fa208605d50615823d7f1688bAndreas Huber            // and thus will grow by 2 bytes per fragment.
8741bceff916a72246fa208605d50615823d7f1688bAndreas Huber            mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
8751bceff916a72246fa208605d50615823d7f1688bAndreas Huber
876e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
877e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
878e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
879e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
880e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 't', 's'):
881e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
882e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
883e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setTimeToSampleParams(
884e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, chunk_data_size);
885e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
886e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
887e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
888e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
889e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
890e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
891e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
892e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
893e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
894e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('s', 't', 's', 's'):
895e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
896e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            status_t err =
897e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                mLastTrack->sampleTable->setSyncSampleParams(
898e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, chunk_data_size);
899e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
900e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (err != OK) {
901e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return err;
902e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
903e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
904e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
905e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
906e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
907e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
908e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('e', 's', 'd', 's'):
909e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
910e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size < 4) {
911e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
912e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
913e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
914e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            uint8_t buffer[256];
915e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size > (off_t)sizeof(buffer)) {
916e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
917e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
918e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
9199a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
920e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
921e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
922e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
923e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
924e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (U32_AT(buffer) != 0) {
925e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                // Should be version 0, flags 0.
926e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_MALFORMED;
927e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
928e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
929e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setData(
930e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4);
931e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
932d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber            if (mPath.size() >= 2
933d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                    && mPath[mPath.size() - 2] == FOURCC('m', 'p', '4', 'a')) {
934d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                // Information from the ESDS must be relied on for proper
935d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                // setup of sample rate and channel count for MPEG4 Audio.
936d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                // The generic header appears to only contain generic
937d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                // information...
938d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
939d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
940d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                        &buffer[4], chunk_data_size - 4);
941d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
942d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                if (err != OK) {
943d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                    return err;
944d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                }
945d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber            }
946d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
947e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
948e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
949e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
950e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
951e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        case FOURCC('a', 'v', 'c', 'C'):
952e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
953e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            char buffer[256];
954e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            if (chunk_data_size > (off_t)sizeof(buffer)) {
955e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_BUFFER_TOO_SMALL;
956e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
957e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
9589a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            if (mDataSource->readAt(
959e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                        data_offset, buffer, chunk_data_size) < chunk_data_size) {
960e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                return ERROR_IO;
961e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            }
962e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
963e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mLastTrack->meta->setData(
964e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                    kKeyAVCC, kTypeAVCC, buffer, chunk_data_size);
965e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
966e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
967e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
968e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
969e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
970c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC('m', 'e', 't', 'a'):
971c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
972c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            uint8_t buffer[4];
9735ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (chunk_data_size < (off_t)sizeof(buffer)) {
9745ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
9755ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
9765ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
977c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (mDataSource->readAt(
978c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                        data_offset, buffer, 4) < 4) {
979c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                return ERROR_IO;
980c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
981c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
982c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (U32_AT(buffer) != 0) {
983c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                // Should be version 0, flags 0.
984c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                return ERROR_MALFORMED;
985c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
986c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
987c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            off_t stop_offset = *offset + chunk_size;
988c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            *offset = data_offset + sizeof(buffer);
989c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            while (*offset < stop_offset) {
990c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                status_t err = parseChunk(offset, depth + 1);
991c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                if (err != OK) {
992c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                    return err;
993c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                }
994c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
9955ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
9965ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            if (*offset != stop_offset) {
9975ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
9985ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            }
999c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1000c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1001c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1002c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC('d', 'a', 't', 'a'):
1003c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1004c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (mPath.size() == 6 && underMetaDataPath(mPath)) {
1005c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                status_t err = parseMetaData(data_offset, chunk_data_size);
1006c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1007c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                if (err != OK) {
1008c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                    return err;
1009c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                }
1010c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
1011c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1012c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            *offset += chunk_size;
1013c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1014c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1015c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1016c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC('m', 'v', 'h', 'd'):
1017c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1018c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (chunk_data_size < 12) {
1019c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                return ERROR_MALFORMED;
1020c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
1021c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1022c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            uint8_t header[12];
1023c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (mDataSource->readAt(
1024c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                        data_offset, header, sizeof(header))
1025c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                    < (ssize_t)sizeof(header)) {
1026c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                return ERROR_IO;
1027c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
1028c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1029c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            int64_t creationTime;
1030c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (header[0] == 1) {
1031c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                creationTime = U64_AT(&header[4]);
10325ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            } else if (header[0] != 0) {
10335ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                return ERROR_MALFORMED;
1034c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            } else {
1035c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                creationTime = U32_AT(&header[4]);
1036c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
1037c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1038c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            String8 s;
1039c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            convertTimeToDate(creationTime, &s);
1040c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1041c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            mFileMetaData->setCString(kKeyDate, s.string());
1042c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1043c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            *offset += chunk_size;
1044c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1045c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1046c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1047e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        default:
1048e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        {
1049e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            *offset += chunk_size;
1050e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            break;
1051e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
1052e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1053e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1054e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
1055e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1056e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1057c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) {
1058c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    if (size < 4) {
1059c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        return ERROR_MALFORMED;
1060c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    }
1061c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1062c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    uint8_t *buffer = new uint8_t[size + 1];
1063c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    if (mDataSource->readAt(
1064c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                offset, buffer, size) != (ssize_t)size) {
1065c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        delete[] buffer;
1066c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        buffer = NULL;
1067c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1068c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        return ERROR_IO;
1069c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    }
1070c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1071c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    uint32_t flags = U32_AT(buffer);
1072c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1073c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    uint32_t metadataKey = 0;
1074c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    switch (mPath[4]) {
1075c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC(0xa9, 'a', 'l', 'b'):
1076c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1077c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            metadataKey = kKeyAlbum;
1078c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1079c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1080c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC(0xa9, 'A', 'R', 'T'):
1081c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1082c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            metadataKey = kKeyArtist;
1083c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1084c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1085c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen        case FOURCC('a', 'A', 'R', 'T'):
1086c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen        {
1087c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen            metadataKey = kKeyAlbumArtist;
1088c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen            break;
1089c5d5ee34d7c1026ca8d5cd8b186e5a73c5230247Marco Nelissen        }
1090c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC(0xa9, 'd', 'a', 'y'):
1091c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1092c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            metadataKey = kKeyYear;
1093c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1094c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1095c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC(0xa9, 'n', 'a', 'm'):
1096c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1097c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            metadataKey = kKeyTitle;
1098c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1099c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1100c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC(0xa9, 'w', 'r', 't'):
1101c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1102c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            metadataKey = kKeyWriter;
1103c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1104c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1105c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC('c', 'o', 'v', 'r'):
1106c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1107c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            metadataKey = kKeyAlbumArt;
1108c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1109c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1110c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC('g', 'n', 'r', 'e'):
1111c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1112c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            metadataKey = kKeyGenre;
1113c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1114c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1115fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen        case FOURCC(0xa9, 'g', 'e', 'n'):
1116fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen        {
1117fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen            metadataKey = kKeyGenre;
1118fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen            break;
1119fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen        }
1120c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        case FOURCC('t', 'r', 'k', 'n'):
1121c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        {
1122c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (size == 16 && flags == 0) {
1123c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                char tmp[16];
1124c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                sprintf(tmp, "%d/%d",
1125c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                        (int)buffer[size - 5], (int)buffer[size - 3]);
1126c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1127c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                mFileMetaData->setCString(kKeyCDTrackNumber, tmp);
1128c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
1129c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1130c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1131fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen        case FOURCC('d', 'i', 's', 'k'):
1132fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen        {
1133fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen            if (size == 14 && flags == 0) {
1134fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                char tmp[16];
1135fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                sprintf(tmp, "%d/%d",
1136fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                        (int)buffer[size - 3], (int)buffer[size - 1]);
1137fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen
1138fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                mFileMetaData->setCString(kKeyDiscNumber, tmp);
1139fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen            }
1140fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen            break;
1141fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen        }
1142fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen
1143c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        default:
1144c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            break;
1145c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    }
1146c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1147c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    if (size >= 8 && metadataKey) {
1148c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        if (metadataKey == kKeyAlbumArt) {
1149c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            mFileMetaData->setData(
1150c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                    kKeyAlbumArt, MetaData::TYPE_NONE,
1151c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                    buffer + 8, size - 8);
1152c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        } else if (metadataKey == kKeyGenre) {
1153c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            if (flags == 0) {
1154fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                // uint8_t genre code, iTunes genre codes are
1155fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                // the standard id3 codes, except they start
1156fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                // at 1 instead of 0 (e.g. Pop is 14, not 13)
1157fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                // We use standard id3 numbering, so subtract 1.
1158fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                int genrecode = (int)buffer[size - 1];
1159fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                genrecode--;
1160fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                if (genrecode < 0) {
1161fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                    genrecode = 255; // reserved for 'unknown genre'
1162fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                }
1163c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                char genre[10];
1164fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                sprintf(genre, "%d", genrecode);
1165c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1166c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                mFileMetaData->setCString(metadataKey, genre);
1167fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen            } else if (flags == 1) {
1168fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                // custom genre string
1169fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                buffer[size] = '\0';
1170fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen
1171fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                mFileMetaData->setCString(
1172fe3b8e9fe5e68ef307fdac3ad94b15215038dbc3Marco Nelissen                        metadataKey, (const char *)buffer + 8);
1173c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            }
1174c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        } else {
1175c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            buffer[size] = '\0';
1176c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1177c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber            mFileMetaData->setCString(
1178c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber                    metadataKey, (const char *)buffer + 8);
1179c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber        }
1180c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    }
1181c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1182c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    delete[] buffer;
1183c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    buffer = NULL;
1184c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1185c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber    return OK;
1186c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber}
1187c2c9dd32511b555c637b8cadb8091eaa6088f92bAndreas Huber
1188be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
1189e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    status_t err;
1190e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if ((err = readMetaData()) != OK) {
1191be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        return NULL;
1192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1194e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    Track *track = mFirstTrack;
1195e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    while (index > 0) {
1196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (track == NULL) {
1197be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber            return NULL;
1198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
1199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        track = track->next;
1201e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        --index;
1202e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
12042a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber    if (track == NULL) {
12052a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber        return NULL;
12062a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber    }
12072a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber
1208be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber    return new MPEG4Source(
1209fa8de752507feaca695123911915070c1ce463b2Andreas Huber            track->meta, mDataSource, track->timescale, track->sampleTable);
1210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1211e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
12125ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber// static
12135ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huberstatus_t MPEG4Extractor::verifyTrack(Track *track) {
12145ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    const char *mime;
12155ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    CHECK(track->meta->findCString(kKeyMIMEType, &mime));
12165ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
12175ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    uint32_t type;
12185ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    const void *data;
12195ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    size_t size;
12205ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
12215ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
12225ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                || type != kTypeAVCC) {
12235ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            return ERROR_MALFORMED;
12245ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber        }
12255ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
12265ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
12275ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber        if (!track->meta->findData(kKeyESDS, &type, &data, &size)
12285ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber                || type != kTypeESDS) {
12295ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber            return ERROR_MALFORMED;
12305ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber        }
12315ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    }
12325ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
12335ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber    return OK;
12345ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber}
12355ee0bce5e006610a06d6d8f3572098b1ccaded6dAndreas Huber
1236d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huberstatus_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
1237d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        const void *esds_data, size_t esds_size) {
1238d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    ESDS esds(esds_data, esds_size);
1239d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    const uint8_t *csd;
1240d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    size_t csd_size;
1241d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    if (esds.getCodecSpecificInfo(
1242d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                (const void **)&csd, &csd_size) != OK) {
1243d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        return ERROR_MALFORMED;
1244d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    }
1245d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1246d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#if 0
1247d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    printf("ESD of size %d\n", csd_size);
1248d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    hexdump(csd, csd_size);
1249d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber#endif
1250d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1251d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    if (csd_size < 2) {
1252d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        return ERROR_MALFORMED;
1253d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    }
1254d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1255d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    uint32_t objectType = csd[0] >> 3;
1256d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1257d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    if (objectType == 31) {
1258d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        return ERROR_UNSUPPORTED;
1259d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    }
1260d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1261d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7);
1262d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    int32_t sampleRate = 0;
1263d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    int32_t numChannels = 0;
1264d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    if (freqIndex == 15) {
1265d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        if (csd_size < 5) {
1266d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber            return ERROR_MALFORMED;
1267d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        }
1268d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1269d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        sampleRate = (csd[1] & 0x7f) << 17
1270d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                        | csd[2] << 9
1271d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                        | csd[3] << 1
1272d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber                        | (csd[4] >> 7);
1273d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1274d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        numChannels = (csd[4] >> 3) & 15;
1275d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    } else {
1276d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        static uint32_t kSamplingRate[] = {
1277d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber            96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1278d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber            16000, 12000, 11025, 8000, 7350
1279d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        };
1280d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1281d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        if (freqIndex == 13 || freqIndex == 14) {
1282d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber            return ERROR_MALFORMED;
1283d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        }
1284d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1285d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        sampleRate = kSamplingRate[freqIndex];
1286d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        numChannels = (csd[1] >> 3) & 15;
1287d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    }
1288d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1289d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    if (numChannels == 0) {
1290d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber        return ERROR_UNSUPPORTED;
1291d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    }
1292d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1293d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    int32_t prevSampleRate;
1294d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    CHECK(mLastTrack->meta->findInt32(kKeySampleRate, &prevSampleRate));
1295d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1296d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    if (prevSampleRate != sampleRate) {
12974a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber        LOGV("mpeg4 audio sample rate different from previous setting. "
1298d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber             "was: %d, now: %d", prevSampleRate, sampleRate);
1299d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    }
1300d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1301d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    mLastTrack->meta->setInt32(kKeySampleRate, sampleRate);
1302d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1303d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    int32_t prevChannelCount;
1304d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    CHECK(mLastTrack->meta->findInt32(kKeyChannelCount, &prevChannelCount));
1305d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1306d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    if (prevChannelCount != numChannels) {
13074a9375ef2a06fc36ec308835ef9e7e4eea2ba69fAndreas Huber        LOGV("mpeg4 audio channel count different from previous setting. "
1308d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber             "was: %d, now: %d", prevChannelCount, numChannels);
1309d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    }
1310d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1311d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    mLastTrack->meta->setInt32(kKeyChannelCount, numChannels);
1312d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1313d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber    return OK;
1314d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber}
1315d2315967b4075875cd6681327ae3043fa2adfbcfAndreas Huber
1316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber////////////////////////////////////////////////////////////////////////////////
1317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1318e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::MPEG4Source(
1319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        const sp<MetaData> &format,
1320be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<DataSource> &dataSource,
1321fa8de752507feaca695123911915070c1ce463b2Andreas Huber        int32_t timeScale,
1322be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<SampleTable> &sampleTable)
1323e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mFormat(format),
1324e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mDataSource(dataSource),
1325fa8de752507feaca695123911915070c1ce463b2Andreas Huber      mTimescale(timeScale),
1326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mSampleTable(sampleTable),
1327e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mCurrentSampleIndex(0),
1328e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mIsAVC(false),
1329db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber      mNALLengthSize(0),
1330e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mStarted(false),
1331e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mGroup(NULL),
1332e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mBuffer(NULL),
13334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber      mWantsNALFragments(false),
13348a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber      mSrcBuffer(NULL) {
1335e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    const char *mime;
1336e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    bool success = mFormat->findCString(kKeyMIMEType, &mime);
13374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    CHECK(success);
1338e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1339e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
1340db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
1341db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    if (mIsAVC) {
1342db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        uint32_t type;
1343db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        const void *data;
1344db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        size_t size;
1345db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK(format->findData(kKeyAVCC, &type, &data, &size));
1346db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
1347db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        const uint8_t *ptr = (const uint8_t *)data;
1348db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
1349db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK(size >= 7);
1350db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK_EQ(ptr[0], 1);  // configurationVersion == 1
1351db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
1352db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        // The number of bytes used to encode the length of a NAL unit.
1353db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        mNALLengthSize = 1 + (ptr[4] & 3);
1354db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    }
1355e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1357e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::~MPEG4Source() {
1358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mStarted) {
1359e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        stop();
1360e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1361e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1362e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1363e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::start(MetaData *params) {
1364ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    Mutex::Autolock autoLock(mLock);
1365ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
13664f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    CHECK(!mStarted);
1367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1368e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int32_t val;
13694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    if (params && params->findInt32(kKeyWantsNALFragments, &val)
1370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        && val != 0) {
13714f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        mWantsNALFragments = true;
1372e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    } else {
13734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        mWantsNALFragments = false;
1374e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1375e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1376e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = new MediaBufferGroup;
1377e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
13781bceff916a72246fa208605d50615823d7f1688bAndreas Huber    int32_t max_size;
13791bceff916a72246fa208605d50615823d7f1688bAndreas Huber    CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size));
1380e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
13811bceff916a72246fa208605d50615823d7f1688bAndreas Huber    mGroup->add_buffer(new MediaBuffer(max_size));
13828a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber
13838a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    mSrcBuffer = new uint8_t[max_size];
1384e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1385e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = true;
1386e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1387e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
1388e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1390e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::stop() {
1391ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    Mutex::Autolock autoLock(mLock);
1392ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
13934f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    CHECK(mStarted);
1394e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1395e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mBuffer != NULL) {
1396e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mBuffer->release();
1397e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mBuffer = NULL;
1398e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1399e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
14008a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    delete[] mSrcBuffer;
14018a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    mSrcBuffer = NULL;
14028a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber
1403e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    delete mGroup;
1404e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mGroup = NULL;
1405e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1406e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mStarted = false;
1407e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mCurrentSampleIndex = 0;
1408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1409e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return OK;
1410e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1411e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1412e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MPEG4Source::getFormat() {
1413ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    Mutex::Autolock autoLock(mLock);
1414ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
1415e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mFormat;
1416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1417e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1418db5d662254f2ed788d32e2466739adc8d655c732Andreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const {
1419db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    switch (mNALLengthSize) {
1420db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        case 1:
1421db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            return *data;
1422db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        case 2:
1423db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            return U16_AT(data);
1424db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        case 3:
1425db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            return ((size_t)data[0] << 16) | U16_AT(&data[1]);
1426db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        case 4:
1427db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            return U32_AT(data);
1428db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    }
1429db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
1430db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    // This cannot happen, mNALLengthSize springs to life by adding 1 to
1431db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    // a 2-bit integer.
1432db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    CHECK(!"Should not be here.");
1433db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
1434db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber    return 0;
1435db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber}
1436db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
1437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::read(
1438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        MediaBuffer **out, const ReadOptions *options) {
1439ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber    Mutex::Autolock autoLock(mLock);
1440ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber
14414f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    CHECK(mStarted);
1442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1443e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *out = NULL;
1444e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1445e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int64_t seekTimeUs;
1446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (options && options->getSeekTo(&seekTimeUs)) {
1447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        uint32_t sampleIndex;
1448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        status_t err = mSampleTable->findClosestSample(
1449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                seekTimeUs * mTimescale / 1000000,
1450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber                &sampleIndex, SampleTable::kSyncSample_Flag);
1451e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1452e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (err != OK) {
1453d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber            if (err == ERROR_OUT_OF_RANGE) {
1454d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber                // An attempt to seek past the end of the stream would
1455d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber                // normally cause this ERROR_OUT_OF_RANGE error. Propagating
1456d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber                // this all the way to the MediaPlayer would cause abnormal
1457d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber                // termination. Legacy behaviour appears to be to behave as if
1458d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber                // we had seeked to the end of stream, ending normally.
1459d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber                err = ERROR_END_OF_STREAM;
1460d7d22eba3c1bb7212ccc566fedb16dbee44f51a2Andreas Huber            }
1461e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return err;
1462e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
1463e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mCurrentSampleIndex = sampleIndex;
1465e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (mBuffer != NULL) {
1466e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mBuffer->release();
1467e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mBuffer = NULL;
1468e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
1469e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1470e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        // fall through
1471e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1472e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
14738a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    off_t offset;
14748a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    size_t size;
14754f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    uint32_t dts;
14764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    bool newBuffer = false;
14774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    if (mBuffer == NULL) {
14784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        newBuffer = true;
1479e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
14801faa92a1e93f311e86dca483ed7702091137de66Andreas Huber        status_t err =
14811faa92a1e93f311e86dca483ed7702091137de66Andreas Huber            mSampleTable->getMetaDataForSample(
14821faa92a1e93f311e86dca483ed7702091137de66Andreas Huber                    mCurrentSampleIndex, &offset, &size, &dts);
1483e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
14844f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (err != OK) {
14854f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return err;
14864f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
14874f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
14884f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        err = mGroup->acquire_buffer(&mBuffer);
14891faa92a1e93f311e86dca483ed7702091137de66Andreas Huber
14904f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (err != OK) {
14914f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK_EQ(mBuffer, NULL);
14924f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return err;
14934f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
14948a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber    }
1495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
14964f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    if (!mIsAVC || mWantsNALFragments) {
14974f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (newBuffer) {
14984f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            ssize_t num_bytes_read =
14999a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
15004f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            if (num_bytes_read < (ssize_t)size) {
15024f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                mBuffer->release();
15034f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                mBuffer = NULL;
15044f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                return ERROR_IO;
15064f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            }
15074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
1508ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber            CHECK(mBuffer != NULL);
15094f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer->set_range(0, size);
15104f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer->meta_data()->clear();
1511fa8de752507feaca695123911915070c1ce463b2Andreas Huber            mBuffer->meta_data()->setInt64(
1512fa8de752507feaca695123911915070c1ce463b2Andreas Huber                    kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
15134f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            ++mCurrentSampleIndex;
15144f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
15154f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15164f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (!mIsAVC) {
15174f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            *out = mBuffer;
15184f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer = NULL;
15194f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15204f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return OK;
15214f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
15224f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15234f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        // Each NAL unit is split up into its constituent fragments and
15244f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        // each one of them returned in its own buffer.
15254f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
1526db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK(mBuffer->range_length() >= mNALLengthSize);
15274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15284f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        const uint8_t *src =
15294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
15304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
1531db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        size_t nal_size = parseNALSize(src);
1532909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
1533909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber            LOGE("incomplete NAL unit.");
1534909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber
1535909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber            mBuffer->release();
1536909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber            mBuffer = NULL;
1537909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber
1538909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber            return ERROR_MALFORMED;
1539909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber        }
15404f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15414f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        MediaBuffer *clone = mBuffer->clone();
1542ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        CHECK(clone != NULL);
1543db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
15444f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
1545ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        CHECK(mBuffer != NULL);
15464f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        mBuffer->set_range(
1547db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber                mBuffer->range_offset() + mNALLengthSize + nal_size,
1548db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber                mBuffer->range_length() - mNALLengthSize - nal_size);
15494f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15504f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        if (mBuffer->range_length() == 0) {
15514f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer->release();
15524f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            mBuffer = NULL;
15534f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
15544f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15554f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        *out = clone;
15564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15574f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        return OK;
15584f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber    } else {
15594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        // Whole NAL units are returned but each fragment is prefixed by
15604f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        // the start code (0x00 00 00 01).
15614f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
1562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        ssize_t num_bytes_read =
15639a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber            mDataSource->readAt(offset, mSrcBuffer, size);
1564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (num_bytes_read < (ssize_t)size) {
1566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mBuffer->release();
1567e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            mBuffer = NULL;
1568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
15694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            return ERROR_IO;
1570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
1571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
15724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        uint8_t *dstData = (uint8_t *)mBuffer->data();
15734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        size_t srcOffset = 0;
15744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        size_t dstOffset = 0;
1575db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber
15764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        while (srcOffset < size) {
1577db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            CHECK(srcOffset + mNALLengthSize <= size);
1578db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
1579db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber            srcOffset += mNALLengthSize;
1580909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber
1581909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber            if (srcOffset + nalLength > size) {
1582909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber                mBuffer->release();
1583909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber                mBuffer = NULL;
1584909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber
1585909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber                return ERROR_MALFORMED;
1586909255a9cf425534e4a8b582a320686852dc59dcAndreas Huber            }
15874f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15884f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            if (nalLength == 0) {
15894f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber                continue;
15904f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            }
15914f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15924f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            CHECK(dstOffset + 4 <= mBuffer->size());
15934f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
15944f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstData[dstOffset++] = 0;
15954f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstData[dstOffset++] = 0;
15964f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstData[dstOffset++] = 0;
15974f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstData[dstOffset++] = 1;
15984f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
15994f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            srcOffset += nalLength;
16004f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber            dstOffset += nalLength;
16014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        }
1602db5d662254f2ed788d32e2466739adc8d655c732Andreas Huber        CHECK_EQ(srcOffset, size);
16034f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber
1604ba7ec917ea91364598de1ba7a29910cec08fd5deAndreas Huber        CHECK(mBuffer != NULL);
16054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber        mBuffer->set_range(0, dstOffset);
1606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mBuffer->meta_data()->clear();
1607fa8de752507feaca695123911915070c1ce463b2Andreas Huber        mBuffer->meta_data()->setInt64(
1608fa8de752507feaca695123911915070c1ce463b2Andreas Huber                kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
1609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        ++mCurrentSampleIndex;
1610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *out = mBuffer;
1612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mBuffer = NULL;
1613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return OK;
1615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1617e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1618be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberbool SniffMPEG4(
1619be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber        const sp<DataSource> &source, String8 *mimeType, float *confidence) {
1620e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    uint8_t header[8];
1621e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
16229a12baf929ea803915d7ab626b200ffefb4fbac7Andreas Huber    ssize_t n = source->readAt(4, header, sizeof(header));
1623e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (n < (ssize_t)sizeof(header)) {
1624e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return false;
1625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1626e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
16286bce6d87b3fd98e68fb54328fb4dc8e40cd2c293Andreas Huber        || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
162901830a0814ae2db9141f49720d9e5aa2457854f0Andreas Huber        || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)) {
1630e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
1631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        *confidence = 0.1;
1632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1633e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return true;
1634e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
1635e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1636e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return false;
1637e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
1638e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1639e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}  // namespace android
1640e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
1641