MPEG4Extractor.cpp revision 66326a5ee0869f1ee4d136a477e6effba428b3cb
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 2066326a5ee0869f1ee4d136a477e6effba428b3cbAndreas Huber#include "include/MPEG4Extractor.h" 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 2289e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <ctype.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdint.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <string.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h> 33dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber#include <media/stagefright/MediaDebug.h> 3418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber#include <media/stagefright/MediaDefs.h> 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaSource.h> 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/String8.h> 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberclass MPEG4Source : public MediaSource { 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberpublic: 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Caller retains ownership of both "dataSource" and "sampleTable". 45693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber MPEG4Source(const sp<MetaData> &format, 46693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 4748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 48693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable); 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t start(MetaData *params = NULL); 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t stop(); 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual sp<MetaData> getFormat(); 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber virtual status_t read( 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **buffer, const ReadOptions *options = NULL); 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberprotected: 59693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber virtual ~MPEG4Source(); 60693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberprivate: 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sp<MetaData> mFormat; 63693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<DataSource> mDataSource; 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t mTimescale; 65693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber sp<SampleTable> mSampleTable; 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mCurrentSampleIndex; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mIsAVC; 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 770024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 780024245e134467d120b40099da16c467dc365e76Andreas Huber 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 12518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 12818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 13118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 132371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 13418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 13718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 14018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 143dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 148693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack(NULL) { 15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 166693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 169693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 172693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 175693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 179693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1827e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 1837e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 199371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 200371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 201371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 202371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2037e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 2047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 2057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 2067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 2077e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 2087e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2097e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 2107e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 2117e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 2127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 2137e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && track->sampleTable->getDecodingTime( 2147e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber sampleIndex, &sampleTime) == OK) { 2157e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 2167e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 2177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 2187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset, hdr, 8) < 8) { 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset + 8, &chunk_size, 8) < 8) { 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size <= sizeof(buffer)) { 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(*offset, buffer, chunk_size) < chunk_size) { 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber hexdump(buffer, chunk_size); 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 308dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 320dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= 4); 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(data_offset, &version, 1) < 1) { 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t ctime, mtime, duration; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t id; 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t width, height; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 36 + 60) { 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[36 + 60]; 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U64_AT(&buffer[4]); 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U64_AT(&buffer[12]); 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[20]); 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U64_AT(&buffer[28]); 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[88]); 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[92]); 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 24 + 60) { 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24 + 60]; 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U32_AT(&buffer[4]); 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U32_AT(&buffer[8]); 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[12]); 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U32_AT(&buffer[20]); 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[76]); 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[80]); 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = new Track; 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->next = NULL; 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mLastTrack) { 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->next = track; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = track; 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack = track; 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta = new MetaData; 3767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = false; 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->timescale = 0; 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->sampleTable = new SampleTable(mDataSource); 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 39620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 41220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 43548c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 25) { 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24]; 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(data_offset, buffer, 24) < 24) { 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(&buffer[4]) != 0) { 45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // pre_defined should be 0. 45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHandlerType = U32_AT(&buffer[8]); 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 474dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 500dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 506371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 51620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 52718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type)) 52818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 52918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // AMR audio is always mono. 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("*** coding='%s' %d channels, size %d, rate %d\n", 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk, num_channels, sample_size, sample_rate); 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 552dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("*** coding='%s' width=%d height=%d\n", 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk, width, height); 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 594dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 60320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 61820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 69520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 69620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 70320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 71420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 71520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 727693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 730693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 73420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 73520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 736693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 73720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 743371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 744371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 745371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 746371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 747693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 74848c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 74920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 755693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 75648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 757693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 76048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 767dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 7680024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 76920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 771dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 783dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 786dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 788dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 790dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t max_size; 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->getMaxSampleSize(&max_size); 797dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(err, OK); 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7990024245e134467d120b40099da16c467dc365e76Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 8000024245e134467d120b40099da16c467dc365e76Andreas Huber // each fragment originally prefixed with a 2 byte length will 8010024245e134467d120b40099da16c467dc365e76Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 8020024245e134467d120b40099da16c467dc365e76Andreas Huber // and thus will grow by 2 bytes per fragment. 8030024245e134467d120b40099da16c467dc365e76Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size + 10 * 2)); 8040024245e134467d120b40099da16c467dc365e76Andreas Huber 8050024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 813dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 81420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 81520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 81720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 81820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8200024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 8210024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 8220024245e134467d120b40099da16c467dc365e76Andreas Huber 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 83520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 83720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 838dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 83920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 84120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 84320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 84420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 84520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->findClosestSample( 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 84720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 84820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = sampleIndex; 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 85720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 86020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8620024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 8630024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 864dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 865dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 866dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 867dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 869dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber status_t err = mSampleTable->getSampleOffsetAndSize( 870dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mCurrentSampleIndex, &offset, &size); 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 872dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 873dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 874dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 87520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 876dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts); 87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 878dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 879dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 880dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 881dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 882dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 883dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 884dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(mBuffer, NULL); 885dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 886dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 8870024245e134467d120b40099da16c467dc365e76Andreas Huber } 88820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 889dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 890dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 891dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 892dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mDataSource->read_at(offset, (uint8_t *)mBuffer->data(), size); 893dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 894dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 895dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 896dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 897dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 898dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 899dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 900dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 901dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 902dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 90348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 90448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 905dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 906dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 907dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 908dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 909dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 910dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 911dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 912dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 913dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 914dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 915dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 916dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 917dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 918dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mBuffer->range_length() >= 2); 919dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 920dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 921dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 922dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 923dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t nal_size = U16_AT(src); 924dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 925dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mBuffer->range_length() >= 2 + nal_size); 926dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 927dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 928dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber clone->set_range(mBuffer->range_offset() + 2, nal_size); 929dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 930dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 931dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->range_offset() + 2 + nal_size, 932dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->range_length() - 2 - nal_size); 933dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 934dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 935dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 936dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 937dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 938dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 939dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 940dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 941dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 942dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 943dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 944dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 945dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 94620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t num_bytes_read = 947dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mDataSource->read_at(offset, mSrcBuffer, size); 94820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 94920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 95020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 95120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 95220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 953dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 956dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 957dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t srcOffset = 0; 958dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t dstOffset = 0; 959dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber while (srcOffset < size) { 960dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(srcOffset + 1 < size); 961dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t nalLength = 962dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (mSrcBuffer[srcOffset] << 8) | mSrcBuffer[srcOffset + 1]; 963dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(srcOffset + 1 + nalLength < size); 964dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += 2; 965dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 966dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (nalLength == 0) { 967dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber continue; 968dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 969dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 970dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 971dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 972dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 973dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 974dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 975dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 1; 976dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 977dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += nalLength; 978dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstOffset += nalLength; 979dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 980dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 981dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, dstOffset); 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 98348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 98448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 994693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool SniffMPEG4( 995693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 99720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t n = source->read_at(4, header, sizeof(header)); 99920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 100020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 100120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 100220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 100420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)) { 100518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.1; 100720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 100920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 101020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1016