MPEG4Extractor.cpp revision 57515f334bcc1f66f95e342bfcaa13bf9ca802ad
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; 69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool mStarted; 70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBufferGroup *mGroup; 72e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 73e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer *mBuffer; 74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 754f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool mWantsNALFragments; 76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 778a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber uint8_t *mSrcBuffer; 788a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MPEG4Source(const MPEG4Source &); 80e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}; 82e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 83e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void hexdump(const void *_data, size_t size) { 84e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const uint8_t *data = (const uint8_t *)_data; 85e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t offset = 0; 86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (offset < size) { 87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("0x%04x ", offset); 88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t n = size - offset; 90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n > 16) { 91e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber n = 16; 92e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 93e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 94e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (size_t i = 0; i < 16; ++i) { 95e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (i == 8) { 96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 97e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 98e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 99e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (offset + i < size) { 100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%02x ", data[offset + i]); 101e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 103e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf(" "); 107e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (size_t i = 0; i < n; ++i) { 109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (isprint(data[offset + i])) { 110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%c", data[offset + i]); 111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("."); 113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 114e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("\n"); 117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber offset += 16; 119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 122e6c409632f773e41f33188272a0072be9fcb783fAndreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch (fourcc) { 124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 125e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 128e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 129e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1302a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber case FOURCC('s', 'a', 'w', 'b'): 131e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 1322a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 134e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 137e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 140e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 1434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!"should not be here."); 144e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 148be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 149e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mDataSource(source), 150e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHaveMetadata(false), 151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack(NULL), 152e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack(NULL) { 153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 155e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 156e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (track) { 158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *next = track->next; 159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 160e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete track; 161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = next; 162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack = mLastTrack = NULL; 164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 166be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersize_t MPEG4Extractor::countTracks() { 167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 169be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return 0; 170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 171e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 172be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber size_t n = 0; 173e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 174e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (track) { 175be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber ++n; 176e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 177e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 178e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 179be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return n; 180e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 181e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 182e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 183e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber size_t index, uint32_t flags) { 184e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 185e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 186e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 187e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 188e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 189e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 190e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 191e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 192e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return NULL; 193e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 194e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 195e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 196e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 197e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 198e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1992a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber if (track == NULL) { 2002a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber return NULL; 2012a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber } 2022a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 203e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if ((flags & kIncludeExtensiveMetaData) 204e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber && !track->includes_expensive_metadata) { 205e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber track->includes_expensive_metadata = true; 206e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber 207e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber const char *mime; 208e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 209e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if (!strncasecmp("video/", mime, 6)) { 210e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber uint32_t sampleIndex; 211e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber uint32_t sampleTime; 212e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 213e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber && track->sampleTable->getDecodingTime( 214e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber sampleIndex, &sampleTime) == OK) { 215e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber track->meta->setInt64( 216e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber kKeyThumbnailTime, 217e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 218e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 219e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 220e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber } 221e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber 222e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return track->meta; 223e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 224e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 225e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 226e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHaveMetadata) { 227e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 228e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 229e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 230e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t offset = 0; 231e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 232e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 233e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 234e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 235e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHaveMetadata) { 236e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 237e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 238e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 239e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 240e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 241e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 242e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 243e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[0] = x >> 24; 244e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[1] = (x >> 16) & 0xff; 245e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[2] = (x >> 8) & 0xff; 246e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[3] = x & 0xff; 247e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber s[4] = '\0'; 248e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 249e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 250e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 251e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t hdr[2]; 252e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(*offset, hdr, 8) < 8) { 253e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 254e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 255e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 256e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 257e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t data_offset = *offset + 8; 258e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 259e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_size == 1) { 260e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(*offset + 8, &chunk_size, 8) < 8) { 261e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 262e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 263e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_size = ntoh64(chunk_size); 264e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset += 8; 265e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 266e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 267e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char chunk[5]; 268e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MakeFourCCString(chunk_type, chunk); 269e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 270e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#if 0 271e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber static const char kWhitespace[] = " "; 272e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 273e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 274e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 275e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 276e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_size <= sizeof(buffer)) { 277e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(*offset, buffer, chunk_size) < chunk_size) { 278e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 279e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 280e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 281e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber hexdump(buffer, chunk_size); 282e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 283e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#endif 284e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 285e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 286e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 287e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber switch(chunk_type) { 288e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 289e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 290e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 291e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 292e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 293e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'b', 'l'): 294e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 295e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 296e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 297e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 298e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 299e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 300e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 301e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset; 302e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 303e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 304e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 305e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 306e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 307e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 3084f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 309e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 310e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 311e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHaveMetadata = true; 312e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 313e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 314e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 315e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 316e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 317e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 318e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 319e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 3204f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(chunk_data_size >= 4); 321e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 322e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 323e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(data_offset, &version, 1) < 1) { 324e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 325e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 326e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 327e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint64_t ctime, mtime, duration; 328e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t id; 329e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t width, height; 330e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 331e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 332e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size != 36 + 60) { 333e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 334e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 335e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 336e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[36 + 60]; 337e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 338e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 339e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 340e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 341e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 342e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ctime = U64_AT(&buffer[4]); 343e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mtime = U64_AT(&buffer[12]); 344e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber id = U32_AT(&buffer[20]); 345e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = U64_AT(&buffer[28]); 346e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber width = U32_AT(&buffer[88]); 347e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber height = U32_AT(&buffer[92]); 348e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 349e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size != 24 + 60) { 350e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 351e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 352e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 353e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[24 + 60]; 354e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 355e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 356e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 357e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 358e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ctime = U32_AT(&buffer[4]); 359e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mtime = U32_AT(&buffer[8]); 360e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber id = U32_AT(&buffer[12]); 361e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = U32_AT(&buffer[20]); 362e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber width = U32_AT(&buffer[76]); 363e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber height = U32_AT(&buffer[80]); 364e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 365e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 366e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = new Track; 367e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->next = NULL; 368e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mLastTrack) { 369e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->next = track; 370e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 371e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mFirstTrack = track; 372e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 373e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack = track; 374e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 375e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->meta = new MetaData; 376e981c33446a98d5ccc0d73c1a840696d77cf0732Andreas Huber track->includes_expensive_metadata = false; 377e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->timescale = 0; 378e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->sampleTable = new SampleTable(mDataSource); 379e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 380e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 381e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 382e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 383e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 384e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 385e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 386e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 387e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 388e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 389e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 390e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 391e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t version; 392e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 393e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, &version, sizeof(version)) 394e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(version)) { 395e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 396e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 397e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 398e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t timescale_offset; 399e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 400e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 401e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 16; 402e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else if (version == 0) { 403e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset = data_offset + 4 + 8; 404e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 405e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 406e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 407e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 408e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t timescale; 409e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 410e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 411e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(timescale)) { 412e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 413e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 414e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 415e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->timescale = ntohl(timescale); 416e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 417e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t duration; 418e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (version == 1) { 419e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 420e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 421e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration)) { 422e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 423e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 424e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntoh64(duration); 425e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 426e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t duration32; 427e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 428e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 429e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber < (ssize_t)sizeof(duration32)) { 430e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 431e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 432e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber duration = ntohl(duration32); 433e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 434fa8de752507feaca695123911915070c1ce463b2Andreas Huber mLastTrack->meta->setInt64( 435fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 436e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 437e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 438e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 439e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 440e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 441e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 442e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 443e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 25) { 444e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 445e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 446e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 447e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[24]; 448e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at(data_offset, buffer, 24) < 24) { 449e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 450e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 451e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 452e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 453e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 454e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 455e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 456e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 457e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(&buffer[4]) != 0) { 458e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // pre_defined should be 0. 459e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 460e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 461e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 462e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mHandlerType = U32_AT(&buffer[8]); 463e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 464e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 465e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 466e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 467e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'd'): 468e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 469e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 8) { 470e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 471e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 472e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 473e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8]; 4744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 475e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 476e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, 8) < 8) { 477e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 478e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 479e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 480e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 481e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 482e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 483e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 484e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 485e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 486e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 487e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (entry_count > 1) { 488e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // For now we only support a single type of media per track. 489e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_UNSUPPORTED; 490e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 491e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 492e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 493e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + 8; 494e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 495e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 496e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 497e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 498e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 499e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 5004f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 501e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 502e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 503e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 504e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'a'): 505e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 5062a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber case FOURCC('s', 'a', 'w', 'b'): 507e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 508e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 509e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 510e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 511e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 512e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[8 + 20]; 513e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 514e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic AudioSampleEntry size. 515e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 516e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 517e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 518e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 519e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 520e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 521e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 522e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 523e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 524e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 525e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 526e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 527e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber FourCC2MIME(chunk_type)) 528e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 529e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber FourCC2MIME(chunk_type))) { 530e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // AMR audio is always mono. 531e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber num_channels = 1; 532e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 533e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 534e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 535e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 536e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 537e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 538e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk, num_channels, sample_size, sample_rate); 539e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 540e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 541e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 542e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 543e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 544e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 545e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 546e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 547e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 548e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 549e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 550e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 551e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 5524f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 553e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 554e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 555e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 556e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('m', 'p', '4', 'v'): 557e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', '2', '6', '3'): 558e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', '1'): 559e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 560e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 561e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 562e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 563e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 564e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[78]; 565e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 566e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Basic VideoSampleEntry size. 567e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 568e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 569e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 570e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 571e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 572e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 573e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 574e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 575e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 576e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 577e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 578e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 579e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber printf("*** coding='%s' width=%d height=%d\n", 580e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk, width, height); 581e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 582e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 583e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 584e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 585e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 586e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber off_t stop_offset = *offset + chunk_size; 587e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset = data_offset + sizeof(buffer); 588e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (*offset < stop_offset) { 589e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = parseChunk(offset, depth + 1); 590e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 591e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 592e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 593e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 5944f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(*offset, stop_offset); 595e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 596e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 597e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 598e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'c', 'o'): 599e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('c', 'o', '6', '4'): 600e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 601e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 602e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 603e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 604e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 605e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 606e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 607e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 608e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 609e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 610e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 611e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 612e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 613e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'c'): 614e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 615e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 616e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 617e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 618e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 619e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 620e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 621e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 622e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 623e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 624e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 625e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 626e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 627e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 'z'): 628e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 'z', '2'): 629e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 630e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 631e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 632e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber chunk_type, data_offset, chunk_data_size); 633e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 634e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 635e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 636e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 637e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 638e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 639e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 640e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 641e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 642e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 't', 's'): 643e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 644e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 645e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 646e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 647e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 648e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 649e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 650e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 651e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 652e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 653e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 654e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 655e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 656e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('s', 't', 's', 's'): 657e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 658e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = 659e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 660e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, chunk_data_size); 661e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 662e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 663e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 664e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 665e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 666e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 667e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 668e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 669e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 670e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('e', 's', 'd', 's'): 671e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 672e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size < 4) { 673e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 674e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 675e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 676e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t buffer[256]; 677e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 678e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 679e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 680e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 681e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 682e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 683e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 684e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 685e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 686e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (U32_AT(buffer) != 0) { 687e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // Should be version 0, flags 0. 688e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_MALFORMED; 689e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 690e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 691e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 692e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 693e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 694e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 695e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 696e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 697e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 698e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 699e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 700e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber char buffer[256]; 701e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 702e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_BUFFER_TOO_SMALL; 703e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 704e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 705e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mDataSource->read_at( 706e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 707e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return ERROR_IO; 708e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 709e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 710e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mLastTrack->meta->setData( 711e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 712e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 713e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 714e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 715e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 716e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 717e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber default: 718e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber { 719e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *offset += chunk_size; 720e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber break; 721e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 722e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 723e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 724e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 725e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 726e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 727be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 728e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err; 729e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if ((err = readMetaData()) != OK) { 730be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 731e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 732e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 733e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber Track *track = mFirstTrack; 734e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber while (index > 0) { 735e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (track == NULL) { 736be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return NULL; 737e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 738e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 739e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber track = track->next; 740e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber --index; 741e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 742e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7432a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber if (track == NULL) { 7442a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber return NULL; 7452a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber } 7462a651177be1d29e8b4bdc84c84060514b15350f0Andreas Huber 747be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber return new MPEG4Source( 748fa8de752507feaca695123911915070c1ce463b2Andreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 749e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 750e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 751e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber//////////////////////////////////////////////////////////////////////////////// 752e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 753e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::MPEG4Source( 754e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const sp<MetaData> &format, 755be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &dataSource, 756fa8de752507feaca695123911915070c1ce463b2Andreas Huber int32_t timeScale, 757be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<SampleTable> &sampleTable) 758e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber : mFormat(format), 759e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mDataSource(dataSource), 760fa8de752507feaca695123911915070c1ce463b2Andreas Huber mTimescale(timeScale), 761e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mSampleTable(sampleTable), 762e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex(0), 763e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mIsAVC(false), 764e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted(false), 765e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup(NULL), 766e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer(NULL), 7674f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments(false), 7688a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer(NULL) { 769e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber const char *mime; 770e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 7714f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(success); 772e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 773e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 774e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 775e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 776e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMPEG4Source::~MPEG4Source() { 777e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mStarted) { 778e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber stop(); 779e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 780e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 781e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 782e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 7834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(!mStarted); 784e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 785e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int32_t val; 7864f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 787e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber && val != 0) { 7884f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = true; 789e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } else { 7904f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mWantsNALFragments = false; 791e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 792e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 793e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = new MediaBufferGroup; 794e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 795e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber size_t max_size; 796e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = mSampleTable->getMaxSampleSize(&max_size); 7974f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(err, OK); 798e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 7998a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 8008a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber // each fragment originally prefixed with a 2 byte length will 8018a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 8028a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber // and thus will grow by 2 bytes per fragment. 8038a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size + 10 * 2)); 8048a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 8058a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = new uint8_t[max_size]; 806e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 807e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = true; 808e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 809e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 810e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 811e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 812e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::stop() { 8134f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 814e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 815e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 816e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 817e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 818e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 819e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8208a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber delete[] mSrcBuffer; 8218a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber mSrcBuffer = NULL; 8228a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber 823e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber delete mGroup; 824e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mGroup = NULL; 825e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 826e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mStarted = false; 827e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex = 0; 828e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 829e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 830e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 831e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 832e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 833e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return mFormat; 834e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 835e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 836e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatus_t MPEG4Source::read( 837e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber MediaBuffer **out, const ReadOptions *options) { 8384f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mStarted); 839e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 840e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = NULL; 841e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 842e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber int64_t seekTimeUs; 843e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 844e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint32_t sampleIndex; 845e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber status_t err = mSampleTable->findClosestSample( 846e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber seekTimeUs * mTimescale / 1000000, 847e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 848e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 849e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (err != OK) { 850e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return err; 851e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 852e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 853e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mCurrentSampleIndex = sampleIndex; 854e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (mBuffer != NULL) { 855e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 856e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 857e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 858e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 859e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber // fall through 860e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 861e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8628a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber off_t offset; 8638a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber size_t size; 8644f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber uint32_t dts; 8654f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber bool newBuffer = false; 8664f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer == NULL) { 8674f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber newBuffer = true; 868e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber status_t err = mSampleTable->getSampleOffsetAndSize( 8704f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mCurrentSampleIndex, &offset, &size); 871e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 8734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 8744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 875e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts); 877e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 8794f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 8804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 8814f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8824f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber err = mGroup->acquire_buffer(&mBuffer); 8834f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (err != OK) { 8844f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK_EQ(mBuffer, NULL); 8854f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return err; 8864f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 8878a432776d003247c12222d8dd6a30ea4621aa2d0Andreas Huber } 888e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 8894f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC || mWantsNALFragments) { 8904f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (newBuffer) { 8914f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ssize_t num_bytes_read = 8924f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mDataSource->read_at(offset, (uint8_t *)mBuffer->data(), size); 8934f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8944f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (num_bytes_read < (ssize_t)size) { 8954f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 8964f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 8974f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 8984f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 8994f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9004f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9014f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, size); 9024f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->meta_data()->clear(); 903fa8de752507feaca695123911915070c1ce463b2Andreas Huber mBuffer->meta_data()->setInt64( 904fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 9054f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber ++mCurrentSampleIndex; 9064f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9074f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9084f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (!mIsAVC) { 9094f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = mBuffer; 9104f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 9114f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9124f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 9134f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9144f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9154f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Each NAL unit is split up into its constituent fragments and 9164f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // each one of them returned in its own buffer. 9174f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9184f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mBuffer->range_length() >= 2); 9194f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9204f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber const uint8_t *src = 9214f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 9224f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9234f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t nal_size = U16_AT(src); 9244f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9254f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(mBuffer->range_length() >= 2 + nal_size); 9264f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9274f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber MediaBuffer *clone = mBuffer->clone(); 9284f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber clone->set_range(mBuffer->range_offset() + 2, nal_size); 9294f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9304f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range( 9314f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->range_offset() + 2 + nal_size, 9324f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->range_length() - 2 - nal_size); 9334f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9344f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (mBuffer->range_length() == 0) { 9354f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->release(); 9364f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer = NULL; 9374f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9384f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9394f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber *out = clone; 9404f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9414f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return OK; 9424f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } else { 9434f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // Whole NAL units are returned but each fragment is prefixed by 9444f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber // the start code (0x00 00 00 01). 9454f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 946e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t num_bytes_read = 9474f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mDataSource->read_at(offset, mSrcBuffer, size); 948e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 949e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (num_bytes_read < (ssize_t)size) { 950e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->release(); 951e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 952e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9534f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber return ERROR_IO; 954e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 955e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 9564f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 9574f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t srcOffset = 0; 9584f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t dstOffset = 0; 9594f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber while (srcOffset < size) { 9604f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(srcOffset + 1 < size); 9614f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber size_t nalLength = 9624f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber (mSrcBuffer[srcOffset] << 8) | mSrcBuffer[srcOffset + 1]; 9634f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(srcOffset + 1 + nalLength < size); 9644f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber srcOffset += 2; 9654f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9664f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber if (nalLength == 0) { 9674f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber continue; 9684f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9694f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9704f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 9714f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9724f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 9734f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 9744f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 0; 9754f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstData[dstOffset++] = 1; 9764f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 9774f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber srcOffset += nalLength; 9784f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber dstOffset += nalLength; 9794f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber } 9804f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber 9814f5e602e1773a2990bb1f34f09875bd5cd057e5aAndreas Huber mBuffer->set_range(0, dstOffset); 982e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer->meta_data()->clear(); 983fa8de752507feaca695123911915070c1ce463b2Andreas Huber mBuffer->meta_data()->setInt64( 984fa8de752507feaca695123911915070c1ce463b2Andreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 985e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ++mCurrentSampleIndex; 986e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 987e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *out = mBuffer; 988e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber mBuffer = NULL; 989e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 990e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return OK; 991e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 992e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 993e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 994be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huberbool SniffMPEG4( 995be06d26cdc70070654f1eedcd08c1c68cd587ad6Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 996e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber uint8_t header[8]; 997e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 998e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber ssize_t n = source->read_at(4, header, sizeof(header)); 999e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (n < (ssize_t)sizeof(header)) { 1000e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 1001e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1002e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1003e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 1004e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)) { 1005e6c409632f773e41f33188272a0072be9fcb783fAndreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 1006e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *confidence = 0.1; 1007e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1008e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return true; 1009e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber } 1010e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1011e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber return false; 1012e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} 1013e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1014e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber} // namespace android 1015e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber 1016