MPEG4Extractor.cpp revision 4f5e602e1773a2990bb1f34f09875bd5cd057e5a
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 20e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <arpa/inet.h> 21e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 22e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <ctype.h> 23e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdint.h> 24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdlib.h> 25e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <string.h> 26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/DataSource.h> 28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MPEG4Extractor.h> 29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBuffer.h> 30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber#include <media/stagefright/MediaDebug.h> 32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaSource.h> 33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h> 34e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/SampleTable.h> 35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/Utils.h> 36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/String8.h> 37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 38e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android { 39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberclass MPEG4Source : public MediaSource { 41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberpublic: 42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 43be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber MPEG4Source(const sp<MetaData> &format, 44be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &dataSource, 45be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<SampleTable> &sampleTable); 46e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 47e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t start(MetaData *params = NULL); 48e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t stop(); 49e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual sp<MetaData> getFormat(); 51e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber virtual status_t read( 53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 55be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberprotected: 56be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber virtual ~MPEG4Source(); 57be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber 58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberprivate: 59e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber sp<MetaData> mFormat; 60be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber sp<DataSource> mDataSource; 61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t mTimescale; 62be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber sp<SampleTable> mSampleTable; 63e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t mCurrentSampleIndex; 64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool mIsAVC; 66e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool mStarted; 67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBufferGroup *mGroup; 69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer *mBuffer; 71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool mWantsNALFragments; 73e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 748a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber uint8_t *mSrcBuffer; 758a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MPEG4Source(const MPEG4Source &); 77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}; 79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 80e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void hexdump(const void *_data, size_t size) { 81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const uint8_t *data = (const uint8_t *)_data; 82e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t offset = 0; 83e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (offset < size) { 84e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("0x%04x ", offset); 85e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t n = size - offset; 87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n > 16) { 88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber n = 16; 89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 91e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (size_t i = 0; i < 16; ++i) { 92e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (i == 8) { 93e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 94e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 95e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (offset + i < size) { 97e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%02x ", data[offset + i]); 98e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 99e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 101e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 103e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (size_t i = 0; i < n; ++i) { 106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (isprint(data[offset + i])) { 107e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%c", data[offset + i]); 108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("."); 110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("\n"); 114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber offset += 16; 116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic const char *const FourCC2MIME(uint32_t fourcc) { 120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch (fourcc) { 121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 122e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return "audio/mp4a-latm"; 123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return "audio/3gpp"; 126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return "video/mp4v-es"; 129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 130e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return "video/3gpp"; 132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return "video/avc"; 135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 1374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!"should not be here."); 138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 142be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mDataSource(source), 144e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHaveMetadata(false), 145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack(NULL), 146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack(NULL) { 147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 149e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 150e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (track) { 152e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *next = track->next; 153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete track; 155e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = next; 156e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack = mLastTrack = NULL; 158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 160be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MPEG4Extractor::countTracks() { 161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 163be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return 0; 164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 166be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber size_t n = 0; 167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (track) { 169be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber ++n; 170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 171e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 172e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 173be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return n; 174e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 175e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 176be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData(size_t index) { 177e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 178e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 179e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 180e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 181e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 182e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 183e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 184e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 185e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 186e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 187e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 188e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 189e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 190e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 191e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return track->meta; 193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 194e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 195e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHaveMetadata) { 197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 199e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 200e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t offset = 0; 201e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 202e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 203e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 204e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 205e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHaveMetadata) { 206e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 207e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 208e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 209e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 210e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 211e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 212e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 213e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[0] = x >> 24; 214e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[1] = (x >> 16) & 0xff; 215e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[2] = (x >> 8) & 0xff; 216e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[3] = x & 0xff; 217e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[4] = '\0'; 218e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 219e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 220e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 221e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t hdr[2]; 222e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(*offset, hdr, 8) < 8) { 223e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 224e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 226e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 227e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t data_offset = *offset + 8; 228e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 229e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_size == 1) { 230e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(*offset + 8, &chunk_size, 8) < 8) { 231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 233e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_size = ntoh64(chunk_size); 234e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset += 8; 235e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 236e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 237e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char chunk[5]; 238e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MakeFourCCString(chunk_type, chunk); 239e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 240e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#if 0 241e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber static const char kWhitespace[] = " "; 242e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 243e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 244e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 245e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 246e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_size <= sizeof(buffer)) { 247e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(*offset, buffer, chunk_size) < chunk_size) { 248e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 249e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 250e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 251e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber hexdump(buffer, chunk_size); 252e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 253e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#endif 254e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 256e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch(chunk_type) { 258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 259e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 261e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 262e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 263e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'b', 'l'): 264e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 266e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 267e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 269e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 270e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset; 272e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 274e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 275e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 2784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 280e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 281e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHaveMetadata = true; 282e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 283e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 284e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 285e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 286e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 287e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 288e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 289e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 2904f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(chunk_data_size >= 4); 291e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 292e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 293e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(data_offset, &version, 1) < 1) { 294e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 295e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 296e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 297e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint64_t ctime, mtime, duration; 298e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t id; 299e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t width, height; 300e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 301e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 302e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size != 36 + 60) { 303e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 304e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 305e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 306e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[36 + 60]; 307e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 308e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 310e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ctime = U64_AT(&buffer[4]); 313e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mtime = U64_AT(&buffer[12]); 314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber id = U32_AT(&buffer[20]); 315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = U64_AT(&buffer[28]); 316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber width = U32_AT(&buffer[88]); 317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber height = U32_AT(&buffer[92]); 318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size != 24 + 60) { 320e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 321e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 322e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 323e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[24 + 60]; 324e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 325e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 327e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 328e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ctime = U32_AT(&buffer[4]); 329e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mtime = U32_AT(&buffer[8]); 330e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber id = U32_AT(&buffer[12]); 331e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = U32_AT(&buffer[20]); 332e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber width = U32_AT(&buffer[76]); 333e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber height = U32_AT(&buffer[80]); 334e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 335e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 336e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = new Track; 337e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->next = NULL; 338e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mLastTrack) { 339e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->next = track; 340e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 341e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack = track; 342e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 343e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack = track; 344e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 345e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->meta = new MetaData; 346e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->timescale = 0; 347e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->sampleTable = new SampleTable(mDataSource); 348e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 349e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 350e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 351e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 354e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 355e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 359e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 360e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 361e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 362e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, &version, sizeof(version)) 363e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(version)) { 364e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 365e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 366e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t timescale_offset; 368e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 369e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 16; 371e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 372e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 8; 373e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 374e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 375e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 376e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 377e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t timescale; 378e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 379e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 380e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(timescale)) { 381e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 382e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 383e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 384e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->timescale = ntohl(timescale); 385e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyTimeScale, mLastTrack->timescale); 386e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 387e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t duration; 388e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 390e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 391e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration)) { 392e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 393e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 394e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntoh64(duration); 395e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 396e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t duration32; 397e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 398e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 399e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration32)) { 400e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 401e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 402e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntohl(duration32); 403e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 404e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyDuration, duration); 405e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 406e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 407e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 409e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 410e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 411e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 412e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 25) { 413e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 414e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 415e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[24]; 417e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(data_offset, buffer, 24) < 24) { 418e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 419e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 420e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 421e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 426e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(&buffer[4]) != 0) { 427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // pre_defined should be 0. 428e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 429e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 430e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 431e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHandlerType = U32_AT(&buffer[8]); 432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 434e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 435e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'd'): 437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 8) { 439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 440e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 441e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8]; 4434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 444e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 445e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, 8) < 8) { 446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 451e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 452e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 453e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 454e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 455e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 456e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (entry_count > 1) { 457e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // For now we only support a single type of media per track. 458e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_UNSUPPORTED; 459e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 460e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 461e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 462e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + 8; 463e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 465e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 466e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 467e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 468e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 4694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 470e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 471e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 472e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 473e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 474e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 475e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 476e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 477e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 478e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 479e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 480e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8 + 20]; 481e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 482e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic AudioSampleEntry size. 483e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 484e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 486e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 487e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 488e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 489e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 490e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 491e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 492e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 494e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (!strcasecmp("audio/3gpp", FourCC2MIME(chunk_type))) { 495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // AMR audio is always mono. 496e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber num_channels = 1; 497e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 498e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 499e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 500e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 501e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 502e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 503e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk, num_channels, sample_size, sample_rate); 504e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 505e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 506e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 507e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 508e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 509e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 510e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 511e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 512e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 513e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 514e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 515e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 516e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 5174f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 518e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 519e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 520e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 522e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 523e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 524e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 525e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 526e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 527e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 528e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 529e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[78]; 530e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 531e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic VideoSampleEntry size. 532e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 533e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 534e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 535e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 536e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 537e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 538e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 540e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 541e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 543e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("*** coding='%s' width=%d height=%d\n", 545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk, width, height); 546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 547e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 548e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 549e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 550e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 551e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 552e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 553e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 554e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 555e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 556e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 5594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 560e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 561e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 563e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'c', 'o'): 564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('c', 'o', '6', '4'): 565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 567e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 569e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 573e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 574e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 575e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 577e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 578e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'c'): 579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 581e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 582e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 583e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 584e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 586e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 587e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 588e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 589e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 590e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 591e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'z'): 593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'z', '2'): 594e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 598e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 600e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 603e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 't', 's'): 608e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 617e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 618e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 619e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 620e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 621e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 's'): 622e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 623e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 624e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 626e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 628e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 629e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 630e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 633e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 634e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 635e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('e', 's', 'd', 's'): 636e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 637e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 638e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 639e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 640e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 641e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[256]; 642e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 643e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 644e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 645e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 654e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 657e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 659e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 661e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 662e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 663e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 664e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 665e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 666e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 667e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 668e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 669e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 670e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 673e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 674e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 675e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 681e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 682e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 683e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 684e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 687e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 689e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 690e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 692be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 693e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 694e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 695be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 696e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 697e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 698e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 699e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 701be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 705e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 708be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return new MPEG4Source( 709e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->meta, mDataSource, track->sampleTable); 710e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber//////////////////////////////////////////////////////////////////////////////// 713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 714e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::MPEG4Source( 715e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const sp<MetaData> &format, 716be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &dataSource, 717be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<SampleTable> &sampleTable) 718e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mFormat(format), 719e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mDataSource(dataSource), 720e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mTimescale(0), 721e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSampleTable(sampleTable), 722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex(0), 723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mIsAVC(false), 724e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted(false), 725e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup(NULL), 726e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer(NULL), 7274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments(false), 7288a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer(NULL) { 729e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *mime; 730e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 7314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(success); 732e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 733e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber success = mFormat->findInt32(kKeyTimeScale, &mTimescale); 7344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(success); 735e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 736e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mIsAVC = !strcasecmp(mime, "video/avc"); 737e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 738e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 739e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::~MPEG4Source() { 740e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mStarted) { 741e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber stop(); 742e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 743e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 744e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 745e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 7464f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!mStarted); 747e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 748e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t val; 7494f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 750e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber && val != 0) { 7514f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = true; 752e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 7534f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = false; 754e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 755e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 756e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = new MediaBufferGroup; 757e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 758e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t max_size; 759e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = mSampleTable->getMaxSampleSize(&max_size); 7604f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(err, OK); 761e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7628a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 7638a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber // each fragment originally prefixed with a 2 byte length will 7648a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 7658a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber // and thus will grow by 2 bytes per fragment. 7668a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size + 10 * 2)); 7678a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 7688a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = new uint8_t[max_size]; 769e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 770e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = true; 771e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 772e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 773e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 774e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 775e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::stop() { 7764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 777e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 778e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 779e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 780e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 781e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 782e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7838a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber delete[] mSrcBuffer; 7848a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = NULL; 7858a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 786e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete mGroup; 787e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = NULL; 788e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 789e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = false; 790e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex = 0; 791e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 792e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 793e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 794e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 795e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 796e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return mFormat; 797e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 798e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 799e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::read( 800e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer **out, const ReadOptions *options) { 8014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 802e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 803e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = NULL; 804e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 805e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t seekTimeUs; 806e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 807e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t sampleIndex; 808e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = mSampleTable->findClosestSample( 809e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber seekTimeUs * mTimescale / 1000000, 810e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 811e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 812e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 813e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 814e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 815e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 816e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex = sampleIndex; 817e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 818e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 819e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 820e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 821e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 822e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // fall through 823e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 824e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8258a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber off_t offset; 8268a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber size_t size; 8274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber uint32_t dts; 8284f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool newBuffer = false; 8294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer == NULL) { 8304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber newBuffer = true; 831e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8324f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber status_t err = mSampleTable->getSampleOffsetAndSize( 8334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mCurrentSampleIndex, &offset, &size); 834e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8354f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 8364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 8374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 838e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts); 840e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8414f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 8424f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 8434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 8444f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8454f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber err = mGroup->acquire_buffer(&mBuffer); 8464f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 8474f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(mBuffer, NULL); 8484f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 8494f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 8508a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber } 851e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8524f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC || mWantsNALFragments) { 8534f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (newBuffer) { 8544f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ssize_t num_bytes_read = 8554f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mDataSource->read_at(offset, (uint8_t *)mBuffer->data(), size); 8564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8574f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (num_bytes_read < (ssize_t)size) { 8584f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 8594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 8604f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8614f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 8624f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 8634f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8644f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, size); 8654f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->meta_data()->clear(); 8664f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->meta_data()->setInt32(kKeyTimeUnits, dts); 8674f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->meta_data()->setInt32(kKeyTimeScale, mTimescale); 8684f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ++mCurrentSampleIndex; 8694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 8704f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8714f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC) { 8724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = mBuffer; 8734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 8744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8754f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 8764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 8774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Each NAL unit is split up into its constituent fragments and 8794f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // each one of them returned in its own buffer. 8804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8814f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mBuffer->range_length() >= 2); 8824f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber const uint8_t *src = 8844f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 8854f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8864f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t nal_size = U16_AT(src); 8874f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8884f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mBuffer->range_length() >= 2 + nal_size); 8894f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8904f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber MediaBuffer *clone = mBuffer->clone(); 8914f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber clone->set_range(mBuffer->range_offset() + 2, nal_size); 8924f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8934f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range( 8944f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->range_offset() + 2 + nal_size, 8954f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->range_length() - 2 - nal_size); 8964f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8974f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer->range_length() == 0) { 8984f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 8994f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 9004f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9024f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = clone; 9034f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9044f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 9054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } else { 9064f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Whole NAL units are returned but each fragment is prefixed by 9074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // the start code (0x00 00 00 01). 9084f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 909e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t num_bytes_read = 9104f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mDataSource->read_at(offset, mSrcBuffer, size); 911e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 912e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (num_bytes_read < (ssize_t)size) { 913e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 914e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 915e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9164f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 917e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 918e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9194f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 9204f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t srcOffset = 0; 9214f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t dstOffset = 0; 9224f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber while (srcOffset < size) { 9234f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(srcOffset + 1 < size); 9244f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t nalLength = 9254f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber (mSrcBuffer[srcOffset] << 8) | mSrcBuffer[srcOffset + 1]; 9264f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(srcOffset + 1 + nalLength < size); 9274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber srcOffset += 2; 9284f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (nalLength == 0) { 9304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber continue; 9314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9324f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 9344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9354f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 9364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 9374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 9384f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 1; 9394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 9404f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber srcOffset += nalLength; 9414f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstOffset += nalLength; 9424f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9444f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, dstOffset); 945e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->meta_data()->clear(); 946e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->meta_data()->setInt32(kKeyTimeUnits, dts); 947e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->meta_data()->setInt32(kKeyTimeScale, mTimescale); 948e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++mCurrentSampleIndex; 949e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 950e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = mBuffer; 951e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 952e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 953e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 954e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 955e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 956e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 957be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberbool SniffMPEG4( 958be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 959e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t header[8]; 960e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 961e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t n = source->read_at(4, header, sizeof(header)); 962e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < (ssize_t)sizeof(header)) { 963e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 964e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 965e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 966e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 967e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)) { 968e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *mimeType = "video/mp4"; 969e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *confidence = 0.1; 970e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 971e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return true; 972e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 973e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 974e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 975e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 976e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 977e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} // namespace android 978e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 979