SampleTable.cpp revision 4931bb5259d10c1fa01e7405fb7aaef58a8ffb22
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 "SampleTable" 18c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//#define LOG_NDEBUG 0 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 22c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include "include/SampleIterator.h" 2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 270c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 33c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 34c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 35c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 36c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source) 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset(-1), 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType(0), 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets(0), 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset(-1), 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets(0), 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset(-1), 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize(0), 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize(0), 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes(0), 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount(0), 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample(NULL), 564931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries(NULL), 574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mNumCompositionTimeDeltaEntries(0), 5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset(-1), 59c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mNumSyncSamples(0), 608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples(NULL), 618bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex(0), 62c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries(NULL) { 63c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = new SampleIterator(this); 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() { 67c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete[] mSampleToChunkEntries; 68c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = NULL; 69c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 708bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber delete[] mSyncSamples; 718bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples = NULL; 728bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber delete[] mCompositionTimeDeltaEntries; 744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = NULL; 754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete[] mTimeToSample; 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = NULL; 78c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 79c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete mSampleIterator; 80c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = NULL; 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams( 84c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetOffset >= 0) { 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 890c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset = data_offset; 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType = type; 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 9934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets = U32_AT(&header[4]); 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetType == kChunkOffsetType32) { 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 4) { 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 8) { 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams( 125c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleToChunkOffset >= 0) { 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset = data_offset; 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 13734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets = U32_AT(&header[4]); 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumSampleToChunkOffsets * 12) { 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = 154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber new SampleToChunkEntry[mNumSampleToChunkOffsets]; 155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint8_t buffer[12]; 158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mDataSource->readAt( 159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) 160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber != (ssize_t)sizeof(buffer)) { 161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 162c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 163c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 164c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. 165c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 166c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber // We want the chunk index to be 0-based. 167c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 168c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 169c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 170c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 171c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams( 176c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeOffset >= 0) { 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1810c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset = data_offset; 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12) { 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[12]; 19034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = U32_AT(&header[4]); 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes = U32_AT(&header[8]); 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (type == kSampleSizeType32) { 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = 32; 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDefaultSampleSize != 0) { 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + mNumSampleSizes * 4) { 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((mDefaultSampleSize & 0xffffff00) != 0) { 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // The high 24 bits are reserved and must be 0. 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = mDefaultSampleSize & 0xf; 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = 0; 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && mSampleSizeFieldSize != 16) { 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams( 236c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mTimeToSample != NULL || data_size < 8) { 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 24234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount = U32_AT(&header[4]); 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = new uint32_t[mTimeToSampleCount * 2]; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; 25634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset + 8, mTimeToSample, size) < (ssize_t)size) { 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample[i] = ntohl(mTimeToSample[i]); 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams( 2694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber off64_t data_offset, size_t data_size) { 2704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber LOGI("There are reordered frames present."); 2714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 2724931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mCompositionTimeDeltaEntries != NULL || data_size < 8) { 2734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 2744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 2754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 2764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber uint8_t header[8]; 2774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mDataSource->readAt( 2784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, header, sizeof(header)) 2794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber < (ssize_t)sizeof(header)) { 2804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_IO; 2814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 2824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 2834931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (U32_AT(header) != 0) { 2844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber // Expected version = 0, flags = 0. 2854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 2864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 2874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 2884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber size_t numEntries = U32_AT(&header[4]); 2894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 2904931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (data_size != (numEntries + 1) * 8) { 2914931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 2924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 2934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 2944931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mNumCompositionTimeDeltaEntries = numEntries; 2954931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries]; 2964931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 2974931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mDataSource->readAt( 2984931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) 2994931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber < (ssize_t)numEntries * 8) { 3004931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber delete[] mCompositionTimeDeltaEntries; 3014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = NULL; 3024931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3034931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_IO; 3044931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3054931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3064931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber for (size_t i = 0; i < 2 * numEntries; ++i) { 3074931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]); 3084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return OK; 3114931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 3124931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 313c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset >= 0 || data_size < 8) { 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset = data_offset; 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 32134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSyncSamples = U32_AT(&header[4]); 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mNumSyncSamples < 2) { 33475fc7654280ac2a72fa8124b88e616219a3e61e2Andreas Huber LOGV("Table of sync samples is empty or has only a single entry!"); 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 3368bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 3378bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples = new uint32_t[mNumSyncSamples]; 3388bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t size = mNumSyncSamples * sizeof(uint32_t); 3398bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) 3408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber != (ssize_t)size) { 3418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber return ERROR_IO; 3428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 3438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 3448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber for (size_t i = 0; i < mNumSyncSamples; ++i) { 3458bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 3468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 3478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const { 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumChunkOffsets; 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const { 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumSampleSizes; 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) { 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = 0; 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sample_size; 366c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(i, &sample_size); 367da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_size > *max_size) { 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = sample_size; 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 380da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) { 381da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber return time1 > time2 ? time1 - time2 : time2 - time1; 382da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber} 383da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 384abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSampleAtTime( 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t req_time, uint32_t *sample_index, uint32_t flags) { 3864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber // XXX this currently uses decoding time, instead of composition time. 3874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 388abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 389abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t cur_sample = 0; 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t time = 0; 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t n = mTimeToSample[2 * i]; 39620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t delta = mTimeToSample[2 * i + 1]; 39720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (req_time < time + n * delta) { 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int j = (req_time - time) / delta; 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 401da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber uint32_t time1 = time + j * delta; 402da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber uint32_t time2 = time1 + delta; 403da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 404abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sampleTime; 405da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber if (i+1 == mTimeToSampleCount 406da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber || (abs_difference(req_time, time1) 407da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber < abs_difference(req_time, time2))) { 408da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber *sample_index = cur_sample + j; 409abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime = time1; 410da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber } else { 411da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber *sample_index = cur_sample + j + 1; 412abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime = time2; 413da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber } 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 415abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 416abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 417abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 418abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (sampleTime > req_time && *sample_index > 0) { 419abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --*sample_index; 420abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 421abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 422abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 423abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 424abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 425abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 426abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (sampleTime < req_time 427abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber && *sample_index + 1 < mNumSampleSizes) { 428abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++*sample_index; 429abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 430abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 431abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 432abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 433abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 434abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber time += delta * n; 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber cur_sample += n; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_OUT_OF_RANGE; 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 447abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear( 448abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 449abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber Mutex::Autolock autoLock(mLock); 450abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = 0; 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset < 0) { 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // All samples are sync-samples. 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = start_sample_index; 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 459abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mNumSyncSamples == 0) { 460abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 461abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return OK; 462abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 463da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 464abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t left = 0; 465abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber while (left < mNumSyncSamples) { 4668bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t x = mSyncSamples[left]; 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 468abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x >= start_sample_index) { 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 471abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 472abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++left; 473abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 474f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong if (left > 0) { 475f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong --left; 476f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong } 477abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 478abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t x; 479abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mDataSource->readAt( 480abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) { 481abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_IO; 482abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 483abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 484abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = ntohl(x); 485abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --x; 486abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 487abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (left + 1 < mNumSyncSamples) { 4888bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t y = mSyncSamples[left + 1]; 489abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 490abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // our sample lies between sync samples x and y. 491abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 492abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleIterator->seekTo(start_sample_index); 493abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 494abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 495abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 496abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 497abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sample_time = mSampleIterator->getSampleTime(); 498abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 499abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleIterator->seekTo(x); 500abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 501abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 502abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 503abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t x_time = mSampleIterator->getSampleTime(); 504abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 505abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleIterator->seekTo(y); 506abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 507abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 508abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 509abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 510abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t y_time = mSampleIterator->getSampleTime(); 511abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 512abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (abs_difference(x_time, sample_time) 513abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber > abs_difference(y_time, sample_time)) { 514abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // Pick the sync sample closest (timewise) to the start-sample. 515abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = y; 516abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++left; 517abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 518abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 519abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 520abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 521abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 522abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 523abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x > start_sample_index) { 524abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(left > 0); 525abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 526abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mDataSource->readAt( 527abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + (left - 1) * 4, &x, 4) != 4) { 528abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_IO; 529abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 530abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 531abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = ntohl(x); 532abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --x; 533abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 534abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(x <= start_sample_index); 535abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 536abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 537abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 538abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 539abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 540abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 541abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x < start_sample_index) { 542abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (left + 1 >= mNumSyncSamples) { 543abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_OUT_OF_RANGE; 544abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 545abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 5468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber x = mSyncSamples[left + 1]; 547abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 548abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(x >= start_sample_index); 549abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 550abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 551abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 552abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 553abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 554abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 555abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 558abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = x; 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 564c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 565c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 5667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (mSyncSampleOffset < 0) { 5677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // All samples are sync-samples. 5687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = 0; 5697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 5707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t bestSampleIndex = 0; 5737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t maxSampleSize = 0; 5747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5757e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 5767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5777e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Consider the first kMaxNumSyncSamplesToScan sync samples and 5787e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // pick the one with the largest (compressed) size as the thumbnail. 5797e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5807e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t numSamplesToScan = mNumSyncSamples; 5817e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 5827e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber numSamplesToScan = kMaxNumSyncSamplesToScan; 5837e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5847e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5857e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber for (size_t i = 0; i < numSamplesToScan; ++i) { 5868bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t x = mSyncSamples[i]; 5877e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5887e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Now x is a sample index. 5897e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t sampleSize; 590c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(x, &sampleSize); 5917e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (err != OK) { 5927e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return err; 5937e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5947e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5957e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (i == 0 || sampleSize > maxSampleSize) { 5967e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber bestSampleIndex = x; 5977e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber maxSampleSize = sampleSize; 5987e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5997e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 6007e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 6017e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = bestSampleIndex; 6027e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 6037e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 6047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber} 6057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 606c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l( 607c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, size_t *sampleSize) { 608c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return mSampleIterator->getSampleSizeDirect( 609c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, sampleSize); 610c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 611c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 612c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample( 613c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, 614c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t *offset, 615c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber size_t *size, 6168bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t *decodingTime, 6178bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool *isSyncSample) { 618c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 619c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 620c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 621c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 622c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 623c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 624c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 625c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (offset) { 626c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = mSampleIterator->getSampleOffset(); 627c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 628c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 629c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (size) { 630c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = mSampleIterator->getSampleSize(); 631c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 632c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 633c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (decodingTime) { 634c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *decodingTime = mSampleIterator->getSampleTime(); 635c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 636c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 6378bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 6388bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = false; 6398bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mSyncSampleOffset < 0) { 6408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber // Every sample is a sync sample. 6418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 6428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } else { 6438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 6448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 6458bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ? mLastSyncSampleIndex : 0; 6468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 6478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 6488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ++i; 6498bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 6508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 6518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 6528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 6538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 6548bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 6558bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex = i; 6568bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 6578bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 6588bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 659c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 660c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 661c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 6624931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) const { 6634931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mCompositionTimeDeltaEntries == NULL) { 6644931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return 0; 6654931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 6664931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 6674931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber uint32_t curSample = 0; 6684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber for (size_t i = 0; i < mNumCompositionTimeDeltaEntries; ++i) { 6694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber uint32_t sampleCount = mCompositionTimeDeltaEntries[2 * i]; 6704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 6714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (sampleIndex < curSample + sampleCount) { 6724931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber uint32_t sampleDelta = mCompositionTimeDeltaEntries[2 * i + 1]; 6734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 6744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return sampleDelta; 6754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 6764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 6774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber curSample += sampleCount; 6784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 6794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 6804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return 0; 6814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 6824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 68320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 68420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 685