SampleTable.cpp revision ffd7950633edeb8e990770e4c8abb81bdcaa6f32
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "SampleTable" 18c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//#define LOG_NDEBUG 0 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 22c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include "include/SampleIterator.h" 2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber#include <media/stagefright/foundation/ADebug.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 303564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia/* TODO: remove after being merged into other branches */ 313564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#ifndef UINT32_MAX 323564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#define UINT32_MAX (4294967295U) 333564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#endif 343564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 42c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 43c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 44c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 45c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 46c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4889aa8fe4cb00d2f24260005b008602232d678684Andreas Huberstruct SampleTable::CompositionDeltaLookup { 4989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber CompositionDeltaLookup(); 5089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 5189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber void setEntries( 5289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber const uint32_t *deltaEntries, size_t numDeltaEntries); 5389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 5489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber uint32_t getCompositionTimeOffset(uint32_t sampleIndex); 5589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 5689aa8fe4cb00d2f24260005b008602232d678684Andreas Huberprivate: 5789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber Mutex mLock; 5889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 5989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber const uint32_t *mDeltaEntries; 6089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber size_t mNumDeltaEntries; 6189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 6289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber size_t mCurrentDeltaEntry; 6389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber size_t mCurrentEntrySampleIndex; 6489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 6589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup); 6689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}; 6789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 6889aa8fe4cb00d2f24260005b008602232d678684Andreas HuberSampleTable::CompositionDeltaLookup::CompositionDeltaLookup() 6989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber : mDeltaEntries(NULL), 7089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mNumDeltaEntries(0), 7189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentDeltaEntry(0), 7289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentEntrySampleIndex(0) { 7389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber} 7489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 7589aa8fe4cb00d2f24260005b008602232d678684Andreas Hubervoid SampleTable::CompositionDeltaLookup::setEntries( 7689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber const uint32_t *deltaEntries, size_t numDeltaEntries) { 7789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber Mutex::Autolock autolock(mLock); 7889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 7989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mDeltaEntries = deltaEntries; 8089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mNumDeltaEntries = numDeltaEntries; 8189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentDeltaEntry = 0; 8289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentEntrySampleIndex = 0; 8389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber} 8489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 8589aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset( 8689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber uint32_t sampleIndex) { 8789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber Mutex::Autolock autolock(mLock); 8889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 8989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber if (mDeltaEntries == NULL) { 9089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return 0; 9189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber } 9289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 9389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber if (sampleIndex < mCurrentEntrySampleIndex) { 9489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentDeltaEntry = 0; 9589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentEntrySampleIndex = 0; 9689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber } 9789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 9889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber while (mCurrentDeltaEntry < mNumDeltaEntries) { 9989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry]; 10089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) { 10189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return mDeltaEntries[2 * mCurrentDeltaEntry + 1]; 10289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber } 10389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 10489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCurrentEntrySampleIndex += sampleCount; 10589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber ++mCurrentDeltaEntry; 10689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber } 10789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 10889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return 0; 10989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber} 11089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 11189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber//////////////////////////////////////////////////////////////////////////////// 11289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 113693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source) 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset(-1), 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType(0), 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets(0), 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset(-1), 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets(0), 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset(-1), 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize(0), 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize(0), 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes(0), 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount(0), 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample(NULL), 1264678a6dc5f09008481524949a9667af5a6190374Andreas Huber mSampleTimeEntries(NULL), 1274931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries(NULL), 1284931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mNumCompositionTimeDeltaEntries(0), 12989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup(new CompositionDeltaLookup), 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset(-1), 131c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mNumSyncSamples(0), 1328bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples(NULL), 1338bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex(0), 134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries(NULL) { 135c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = new SampleIterator(this); 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() { 139c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete[] mSampleToChunkEntries; 140c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = NULL; 141c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 1428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber delete[] mSyncSamples; 1438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples = NULL; 1448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 14589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber delete mCompositionDeltaLookup; 14689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup = NULL; 14789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 1484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber delete[] mCompositionTimeDeltaEntries; 1494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = NULL; 1504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 1514678a6dc5f09008481524949a9667af5a6190374Andreas Huber delete[] mSampleTimeEntries; 1524678a6dc5f09008481524949a9667af5a6190374Andreas Huber mSampleTimeEntries = NULL; 1534678a6dc5f09008481524949a9667af5a6190374Andreas Huber 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete[] mTimeToSample; 15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = NULL; 156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete mSampleIterator; 158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = NULL; 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 161169c286ed166499c5099d2b336967e0bf3d25551Andreas Huberbool SampleTable::isValid() const { 162169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return mChunkOffsetOffset >= 0 163169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber && mSampleToChunkOffset >= 0 164169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber && mSampleSizeOffset >= 0 165169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber && mTimeToSample != NULL; 166169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber} 167169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams( 169c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetOffset >= 0) { 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1740c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset = data_offset; 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType = type; 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 18434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets = U32_AT(&header[4]); 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetType == kChunkOffsetType32) { 197ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin if ((data_size - 8) / 4 < mNumChunkOffsets) { 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 201ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin if ((data_size - 8) / 8 < mNumChunkOffsets) { 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams( 210c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleToChunkOffset >= 0) { 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset = data_offset; 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 22234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets = U32_AT(&header[4]); 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 234ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin if ((data_size - 8) / 12 < mNumSampleToChunkOffsets) { 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 238ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar if (SIZE_MAX / sizeof(SampleToChunkEntry) <= (size_t)mNumSampleToChunkOffsets) 239c24607c29c96f939aed9e33bfa702b1dd79da4b7Joshua J. Drake return ERROR_OUT_OF_RANGE; 240c24607c29c96f939aed9e33bfa702b1dd79da4b7Joshua J. Drake 241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = 242ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets]; 243ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake if (!mSampleToChunkEntries) 244ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return ERROR_OUT_OF_RANGE; 245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint8_t buffer[12]; 248ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin 249ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin if (((SIZE_MAX / 12) - 8 - i) < mSampleToChunkOffset) { 250ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin return ERROR_MALFORMED; 251ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin } 252ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin 253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mDataSource->readAt( 254c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) 255c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber != (ssize_t)sizeof(buffer)) { 256c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 257c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 258c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 259c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. 260c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 261c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber // We want the chunk index to be 0-based. 262c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 263c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 264c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 265c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 266c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams( 271c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeOffset >= 0) { 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2760c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset = data_offset; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12) { 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[12]; 28534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = U32_AT(&header[4]); 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes = U32_AT(&header[8]); 2973564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia if (mNumSampleSizes > (UINT32_MAX - 12) / 16) { 2983564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia return ERROR_MALFORMED; 2993564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia } 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (type == kSampleSizeType32) { 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = 32; 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDefaultSampleSize != 0) { 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + mNumSampleSizes * 4) { 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((mDefaultSampleSize & 0xffffff00) != 0) { 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // The high 24 bits are reserved and must be 0. 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3179f753df58a70f20db220af31cb202bbd21b30f36Andreas Huber mSampleSizeFieldSize = mDefaultSampleSize & 0xff; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = 0; 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && mSampleSizeFieldSize != 16) { 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams( 334c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mTimeToSample != NULL || data_size < 8) { 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 34034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount = U32_AT(&header[4]); 351a105482ae577852ffd08ce88ae5d1ba81db875acWei Jia uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); 3522c5fb0c7249ba7e5d79236c61a1c94a489041e65Wei Jia if (allocSize > UINT32_MAX) { 353edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih return ERROR_OUT_OF_RANGE; 354edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih } 355ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2]; 356ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake if (!mTimeToSample) 357ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return ERROR_OUT_OF_RANGE; 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; 36034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset + 8, mTimeToSample, size) < (ssize_t)size) { 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample[i] = ntohl(mTimeToSample[i]); 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3724931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams( 3734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber off64_t data_offset, size_t data_size) { 374df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("There are reordered frames present."); 3754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mCompositionTimeDeltaEntries != NULL || data_size < 8) { 3774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 3784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber uint8_t header[8]; 3814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mDataSource->readAt( 3824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, header, sizeof(header)) 3834931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber < (ssize_t)sizeof(header)) { 3844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_IO; 3854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (U32_AT(header) != 0) { 3884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber // Expected version = 0, flags = 0. 3894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 3904931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3914931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber size_t numEntries = U32_AT(&header[4]); 3934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 394ffd7950633edeb8e990770e4c8abb81bdcaa6f32Dan Austin if (((SIZE_MAX / 8) - 1 < numEntries) || (data_size != (numEntries + 1) * 8)) { 3954931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 3964931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3974931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3984931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mNumCompositionTimeDeltaEntries = numEntries; 399a105482ae577852ffd08ce88ae5d1ba81db875acWei Jia uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t); 4002c5fb0c7249ba7e5d79236c61a1c94a489041e65Wei Jia if (allocSize > UINT32_MAX) { 401edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih return ERROR_OUT_OF_RANGE; 402edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih } 403edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih 404ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries]; 405ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake if (!mCompositionTimeDeltaEntries) 406ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return ERROR_OUT_OF_RANGE; 4074931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mDataSource->readAt( 4094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) 4104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber < (ssize_t)numEntries * 8) { 4114931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber delete[] mCompositionTimeDeltaEntries; 4124931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = NULL; 4134931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4144931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_IO; 4154931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 4164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4174931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber for (size_t i = 0; i < 2 * numEntries; ++i) { 4184931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]); 4194931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 4204931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 42189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup->setEntries( 42289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries); 42389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 4244931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return OK; 4254931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 4264931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 427c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset >= 0 || data_size < 8) { 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset = data_offset; 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 43534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSyncSamples = U32_AT(&header[4]); 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mNumSyncSamples < 2) { 4483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Table of sync samples is empty or has only a single entry!"); 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 4508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 451e2e812e58e8d2716b00d7d82db99b08d3afb4b32Joshua J. Drake uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t); 452edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih if (allocSize > SIZE_MAX) { 453edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih return ERROR_OUT_OF_RANGE; 454edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih } 455edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih 456ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake mSyncSamples = new (std::nothrow) uint32_t[mNumSyncSamples]; 457ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake if (!mSyncSamples) 458ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return ERROR_OUT_OF_RANGE; 459ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake 4608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t size = mNumSyncSamples * sizeof(uint32_t); 4618bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) 4628bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber != (ssize_t)size) { 4638bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber return ERROR_IO; 4648bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 4658bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 4668bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber for (size_t i = 0; i < mNumSyncSamples; ++i) { 4678bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 4688bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 4698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const { 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumChunkOffsets; 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const { 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumSampleSizes; 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) { 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = 0; 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sample_size; 488c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(i, &sample_size); 489da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_size > *max_size) { 49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = sample_size; 49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 502da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) { 503da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber return time1 > time2 ? time1 - time2 : time2 - time1; 504da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber} 505da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 5064678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static 5074678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) { 5084678a6dc5f09008481524949a9667af5a6190374Andreas Huber const SampleTimeEntry *a = (const SampleTimeEntry *)_a; 5094678a6dc5f09008481524949a9667af5a6190374Andreas Huber const SampleTimeEntry *b = (const SampleTimeEntry *)_b; 5104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 5114678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (a->mCompositionTime < b->mCompositionTime) { 5124678a6dc5f09008481524949a9667af5a6190374Andreas Huber return -1; 5134678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else if (a->mCompositionTime > b->mCompositionTime) { 5144678a6dc5f09008481524949a9667af5a6190374Andreas Huber return 1; 5154678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 516abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 5174678a6dc5f09008481524949a9667af5a6190374Andreas Huber return 0; 5184678a6dc5f09008481524949a9667af5a6190374Andreas Huber} 5194678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5204678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() { 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5233564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) { 5244678a6dc5f09008481524949a9667af5a6190374Andreas Huber return; 5254678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5264678a6dc5f09008481524949a9667af5a6190374Andreas Huber 527ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes]; 528ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake if (!mSampleTimeEntries) 529ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake return; 5304678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5314678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t sampleIndex = 0; 5324678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t sampleTime = 0; 5334678a6dc5f09008481524949a9667af5a6190374Andreas Huber 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t n = mTimeToSample[2 * i]; 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t delta = mTimeToSample[2 * i + 1]; 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5384678a6dc5f09008481524949a9667af5a6190374Andreas Huber for (uint32_t j = 0; j < n; ++j) { 53965a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber if (sampleIndex < mNumSampleSizes) { 54065a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // Technically this should always be the case if the file 54165a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // is well-formed, but you know... there's (gasp) malformed 54265a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // content out there. 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54465a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex; 545abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 54689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber uint32_t compTimeDelta = 54789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup->getCompositionTimeOffset( 54889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber sampleIndex); 54989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 55065a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber mSampleTimeEntries[sampleIndex].mCompositionTime = 55189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber sampleTime + compTimeDelta; 55265a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber } 5534678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5544678a6dc5f09008481524949a9667af5a6190374Andreas Huber ++sampleIndex; 5554678a6dc5f09008481524949a9667af5a6190374Andreas Huber sampleTime += delta; 5564678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5574678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5584678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5594678a6dc5f09008481524949a9667af5a6190374Andreas Huber qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry), 5604678a6dc5f09008481524949a9667af5a6190374Andreas Huber CompareIncreasingTime); 5614678a6dc5f09008481524949a9667af5a6190374Andreas Huber} 5624678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5634678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime( 564599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint64_t req_time, uint64_t scale_num, uint64_t scale_den, 565599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t *sample_index, uint32_t flags) { 5664678a6dc5f09008481524949a9667af5a6190374Andreas Huber buildSampleEntriesTable(); 5674678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5683564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia if (mSampleTimeEntries == NULL) { 5693564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia return ERROR_OUT_OF_RANGE; 5703564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia } 5713564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia 5724678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t left = 0; 573225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t right_plus_one = mNumSampleSizes; 574225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar while (left < right_plus_one) { 575225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t center = left + (right_plus_one - left) / 2; 576599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint64_t centerTime = 577599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar getSampleTime(center, scale_num, scale_den); 5784678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5794678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (req_time < centerTime) { 580225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar right_plus_one = center; 5814678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else if (req_time > centerTime) { 5824678a6dc5f09008481524949a9667af5a6190374Andreas Huber left = center + 1; 5834678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else { 584599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = mSampleTimeEntries[center].mSampleIndex; 585599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return OK; 5864678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5874678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5884678a6dc5f09008481524949a9667af5a6190374Andreas Huber 589599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t closestIndex = left; 590599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 591599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (closestIndex == mNumSampleSizes) { 592a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber if (flags == kFlagAfter) { 593a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber return ERROR_OUT_OF_RANGE; 594a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber } 595599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagBefore; 596599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } else if (closestIndex == 0) { 597599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (flags == kFlagBefore) { 598599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // normally we should return out of range, but that is 599599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // treated as end-of-stream. instead return first sample 600599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // 601599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // return ERROR_OUT_OF_RANGE; 602599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 603599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagAfter; 6044678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 6054678a6dc5f09008481524949a9667af5a6190374Andreas Huber 6064678a6dc5f09008481524949a9667af5a6190374Andreas Huber switch (flags) { 6074678a6dc5f09008481524949a9667af5a6190374Andreas Huber case kFlagBefore: 6084678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 609599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --closestIndex; 6104678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 6114678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6134678a6dc5f09008481524949a9667af5a6190374Andreas Huber case kFlagAfter: 6144678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 615599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // nothing to do 6164678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 61720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 61820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6194678a6dc5f09008481524949a9667af5a6190374Andreas Huber default: 6204678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 6214678a6dc5f09008481524949a9667af5a6190374Andreas Huber CHECK(flags == kFlagClosest); 622599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // pick closest based on timestamp. use abs_difference for safety 623599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (abs_difference( 624599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar getSampleTime(closestIndex, scale_num, scale_den), req_time) > 625599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar abs_difference( 626599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) { 627599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --closestIndex; 6284678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 6294678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 6304678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6334678a6dc5f09008481524949a9667af5a6190374Andreas Huber *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; 6344678a6dc5f09008481524949a9667af5a6190374Andreas Huber return OK; 63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 63620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 637abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear( 638abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 639abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber Mutex::Autolock autoLock(mLock); 640abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = 0; 64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset < 0) { 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // All samples are sync-samples. 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = start_sample_index; 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 649abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mNumSyncSamples == 0) { 650abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 651abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return OK; 652abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 653da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 654abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t left = 0; 655225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t right_plus_one = mNumSyncSamples; 656225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar while (left < right_plus_one) { 657225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar uint32_t center = left + (right_plus_one - left) / 2; 6588f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber uint32_t x = mSyncSamples[center]; 65920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6608f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber if (start_sample_index < x) { 661225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar right_plus_one = center; 6628f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } else if (start_sample_index > x) { 6638f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber left = center + 1; 6648f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } else { 665599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = x; 666599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return OK; 66720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 668f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong } 669599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 6708d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng if (left == mNumSyncSamples) { 6718d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng if (flags == kFlagAfter) { 67229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("tried to find a sync frame after the last one: %d", left); 6738d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng return ERROR_OUT_OF_RANGE; 6748d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng } 675599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagBefore; 6768d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng } 677599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar else if (left == 0) { 678599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (flags == kFlagBefore) { 679599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar ALOGE("tried to find a sync frame before the first one: %d", left); 680abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 681599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // normally we should return out of range, but that is 682599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // treated as end-of-stream. instead seek to first sync 683599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // 684599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // return ERROR_OUT_OF_RANGE; 685abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 686599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar flags = kFlagAfter; 687abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 688abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 689599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // Now ssi[left - 1] <(=) start_sample_index <= ssi[left] 690abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 691abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 692abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 693599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --left; 694abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 695abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 696abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 697abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 698599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // nothing to do 699abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 700abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 701abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 702599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar { 703599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // this route is not used, but implement it nonetheless 704599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar CHECK(flags == kFlagClosest); 705599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 706599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar status_t err = mSampleIterator->seekTo(start_sample_index); 707599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 708599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 709599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 710599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t sample_time = mSampleIterator->getSampleTime(); 711599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 712599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar err = mSampleIterator->seekTo(mSyncSamples[left]); 713599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 714599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 715599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 716599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t upper_time = mSampleIterator->getSampleTime(); 717599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 718599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar err = mSampleIterator->seekTo(mSyncSamples[left - 1]); 719599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (err != OK) { 720599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar return err; 721599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 722599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar uint32_t lower_time = mSampleIterator->getSampleTime(); 723599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar 724599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar // use abs_difference for safety 725599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar if (abs_difference(upper_time, sample_time) > 726599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar abs_difference(sample_time, lower_time)) { 727599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar --left; 728599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 729abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 730599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar } 73120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 733599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar *sample_index = mSyncSamples[left]; 73420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 73520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 73620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 738c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 739c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 7407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (mSyncSampleOffset < 0) { 7417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // All samples are sync-samples. 7427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = 0; 7437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 7447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 7457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t bestSampleIndex = 0; 7477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t maxSampleSize = 0; 7487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 7507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Consider the first kMaxNumSyncSamplesToScan sync samples and 7527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // pick the one with the largest (compressed) size as the thumbnail. 7537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t numSamplesToScan = mNumSyncSamples; 7557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 7567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber numSamplesToScan = kMaxNumSyncSamplesToScan; 7577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 7587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber for (size_t i = 0; i < numSamplesToScan; ++i) { 7608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t x = mSyncSamples[i]; 7617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7627e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Now x is a sample index. 7637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t sampleSize; 764c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(x, &sampleSize); 7657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (err != OK) { 7667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return err; 7677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 7687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (i == 0 || sampleSize > maxSampleSize) { 7707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber bestSampleIndex = x; 7717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber maxSampleSize = sampleSize; 7727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 7737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 7747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7757e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = bestSampleIndex; 7767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7777e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 7787e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber} 7797e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 780c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l( 781c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, size_t *sampleSize) { 782c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return mSampleIterator->getSampleSizeDirect( 783c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, sampleSize); 784c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 785c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 786c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample( 787c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, 788c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t *offset, 789c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber size_t *size, 7904678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t *compositionTime, 791170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih bool *isSyncSample, 792170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih uint32_t *sampleDuration) { 793c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 794c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 795c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 796c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 797c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 798c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 799c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 800c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (offset) { 801c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = mSampleIterator->getSampleOffset(); 802c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 803c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 804c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (size) { 805c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = mSampleIterator->getSampleSize(); 806c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 807c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 8084678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (compositionTime) { 8094678a6dc5f09008481524949a9667af5a6190374Andreas Huber *compositionTime = mSampleIterator->getSampleTime(); 810c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 811c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 8128bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 8138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = false; 8148bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mSyncSampleOffset < 0) { 8158bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber // Every sample is a sync sample. 8168bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 8178bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } else { 8188bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 8198bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 8208bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ? mLastSyncSampleIndex : 0; 8218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 8228bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 8238bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ++i; 8248bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 8258bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 8268bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 8278bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 8288bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 8298bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 8308bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex = i; 8318bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 8328bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 8338bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 834170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih if (sampleDuration) { 835170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih *sampleDuration = mSampleIterator->getSampleDuration(); 836170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih } 837170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih 838c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 839c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 840c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 84189aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) { 84289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex); 8434931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 8444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 84520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 84620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 847