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