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 2375226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen#include "SampleTable.h" 2475226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen#include "SampleIterator.h" 2589e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 282a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen#include <media/DataSourceBase.h> 2989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber#include <media/stagefright/foundation/ADebug.h> 30607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang#include <media/stagefright/foundation/ByteUtils.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 1172a243f08193fe9ff1afe018e9953f01c44ced9deMarco NelissenSampleTable::SampleTable(DataSourceBase *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; 704ed80276361a18380bacc22bde92689e0e4901726Bartosz Bialek if (sampleTime > UINT32_MAX - delta) { 705ed80276361a18380bacc22bde92689e0e4901726Bartosz Bialek ALOGE("%u + %u would overflow, clamping", 706ed80276361a18380bacc22bde92689e0e4901726Bartosz Bialek sampleTime, delta); 707ed80276361a18380bacc22bde92689e0e4901726Bartosz Bialek sampleTime = UINT32_MAX; 708ed80276361a18380bacc22bde92689e0e4901726Bartosz Bialek } else { 709ed80276361a18380bacc22bde92689e0e4901726Bartosz Bialek sampleTime += delta; 710ed80276361a18380bacc22bde92689e0e4901726Bartosz Bialek } 7114678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7124678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7134678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7144678a6dc5f09008481524949a9667af5a6190374Andreas Huber qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry), 7154678a6dc5f09008481524949a9667af5a6190374Andreas Huber CompareIncreasingTime); 7164678a6dc5f09008481524949a9667af5a6190374Andreas Huber} 7174678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7184678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime( 719599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint64_t req_time, uint64_t scale_num, uint64_t scale_den, 720599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t *sample_index, uint32_t flags) { 7214678a6dc5f09008481524949a9667af5a6190374Andreas Huber buildSampleEntriesTable(); 7224678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7233564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia if (mSampleTimeEntries == NULL) { 7243564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia return ERROR_OUT_OF_RANGE; 7253564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia } 7263564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia 727d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang if (flags == kFlagFrameIndex) { 728d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang if (req_time >= mNumSampleSizes) { 729d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang return ERROR_OUT_OF_RANGE; 730d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang } 731d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang *sample_index = mSampleTimeEntries[req_time].mSampleIndex; 732d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang return OK; 733d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang } 734d3e0d861aa68a7ef129fe228595bff734448ebc8Chong Zhang 7354678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t left = 0; 736225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t right_plus_one = mNumSampleSizes; 737225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar while (left < right_plus_one) { 738225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t center = left + (right_plus_one - left) / 2; 739599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint64_t centerTime = 740599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar getSampleTime(center, scale_num, scale_den); 7414678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7424678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (req_time < centerTime) { 743225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar right_plus_one = center; 7444678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else if (req_time > centerTime) { 7454678a6dc5f09008481524949a9667af5a6190374Andreas Huber left = center + 1; 7464678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else { 747599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = mSampleTimeEntries[center].mSampleIndex; 748599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return OK; 7494678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7504678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7514678a6dc5f09008481524949a9667af5a6190374Andreas Huber 752599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t closestIndex = left; 753599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 754599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (closestIndex == mNumSampleSizes) { 755a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber if (flags == kFlagAfter) { 756a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber return ERROR_OUT_OF_RANGE; 757a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber } 758599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagBefore; 759599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } else if (closestIndex == 0) { 760599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (flags == kFlagBefore) { 761599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // normally we should return out of range, but that is 762599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // treated as end-of-stream. instead return first sample 763599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // 764599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // return ERROR_OUT_OF_RANGE; 765599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 766599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagAfter; 7674678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7684678a6dc5f09008481524949a9667af5a6190374Andreas Huber 7694678a6dc5f09008481524949a9667af5a6190374Andreas Huber switch (flags) { 7704678a6dc5f09008481524949a9667af5a6190374Andreas Huber case kFlagBefore: 7714678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 772599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --closestIndex; 7734678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 7744678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 77520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7764678a6dc5f09008481524949a9667af5a6190374Andreas Huber case kFlagAfter: 7774678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 778599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // nothing to do 7794678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 78020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 78120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7824678a6dc5f09008481524949a9667af5a6190374Andreas Huber default: 7834678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 7844678a6dc5f09008481524949a9667af5a6190374Andreas Huber CHECK(flags == kFlagClosest); 785599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // pick closest based on timestamp. use abs_difference for safety 786599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (abs_difference( 787599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar getSampleTime(closestIndex, scale_num, scale_den), req_time) > 788599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar abs_difference( 789599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) { 790599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --closestIndex; 7914678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 7924678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 7934678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 79420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 79520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7964678a6dc5f09008481524949a9667af5a6190374Andreas Huber *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; 7974678a6dc5f09008481524949a9667af5a6190374Andreas Huber return OK; 79820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 79920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 800abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear( 801abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 802abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber Mutex::Autolock autoLock(mLock); 803abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 80420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = 0; 80520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 80620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset < 0) { 80720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // All samples are sync-samples. 80820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = start_sample_index; 80920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 81020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 81120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 812abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mNumSyncSamples == 0) { 813abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 814abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return OK; 815abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 816da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 817abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t left = 0; 818225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t right_plus_one = mNumSyncSamples; 819225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar while (left < right_plus_one) { 820225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t center = left + (right_plus_one - left) / 2; 8218f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber uint32_t x = mSyncSamples[center]; 82220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8238f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber if (start_sample_index < x) { 824225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar right_plus_one = center; 8258f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } else if (start_sample_index > x) { 8268f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber left = center + 1; 8278f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } else { 828599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = x; 829599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return OK; 83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 831f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong } 832599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 8338d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng if (left == mNumSyncSamples) { 8348d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng if (flags == kFlagAfter) { 83529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("tried to find a sync frame after the last one: %d", left); 8368d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng return ERROR_OUT_OF_RANGE; 8378d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng } 838599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagBefore; 8398d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng } 840599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar else if (left == 0) { 841599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (flags == kFlagBefore) { 842599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar ALOGE("tried to find a sync frame before the first one: %d", left); 843abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 844599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // normally we should return out of range, but that is 845599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // treated as end-of-stream. instead seek to first sync 846599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // 847599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // return ERROR_OUT_OF_RANGE; 848abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 849599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagAfter; 850abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 851abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 852599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // Now ssi[left - 1] <(=) start_sample_index <= ssi[left] 853abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 854abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 855abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 856599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --left; 857abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 858abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 859abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 860abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 861599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // nothing to do 862abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 863abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 864abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 865599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar { 866599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // this route is not used, but implement it nonetheless 867599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar CHECK(flags == kFlagClosest); 868599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 869599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar status_t err = mSampleIterator->seekTo(start_sample_index); 870599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 871599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 872599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 873599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t sample_time = mSampleIterator->getSampleTime(); 874599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 875599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar err = mSampleIterator->seekTo(mSyncSamples[left]); 876599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 877599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 878599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 879599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t upper_time = mSampleIterator->getSampleTime(); 880599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 881599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar err = mSampleIterator->seekTo(mSyncSamples[left - 1]); 882599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 883599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 884599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 885599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t lower_time = mSampleIterator->getSampleTime(); 886599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 887599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // use abs_difference for safety 888599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (abs_difference(upper_time, sample_time) > 889599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar abs_difference(sample_time, lower_time)) { 890599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --left; 891599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 892abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 893599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 89420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 89520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 896599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = mSyncSamples[left]; 89720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 89820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 89920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9007e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 901c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 902c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 9037e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (mSyncSampleOffset < 0) { 9047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // All samples are sync-samples. 9057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = 0; 9067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 9077e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9087e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9097e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t bestSampleIndex = 0; 9107e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t maxSampleSize = 0; 9117e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 9137e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9147e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Consider the first kMaxNumSyncSamplesToScan sync samples and 9157e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // pick the one with the largest (compressed) size as the thumbnail. 9167e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t numSamplesToScan = mNumSyncSamples; 9187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 9197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber numSamplesToScan = kMaxNumSyncSamplesToScan; 9207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9227e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber for (size_t i = 0; i < numSamplesToScan; ++i) { 9238bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t x = mSyncSamples[i]; 9247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Now x is a sample index. 9267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t sampleSize; 927c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(x, &sampleSize); 9287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (err != OK) { 9297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return err; 9307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (i == 0 || sampleSize > maxSampleSize) { 9337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber bestSampleIndex = x; 9347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber maxSampleSize = sampleSize; 9357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 9377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = bestSampleIndex; 9397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 9407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 9417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber} 9427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 943c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l( 944c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, size_t *sampleSize) { 945c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return mSampleIterator->getSampleSizeDirect( 946c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, sampleSize); 947c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 948c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 949c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample( 950c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, 951c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t *offset, 952c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber size_t *size, 9534678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t *compositionTime, 954170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih bool *isSyncSample, 955170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t *sampleDuration) { 956c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 957c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 958c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 959c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 960c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 961c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 962c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 963c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (offset) { 964c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = mSampleIterator->getSampleOffset(); 965c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 966c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 967c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (size) { 968c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = mSampleIterator->getSampleSize(); 969c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 970c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 9714678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (compositionTime) { 9724678a6dc5f09008481524949a9667af5a6190374Andreas Huber *compositionTime = mSampleIterator->getSampleTime(); 973c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 974c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 9758bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 9768bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = false; 9778bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mSyncSampleOffset < 0) { 9788bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber // Every sample is a sync sample. 9798bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 9808bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } else { 9818bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 9828bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 9838bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ? mLastSyncSampleIndex : 0; 9848bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 9858bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 9868bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ++i; 9878bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 9888bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 9898bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 9908bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 9918bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 9928bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 9938bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex = i; 9948bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 9958bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 9968bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 997170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih if (sampleDuration) { 998170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih *sampleDuration = mSampleIterator->getSampleDuration(); 999170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih } 1000170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih 1001c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 1002c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 1003c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1004b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissenint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) { 100589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex); 10064931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 10074931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 100820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 1009