MPEG4Extractor.cpp revision 18291bc20e55e8f3fd5feb786771a8ed32c19c59
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, 46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 57693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 58693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 61693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 63693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 750024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 760024245e134467d120b40099da16c467dc365e76Andreas Huber 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 12318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 12618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 12918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 130371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 13218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 13518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 13818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 141dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 146693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack(NULL) { 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 164693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 167693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 170693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 173693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 177693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 180693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData(size_t index) { 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 196371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 197371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 198371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 199371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset, hdr, 8) < 8) { 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset + 8, &chunk_size, 8) < 8) { 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size <= sizeof(buffer)) { 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset, buffer, chunk_size) < chunk_size) { 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber hexdump(buffer, chunk_size); 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 286dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 298dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= 4); 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(data_offset, &version, 1) < 1) { 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t ctime, mtime, duration; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t id; 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t width, height; 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 36 + 60) { 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[36 + 60]; 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U64_AT(&buffer[4]); 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U64_AT(&buffer[12]); 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[20]); 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U64_AT(&buffer[28]); 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[88]); 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[92]); 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 24 + 60) { 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24 + 60]; 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U32_AT(&buffer[4]); 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U32_AT(&buffer[8]); 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[12]); 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U32_AT(&buffer[20]); 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[76]); 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[80]); 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = new Track; 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->next = NULL; 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mLastTrack) { 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->next = track; 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = track; 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack = track; 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta = new MetaData; 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->timescale = 0; 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->sampleTable = new SampleTable(mDataSource); 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyTimeScale, mLastTrack->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 } 41220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyDuration, duration); 41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 25) { 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24]; 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(data_offset, buffer, 24) < 24) { 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(&buffer[4]) != 0) { 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // pre_defined should be 0. 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHandlerType = U32_AT(&buffer[8]); 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 451dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 477dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 483371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 50418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type)) 50518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 50618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // AMR audio is always mono. 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk, num_channels, sample_size, sample_rate); 51620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 529dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("*** coding='%s' width=%d height=%d\n", 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk, width, height); 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 571dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 63720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 63820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 65620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 66620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 69520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 69620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 69720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 69820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 70320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 704693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 707693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 713693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 71420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 720371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 721371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 722371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 723371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 724693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta, mDataSource, track->sampleTable); 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 732693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 733693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 73420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 73520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 73620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimescale(0), 73720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 73820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 73920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 743dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 7440024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 74620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 747dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 74820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber success = mFormat->findInt32(kKeyTimeScale, &mTimescale); 750dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 76020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 762dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 765dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 767dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 769dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t max_size; 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->getMaxSampleSize(&max_size); 776dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(err, OK); 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7780024245e134467d120b40099da16c467dc365e76Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 7790024245e134467d120b40099da16c467dc365e76Andreas Huber // each fragment originally prefixed with a 2 byte length will 7800024245e134467d120b40099da16c467dc365e76Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 7810024245e134467d120b40099da16c467dc365e76Andreas Huber // and thus will grow by 2 bytes per fragment. 7820024245e134467d120b40099da16c467dc365e76Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size + 10 * 2)); 7830024245e134467d120b40099da16c467dc365e76Andreas Huber 7840024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 792dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7990024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 8000024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 8010024245e134467d120b40099da16c467dc365e76Andreas Huber 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 81320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 817dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 82020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->findClosestSample( 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = sampleIndex; 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8410024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 8420024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 843dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 844dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 845dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 846dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 848dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber status_t err = mSampleTable->getSampleOffsetAndSize( 849dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mCurrentSampleIndex, &offset, &size); 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 851dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 852dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 853dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 855dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts); 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 857dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 858dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 859dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 860dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 861dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 862dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 863dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(mBuffer, NULL); 864dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 865dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 8660024245e134467d120b40099da16c467dc365e76Andreas Huber } 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 868dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 869dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 870dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 871dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mDataSource->read_at(offset, (uint8_t *)mBuffer->data(), size); 872dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 873dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 874dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 875dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 876dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 877dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 878dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 879dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 880dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 881dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 882dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyTimeUnits, dts); 883dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->setInt32(kKeyTimeScale, mTimescale); 884dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 885dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 886dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 887dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 888dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 889dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 890dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 891dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 892dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 893dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 894dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 895dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 896dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 897dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mBuffer->range_length() >= 2); 898dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 899dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 900dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 901dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 902dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t nal_size = U16_AT(src); 903dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 904dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mBuffer->range_length() >= 2 + nal_size); 905dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 906dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 907dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber clone->set_range(mBuffer->range_offset() + 2, nal_size); 908dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 909dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 910dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->range_offset() + 2 + nal_size, 911dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->range_length() - 2 - nal_size); 912dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 913dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 914dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 915dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 916dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 917dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 918dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 919dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 920dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 921dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 922dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 923dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 924dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 92520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t num_bytes_read = 926dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mDataSource->read_at(offset, mSrcBuffer, size); 92720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 92920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 93020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 932dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 93320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 935dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 936dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t srcOffset = 0; 937dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t dstOffset = 0; 938dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber while (srcOffset < size) { 939dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(srcOffset + 1 < size); 940dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t nalLength = 941dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (mSrcBuffer[srcOffset] << 8) | mSrcBuffer[srcOffset + 1]; 942dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(srcOffset + 1 + nalLength < size); 943dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += 2; 944dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 945dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (nalLength == 0) { 946dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber continue; 947dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 948dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 949dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 950dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 951dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 952dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 953dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 954dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 1; 955dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 956dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += nalLength; 957dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstOffset += nalLength; 958dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 959dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 960dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, dstOffset); 96120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 96220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->setInt32(kKeyTimeUnits, dts); 96320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->setInt32(kKeyTimeScale, mTimescale); 96420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 96520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 96720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 96820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 96920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 97020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 97120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 97220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 973693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool SniffMPEG4( 974693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 97520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 97620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 97720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t n = source->read_at(4, header, sizeof(header)); 97820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 97920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 98020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)) { 98418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.1; 98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 995