MPEG4Extractor.cpp revision 72b8c5ae6a5f97a4fcfc6d23d33159d6ae50179c
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), 15772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mLastTrack(NULL), 15872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData(new MetaData) { 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Extractor::~MPEG4Extractor() { 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *next = track->next; 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete track; 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = next; 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = mLastTrack = NULL; 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1727be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Hubersp<MetaData> MPEG4Extractor::getMetaData() { 1737be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber status_t err; 1747be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber if ((err = readMetaData()) != OK) { 17572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return new MetaData; 1767be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber } 1777be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 17872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return mFileMetaData; 1797be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber} 1807be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 181693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersize_t MPEG4Extractor::countTracks() { 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 184693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return 0; 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 187693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber size_t n = 0; 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (track) { 190693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber ++n; 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 194693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return n; 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1977e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Hubersp<MetaData> MPEG4Extractor::getTrackMetaData( 1987e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t index, uint32_t flags) { 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return NULL; 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 214371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 215371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 216371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 217371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 2187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if ((flags & kIncludeExtensiveMetaData) 2197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber && !track->includes_expensive_metadata) { 2207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = true; 2217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 2227e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber const char *mime; 2237e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber CHECK(track->meta->findCString(kKeyMIMEType, &mime)); 2247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (!strncasecmp("video/", mime, 6)) { 2257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleIndex; 2267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t sampleTime; 2277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK 228c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber && track->sampleTable->getMetaDataForSample( 229c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, NULL /* offset */, NULL /* size */, 230c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &sampleTime) == OK) { 2317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->meta->setInt64( 2327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber kKeyThumbnailTime, 2337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber ((int64_t)sampleTime * 1000000) / track->timescale); 2347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 2377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return track->meta; 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::readMetaData() { 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t offset = 0; 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while ((err = parseChunk(&offset, 0)) == OK) { 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 2507be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHaveMetadata) { 25272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mHasVideo) { 25372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "video/mp4"); 25472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 25572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyMIMEType, "audio/mp4"); 25672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 25772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 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 27272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstruct PathAdder { 27372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(Vector<uint32_t> *path, uint32_t chunkType) 27472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber : mPath(path) { 27572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->push(chunkType); 27672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 27772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 27872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber ~PathAdder() { 27972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mPath->pop(); 28072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 28172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 28272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberprivate: 28372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber Vector<uint32_t> *mPath; 28472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 28572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder(const PathAdder &); 28672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder &operator=(const PathAdder &); 28772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber}; 28872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 28972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic bool underMetaDataPath(const Vector<uint32_t> &path) { 29072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return path.size() >= 5 29172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[0] == FOURCC('m', 'o', 'o', 'v') 29272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[1] == FOURCC('u', 'd', 't', 'a') 29372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[2] == FOURCC('m', 'e', 't', 'a') 29472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && path[3] == FOURCC('i', 'l', 's', 't'); 29572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 29672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 29772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber// Given a time in seconds since Jan 1 1904, produce a human-readable string. 29872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatic void convertTimeToDate(int64_t time_1904, String8 *s) { 29972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600); 30072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 30172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[32]; 30272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970)); 30372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 30472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber s->setTo(tmp); 30572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 30672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t hdr[2]; 30934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset, hdr, 8) < 8) { 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t chunk_size = ntohl(hdr[0]); 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_type = ntohl(hdr[1]); 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t data_offset = *offset + 8; 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size == 1) { 31734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) { 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_size = ntoh64(chunk_size); 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset += 8; 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char chunk[5]; 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MakeFourCCString(chunk_type, chunk); 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#if 0 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber static const char kWhitespace[] = " "; 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth]; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber printf("%sfound chunk '%s' of size %lld\n", indent, chunk, chunk_size); 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_size <= sizeof(buffer)) { 33472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt(*offset, buffer, chunk_size) 33572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)chunk_size) { 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber hexdump(buffer, chunk_size); 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#endif 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber PathAdder autoAdder(&mPath, chunk_type); 34472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t chunk_data_size = *offset + chunk_size - data_offset; 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_type != FOURCC('c', 'p', 'r', 't') 34872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber && mPath.size() == 5 && underMetaDataPath(mPath)) { 34972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 35072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset; 35172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 35272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 35372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 35472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 35572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 35672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 35772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(*offset, stop_offset); 35872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 35972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 36072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 36172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch(chunk_type) { 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'v'): 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'k'): 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'i', 'a'): 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'i', 'n', 'f'): 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('d', 'i', 'n', 'f'): 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'b', 'l'): 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'v', 'e', 'x'): 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'o', 'o', 'f'): 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'r', 'a', 'f'): 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'f', 'r', 'a'): 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'k', 'i' ,'p'): 37472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('u', 'd', 't', 'a'): 37572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('i', 'l', 's', 't'): 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset; 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 385dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_type == FOURCC('m', 'o', 'o', 'v')) { 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHaveMetadata = true; 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return UNKNOWN_ERROR; // Return a dummy error. 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('t', 'k', 'h', 'd'): 39620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 397dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= 4); 39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 40034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, &version, 1) < 1) { 40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t ctime, mtime, duration; 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t id; 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t width, height; 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 36 + 60) { 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[36 + 60]; 41434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U64_AT(&buffer[4]); 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U64_AT(&buffer[12]); 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[20]); 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U64_AT(&buffer[28]); 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[88]); 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[92]); 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size != 24 + 60) { 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24 + 60]; 43134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ctime = U32_AT(&buffer[4]); 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mtime = U32_AT(&buffer[8]); 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber id = U32_AT(&buffer[12]); 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = U32_AT(&buffer[20]); 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber width = U32_AT(&buffer[76]); 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber height = U32_AT(&buffer[80]); 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = new Track; 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->next = NULL; 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mLastTrack) { 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->next = track; 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mFirstTrack = track; 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack = track; 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta = new MetaData; 4537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber track->includes_expensive_metadata = false; 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->timescale = 0; 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->sampleTable = new SampleTable(mDataSource); 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track->meta->setCString(kKeyMIMEType, "application/octet-stream"); 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'd', 'h', 'd'): 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t version; 46934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, &version, sizeof(version)) 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(version)) { 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t timescale_offset; 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 16; 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (version == 0) { 48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset = data_offset + 4 + 8; 48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t timescale; 48634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset, ×cale, sizeof(timescale)) 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(timescale)) { 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->timescale = ntohl(timescale); 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t duration; 49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (version == 1) { 49634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration, sizeof(duration)) 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration)) { 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntoh64(duration); 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t duration32; 50434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber timescale_offset + 4, &duration32, sizeof(duration32)) 50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber < (ssize_t)sizeof(duration32)) { 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber duration = ntohl(duration32); 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51148c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mLastTrack->meta->setInt64( 51248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyDuration, (duration * 1000000) / mLastTrack->timescale); 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 51620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('h', 'd', 'l', 'r'): 51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 25) { 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[24]; 52534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt(data_offset, buffer, 24) < 24) { 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(&buffer[4]) != 0) { 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // pre_defined should be 0. 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mHandlerType = U32_AT(&buffer[8]); 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'd'): 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 8) { 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8]; 551dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 55234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, 8) < 8) { 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t entry_count = U32_AT(&buffer[4]); 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (entry_count > 1) { 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // For now we only support a single type of media per track. 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_UNSUPPORTED; 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + 8; 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < entry_count; ++i) { 57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 577dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'a'): 58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 'a', 'm', 'r'): 583371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber case FOURCC('s', 'a', 'w', 'b'): 58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) { 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[8 + 20]; 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic AudioSampleEntry size. 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t num_channels = U16_AT(&buffer[16]); 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60318291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, 60418291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type)) 60518291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, 60618291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber FourCC2MIME(chunk_type))) { 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // AMR audio is always mono. 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber num_channels = 1; 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t sample_size = U16_AT(&buffer[18]); 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_rate = U32_AT(&buffer[24]) >> 16; 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 614134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' %d channels, size %d, rate %d\n", 615134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, num_channels, sample_size, sample_rate); 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 61820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyChannelCount, num_channels); 61920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeySampleRate, sample_rate); 62020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 629dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('m', 'p', '4', 'v'): 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', '2', '6', '3'): 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', '1'): 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 6377be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber mHasVideo = true; 6387be6407f2ad7f2b0782d195d9f792072c084d6f5Andreas Huber 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) { 64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[78]; 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < (ssize_t)sizeof(buffer)) { 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Basic VideoSampleEntry size. 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 65420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t data_ref_index = U16_AT(&buffer[6]); 65520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t width = U16_AT(&buffer[6 + 18]); 65620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t height = U16_AT(&buffer[6 + 20]); 65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 658134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // printf("*** coding='%s' width=%d height=%d\n", 659134ee6a324c35f39e3576172e4eae4c6de6eb9dcAndreas Huber // chunk, width, height); 66020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setCString(kKeyMIMEType, FourCC2MIME(chunk_type)); 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyWidth, width); 66320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setInt32(kKeyHeight, height); 66420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber off_t stop_offset = *offset + chunk_size; 66620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = data_offset + sizeof(buffer); 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (*offset < stop_offset) { 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = parseChunk(offset, depth + 1); 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 67120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 673dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(*offset, stop_offset); 67420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 67520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'c', 'o'): 67820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('c', 'o', '6', '4'): 67920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 68020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 68120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setChunkOffsetParams( 68220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 68520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 68620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 68720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 68820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 68920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 69020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 69120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'c'): 69320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 69420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 69520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleToChunkParams( 69620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 69720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 69820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 69920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 70020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 70320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 70420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 70520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 70620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 'z'): 70720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 'z', '2'): 70820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 70920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 71020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSampleSizeParams( 71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_type, data_offset, chunk_data_size); 71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 71320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 71420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 71520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 717738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber size_t max_size; 718738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK_EQ(mLastTrack->sampleTable->getMaxSampleSize(&max_size), OK); 719738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 720738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // Assume that a given buffer only contains at most 10 fragments, 721738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // each fragment originally prefixed with a 2 byte length will 722738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion, 723738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber // and thus will grow by 2 bytes per fragment. 724738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2); 725738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber 72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 72820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 't', 's'): 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 73320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setTimeToSampleParams( 73420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 73520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 73620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 73720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 73820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 74220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 74320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 74420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('s', 't', 's', 's'): 74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 74620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = 74720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->sampleTable->setSyncSampleParams( 74820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, chunk_data_size); 74920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 75520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('e', 's', 'd', 's'): 75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 76020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size < 4) { 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[256]; 76520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 77020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 77120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 77220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(buffer) != 0) { 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Should be version 0, flags 0. 77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 77720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 77820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 77920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyESDS, kTypeESDS, &buffer[4], chunk_data_size - 4); 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 78320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 78620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case FOURCC('a', 'v', 'c', 'C'): 78720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 78820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber char buffer[256]; 78920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_data_size > (off_t)sizeof(buffer)) { 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_BUFFER_TOO_SMALL; 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, buffer, chunk_data_size) < chunk_data_size) { 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mLastTrack->meta->setData( 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber kKeyAVCC, kTypeAVCC, buffer, chunk_data_size); 80020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 80220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 80320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'e', 't', 'a'): 80672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 80772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t buffer[4]; 80872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK(chunk_data_size >= (off_t)sizeof(buffer)); 80972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 81072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, buffer, 4) < 4) { 81172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 81272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 81372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 81472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (U32_AT(buffer) != 0) { 81572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // Should be version 0, flags 0. 81672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 81772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 81872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 81972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber off_t stop_offset = *offset + chunk_size; 82072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset = data_offset + sizeof(buffer); 82172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber while (*offset < stop_offset) { 82272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseChunk(offset, depth + 1); 82372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 82472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 82572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 82672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 82772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(*offset, stop_offset); 82872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 82972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 83072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 83172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('d', 'a', 't', 'a'): 83272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 83372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mPath.size() == 6 && underMetaDataPath(mPath)) { 83472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber status_t err = parseMetaData(data_offset, chunk_data_size); 83572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 83672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (err != OK) { 83772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return err; 83872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 83972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 84072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 84172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 84272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 84372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 84472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 84572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('m', 'v', 'h', 'd'): 84672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 84772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (chunk_data_size < 12) { 84872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 84972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 85072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 85172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t header[12]; 85272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 85372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber data_offset, header, sizeof(header)) 85472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber < (ssize_t)sizeof(header)) { 85572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 85672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 85772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 85872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber int64_t creationTime; 85972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (header[0] == 1) { 86072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U64_AT(&header[4]); 86172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 86272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber CHECK_EQ(header[0], 0); 86372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber creationTime = U32_AT(&header[4]); 86472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 86572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 86672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber String8 s; 86772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber convertTimeToDate(creationTime, &s); 86872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 86972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyDate, s.string()); 87072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 87172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber *offset += chunk_size; 87272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 87372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 87472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 87520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 87620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 87720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += chunk_size; 87820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 87920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 88572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huberstatus_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { 88672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size < 4) { 88772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_MALFORMED; 88872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 88972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 89072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint8_t *buffer = new uint8_t[size + 1]; 89172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (mDataSource->readAt( 89272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber offset, buffer, size) != (ssize_t)size) { 89372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 89472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 89572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 89672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return ERROR_IO; 89772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 89872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 89972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t flags = U32_AT(buffer); 90072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 90172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber uint32_t metadataKey = 0; 90272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber switch (mPath[4]) { 90372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'a', 'l', 'b'): 90472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 90572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbum; 90672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 90772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 90872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'A', 'R', 'T'): 90972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 91072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyArtist; 91172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 91272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 91372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'd', 'a', 'y'): 91472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 91572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyYear; 91672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 91772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 91872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'n', 'a', 'm'): 91972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 92072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyTitle; 92172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 92272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 92372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC(0xa9, 'w', 'r', 't'): 92472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 92572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyWriter; 92672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 92772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 92872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('c', 'o', 'v', 'r'): 92972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 93072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyAlbumArt; 93172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 93272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 93372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('g', 'n', 'r', 'e'): 93472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 93572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey = kKeyGenre; 93672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 93772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 93872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber case FOURCC('t', 'r', 'k', 'n'): 93972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber { 94072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size == 16 && flags == 0) { 94172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char tmp[16]; 94272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(tmp, "%d/%d", 94372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber (int)buffer[size - 5], (int)buffer[size - 3]); 94472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 94572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber printf("track: %s\n", tmp); 94672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(kKeyCDTrackNumber, tmp); 94772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 94872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 94972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 95072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber default: 95172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber break; 95272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 95372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 95472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (size >= 8 && metadataKey) { 95572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (metadataKey == kKeyAlbumArt) { 95672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setData( 95772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber kKeyAlbumArt, MetaData::TYPE_NONE, 95872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer + 8, size - 8); 95972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else if (metadataKey == kKeyGenre) { 96072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber if (flags == 0) { 96172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber // uint8_t 96272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber char genre[10]; 96372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber sprintf(genre, "%d", (int)buffer[size - 1]); 96472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 96572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString(metadataKey, genre); 96672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 96772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } else { 96872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer[size] = '\0'; 96972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 97072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber mFileMetaData->setCString( 97172b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber metadataKey, (const char *)buffer + 8); 97272b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 97372b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber } 97472b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 97572b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber delete[] buffer; 97672b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber buffer = NULL; 97772b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 97872b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber return OK; 97972b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber} 98072b8c5ae6a5f97a4fcfc6d23d33159d6ae50179cAndreas Huber 981693d271e62a3726689ff68f4505ba49228eb94b2Andreas Hubersp<MediaSource> MPEG4Extractor::getTrack(size_t index) { 98220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err; 98320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((err = readMetaData()) != OK) { 984693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 98520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 98620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 98720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Track *track = mFirstTrack; 98820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index > 0) { 98920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (track == NULL) { 990693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return NULL; 99120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 99320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber track = track->next; 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber --index; 99520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 99620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 997371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber if (track == NULL) { 998371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber return NULL; 999371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber } 1000371e243b6638e74e577d56a24eee7d5a97e36d2bAndreas Huber 1001693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber return new MPEG4Source( 100248c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber track->meta, mDataSource, track->timescale, track->sampleTable); 100320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 100420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber//////////////////////////////////////////////////////////////////////////////// 100620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 100720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::MPEG4Source( 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const sp<MetaData> &format, 1009693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &dataSource, 101048c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber int32_t timeScale, 1011693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<SampleTable> &sampleTable) 101220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mFormat(format), 101320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDataSource(dataSource), 101448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mTimescale(timeScale), 101520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleTable(sampleTable), 101620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex(0), 101720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mIsAVC(false), 10186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize(0), 101920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted(false), 102020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup(NULL), 102120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer(NULL), 1022dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments(false), 10230024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer(NULL) { 102420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const char *mime; 102520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber bool success = mFormat->findCString(kKeyMIMEType, &mime); 1026dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(success); 102720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 102818291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC); 10296064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 10306064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber if (mIsAVC) { 10316064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber uint32_t type; 10326064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const void *data; 10336064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t size; 10346064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(format->findData(kKeyAVCC, &type, &data, &size)); 10356064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 10366064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber const uint8_t *ptr = (const uint8_t *)data; 10376064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 10386064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(size >= 7); 10396064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(ptr[0], 1); // configurationVersion == 1 10406064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 10416064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // The number of bytes used to encode the length of a NAL unit. 10426064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mNALLengthSize = 1 + (ptr[4] & 3); 10436064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 104420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 104520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 104620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMPEG4Source::~MPEG4Source() { 104720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mStarted) { 104820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber stop(); 104920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 105020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 105120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::start(MetaData *params) { 1053dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(!mStarted); 105420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 105520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int32_t val; 1056dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (params && params->findInt32(kKeyWantsNALFragments, &val) 105720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && val != 0) { 1058dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = true; 105920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 1060dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mWantsNALFragments = false; 106120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 106220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 106320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = new MediaBufferGroup; 106420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1065738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber int32_t max_size; 1066738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber CHECK(mFormat->findInt32(kKeyMaxInputSize, &max_size)); 106720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1068738c4315859395bfeeaae3d4c9d6fb9f414778f1Andreas Huber mGroup->add_buffer(new MediaBuffer(max_size)); 10690024245e134467d120b40099da16c467dc365e76Andreas Huber 10700024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = new uint8_t[max_size]; 107120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = true; 107320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 107520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 107620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 107720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::stop() { 1078dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 107920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 108020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 108120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 108220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 108320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 108420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10850024245e134467d120b40099da16c467dc365e76Andreas Huber delete[] mSrcBuffer; 10860024245e134467d120b40099da16c467dc365e76Andreas Huber mSrcBuffer = NULL; 10870024245e134467d120b40099da16c467dc365e76Andreas Huber 108820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete mGroup; 108920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mGroup = NULL; 109020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mStarted = false; 109220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = 0; 109320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 109520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 109620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 109720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MPEG4Source::getFormat() { 109820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mFormat; 109920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 110020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11016064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Hubersize_t MPEG4Source::parseNALSize(const uint8_t *data) const { 11026064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber switch (mNALLengthSize) { 11036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 1: 11046064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return *data; 11056064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 2: 11066064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U16_AT(data); 11076064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 3: 11086064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return ((size_t)data[0] << 16) | U16_AT(&data[1]); 11096064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber case 4: 11106064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return U32_AT(data); 11116064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber } 11126064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 11136064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // This cannot happen, mNALLengthSize springs to life by adding 1 to 11146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber // a 2-bit integer. 11156064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(!"Should not be here."); 11166064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 11176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber return 0; 11186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber} 11196064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 112020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MPEG4Source::read( 112120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer **out, const ReadOptions *options) { 1122dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(mStarted); 112320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = NULL; 112520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 112620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int64_t seekTimeUs; 112720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (options && options->getSeekTo(&seekTimeUs)) { 112820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sampleIndex; 112920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = mSampleTable->findClosestSample( 113020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber seekTimeUs * mTimescale / 1000000, 113120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &sampleIndex, SampleTable::kSyncSample_Flag); 113220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 113420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 113520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 113620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 113720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mCurrentSampleIndex = sampleIndex; 113820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mBuffer != NULL) { 113920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 114020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 114120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 114320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // fall through 114420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 114520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11460024245e134467d120b40099da16c467dc365e76Andreas Huber off_t offset; 11470024245e134467d120b40099da16c467dc365e76Andreas Huber size_t size; 1148dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint32_t dts; 1149dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber bool newBuffer = false; 1150dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer == NULL) { 1151dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber newBuffer = true; 115220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = 1154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleTable->getMetaDataForSample( 1155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentSampleIndex, &offset, &size, &dts); 115620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1157dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1158dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1159dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1160dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1161dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber err = mGroup->acquire_buffer(&mBuffer); 1162c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1163dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (err != OK) { 1164dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK_EQ(mBuffer, NULL); 1165dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return err; 1166dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 11670024245e134467d120b40099da16c467dc365e76Andreas Huber } 116820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1169dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC || mWantsNALFragments) { 1170dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (newBuffer) { 1171dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ssize_t num_bytes_read = 117234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size); 1173dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1174dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (num_bytes_read < (ssize_t)size) { 1175dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1176dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1177dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1178dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 1179dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1180dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1181dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, size); 1182dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->meta_data()->clear(); 118348c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 118448c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 1185dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber ++mCurrentSampleIndex; 1186dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1187dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1188dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (!mIsAVC) { 1189dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = mBuffer; 1190dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1191dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1192dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1193dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1194dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1195dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Each NAL unit is split up into its constituent fragments and 1196dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // each one of them returned in its own buffer. 1197dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 11986064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(mBuffer->range_length() >= mNALLengthSize); 1199dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1200dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber const uint8_t *src = 1201dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber (const uint8_t *)mBuffer->data() + mBuffer->range_offset(); 1202dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 12036064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nal_size = parseNALSize(src); 1204e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (mBuffer->range_length() < mNALLengthSize + nal_size) { 1205e8a084958c27327b0aca749f69095605d2a21309Andreas Huber LOGE("incomplete NAL unit."); 1206e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1207e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1208e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1209e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1210e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1211e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1212dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1213dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber MediaBuffer *clone = mBuffer->clone(); 12146064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size); 1215dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1216dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range( 12176064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_offset() + mNALLengthSize + nal_size, 12186064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber mBuffer->range_length() - mNALLengthSize - nal_size); 1219dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1220dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (mBuffer->range_length() == 0) { 1221dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->release(); 1222dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer = NULL; 1223dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1224dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1225dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber *out = clone; 1226dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1227dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return OK; 1228dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } else { 1229dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // Whole NAL units are returned but each fragment is prefixed by 1230dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber // the start code (0x00 00 00 01). 1231dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 123220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ssize_t num_bytes_read = 123334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber mDataSource->readAt(offset, mSrcBuffer, size); 123420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 123520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (num_bytes_read < (ssize_t)size) { 123620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->release(); 123720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 123820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1239dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber return ERROR_IO; 124020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 124120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1242dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber uint8_t *dstData = (uint8_t *)mBuffer->data(); 1243dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t srcOffset = 0; 1244dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber size_t dstOffset = 0; 12456064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber 1246dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber while (srcOffset < size) { 12476064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK(srcOffset + mNALLengthSize <= size); 12486064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber size_t nalLength = parseNALSize(&mSrcBuffer[srcOffset]); 12496064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber srcOffset += mNALLengthSize; 1250e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1251e8a084958c27327b0aca749f69095605d2a21309Andreas Huber if (srcOffset + nalLength > size) { 1252e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer->release(); 1253e8a084958c27327b0aca749f69095605d2a21309Andreas Huber mBuffer = NULL; 1254e8a084958c27327b0aca749f69095605d2a21309Andreas Huber 1255e8a084958c27327b0aca749f69095605d2a21309Andreas Huber return ERROR_MALFORMED; 1256e8a084958c27327b0aca749f69095605d2a21309Andreas Huber } 1257dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1258dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber if (nalLength == 0) { 1259dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber continue; 1260dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 1261dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1262dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber CHECK(dstOffset + 4 <= mBuffer->size()); 1263dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1264dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1265dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1266dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 0; 1267dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstData[dstOffset++] = 1; 1268dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength); 1269dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber srcOffset += nalLength; 1270dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber dstOffset += nalLength; 1271dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber } 12726064017c61aa0bcadcff3119e176eab5fc3c001bAndreas Huber CHECK_EQ(srcOffset, size); 1273dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber 1274dbc03445db2bbf83b64f0c0a5dc62e61408864d7Andreas Huber mBuffer->set_range(0, dstOffset); 127520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer->meta_data()->clear(); 127648c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber mBuffer->meta_data()->setInt64( 127748c948b1137e7bbdb161b51908657ab72ac5e2daAndreas Huber kKeyTime, ((int64_t)dts * 1000000) / mTimescale); 127820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++mCurrentSampleIndex; 127920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *out = mBuffer; 128120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mBuffer = NULL; 128220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 128320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 128420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 128520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 128620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1287693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huberbool SniffMPEG4( 1288693d271e62a3726689ff68f4505ba49228eb94b2Andreas Huber const sp<DataSource> &source, String8 *mimeType, float *confidence) { 128920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 129020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber ssize_t n = source->readAt(4, header, sizeof(header)); 129220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (n < (ssize_t)sizeof(header)) { 129320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 129420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 129520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 129620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8) 12970dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8) 12980dba73763a04d39faf999dcc5ef12af3c99535a7Andreas Huber || !memcmp(header, "ftypM4A ", 8)) { 129918291bc20e55e8f3fd5feb786771a8ed32c19c59Andreas Huber *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4; 130020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *confidence = 0.1; 130120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return true; 130320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 130420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return false; 130620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 130720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 130820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 130920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1310