MPEG4Extractor.cpp revision 48c948b1137e7bbdb161b51908657ab72ac5e2da
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MPEG4Extractor" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MPEG4Extractor.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 31dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber#include <media/stagefright/MediaDebug.h> 3218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/SampleTable.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 44693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 45693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 47693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 58693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 62693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 64693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 760024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 770024245e134467d120b40099da16c467dc365e76Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 12418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 12718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 13018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 131371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 13318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 13618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 13918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 142dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 147693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack(NULL) { 15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 165693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 168693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 171693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 174693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 178693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData(size_t index) { 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 197371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 198371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 199371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 200371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset, hdr, 8) < 8) { 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset + 8, &chunk_size, 8) < 8) { 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size <= sizeof(buffer)) { 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset, buffer, chunk_size) < chunk_size) { 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber hexdump(buffer, chunk_size); 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 287dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 299dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= 4); 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(data_offset, &version, 1) < 1) { 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t ctime, mtime, duration; 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t id; 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t width, height; 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 36 + 60) { 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[36 + 60]; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U64_AT(&buffer[4]); 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U64_AT(&buffer[12]); 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[20]); 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U64_AT(&buffer[28]); 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[88]); 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[92]); 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 24 + 60) { 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24 + 60]; 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U32_AT(&buffer[4]); 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U32_AT(&buffer[8]); 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[12]); 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U32_AT(&buffer[20]); 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[76]); 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[80]); 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = new Track; 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->next = NULL; 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mLastTrack) { 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->next = track; 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = track; 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack = track; 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta = new MetaData; 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->timescale = 0; 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->sampleTable = new SampleTable(mDataSource); 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 39620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 39720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 41348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 25) { 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24]; 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(data_offset, buffer, 24) < 24) { 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(&buffer[4]) != 0) { 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // pre_defined should be 0. 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHandlerType = U32_AT(&buffer[8]); 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 452dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 478dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 484371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 50518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type)) 50618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 50718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // AMR audio is always mono. 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 51620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk, num_channels, sample_size, sample_rate); 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 530dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 55120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("*** coding='%s' width=%d height=%d\n", 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk, width, height); 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 572dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 61820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 63720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 63820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 65620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 66620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 69620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 69720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 69820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 70320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 70420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 705693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 708693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 71320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 714693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 71520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 721371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 722371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 723371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 724371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 725693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 72648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 73020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 73448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 735693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 73620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 73720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 73848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 73920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 74320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 74420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 745dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 7460024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 74720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 74820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 749dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 75520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 761dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 764dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 766dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 768dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t max_size; 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->getMaxSampleSize(&max_size); 775dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(err, OK); 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7770024245e134467d120b40099da16c467dc365e76Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 7780024245e134467d120b40099da16c467dc365e76Andreas Huber // each fragment originally prefixed with a 2 byte length will 7790024245e134467d120b40099da16c467dc365e76Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 7800024245e134467d120b40099da16c467dc365e76Andreas Huber // and thus will grow by 2 bytes per fragment. 7810024245e134467d120b40099da16c467dc365e76Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size + 10 * 2)); 7820024245e134467d120b40099da16c467dc365e76Andreas Huber 7830024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 791dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7980024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 7990024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 8000024245e134467d120b40099da16c467dc365e76Andreas Huber 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 816dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->findClosestSample( 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = sampleIndex; 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 83820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8400024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 8410024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 842dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 843dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 844dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 845dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 847dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber status_t err = mSampleTable->getSampleOffsetAndSize( 848dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mCurrentSampleIndex, &offset, &size); 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 850dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 851dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 852dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 854dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts); 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 856dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 857dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 858dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 859dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 860dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 861dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 862dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(mBuffer, NULL); 863dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 864dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 8650024245e134467d120b40099da16c467dc365e76Andreas Huber } 86620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 867dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 868dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 869dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 870dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mDataSource->read_at(offset, (uint8_t *)mBuffer->data(), size); 871dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 872dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 873dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 874dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 875dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 876dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 877dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 878dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 879dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 880dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 88148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 88248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 883dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 884dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 885dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 886dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 887dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 888dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 889dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 890dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 891dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 892dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 893dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 894dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 895dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 896dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mBuffer->range_length() >= 2); 897dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 898dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 899dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 900dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 901dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t nal_size = U16_AT(src); 902dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 903dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mBuffer->range_length() >= 2 + nal_size); 904dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 905dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 906dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber clone->set_range(mBuffer->range_offset() + 2, nal_size); 907dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 908dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 909dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->range_offset() + 2 + nal_size, 910dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->range_length() - 2 - nal_size); 911dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 912dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 913dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 914dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 915dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 916dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 917dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 918dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 919dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 920dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 921dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 922dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 923dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t num_bytes_read = 925dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mDataSource->read_at(offset, mSrcBuffer, size); 92620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 931dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 93220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 934dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 935dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t srcOffset = 0; 936dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t dstOffset = 0; 937dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber while (srcOffset < size) { 938dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(srcOffset + 1 < size); 939dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t nalLength = 940dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (mSrcBuffer[srcOffset] << 8) | mSrcBuffer[srcOffset + 1]; 941dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(srcOffset + 1 + nalLength < size); 942dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += 2; 943dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 944dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (nalLength == 0) { 945dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber continue; 946dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 947dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 948dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 949dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 950dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 951dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 952dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 953dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 1; 954dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 955dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += nalLength; 956dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstOffset += nalLength; 957dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 958dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 959dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, dstOffset); 96020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 96148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 96248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 96320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 972693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool SniffMPEG4( 973693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 97420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 97520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t n = source->read_at(4, header, sizeof(header)); 97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 97820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)) { 98318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 98420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.1; 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 994