SampleTable.cpp revision 158c197b668ad684f92829db6a31bee3aec794ba
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 211ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim#include <limits> 221ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim 2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 24c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include "include/SampleIterator.h" 2589e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber#include <media/stagefright/foundation/ADebug.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 323564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia/* TODO: remove after being merged into other branches */ 333564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#ifndef UINT32_MAX 343564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#define UINT32_MAX (4294967295U) 353564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#endif 363564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 42c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 43c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 44c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 45c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 46c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 47c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 48c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 501ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kimconst off64_t kMaxOffset = std::numeric_limits<off64_t>::max(); 511ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim 5289aa8fe4cb00d2f24260005b008602232d678684Andreas Huberstruct SampleTable::CompositionDeltaLookup { 5389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber CompositionDeltaLookup(); 5489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 5589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber void setEntries( 56b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen const int32_t *deltaEntries, size_t numDeltaEntries); 5789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 58b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen int32_t getCompositionTimeOffset(uint32_t sampleIndex); 5989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 6089aa8fe4cb00d2f24260005b008602232d678684Andreas Huberprivate: 6189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber Mutex mLock; 6289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 63b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen const int32_t *mDeltaEntries; 6489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber size_t mNumDeltaEntries; 6589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 6689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber size_t mCurrentDeltaEntry; 6789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber size_t mCurrentEntrySampleIndex; 6889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 6989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup); 7089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}; 7189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 7289aa8fe4cb00d2f24260005b008602232d678684Andreas HuberSampleTable::CompositionDeltaLookup::CompositionDeltaLookup() 7389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber : mDeltaEntries(NULL), 7489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mNumDeltaEntries(0), 7589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentDeltaEntry(0), 7689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentEntrySampleIndex(0) { 7789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber} 7889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 7989aa8fe4cb00d2f24260005b008602232d678684Andreas Hubervoid SampleTable::CompositionDeltaLookup::setEntries( 80b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen const int32_t *deltaEntries, size_t numDeltaEntries) { 8189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber Mutex::Autolock autolock(mLock); 8289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 8389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mDeltaEntries = deltaEntries; 8489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mNumDeltaEntries = numDeltaEntries; 8589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentDeltaEntry = 0; 8689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentEntrySampleIndex = 0; 8789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber} 8889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 89b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissenint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset( 9089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber uint32_t sampleIndex) { 9189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber Mutex::Autolock autolock(mLock); 9289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 9389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber if (mDeltaEntries == NULL) { 9489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return 0; 9589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber } 9689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 9789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber if (sampleIndex < mCurrentEntrySampleIndex) { 9889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentDeltaEntry = 0; 9989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentEntrySampleIndex = 0; 10089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber } 10189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 10289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber while (mCurrentDeltaEntry < mNumDeltaEntries) { 10389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry]; 10489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) { 10589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return mDeltaEntries[2 * mCurrentDeltaEntry + 1]; 10689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber } 10789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 10889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentEntrySampleIndex += sampleCount; 10989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber ++mCurrentDeltaEntry; 11089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber } 11189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 11289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return 0; 11389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber} 11489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 11589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber//////////////////////////////////////////////////////////////////////////////// 11689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 117693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source) 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset(-1), 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType(0), 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets(0), 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset(-1), 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets(0), 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset(-1), 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize(0), 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize(0), 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes(0), 12870dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa mHasTimeToSample(false), 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount(0), 130583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTimeToSample(NULL), 1314678a6dc5f09008481524949a9667af5a6190374Andreas Huber mSampleTimeEntries(NULL), 1324931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries(NULL), 1334931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mNumCompositionTimeDeltaEntries(0), 13489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup(new CompositionDeltaLookup), 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset(-1), 136c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mNumSyncSamples(0), 1378bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples(NULL), 1388bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex(0), 139583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mSampleToChunkEntries(NULL), 140583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTotalSize(0) { 141c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = new SampleIterator(this); 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() { 145c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete[] mSampleToChunkEntries; 146c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = NULL; 147c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber delete[] mSyncSamples; 1498bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples = NULL; 1508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 151583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa delete[] mTimeToSample; 152583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTimeToSample = NULL; 153583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa 15489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber delete mCompositionDeltaLookup; 15589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup = NULL; 15689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 1574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber delete[] mCompositionTimeDeltaEntries; 1584931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = NULL; 1594931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 1604678a6dc5f09008481524949a9667af5a6190374Andreas Huber delete[] mSampleTimeEntries; 1614678a6dc5f09008481524949a9667af5a6190374Andreas Huber mSampleTimeEntries = NULL; 1624678a6dc5f09008481524949a9667af5a6190374Andreas Huber 163c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete mSampleIterator; 164c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = NULL; 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 167169c286ed166499c5099d2b336967e0bf3d25551Andreas Huberbool SampleTable::isValid() const { 168169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return mChunkOffsetOffset >= 0 169169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber && mSampleToChunkOffset >= 0 170169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber && mSampleSizeOffset >= 0 17170dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa && mHasTimeToSample; 172169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber} 173169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams( 175c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetOffset >= 0) { 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1800c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset = data_offset; 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType = type; 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 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 mNumChunkOffsets = U32_AT(&header[4]); 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetType == kChunkOffsetType32) { 203ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin if ((data_size - 8) / 4 < mNumChunkOffsets) { 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 207ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin if ((data_size - 8) / 8 < mNumChunkOffsets) { 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams( 216c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleToChunkOffset >= 0) { 2181cb23b033987e86827a4fa96550c6a3670b688f1Marco Nelissen // already set 2191cb23b033987e86827a4fa96550c6a3670b688f1Marco Nelissen return ERROR_MALFORMED; 2201cb23b033987e86827a4fa96550c6a3670b688f1Marco Nelissen } 2211cb23b033987e86827a4fa96550c6a3670b688f1Marco Nelissen 2221cb23b033987e86827a4fa96550c6a3670b688f1Marco Nelissen if (data_offset < 0) { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset = data_offset; 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 23334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets = U32_AT(&header[4]); 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2451ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) { 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2491ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <= 250583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (uint64_t)mNumSampleToChunkOffsets) { 251583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Sample-to-chunk table size too large."); 2525c134e6b2047b10877f02a46f4bb293537269f00Joshua J. Drake return ERROR_OUT_OF_RANGE; 253583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 254583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa 255583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTotalSize += (uint64_t)mNumSampleToChunkOffsets * 256583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa sizeof(SampleToChunkEntry); 257583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (mTotalSize > kMaxTotalSize) { 258583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Sample-to-chunk table size would make sample table too large.\n" 259583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Requested sample-to-chunk table size = %llu\n" 260583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Eventual sample table size >= %llu\n" 261583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Allowed sample table size = %llu\n", 262583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mNumSampleToChunkOffsets * 263583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa sizeof(SampleToChunkEntry), 264583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mTotalSize, 265583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)kMaxTotalSize); 266c24607c29c96f939aed9e33bfa702b1dd79da4b7Joshua J. Drake return ERROR_OUT_OF_RANGE; 267583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 268c24607c29c96f939aed9e33bfa702b1dd79da4b7Joshua J. Drake 269c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = 270ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets]; 271583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (!mSampleToChunkEntries) { 272583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Cannot allocate sample-to-chunk table with %llu entries.", 273583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mNumSampleToChunkOffsets); 274ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return ERROR_OUT_OF_RANGE; 275583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 276583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa 277583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (mNumSampleToChunkOffsets == 0) { 278583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa return OK; 279583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 280583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa 2811ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim if ((off64_t)(kMaxOffset - 8 - 282583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry))) 283583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa < mSampleToChunkOffset) { 284583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa return ERROR_MALFORMED; 285583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 286c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 287c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 2881ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim uint8_t buffer[sizeof(SampleToChunkEntry)]; 289ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin 290c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mDataSource->readAt( 2911ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry), 2921ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim buffer, 2931ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim sizeof(buffer)) 294c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber != (ssize_t)sizeof(buffer)) { 295c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 297dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen // chunk index is 1 based in the spec. 298dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen if (U32_AT(buffer) < 1) { 299dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen ALOGE("b/23534160"); 300dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen return ERROR_OUT_OF_RANGE; 301dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen } 302c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 303c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber // We want the chunk index to be 0-based. 304c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 305c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 306c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 307c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 308c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams( 313c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeOffset >= 0) { 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3180c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset = data_offset; 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12) { 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[12]; 32734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = U32_AT(&header[4]); 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes = U32_AT(&header[8]); 3393564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia if (mNumSampleSizes > (UINT32_MAX - 12) / 16) { 340c27cee30d9359fa83e33b4f87f88e6bb9ef66341Wei Jia ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes); 3413564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia return ERROR_MALFORMED; 3423564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia } 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (type == kSampleSizeType32) { 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = 32; 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDefaultSampleSize != 0) { 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + mNumSampleSizes * 4) { 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((mDefaultSampleSize & 0xffffff00) != 0) { 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // The high 24 bits are reserved and must be 0. 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3609f753df58a70f20db220af31cb202bbd21b30f36Andreas Huber mSampleSizeFieldSize = mDefaultSampleSize & 0xff; 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = 0; 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && mSampleSizeFieldSize != 16) { 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams( 377c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 37870dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa if (mHasTimeToSample || data_size < 8) { 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 38334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount = U32_AT(&header[4]); 3941ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) { 395a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // Choose this bound because 396a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one 397a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // time-to-sample entry in the time-to-sample table. 398a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // 2) mTimeToSampleCount is the number of entries of the time-to-sample 399a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // table. 400a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // 3) We hope that the table size does not exceed UINT32_MAX. 401583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Time-to-sample table size too large."); 402edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih return ERROR_OUT_OF_RANGE; 403edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih } 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 405a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // Note: At this point, we know that mTimeToSampleCount * 2 will not 406a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // overflow because of the above condition. 407583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa 408583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); 409583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTotalSize += allocSize; 410583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (mTotalSize > kMaxTotalSize) { 411583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Time-to-sample table size would make sample table too large.\n" 412583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Requested time-to-sample table size = %llu\n" 413583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Eventual sample table size >= %llu\n" 414583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Allowed sample table size = %llu\n", 415583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)allocSize, 416583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mTotalSize, 417583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)kMaxTotalSize); 418583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa return ERROR_OUT_OF_RANGE; 419583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 420583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa 421583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2]; 422583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (!mTimeToSample) { 423583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Cannot allocate time-to-sample table with %llu entries.", 424583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mTimeToSampleCount); 425583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa return ERROR_OUT_OF_RANGE; 426583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 427583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa 428583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (mDataSource->readAt(data_offset + 8, mTimeToSample, 429583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (size_t)allocSize) < (ssize_t)allocSize) { 430583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Incomplete data read for time-to-sample table."); 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 434583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) { 435583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTimeToSample[i] = ntohl(mTimeToSample[i]); 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43770dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa 43870dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa mHasTimeToSample = true; 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 442b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen// NOTE: per 14996-12, version 0 ctts contains unsigned values, while version 1 443b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen// contains signed values, however some software creates version 0 files that 444b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen// contain signed values, so we're always treating the values as signed, 445b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen// regardless of version. 4464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams( 4474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber off64_t data_offset, size_t data_size) { 448df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("There are reordered frames present."); 4494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mCompositionTimeDeltaEntries != NULL || data_size < 8) { 4514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 4524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 4534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4544931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber uint8_t header[8]; 4554931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mDataSource->readAt( 4564931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, header, sizeof(header)) 4574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber < (ssize_t)sizeof(header)) { 4584931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_IO; 4594931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 4604931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 461b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen uint32_t flags = U32_AT(header); 462b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen uint32_t version = flags >> 24; 463b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen flags &= 0xffffff; 464b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen 465b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen if ((version != 0 && version != 1) || flags != 0) { 466b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen // Expected version = 0 or 1, flags = 0. 4674931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 4684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 4694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber size_t numEntries = U32_AT(&header[4]); 4714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 472ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin if (((SIZE_MAX / 8) - 1 < numEntries) || (data_size != (numEntries + 1) * 8)) { 4734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 4744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 4754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mNumCompositionTimeDeltaEntries = numEntries; 477978a6cd08746164ee1f37405d55e0f0bed8f8c24Pawin Vongmasa uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(int32_t); 4781ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim if (allocSize > kMaxTotalSize) { 479583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Composition-time-to-sample table size too large."); 480edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih return ERROR_OUT_OF_RANGE; 481edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih } 482edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih 483583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTotalSize += allocSize; 484583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (mTotalSize > kMaxTotalSize) { 485583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Composition-time-to-sample table would make sample table too large.\n" 486583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Requested composition-time-to-sample table size = %llu\n" 487583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Eventual sample table size >= %llu\n" 488583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Allowed sample table size = %llu\n", 489583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)allocSize, 490583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mTotalSize, 491583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)kMaxTotalSize); 492edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih return ERROR_OUT_OF_RANGE; 493edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih } 494edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih 495b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen mCompositionTimeDeltaEntries = new (std::nothrow) int32_t[2 * numEntries]; 496583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (!mCompositionTimeDeltaEntries) { 497583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Cannot allocate composition-time-to-sample table with %llu " 498583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa "entries.", (unsigned long long)numEntries); 499ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return ERROR_OUT_OF_RANGE; 500583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 5014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 502583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (mDataSource->readAt(data_offset + 8, mCompositionTimeDeltaEntries, 503583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (size_t)allocSize) < (ssize_t)allocSize) { 5044931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber delete[] mCompositionTimeDeltaEntries; 5054931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = NULL; 5064931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 5074931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_IO; 5084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 5094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 5104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber for (size_t i = 0; i < 2 * numEntries; ++i) { 5114931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]); 5124931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 5134931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 51489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup->setEntries( 51589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries); 51689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 5174931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return OK; 5184931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 5194931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 520c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset >= 0 || data_size < 8) { 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 52634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 536a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen uint32_t numSyncSamples = U32_AT(&header[4]); 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 538a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen if (numSyncSamples < 2) { 5393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Table of sync samples is empty or has only a single entry!"); 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 542a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen uint64_t allocSize = (uint64_t)numSyncSamples * sizeof(uint32_t); 5431ab38dcf9bc3388c54adba8c144fd1ee018cd8c5Wonsik Kim if (allocSize > kMaxTotalSize) { 544583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Sync sample table size too large."); 545edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih return ERROR_OUT_OF_RANGE; 546edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih } 547edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih 548583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTotalSize += allocSize; 549583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (mTotalSize > kMaxTotalSize) { 550583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Sync sample table size would make sample table too large.\n" 551583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Requested sync sample table size = %llu\n" 552583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Eventual sample table size >= %llu\n" 553583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Allowed sample table size = %llu\n", 554583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)allocSize, 555583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mTotalSize, 556583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)kMaxTotalSize); 557edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih return ERROR_OUT_OF_RANGE; 558edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih } 559edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih 560a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen mSyncSamples = new (std::nothrow) uint32_t[numSyncSamples]; 561583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (!mSyncSamples) { 562583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Cannot allocate sync sample table with %llu entries.", 563a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen (unsigned long long)numSyncSamples); 564ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return ERROR_OUT_OF_RANGE; 565583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 566ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake 567a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen if (mDataSource->readAt(data_offset + 8, mSyncSamples, 568583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (size_t)allocSize) != (ssize_t)allocSize) { 569158c197b668ad684f92829db6a31bee3aec794baCaroline Tice delete[] mSyncSamples; 570a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen mSyncSamples = NULL; 5718bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber return ERROR_IO; 5728bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 5738bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 574a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen for (size_t i = 0; i < numSyncSamples; ++i) { 575698616546b4f2936c8bbf0dee0f8139ebc446278Roger if (mSyncSamples[i] == 0) { 576698616546b4f2936c8bbf0dee0f8139ebc446278Roger ALOGE("b/32423862, unexpected zero value in stss"); 577698616546b4f2936c8bbf0dee0f8139ebc446278Roger continue; 578698616546b4f2936c8bbf0dee0f8139ebc446278Roger } 5798bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 5808bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 5818bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 582a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen mSyncSampleOffset = data_offset; 583a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen mNumSyncSamples = numSyncSamples; 584a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen 58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const { 58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumChunkOffsets; 59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const { 59320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumSampleSizes; 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) { 59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = 0; 60020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sample_size; 603c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(i, &sample_size); 604da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 60620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_size > *max_size) { 61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = sample_size; 61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 617da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) { 618da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber return time1 > time2 ? time1 - time2 : time2 - time1; 619da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber} 620da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 6214678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static 6224678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) { 6234678a6dc5f09008481524949a9667af5a6190374Andreas Huber const SampleTimeEntry *a = (const SampleTimeEntry *)_a; 6244678a6dc5f09008481524949a9667af5a6190374Andreas Huber const SampleTimeEntry *b = (const SampleTimeEntry *)_b; 6254931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 6264678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (a->mCompositionTime < b->mCompositionTime) { 6274678a6dc5f09008481524949a9667af5a6190374Andreas Huber return -1; 6284678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else if (a->mCompositionTime > b->mCompositionTime) { 6294678a6dc5f09008481524949a9667af5a6190374Andreas Huber return 1; 6304678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 631abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 6324678a6dc5f09008481524949a9667af5a6190374Andreas Huber return 0; 6334678a6dc5f09008481524949a9667af5a6190374Andreas Huber} 6344678a6dc5f09008481524949a9667af5a6190374Andreas Huber 6354678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() { 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 63720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6383564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) { 639cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia if (mNumSampleSizes == 0) { 640cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes); 641cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia } 6424678a6dc5f09008481524949a9667af5a6190374Andreas Huber return; 6434678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 6444678a6dc5f09008481524949a9667af5a6190374Andreas Huber 645583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry); 646583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (mTotalSize > kMaxTotalSize) { 647583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Sample entry table size would make sample table too large.\n" 648583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Requested sample entry table size = %llu\n" 649583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Eventual sample table size >= %llu\n" 650583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa " Allowed sample table size = %llu\n", 651583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry), 652583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mTotalSize, 653583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)kMaxTotalSize); 654583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa return; 655583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 656583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa 657ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes]; 658583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa if (!mSampleTimeEntries) { 659583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa ALOGE("Cannot allocate sample entry table with %llu entries.", 660583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa (unsigned long long)mNumSampleSizes); 661ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return; 662583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa } 6634678a6dc5f09008481524949a9667af5a6190374Andreas Huber 6644678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t sampleIndex = 0; 6654678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t sampleTime = 0; 6664678a6dc5f09008481524949a9667af5a6190374Andreas Huber 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 66820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t n = mTimeToSample[2 * i]; 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t delta = mTimeToSample[2 * i + 1]; 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6714678a6dc5f09008481524949a9667af5a6190374Andreas Huber for (uint32_t j = 0; j < n; ++j) { 67265a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber if (sampleIndex < mNumSampleSizes) { 67365a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // Technically this should always be the case if the file 67465a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // is well-formed, but you know... there's (gasp) malformed 67565a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // content out there. 67620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 67765a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex; 678abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 679b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen int32_t compTimeDelta = 68089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup->getCompositionTimeOffset( 68189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber sampleIndex); 68289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 683b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen if ((compTimeDelta < 0 && sampleTime < 684b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen (compTimeDelta == INT32_MIN ? 685b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen INT32_MAX : uint32_t(-compTimeDelta))) 686b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen || (compTimeDelta > 0 && 687b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen sampleTime > UINT32_MAX - compTimeDelta)) { 688b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen ALOGE("%u + %d would overflow, clamping", 689b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen sampleTime, compTimeDelta); 690b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen if (compTimeDelta < 0) { 691b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen sampleTime = 0; 692b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen } else { 693b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen sampleTime = UINT32_MAX; 694b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen } 695b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen compTimeDelta = 0; 696b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen } 697b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen 69865a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber mSampleTimeEntries[sampleIndex].mCompositionTime = 699b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen compTimeDelta > 0 ? sampleTime + compTimeDelta: 700b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen sampleTime - (-compTimeDelta); 70165a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber } 7024678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7034678a6dc5f09008481524949a9667af5a6190374Andreas Huber ++sampleIndex; 7044678a6dc5f09008481524949a9667af5a6190374Andreas Huber sampleTime += delta; 7054678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7064678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7074678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7084678a6dc5f09008481524949a9667af5a6190374Andreas Huber qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry), 7094678a6dc5f09008481524949a9667af5a6190374Andreas Huber CompareIncreasingTime); 7104678a6dc5f09008481524949a9667af5a6190374Andreas Huber} 7114678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7124678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime( 713599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint64_t req_time, uint64_t scale_num, uint64_t scale_den, 714599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t *sample_index, uint32_t flags) { 7154678a6dc5f09008481524949a9667af5a6190374Andreas Huber buildSampleEntriesTable(); 7164678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7173564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia if (mSampleTimeEntries == NULL) { 7183564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia return ERROR_OUT_OF_RANGE; 7193564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia } 7203564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia 7214678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t left = 0; 722225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t right_plus_one = mNumSampleSizes; 723225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar while (left < right_plus_one) { 724225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t center = left + (right_plus_one - left) / 2; 725599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint64_t centerTime = 726599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar getSampleTime(center, scale_num, scale_den); 7274678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7284678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (req_time < centerTime) { 729225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar right_plus_one = center; 7304678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else if (req_time > centerTime) { 7314678a6dc5f09008481524949a9667af5a6190374Andreas Huber left = center + 1; 7324678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else { 733599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = mSampleTimeEntries[center].mSampleIndex; 734599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return OK; 7354678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7364678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7374678a6dc5f09008481524949a9667af5a6190374Andreas Huber 738599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t closestIndex = left; 739599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 740599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (closestIndex == mNumSampleSizes) { 741a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber if (flags == kFlagAfter) { 742a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber return ERROR_OUT_OF_RANGE; 743a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber } 744599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagBefore; 745599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } else if (closestIndex == 0) { 746599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (flags == kFlagBefore) { 747599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // normally we should return out of range, but that is 748599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // treated as end-of-stream. instead return first sample 749599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // 750599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // return ERROR_OUT_OF_RANGE; 751599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 752599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagAfter; 7534678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7544678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7554678a6dc5f09008481524949a9667af5a6190374Andreas Huber switch (flags) { 7564678a6dc5f09008481524949a9667af5a6190374Andreas Huber case kFlagBefore: 7574678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 758599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --closestIndex; 7594678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 7604678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7624678a6dc5f09008481524949a9667af5a6190374Andreas Huber case kFlagAfter: 7634678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 764599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // nothing to do 7654678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 76620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 76720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7684678a6dc5f09008481524949a9667af5a6190374Andreas Huber default: 7694678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 7704678a6dc5f09008481524949a9667af5a6190374Andreas Huber CHECK(flags == kFlagClosest); 771599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // pick closest based on timestamp. use abs_difference for safety 772599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (abs_difference( 773599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar getSampleTime(closestIndex, scale_num, scale_den), req_time) > 774599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar abs_difference( 775599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) { 776599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --closestIndex; 7774678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7784678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 7794678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7824678a6dc5f09008481524949a9667af5a6190374Andreas Huber *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; 7834678a6dc5f09008481524949a9667af5a6190374Andreas Huber return OK; 78420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 78520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 786abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear( 787abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 788abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber Mutex::Autolock autoLock(mLock); 789abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 79020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = 0; 79120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 79220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset < 0) { 79320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // All samples are sync-samples. 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = start_sample_index; 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 79620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 798abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mNumSyncSamples == 0) { 799abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 800abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return OK; 801abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 802da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 803abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t left = 0; 804225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t right_plus_one = mNumSyncSamples; 805225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar while (left < right_plus_one) { 806225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t center = left + (right_plus_one - left) / 2; 8078f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber uint32_t x = mSyncSamples[center]; 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8098f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber if (start_sample_index < x) { 810225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar right_plus_one = center; 8118f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } else if (start_sample_index > x) { 8128f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber left = center + 1; 8138f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } else { 814599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = x; 815599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return OK; 81620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 817f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong } 818599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 8198d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng if (left == mNumSyncSamples) { 8208d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng if (flags == kFlagAfter) { 82129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("tried to find a sync frame after the last one: %d", left); 8228d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng return ERROR_OUT_OF_RANGE; 8238d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng } 824599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagBefore; 8258d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng } 826599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar else if (left == 0) { 827599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (flags == kFlagBefore) { 828599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar ALOGE("tried to find a sync frame before the first one: %d", left); 829abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 830599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // normally we should return out of range, but that is 831599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // treated as end-of-stream. instead seek to first sync 832599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // 833599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // return ERROR_OUT_OF_RANGE; 834abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 835599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagAfter; 836abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 837abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 838599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // Now ssi[left - 1] <(=) start_sample_index <= ssi[left] 839abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 840abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 841abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 842599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --left; 843abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 844abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 845abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 846abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 847599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // nothing to do 848abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 849abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 850abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 851599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar { 852599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // this route is not used, but implement it nonetheless 853599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar CHECK(flags == kFlagClosest); 854599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 855599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar status_t err = mSampleIterator->seekTo(start_sample_index); 856599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 857599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 858599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 859599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t sample_time = mSampleIterator->getSampleTime(); 860599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 861599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar err = mSampleIterator->seekTo(mSyncSamples[left]); 862599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 863599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 864599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 865599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t upper_time = mSampleIterator->getSampleTime(); 866599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 867599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar err = mSampleIterator->seekTo(mSyncSamples[left - 1]); 868599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 869599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 870599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 871599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t lower_time = mSampleIterator->getSampleTime(); 872599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 873599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // use abs_difference for safety 874599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (abs_difference(upper_time, sample_time) > 875599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar abs_difference(sample_time, lower_time)) { 876599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --left; 877599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 878abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 879599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 88020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 88120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 882599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = mSyncSamples[left]; 88320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 88420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 88520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8867e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 887c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 888c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 8897e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (mSyncSampleOffset < 0) { 8907e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // All samples are sync-samples. 8917e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = 0; 8927e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 8937e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 8947e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 8957e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t bestSampleIndex = 0; 8967e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t maxSampleSize = 0; 8977e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 8987e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 8997e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9007e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Consider the first kMaxNumSyncSamplesToScan sync samples and 9017e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // pick the one with the largest (compressed) size as the thumbnail. 9027e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9037e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t numSamplesToScan = mNumSyncSamples; 9047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 9057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber numSamplesToScan = kMaxNumSyncSamplesToScan; 9067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9077e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9087e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber for (size_t i = 0; i < numSamplesToScan; ++i) { 9098bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t x = mSyncSamples[i]; 9107e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9117e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Now x is a sample index. 9127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t sampleSize; 913c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(x, &sampleSize); 9147e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (err != OK) { 9157e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return err; 9167e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (i == 0 || sampleSize > maxSampleSize) { 9197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber bestSampleIndex = x; 9207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber maxSampleSize = sampleSize; 9217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9227e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9237e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = bestSampleIndex; 9257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 9277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber} 9287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 929c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l( 930c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, size_t *sampleSize) { 931c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return mSampleIterator->getSampleSizeDirect( 932c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, sampleSize); 933c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 934c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 935c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample( 936c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, 937c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t *offset, 938c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber size_t *size, 9394678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t *compositionTime, 940170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih bool *isSyncSample, 941170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t *sampleDuration) { 942c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 943c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 944c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 945c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 946c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 947c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 948c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 949c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (offset) { 950c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = mSampleIterator->getSampleOffset(); 951c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 952c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 953c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (size) { 954c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = mSampleIterator->getSampleSize(); 955c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 956c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 9574678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (compositionTime) { 9584678a6dc5f09008481524949a9667af5a6190374Andreas Huber *compositionTime = mSampleIterator->getSampleTime(); 959c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 960c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 9618bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 9628bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = false; 9638bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mSyncSampleOffset < 0) { 9648bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber // Every sample is a sync sample. 9658bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 9668bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } else { 9678bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 9688bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 9698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ? mLastSyncSampleIndex : 0; 9708bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 9718bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 9728bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ++i; 9738bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 9748bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 9758bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 9768bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 9778bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 9788bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 9798bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex = i; 9808bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 9818bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 9828bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 983170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih if (sampleDuration) { 984170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih *sampleDuration = mSampleIterator->getSampleDuration(); 985170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih } 986170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih 987c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 988c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 989c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 990b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissenint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) { 99189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex); 9924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 9934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 99420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 995