MPEG4Extractor.cpp revision e8a084958c27327b0aca749f69095605d2a21309
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; 696064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t mNALLengthSize; 706064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool mStarted; 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBufferGroup *mGroup; 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *mBuffer; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool mWantsNALFragments; 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 790024245e134467d120b40099da16c467dc365e76Andreas Huber uint8_t *mSrcBuffer; 800024245e134467d120b40099da16c467dc365e76Andreas Huber 816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t parseNALSize(const uint8_t *data) const; 826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source(const MPEG4Source &); 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MPEG4Source &operator=(const MPEG4Source &); 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}; 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void hexdump(const void *_data, size_t size) { 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const uint8_t *data = (const uint8_t *)_data; 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t offset = 0; 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (offset < size) { 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("0x%04x ", offset); 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t n = size - offset; 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n > 16) { 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber n = 16; 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < 16; ++i) { 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (i == 8) { 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (offset + i < size) { 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%02x ", data[offset + i]); 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf(" "); 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (size_t i = 0; i < n; ++i) { 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (isprint(data[offset + i])) { 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%c", data[offset + i]); 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("."); 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("\n"); 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber offset += 16; 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huberstatic const char *FourCC2MIME(uint32_t fourcc) { 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (fourcc) { 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 12918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AAC; 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 13218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_NB; 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 134371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 13518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_AUDIO_AMR_WB; 136371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 13818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_MPEG4; 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 14118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_H263; 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 14418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber return MEDIA_MIMETYPE_VIDEO_AVC; 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 147dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!"should not be here."); 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 152693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberMPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source) 15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata(false), 1557be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo(false), 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack(NULL), 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack(NULL) { 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1717be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 1727be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber sp<MetaData> meta = new MetaData; 1737be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1747be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 1757be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 1767be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 1777be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 1787be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1797be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if (mHasVideo) { 1807be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber meta->setCString(kKeyMIMEType, "video/mp4"); 1817be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } else { 1827be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber meta->setCString(kKeyMIMEType, "audio/mp4"); 1837be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 1847be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 1857be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber return meta; 1867be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 1877be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 188693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 191693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 197693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 201693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 2057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 221371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 222371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 223371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 224371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 2267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 2277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 2287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 2297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 2307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 2327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 2337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 2347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 2357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && track->sampleTable->getDecodingTime( 2367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber sampleIndex, &sampleTime) == OK) { 2377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 2387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 2397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 2407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 2567be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic void MakeFourCCString(uint32_t x, char *s) { 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[0] = x >> 24; 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[1] = (x >> 16) & 0xff; 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[2] = (x >> 8) & 0xff; 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[3] = x & 0xff; 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber s[4] = '\0'; 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 27434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 28234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size <= sizeof(buffer)) { 29934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, buffer, chunk_size) < chunk_size) { 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber hexdump(buffer, chunk_size); 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 330dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 342dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= 4); 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 34534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t ctime, mtime, duration; 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t id; 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t width, height; 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 36 + 60) { 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[36 + 60]; 35934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U64_AT(&buffer[4]); 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U64_AT(&buffer[12]); 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[20]); 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U64_AT(&buffer[28]); 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[88]); 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[92]); 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 24 + 60) { 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24 + 60]; 37634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U32_AT(&buffer[4]); 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U32_AT(&buffer[8]); 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[12]); 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U32_AT(&buffer[20]); 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[76]); 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[80]); 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = new Track; 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->next = NULL; 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mLastTrack) { 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->next = track; 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = track; 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack = track; 39620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta = new MetaData; 3987e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = false; 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->timescale = 0; 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->sampleTable = new SampleTable(mDataSource); 40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 41434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 43134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 44134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 44934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 45748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 25) { 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24]; 47034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, buffer, 24) < 24) { 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(&buffer[4]) != 0) { 48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // pre_defined should be 0. 48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHandlerType = U32_AT(&buffer[8]); 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 496dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 49734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 51620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 522dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 528371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 54918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type)) 55018291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 55118291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 55220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // AMR audio is always mono. 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 559134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' %d channels, size %d, rate %d\n", 560134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, num_channels, sample_size, sample_rate); 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 574dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 5827be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 5837be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 603134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 604134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 618dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 61920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 63820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 65620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 662738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 663738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 664738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 665738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 666738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 667738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 668738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 669738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 670738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 67320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 69620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 69720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 70420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 71520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 71720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 72220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 73320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 73420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 73520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 73620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 73920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 74420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 74720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 74820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 760693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 763693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 769693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 776371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 777371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 778371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 779371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 780693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 78148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 788693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 78948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 790693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 79348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 7976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 801dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 8020024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 805dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80718291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 8086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 8106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 8116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 8126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 8136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 8146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 8166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 8186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(ptr[0], 1); // configurationVersion == 1 8196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8206064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 8216064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 8226064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 82320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 82420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 82520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 82720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 82820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 82920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 832dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 83320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 83420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 835dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 83620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 837dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 83820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 839dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 84120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 84220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 84320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 844738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 845738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 847738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 8480024245e134467d120b40099da16c467dc365e76Andreas Huber 8490024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 85020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 85220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 85420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 85520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 857dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 85820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 85920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 86020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 86120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 86220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8640024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 8650024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 8660024245e134467d120b40099da16c467dc365e76Andreas Huber 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 86920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 87120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 87220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 87420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 87520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 87620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8806064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 8816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 8826064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 8836064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 8846064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 8856064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 8866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 8876064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 8886064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 8896064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 8906064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 8916064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8926064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 8936064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 8946064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 8956064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 8966064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 8976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 8986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 89920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 90020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 901dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 90220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 90320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 90420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 90520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 90620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 90720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 90820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->findClosestSample( 90920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 91020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 91120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 91320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 91420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 91520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 91620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = sampleIndex; 91720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 91820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 91920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 92020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 92220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 92320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 92420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9250024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 9260024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 927dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 928dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 929dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 930dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 93120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 932dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber status_t err = mSampleTable->getSampleOffsetAndSize( 933dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mCurrentSampleIndex, &offset, &size); 93420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 935dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 936dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 937dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 93820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 939dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mSampleTable->getDecodingTime(mCurrentSampleIndex, &dts); 94020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 941dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 942dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 943dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 944dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 945dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 946dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 947dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(mBuffer, NULL); 948dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 949dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 9500024245e134467d120b40099da16c467dc365e76Andreas Huber } 95120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 952dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 953dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 954dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 95534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 956dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 957dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 958dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 959dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 960dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 961dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 962dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 963dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 964dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 965dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 96648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 96748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 968dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 969dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 970dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 971dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 972dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 973dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 974dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 975dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 976dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 977dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 978dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 979dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 980dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 9816064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 982dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 983dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 984dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 985dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 9866064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 987e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 988e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 989e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 990e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 991e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 992e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 993e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 994e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 995dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 996dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 9976064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 998dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 999dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 10006064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 10016064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 1002dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1003dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 1004dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1005dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1006dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1007dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1008dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 1009dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1010dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1011dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 1012dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 1013dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 1014dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t num_bytes_read = 101634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, mSrcBuffer, size); 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 101820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 102020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 102120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1022dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 102320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 102420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1025dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 1026dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t srcOffset = 0; 1027dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t dstOffset = 0; 10286064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 1029dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber while (srcOffset < size) { 10306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(srcOffset + mNALLengthSize <= size); 10316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 10326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber srcOffset += mNALLengthSize; 1033e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1034e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (srcOffset + nalLength > size) { 1035e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1036e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1037e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1038e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1039e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1040dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1041dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (nalLength == 0) { 1042dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber continue; 1043dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1044dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1045dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 1046dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1047dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1048dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1049dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1050dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 1; 1051dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1052dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += nalLength; 1053dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstOffset += nalLength; 1054dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 10556064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(srcOffset, size); 1056dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1057dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, dstOffset); 105820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 105948c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 106048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 106520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 106720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 106920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1070693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool SniffMPEG4( 1071693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 107220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 107320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 107520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 107620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 107720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 107820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 10800dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 10810dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypM4A ", 8)) { 108218291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 108320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.1; 108420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 108620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 108720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 108920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 109020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 109220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1093