SampleTable.cpp revision a3630a418b4f65277a42cd4018cd3b0b7e134d0c
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 30108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia/* TODO: remove after being merged into other branches */ 31108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia#ifndef UINT32_MAX 32108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia#define UINT32_MAX (4294967295U) 33108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia#endif 34108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei 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), 125a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa mTimeToSample(), 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 154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete mSampleIterator; 155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = NULL; 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 158169c286ed166499c5099d2b336967e0bf3d25551Andreas Huberbool SampleTable::isValid() const { 159169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber return mChunkOffsetOffset >= 0 160169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber && mSampleToChunkOffset >= 0 161169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber && mSampleSizeOffset >= 0 162a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa && !mTimeToSample.empty(); 163169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber} 164169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams( 166c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetOffset >= 0) { 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1710c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset = data_offset; 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType = type; 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 18134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets = U32_AT(&header[4]); 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetType == kChunkOffsetType32) { 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 4) { 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 8) { 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams( 207c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleToChunkOffset >= 0) { 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset = data_offset; 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 21934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets = U32_AT(&header[4]); 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumSampleToChunkOffsets * 12) { 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2355c4428f6391478ae983e1fcf7c42c832aa1a5e69Joshua J. Drake if (SIZE_MAX / sizeof(SampleToChunkEntry) <= mNumSampleToChunkOffsets) 2365c4428f6391478ae983e1fcf7c42c832aa1a5e69Joshua J. Drake return ERROR_OUT_OF_RANGE; 2375c4428f6391478ae983e1fcf7c42c832aa1a5e69Joshua J. Drake 238c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = 239c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber new SampleToChunkEntry[mNumSampleToChunkOffsets]; 240c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint8_t buffer[12]; 243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mDataSource->readAt( 244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) 245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber != (ssize_t)sizeof(buffer)) { 246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. 250c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber // We want the chunk index to be 0-based. 252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 254c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 255c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 256c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams( 261c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeOffset >= 0) { 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2660c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset = data_offset; 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12) { 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[12]; 27534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = U32_AT(&header[4]); 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes = U32_AT(&header[8]); 287108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia if (mNumSampleSizes > (UINT32_MAX - 12) / 16) { 288c27cee30d9359fa83e33b4f87f88e6bb9ef66341Wei Jia ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes); 289108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia return ERROR_MALFORMED; 290108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia } 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (type == kSampleSizeType32) { 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = 32; 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDefaultSampleSize != 0) { 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + mNumSampleSizes * 4) { 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((mDefaultSampleSize & 0xffffff00) != 0) { 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // The high 24 bits are reserved and must be 0. 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3089f753df58a70f20db220af31cb202bbd21b30f36Andreas Huber mSampleSizeFieldSize = mDefaultSampleSize & 0xff; 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = 0; 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && mSampleSizeFieldSize != 16) { 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams( 325c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 326a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa if (!mTimeToSample.empty() || data_size < 8) { 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 33134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount = U32_AT(&header[4]); 342a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa if ((uint64_t)mTimeToSampleCount > 343a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) { 344a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // Choose this bound because 345a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one 346a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // time-to-sample entry in the time-to-sample table. 347a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // 2) mTimeToSampleCount is the number of entries of the time-to-sample 348a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // table. 349a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // 3) We hope that the table size does not exceed UINT32_MAX. 350a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa ALOGE(" Error: Time-to-sample table size too large."); 351f106b1993143df44282777253244ce67974c9d4aRobert Shih return ERROR_OUT_OF_RANGE; 352f106b1993143df44282777253244ce67974c9d4aRobert Shih } 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 354a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // Note: At this point, we know that mTimeToSampleCount * 2 will not 355a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa // overflow because of the above condition. 356a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa if (!mDataSource->getVector(data_offset + 8, &mTimeToSample, 357a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa mTimeToSampleCount * 2)) { 358a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa ALOGE(" Error: Incomplete data read for time-to-sample table."); 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 362a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa for (size_t i = 0; i < mTimeToSample.size(); ++i) { 363a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa mTimeToSample.editItemAt(i) = ntohl(mTimeToSample[i]); 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams( 3694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber off64_t data_offset, size_t data_size) { 370df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block ALOGI("There are reordered frames present."); 3714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3724931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mCompositionTimeDeltaEntries != NULL || data_size < 8) { 3734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 3744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber uint8_t header[8]; 3774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mDataSource->readAt( 3784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset, header, sizeof(header)) 3794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber < (ssize_t)sizeof(header)) { 3804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_IO; 3814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3834931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (U32_AT(header) != 0) { 3844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber // Expected version = 0, flags = 0. 3854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 3864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber size_t numEntries = U32_AT(&header[4]); 3894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3904931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (data_size != (numEntries + 1) * 8) { 3914931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_MALFORMED; 3924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 3934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 3944931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mNumCompositionTimeDeltaEntries = numEntries; 395738a753a3ca7bf8f9f608ca941575626265294e4Wei Jia uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t); 396f106b1993143df44282777253244ce67974c9d4aRobert Shih if (allocSize > SIZE_MAX) { 397f106b1993143df44282777253244ce67974c9d4aRobert Shih return ERROR_OUT_OF_RANGE; 398f106b1993143df44282777253244ce67974c9d4aRobert Shih } 399f106b1993143df44282777253244ce67974c9d4aRobert Shih 4004931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries]; 4014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4024931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber if (mDataSource->readAt( 4034931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8) 4044931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber < (ssize_t)numEntries * 8) { 4054931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber delete[] mCompositionTimeDeltaEntries; 4064931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries = NULL; 4074931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return ERROR_IO; 4094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 4104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 4114931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber for (size_t i = 0; i < 2 * numEntries; ++i) { 4124931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]); 4134931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber } 4144931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 41589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup->setEntries( 41689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries); 41789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 4184931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber return OK; 4194931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 4204931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 421c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset >= 0 || data_size < 8) { 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset = data_offset; 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 42934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSyncSamples = U32_AT(&header[4]); 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mNumSyncSamples < 2) { 4423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Table of sync samples is empty or has only a single entry!"); 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 4448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 4453cc11bfc00cbb3ed87a4464777a75606b4973b51Joshua J. Drake uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t); 446f106b1993143df44282777253244ce67974c9d4aRobert Shih if (allocSize > SIZE_MAX) { 447f106b1993143df44282777253244ce67974c9d4aRobert Shih return ERROR_OUT_OF_RANGE; 448f106b1993143df44282777253244ce67974c9d4aRobert Shih } 449f106b1993143df44282777253244ce67974c9d4aRobert Shih 4508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples = new uint32_t[mNumSyncSamples]; 4518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t size = mNumSyncSamples * sizeof(uint32_t); 4528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) 4538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber != (ssize_t)size) { 4548bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber return ERROR_IO; 4558bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 4568bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 4578bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber for (size_t i = 0; i < mNumSyncSamples; ++i) { 4588bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 4598bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 4608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const { 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumChunkOffsets; 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const { 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumSampleSizes; 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) { 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = 0; 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sample_size; 479c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(i, &sample_size); 480da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_size > *max_size) { 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = sample_size; 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 493da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) { 494da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber return time1 > time2 ? time1 - time2 : time2 - time1; 495da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber} 496da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 4974678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static 4984678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) { 4994678a6dc5f09008481524949a9667af5a6190374Andreas Huber const SampleTimeEntry *a = (const SampleTimeEntry *)_a; 5004678a6dc5f09008481524949a9667af5a6190374Andreas Huber const SampleTimeEntry *b = (const SampleTimeEntry *)_b; 5014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 5024678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (a->mCompositionTime < b->mCompositionTime) { 5034678a6dc5f09008481524949a9667af5a6190374Andreas Huber return -1; 5044678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else if (a->mCompositionTime > b->mCompositionTime) { 5054678a6dc5f09008481524949a9667af5a6190374Andreas Huber return 1; 5064678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 507abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 5084678a6dc5f09008481524949a9667af5a6190374Andreas Huber return 0; 5094678a6dc5f09008481524949a9667af5a6190374Andreas Huber} 5104678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5114678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() { 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 514108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) { 515cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia if (mNumSampleSizes == 0) { 516cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes); 517cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia } 5184678a6dc5f09008481524949a9667af5a6190374Andreas Huber return; 5194678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5204678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5214678a6dc5f09008481524949a9667af5a6190374Andreas Huber mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes]; 5224678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5234678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t sampleIndex = 0; 5244678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t sampleTime = 0; 5254678a6dc5f09008481524949a9667af5a6190374Andreas Huber 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t n = mTimeToSample[2 * i]; 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t delta = mTimeToSample[2 * i + 1]; 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5304678a6dc5f09008481524949a9667af5a6190374Andreas Huber for (uint32_t j = 0; j < n; ++j) { 53165a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber if (sampleIndex < mNumSampleSizes) { 53265a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // Technically this should always be the case if the file 53365a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // is well-formed, but you know... there's (gasp) malformed 53465a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber // content out there. 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53665a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex; 537abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 53889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber uint32_t compTimeDelta = 53989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber mCompositionDeltaLookup->getCompositionTimeOffset( 54089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber sampleIndex); 54189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber 54265a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber mSampleTimeEntries[sampleIndex].mCompositionTime = 54389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber sampleTime + compTimeDelta; 54465a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber } 5454678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5464678a6dc5f09008481524949a9667af5a6190374Andreas Huber ++sampleIndex; 5474678a6dc5f09008481524949a9667af5a6190374Andreas Huber sampleTime += delta; 5484678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5494678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5504678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5514678a6dc5f09008481524949a9667af5a6190374Andreas Huber qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry), 5524678a6dc5f09008481524949a9667af5a6190374Andreas Huber CompareIncreasingTime); 5534678a6dc5f09008481524949a9667af5a6190374Andreas Huber} 5544678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5554678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime( 5564678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t req_time, uint32_t *sample_index, uint32_t flags) { 5574678a6dc5f09008481524949a9667af5a6190374Andreas Huber buildSampleEntriesTable(); 5584678a6dc5f09008481524949a9667af5a6190374Andreas Huber 559108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia if (mSampleTimeEntries == NULL) { 560108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia return ERROR_OUT_OF_RANGE; 561108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia } 562108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia 5634678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t left = 0; 5644678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t right = mNumSampleSizes; 5654678a6dc5f09008481524949a9667af5a6190374Andreas Huber while (left < right) { 5664678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t center = (left + right) / 2; 5674678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime; 5684678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5694678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (req_time < centerTime) { 5704678a6dc5f09008481524949a9667af5a6190374Andreas Huber right = center; 5714678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else if (req_time > centerTime) { 5724678a6dc5f09008481524949a9667af5a6190374Andreas Huber left = center + 1; 5734678a6dc5f09008481524949a9667af5a6190374Andreas Huber } else { 5744678a6dc5f09008481524949a9667af5a6190374Andreas Huber left = center; 5754678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 5764678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5774678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5784678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5794678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (left == mNumSampleSizes) { 580a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber if (flags == kFlagAfter) { 581a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber return ERROR_OUT_OF_RANGE; 582a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber } 583a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber 5844678a6dc5f09008481524949a9667af5a6190374Andreas Huber --left; 5854678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 5864678a6dc5f09008481524949a9667af5a6190374Andreas Huber 5874678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t closestIndex = left; 588abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 5894678a6dc5f09008481524949a9667af5a6190374Andreas Huber switch (flags) { 5904678a6dc5f09008481524949a9667af5a6190374Andreas Huber case kFlagBefore: 5914678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 5924678a6dc5f09008481524949a9667af5a6190374Andreas Huber while (closestIndex > 0 5934678a6dc5f09008481524949a9667af5a6190374Andreas Huber && mSampleTimeEntries[closestIndex].mCompositionTime 5944678a6dc5f09008481524949a9667af5a6190374Andreas Huber > req_time) { 5954678a6dc5f09008481524949a9667af5a6190374Andreas Huber --closestIndex; 59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 5974678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 5984678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 59920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6004678a6dc5f09008481524949a9667af5a6190374Andreas Huber case kFlagAfter: 6014678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 6024678a6dc5f09008481524949a9667af5a6190374Andreas Huber while (closestIndex + 1 < mNumSampleSizes 6034678a6dc5f09008481524949a9667af5a6190374Andreas Huber && mSampleTimeEntries[closestIndex].mCompositionTime 6044678a6dc5f09008481524949a9667af5a6190374Andreas Huber < req_time) { 6054678a6dc5f09008481524949a9667af5a6190374Andreas Huber ++closestIndex; 6064678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 6074678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6104678a6dc5f09008481524949a9667af5a6190374Andreas Huber default: 6114678a6dc5f09008481524949a9667af5a6190374Andreas Huber { 6124678a6dc5f09008481524949a9667af5a6190374Andreas Huber CHECK(flags == kFlagClosest); 6134678a6dc5f09008481524949a9667af5a6190374Andreas Huber 6144678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (closestIndex > 0) { 6154678a6dc5f09008481524949a9667af5a6190374Andreas Huber // Check left neighbour and pick closest. 6164678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t absdiff1 = 6174678a6dc5f09008481524949a9667af5a6190374Andreas Huber abs_difference( 6184678a6dc5f09008481524949a9667af5a6190374Andreas Huber mSampleTimeEntries[closestIndex].mCompositionTime, 6194678a6dc5f09008481524949a9667af5a6190374Andreas Huber req_time); 6204678a6dc5f09008481524949a9667af5a6190374Andreas Huber 6214678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t absdiff2 = 6224678a6dc5f09008481524949a9667af5a6190374Andreas Huber abs_difference( 6234678a6dc5f09008481524949a9667af5a6190374Andreas Huber mSampleTimeEntries[closestIndex - 1].mCompositionTime, 6244678a6dc5f09008481524949a9667af5a6190374Andreas Huber req_time); 6254678a6dc5f09008481524949a9667af5a6190374Andreas Huber 6264678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (absdiff1 > absdiff2) { 6274678a6dc5f09008481524949a9667af5a6190374Andreas Huber closestIndex = closestIndex - 1; 6284678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 6294678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 6304678a6dc5f09008481524949a9667af5a6190374Andreas Huber 6314678a6dc5f09008481524949a9667af5a6190374Andreas Huber break; 6324678a6dc5f09008481524949a9667af5a6190374Andreas Huber } 63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6354678a6dc5f09008481524949a9667af5a6190374Andreas Huber *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex; 6364678a6dc5f09008481524949a9667af5a6190374Andreas Huber 6374678a6dc5f09008481524949a9667af5a6190374Andreas Huber return OK; 63820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 640abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear( 641abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 642abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber Mutex::Autolock autoLock(mLock); 643abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = 0; 64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset < 0) { 64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // All samples are sync-samples. 64820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = start_sample_index; 64920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 65020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 65120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 652abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mNumSyncSamples == 0) { 653abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 654abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return OK; 655abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 656da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 657abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t left = 0; 6588f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber uint32_t right = mNumSyncSamples; 6598f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber while (left < right) { 6608f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber uint32_t center = left + (right - left) / 2; 6618f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber uint32_t x = mSyncSamples[center]; 66220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6638f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber if (start_sample_index < x) { 6648f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber right = center; 6658f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } else if (start_sample_index > x) { 6668f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber left = center + 1; 6678f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } else { 6688f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber left = center; 66920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 67020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 671f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong } 6728d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng if (left == mNumSyncSamples) { 6738d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng if (flags == kFlagAfter) { 67429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("tried to find a sync frame after the last one: %d", left); 6758d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng return ERROR_OUT_OF_RANGE; 6768d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng } 6778d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng left = left - 1; 6788d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng } 679abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 6808f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber // Now ssi[left] is the sync sample index just before (or at) 6818f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber // start_sample_index. 6828f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber // Also start_sample_index < ssi[left + 1], if left + 1 < mNumSyncSamples. 683abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 6848f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber uint32_t x = mSyncSamples[left]; 685abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 686abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (left + 1 < mNumSyncSamples) { 6878bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t y = mSyncSamples[left + 1]; 688abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 689abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // our sample lies between sync samples x and y. 690abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 691abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleIterator->seekTo(start_sample_index); 692abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 693abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 694abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 695abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 696abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sample_time = mSampleIterator->getSampleTime(); 697abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 698abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleIterator->seekTo(x); 699abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 700abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 701abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 702abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t x_time = mSampleIterator->getSampleTime(); 703abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 704abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleIterator->seekTo(y); 705abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 706abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 707abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 708abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 709abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t y_time = mSampleIterator->getSampleTime(); 710abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 711abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (abs_difference(x_time, sample_time) 712abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber > abs_difference(y_time, sample_time)) { 713abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // Pick the sync sample closest (timewise) to the start-sample. 714abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = y; 715abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++left; 716abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 717abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 718abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 719abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 720abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 721abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 722abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x > start_sample_index) { 723abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(left > 0); 724abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 7258f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber x = mSyncSamples[left - 1]; 726abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 7278f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber if (x > start_sample_index) { 7288f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber // The table of sync sample indices was not sorted 7298f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber // properly. 7308f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber return ERROR_MALFORMED; 7318f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } 732abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 733abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 734abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 735abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 736abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 737abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 738abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x < start_sample_index) { 739abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (left + 1 >= mNumSyncSamples) { 740abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_OUT_OF_RANGE; 741abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 742abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 7438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber x = mSyncSamples[left + 1]; 744abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 7458f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber if (x < start_sample_index) { 7468f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber // The table of sync sample indices was not sorted 7478f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber // properly. 7488f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber return ERROR_MALFORMED; 7498f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber } 750abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 751abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 752abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 753abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 754abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 755abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 756abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 759abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = x; 76020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 76120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 76220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 76320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 765c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 766c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 7677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (mSyncSampleOffset < 0) { 7687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // All samples are sync-samples. 7697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = 0; 7707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 7717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 7727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t bestSampleIndex = 0; 7747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t maxSampleSize = 0; 7757e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 7777e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7787e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Consider the first kMaxNumSyncSamplesToScan sync samples and 7797e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // pick the one with the largest (compressed) size as the thumbnail. 7807e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7817e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t numSamplesToScan = mNumSyncSamples; 7827e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 7837e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber numSamplesToScan = kMaxNumSyncSamplesToScan; 7847e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 7857e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7867e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber for (size_t i = 0; i < numSamplesToScan; ++i) { 7878bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t x = mSyncSamples[i]; 7887e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7897e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Now x is a sample index. 7907e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t sampleSize; 791c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(x, &sampleSize); 7927e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (err != OK) { 7937e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return err; 7947e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 7957e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 7967e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (i == 0 || sampleSize > maxSampleSize) { 7977e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber bestSampleIndex = x; 7987e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber maxSampleSize = sampleSize; 7997e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 8007e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 8017e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 8027e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = bestSampleIndex; 8037e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 8047e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 8057e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber} 8067e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 807c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l( 808c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, size_t *sampleSize) { 809c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return mSampleIterator->getSampleSizeDirect( 810c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, sampleSize); 811c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 812c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 813c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample( 814c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, 815c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t *offset, 816c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber size_t *size, 8174678a6dc5f09008481524949a9667af5a6190374Andreas Huber uint32_t *compositionTime, 8188bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool *isSyncSample) { 819c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 820c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 821c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 822c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 823c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 824c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 825c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 826c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (offset) { 827c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = mSampleIterator->getSampleOffset(); 828c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 829c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 830c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (size) { 831c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = mSampleIterator->getSampleSize(); 832c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 833c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 8344678a6dc5f09008481524949a9667af5a6190374Andreas Huber if (compositionTime) { 8354678a6dc5f09008481524949a9667af5a6190374Andreas Huber *compositionTime = mSampleIterator->getSampleTime(); 836c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 837c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 8388bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 8398bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = false; 8408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mSyncSampleOffset < 0) { 8418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber // Every sample is a sync sample. 8428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 8438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } else { 8448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 8458bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 8468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ? mLastSyncSampleIndex : 0; 8478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 8488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 8498bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ++i; 8508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 8518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 8528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 8538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 8548bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 8558bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 8568bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex = i; 8578bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 8588bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 8598bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 860c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 861c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 862c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 86389aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) { 86489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex); 8654931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber} 8664931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber 86720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 86820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 869