1c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber/* 2c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * Copyright (C) 2010 The Android Open Source Project 3c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * 4c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * you may not use this file except in compliance with the License. 6c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * You may obtain a copy of the License at 7c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * 8c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * 10c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * Unless required by applicable law or agreed to in writing, software 11c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * See the License for the specific language governing permissions and 14c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * limitations under the License. 15c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber */ 16c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 17c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#define LOG_TAG "SampleIterator" 18c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//#define LOG_NDEBUG 0 19c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include <utils/Log.h> 20c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 2175226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen#include "SampleIterator.h" 22c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 23c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include <arpa/inet.h> 24c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 252a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen#include <media/DataSourceBase.h> 26f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 27607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang#include <media/stagefright/foundation/ByteUtils.h> 28c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 2975226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen#include "SampleTable.h" 30c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 31c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Hubernamespace android { 32c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 33c57b67905c2128ddadfeca96785ee1f593b6605aAndreas HuberSampleIterator::SampleIterator(SampleTable *table) 34c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber : mTable(table), 35c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mInitialized(false), 36c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTimeToSampleIndex(0), 37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSSampleIndex(0), 38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSSampleTime(0), 39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSCount(0), 40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSDuration(0) { 41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber reset(); 42c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 43c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 44c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Hubervoid SampleIterator::reset() { 45c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkIndex = 0; 46c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mFirstChunk = 0; 47c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mFirstChunkSampleIndex = 0; 48c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mStopChunk = 0; 49c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mStopChunkSampleIndex = 0; 50c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSamplesPerChunk = 0; 51c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mChunkDesc = 0; 52c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 53c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 54c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::seekTo(uint32_t sampleIndex) { 553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("seekTo(%d)", sampleIndex); 56c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 57213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber if (sampleIndex >= mTable->mNumSampleSizes) { 58213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber return ERROR_END_OF_STREAM; 59213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber } 60213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber 61c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mSampleToChunkOffset < 0 62c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber || mTable->mChunkOffsetOffset < 0 63c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber || mTable->mSampleSizeOffset < 0 64c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber || mTable->mTimeToSampleCount == 0) { 65c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 66c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_MALFORMED; 67c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 68c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 69c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mInitialized && mCurrentSampleIndex == sampleIndex) { 70c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 71c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 72c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 73c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (!mInitialized || sampleIndex < mFirstChunkSampleIndex) { 74c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber reset(); 75c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 76c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 77c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (sampleIndex >= mStopChunkSampleIndex) { 78c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 79c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = findChunkRange(sampleIndex)) != OK) { 8029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("findChunkRange failed"); 81c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 82c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 83c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 84c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 85c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber CHECK(sampleIndex < mStopChunkSampleIndex); 86c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 870386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia if (mSamplesPerChunk == 0) { 880386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia ALOGE("b/22802344"); 890386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia return ERROR_MALFORMED; 900386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia } 910386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia 92c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t chunk = 93c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber (sampleIndex - mFirstChunkSampleIndex) / mSamplesPerChunk 94c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber + mFirstChunk; 95c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 96c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (!mInitialized || chunk != mCurrentChunkIndex) { 97c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 98c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = getChunkOffset(chunk, &mCurrentChunkOffset)) != OK) { 9929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("getChunkOffset return error"); 100c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 101c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 102c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 103c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentChunkSampleSizes.clear(); 104c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 105c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t firstChunkSampleIndex = 106c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mFirstChunkSampleIndex 10703237ce0f9584c98ccda76c2474a4ae84c763f5bRobert Shih + mSamplesPerChunk * (chunk - mFirstChunk); 108c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 109c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber for (uint32_t i = 0; i < mSamplesPerChunk; ++i) { 110c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber size_t sampleSize; 111c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = getSampleSizeDirect( 112c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber firstChunkSampleIndex + i, &sampleSize)) != OK) { 11329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("getSampleSizeDirect return error"); 11403237ce0f9584c98ccda76c2474a4ae84c763f5bRobert Shih mCurrentChunkSampleSizes.clear(); 115c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 116c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 117c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 118c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentChunkSampleSizes.push(sampleSize); 119c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 12003237ce0f9584c98ccda76c2474a4ae84c763f5bRobert Shih 12103237ce0f9584c98ccda76c2474a4ae84c763f5bRobert Shih mCurrentChunkIndex = chunk; 122c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 123c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 124c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t chunkRelativeSampleIndex = 125c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber (sampleIndex - mFirstChunkSampleIndex) % mSamplesPerChunk; 126c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 127c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentSampleOffset = mCurrentChunkOffset; 128c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber for (uint32_t i = 0; i < chunkRelativeSampleIndex; ++i) { 129c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentSampleOffset += mCurrentChunkSampleSizes[i]; 130c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 131c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 132c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentSampleSize = mCurrentChunkSampleSizes[chunkRelativeSampleIndex]; 133c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (sampleIndex < mTTSSampleIndex) { 134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTimeToSampleIndex = 0; 135c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSSampleIndex = 0; 136c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSSampleTime = 0; 137c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSCount = 0; 138c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSDuration = 0; 139c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 140c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 141c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 142170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih if ((err = findSampleTimeAndDuration( 143170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih sampleIndex, &mCurrentSampleTime, &mCurrentSampleDuration)) != OK) { 14429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("findSampleTime return error"); 145c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 146c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 147c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 148c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mCurrentSampleIndex = sampleIndex; 149c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 150c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mInitialized = true; 151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::findChunkRange(uint32_t sampleIndex) { 156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber CHECK(sampleIndex >= mFirstChunkSampleIndex); 157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber while (sampleIndex >= mStopChunkSampleIndex) { 159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mSampleToChunkIndex == mTable->mNumSampleToChunkOffsets) { 160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_OUT_OF_RANGE; 161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 162c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 163c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mFirstChunkSampleIndex = mStopChunkSampleIndex; 164c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 165c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber const SampleTable::SampleToChunkEntry *entry = 166c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &mTable->mSampleToChunkEntries[mSampleToChunkIndex]; 167c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 168c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mFirstChunk = entry->startChunk; 169c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSamplesPerChunk = entry->samplesPerChunk; 170c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mChunkDesc = entry->chunkDesc; 171c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 172c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mSampleToChunkIndex + 1 < mTable->mNumSampleToChunkOffsets) { 173c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mStopChunk = entry[1].startChunk; 174c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 175b0ed640b15b57b7262a34e549e76d44db5b155dbMarco Nelissen if (mSamplesPerChunk == 0 || mStopChunk < mFirstChunk || 176cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker (mStopChunk - mFirstChunk) > UINT32_MAX / mSamplesPerChunk || 177cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker ((mStopChunk - mFirstChunk) * mSamplesPerChunk > 178cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker UINT32_MAX - mFirstChunkSampleIndex)) { 179cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker 180cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker return ERROR_OUT_OF_RANGE; 181cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker } 182c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mStopChunkSampleIndex = 183c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mFirstChunkSampleIndex 184c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber + (mStopChunk - mFirstChunk) * mSamplesPerChunk; 185c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } else { 186c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mStopChunk = 0xffffffff; 187c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mStopChunkSampleIndex = 0xffffffff; 188c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 189c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 190c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber ++mSampleToChunkIndex; 191c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 192c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 193c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 194c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 195c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 196c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleIterator::getChunkOffset(uint32_t chunk, off64_t *offset) { 197c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = 0; 198c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 199c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (chunk >= mTable->mNumChunkOffsets) { 200c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_OUT_OF_RANGE; 201c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 202c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 203c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mChunkOffsetType == SampleTable::kChunkOffsetType32) { 204c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t offset32; 205c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 206c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mDataSource->readAt( 207c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTable->mChunkOffsetOffset + 8 + 4 * chunk, 208c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &offset32, 209c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sizeof(offset32)) < (ssize_t)sizeof(offset32)) { 210c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 211c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 212c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 213c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = ntohl(offset32); 214c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } else { 215c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber CHECK_EQ(mTable->mChunkOffsetType, SampleTable::kChunkOffsetType64); 216c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 217c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint64_t offset64; 218c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mDataSource->readAt( 219c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTable->mChunkOffsetOffset + 8 + 8 * chunk, 220c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &offset64, 221c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sizeof(offset64)) < (ssize_t)sizeof(offset64)) { 222c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 223c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 224c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 225c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = ntoh64(offset64); 226c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 227c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 228c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 229c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 230c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 231c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::getSampleSizeDirect( 232c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, size_t *size) { 233c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = 0; 234c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 235c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (sampleIndex >= mTable->mNumSampleSizes) { 236c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_OUT_OF_RANGE; 237c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 238c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 239c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mDefaultSampleSize > 0) { 240c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = mTable->mDefaultSampleSize; 241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber switch (mTable->mSampleSizeFieldSize) { 245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber case 32: 246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber { 24716c8f0ddb60293a694c39aec90aeb0a8663234cashaohongsheng uint32_t x; 248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mDataSource->readAt( 249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTable->mSampleSizeOffset + 12 + 4 * sampleIndex, 25016c8f0ddb60293a694c39aec90aeb0a8663234cashaohongsheng &x, sizeof(x)) < (ssize_t)sizeof(x)) { 251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 25416c8f0ddb60293a694c39aec90aeb0a8663234cashaohongsheng *size = ntohl(x); 255c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber break; 256c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 257c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 258c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber case 16: 259c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber { 260c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint16_t x; 261c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mDataSource->readAt( 262c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTable->mSampleSizeOffset + 12 + 2 * sampleIndex, 263c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &x, sizeof(x)) < (ssize_t)sizeof(x)) { 264c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 265c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 266c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 267c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = ntohs(x); 268c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber break; 269c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 270c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 271c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber case 8: 272c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber { 273c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint8_t x; 274c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mDataSource->readAt( 275c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTable->mSampleSizeOffset + 12 + sampleIndex, 276c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &x, sizeof(x)) < (ssize_t)sizeof(x)) { 277c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 278c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 279c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 280c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = x; 281c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber break; 282c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 283c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 284c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber default: 285c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber { 2860bdcf66bf30dfe60b44ea2d69bc846cca33fc3f3Colin Cross CHECK_EQ(mTable->mSampleSizeFieldSize, 4u); 287c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 288c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint8_t x; 289c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mTable->mDataSource->readAt( 290c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTable->mSampleSizeOffset + 12 + sampleIndex / 2, 291c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber &x, sizeof(x)) < (ssize_t)sizeof(x)) { 292c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 293c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 294c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 295c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = (sampleIndex & 1) ? x & 0x0f : x >> 4; 296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber break; 297c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 298c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 299c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 300c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 301c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 302c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 303170056540e9ce65261b45efd15f67e72e2df1bedRobert Shihstatus_t SampleIterator::findSampleTimeAndDuration( 304170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t sampleIndex, uint32_t *time, uint32_t *duration) { 305c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (sampleIndex >= mTable->mNumSampleSizes) { 306c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_OUT_OF_RANGE; 307c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 308c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 309833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen while (true) { 310833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen if (mTTSSampleIndex > UINT32_MAX - mTTSCount) { 311833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen return ERROR_OUT_OF_RANGE; 312833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen } 313833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen if(sampleIndex < mTTSSampleIndex + mTTSCount) { 314833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen break; 315833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen } 316833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen if (mTimeToSampleIndex == mTable->mTimeToSampleCount || 317bbc0c8bb5478ee59970977033802185cccf10b48Marco Nelissen (mTTSDuration != 0 && mTTSCount > UINT32_MAX / mTTSDuration) || 318833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen mTTSSampleTime > UINT32_MAX - (mTTSCount * mTTSDuration)) { 319c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_OUT_OF_RANGE; 320c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 321c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 322c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSSampleIndex += mTTSCount; 323c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSSampleTime += mTTSCount * mTTSDuration; 324c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 325c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSCount = mTable->mTimeToSample[2 * mTimeToSampleIndex]; 326c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mTTSDuration = mTable->mTimeToSample[2 * mTimeToSampleIndex + 1]; 327c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 328c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber ++mTimeToSampleIndex; 329c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 330c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 331c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex); 332c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 333b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen int32_t offset = mTable->getCompositionTimeOffset(sampleIndex); 334b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen if ((offset < 0 && *time < (offset == INT32_MIN ? 335b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen INT32_MAX : uint32_t(-offset))) || 336b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen (offset > 0 && *time > UINT32_MAX - offset)) { 337b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen ALOGE("%u + %d would overflow", *time, offset); 338b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen return ERROR_OUT_OF_RANGE; 339b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen } 340b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen if (offset > 0) { 341b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen *time += offset; 342b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen } else { 343b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen *time -= (offset == INT32_MIN ? INT32_MAX : (-offset)); 344b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen } 3454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 346170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih *duration = mTTSDuration; 347170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih 348c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 349c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 350c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 351c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} // namespace android 352c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 353