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