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