SampleTable.cpp revision 89e69da4d86348409994c9dafbbb2634ccd7c196
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" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2089e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h" 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 250c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic const uint32_t kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic const uint32_t kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic const uint32_t kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic const uint32_t kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source) 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset(-1), 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType(0), 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets(0), 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset(-1), 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets(0), 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset(-1), 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize(0), 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize(0), 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes(0), 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount(0), 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample(NULL), 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset(-1), 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSyncSamples(0) { 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() { 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete[] mTimeToSample; 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = NULL; 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams( 58549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber uint32_t type, off_t data_offset, size_t data_size) { 5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetOffset >= 0) { 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 630c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset = data_offset; 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType = type; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets = U32_AT(&header[4]); 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetType == kChunkOffsetType32) { 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 4) { 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 8) { 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams( 99549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber off_t data_offset, size_t data_size) { 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleToChunkOffset >= 0) { 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset = data_offset; 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets = U32_AT(&header[4]); 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumSampleToChunkOffsets * 12) { 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams( 131549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber uint32_t type, off_t data_offset, size_t data_size) { 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeOffset >= 0) { 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1360c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset = data_offset; 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12) { 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[12]; 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = U32_AT(&header[4]); 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes = U32_AT(&header[8]); 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (type == kSampleSizeType32) { 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = 32; 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDefaultSampleSize != 0) { 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + mNumSampleSizes * 4) { 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((mDefaultSampleSize & 0xffffff00) != 0) { 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // The high 24 bits are reserved and must be 0. 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = mDefaultSampleSize & 0xf; 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = 0; 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && mSampleSizeFieldSize != 16) { 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams( 191549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber off_t data_offset, size_t data_size) { 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mTimeToSample != NULL || data_size < 8) { 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount = U32_AT(&header[4]); 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = new uint32_t[mTimeToSampleCount * 2]; 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset + 8, mTimeToSample, size) < (ssize_t)size) { 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample[i] = ntohl(mTimeToSample[i]); 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 223549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huberstatus_t SampleTable::setSyncSampleParams(off_t data_offset, size_t data_size) { 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset >= 0 || data_size < 8) { 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset = data_offset; 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSyncSamples = U32_AT(&header[4]); 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mNumSyncSamples < 2) { 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber LOGW("Table of sync samples is empty or has only a single entry!"); 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const { 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumChunkOffsets; 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getChunkOffset(uint32_t chunk_index, off_t *offset) { 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = 0; 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetOffset < 0) { 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (chunk_index >= mNumChunkOffsets) { 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_OUT_OF_RANGE; 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetType == kChunkOffsetType32) { 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t offset32; 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset + 8 + 4 * chunk_index, 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &offset32, 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sizeof(offset32)) < (ssize_t)sizeof(offset32)) { 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = ntohl(offset32); 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 27683dc92f8733a7da4a8addf6075c58d3ddb47aa5cAndreas Huber CHECK_EQ(mChunkOffsetType, kChunkOffsetType64); 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint64_t offset64; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset + 8 + 8 * chunk_index, 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &offset64, 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sizeof(offset64)) < (ssize_t)sizeof(offset64)) { 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = ntoh64(offset64); 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getChunkForSample( 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_index, 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t *chunk_index, 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t *chunk_relative_sample_index, 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t *desc_index) { 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *chunk_index = 0; 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *chunk_relative_sample_index = 0; 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *desc_index = 0; 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleToChunkOffset < 0) { 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_index >= countSamples()) { 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_END_OF_STREAM; 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t first_chunk = 0; 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t samples_per_chunk = 0; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_desc_index = 0; 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t index = 0; 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (index < mNumSampleToChunkOffsets) { 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t buffer[12]; 31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at(mSampleToChunkOffset + 8 + index * 12, 31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t stop_chunk = U32_AT(buffer); 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_index < (stop_chunk - first_chunk) * samples_per_chunk) { 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sample_index -= (stop_chunk - first_chunk) * samples_per_chunk; 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber first_chunk = stop_chunk; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber samples_per_chunk = U32_AT(&buffer[4]); 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber chunk_desc_index = U32_AT(&buffer[8]); 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber ++index; 33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *chunk_index = sample_index / samples_per_chunk + first_chunk - 1; 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *chunk_relative_sample_index = sample_index % samples_per_chunk; 33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *desc_index = chunk_desc_index; 33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const { 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumSampleSizes; 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getSampleSize( 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_index, size_t *sample_size) { 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_size = 0; 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeOffset < 0) { 35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_index >= mNumSampleSizes) { 35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_OUT_OF_RANGE; 35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDefaultSampleSize > 0) { 35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_size = mDefaultSampleSize; 35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber switch (mSampleSizeFieldSize) { 36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case 32: 36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset + 12 + 4 * sample_index, 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sample_size, sizeof(*sample_size)) < (ssize_t)sizeof(*sample_size)) { 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_size = ntohl(*sample_size); 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case 16: 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint16_t x; 37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset + 12 + 2 * sample_index, 38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &x, sizeof(x)) < (ssize_t)sizeof(x)) { 38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_size = ntohs(x); 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber case 8: 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t x; 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset + 12 + sample_index, 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &x, sizeof(x)) < (ssize_t)sizeof(x)) { 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 39520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_size = x; 39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber default: 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber { 4030c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK_EQ(mSampleSizeFieldSize, 4); 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t x; 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset + 12 + sample_index / 2, 40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &x, sizeof(x)) < (ssize_t)sizeof(x)) { 40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_size = (sample_index & 1) ? x & 0x0f : x >> 4; 41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getSampleOffsetAndSize( 42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t sample_index, off_t *offset, size_t *size) { 42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset = 0; 42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *size = 0; 42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_index; 42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t chunk_relative_sample_index; 42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t desc_index; 43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = getChunkForSample( 43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber sample_index, &chunk_index, &chunk_relative_sample_index, 43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber &desc_index); 43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber err = getChunkOffset(chunk_index, offset); 43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t j = 0; j < chunk_relative_sample_index; ++j) { 44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sample_size; 44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber err = getSampleSize(sample_index - j - 1, &sample_size); 44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 44920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 45020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *offset += sample_size; 45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber err = getSampleSize(sample_index, size); 45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) { 46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = 0; 46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sample_size; 47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber status_t err = getSampleSize(i, &sample_size); 47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_size > *max_size) { 47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = sample_size; 47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getDecodingTime(uint32_t sample_index, uint32_t *time) { 48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // XXX FIXME idiotic (for the common use-case) O(n) algorithm below... 48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_index >= mNumSampleSizes) { 49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_OUT_OF_RANGE; 49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t cur_sample = 0; 49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *time = 0; 49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t n = mTimeToSample[2 * i]; 49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t delta = mTimeToSample[2 * i + 1]; 49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_index < cur_sample + n) { 50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *time += delta * (sample_index - cur_sample); 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *time += delta * n; 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber cur_sample += n; 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_OUT_OF_RANGE; 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::findClosestSample( 51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t req_time, uint32_t *sample_index, uint32_t flags) { 51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 51620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t cur_sample = 0; 51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t time = 0; 51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t n = mTimeToSample[2 * i]; 52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t delta = mTimeToSample[2 * i + 1]; 52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (req_time < time + n * delta) { 52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int j = (req_time - time) / delta; 52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = cur_sample + j; 52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 52820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (flags & kSyncSample_Flag) { 52920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return findClosestSyncSample(*sample_index, sample_index); 53020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber time += delta * n; 53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber cur_sample += n; 53720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_OUT_OF_RANGE; 54020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::findClosestSyncSample( 54320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t start_sample_index, uint32_t *sample_index) { 54420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = 0; 54520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 54620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset < 0) { 54720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // All samples are sync-samples. 54820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = start_sample_index; 54920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 55020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 55120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 55220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t x; 55320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t left = 0; 55420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t right = mNumSyncSamples; 55520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber while (left < right) { 55620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t mid = (left + right) / 2; 55720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDataSource->read_at( 55820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset + 8 + (mid - 1) * 4, &x, 4) != 4) { 55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 56020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber x = ntohl(x); 56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (x < (start_sample_index + 1)) { 56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber left = mid + 1; 56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else if (x > (start_sample_index + 1)) { 56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber right = mid; 56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = x - 1; 57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 57920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 580