SampleTable.cpp revision c7fc37a3dab9bd1f96713649f351b5990e6316ff
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 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h> 270c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h> 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 33c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o'); 34c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 35c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4'); 36c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z'); 38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static 39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2'); 40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//////////////////////////////////////////////////////////////////////////////// 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 43693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source) 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mDataSource(source), 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset(-1), 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType(0), 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets(0), 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset(-1), 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets(0), 5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset(-1), 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize(0), 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize(0), 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes(0), 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount(0), 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample(NULL), 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset(-1), 57c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mNumSyncSamples(0), 588bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples(NULL), 598bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex(0), 60c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries(NULL) { 61c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = new SampleIterator(this); 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() { 65c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete[] mSampleToChunkEntries; 66c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = NULL; 67c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 688bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber delete[] mSyncSamples; 698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples = NULL; 708bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete[] mTimeToSample; 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = NULL; 73c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 74c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete mSampleIterator; 75c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = NULL; 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams( 79c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetOffset >= 0) { 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 840c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset = data_offset; 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType = type; 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 9434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets = U32_AT(&header[4]); 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetType == kChunkOffsetType32) { 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 4) { 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 8) { 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams( 120c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleToChunkOffset >= 0) { 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset = data_offset; 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 13234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets = U32_AT(&header[4]); 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumSampleToChunkOffsets * 12) { 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 148c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = 149c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber new SampleToChunkEntry[mNumSampleToChunkOffsets]; 150c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint8_t buffer[12]; 153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mDataSource->readAt( 154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) 155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber != (ssize_t)sizeof(buffer)) { 156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. 160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber // We want the chunk index to be 0-based. 162c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 163c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 164c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 165c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 166c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams( 171c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong uint32_t type, off64_t data_offset, size_t data_size) { 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeOffset >= 0) { 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1760c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset = data_offset; 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12) { 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[12]; 18534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = U32_AT(&header[4]); 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes = U32_AT(&header[8]); 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (type == kSampleSizeType32) { 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = 32; 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDefaultSampleSize != 0) { 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + mNumSampleSizes * 4) { 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((mDefaultSampleSize & 0xffffff00) != 0) { 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // The high 24 bits are reserved and must be 0. 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = mDefaultSampleSize & 0xf; 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = 0; 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && mSampleSizeFieldSize != 16) { 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams( 231c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t data_offset, size_t data_size) { 23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mTimeToSample != NULL || data_size < 8) { 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 23734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount = U32_AT(&header[4]); 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = new uint32_t[mTimeToSampleCount * 2]; 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; 25134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset + 8, mTimeToSample, size) < (ssize_t)size) { 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample[i] = ntohl(mTimeToSample[i]); 25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 263c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) { 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset >= 0 || data_size < 8) { 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset = data_offset; 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 27134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSyncSamples = U32_AT(&header[4]); 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mNumSyncSamples < 2) { 28475fc7654280ac2a72fa8124b88e616219a3e61e2Andreas Huber LOGV("Table of sync samples is empty or has only a single entry!"); 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 2868bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 2878bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples = new uint32_t[mNumSyncSamples]; 2888bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t size = mNumSyncSamples * sizeof(uint32_t); 2898bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size) 2908bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber != (ssize_t)size) { 2918bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber return ERROR_IO; 2928bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 2938bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 2948bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber for (size_t i = 0; i < mNumSyncSamples; ++i) { 2958bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1; 2968bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 2978bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const { 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumChunkOffsets; 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const { 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumSampleSizes; 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) { 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = 0; 31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sample_size; 316c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(i, &sample_size); 317da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_size > *max_size) { 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = sample_size; 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 330da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) { 331da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber return time1 > time2 ? time1 - time2 : time2 - time1; 332da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber} 333da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 334abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSampleAtTime( 33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t req_time, uint32_t *sample_index, uint32_t flags) { 336abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 337abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t cur_sample = 0; 34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t time = 0; 34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t n = mTimeToSample[2 * i]; 34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t delta = mTimeToSample[2 * i + 1]; 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (req_time < time + n * delta) { 34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int j = (req_time - time) / delta; 34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 349da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber uint32_t time1 = time + j * delta; 350da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber uint32_t time2 = time1 + delta; 351da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 352abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sampleTime; 353da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber if (i+1 == mTimeToSampleCount 354da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber || (abs_difference(req_time, time1) 355da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber < abs_difference(req_time, time2))) { 356da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber *sample_index = cur_sample + j; 357abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime = time1; 358da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber } else { 359da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber *sample_index = cur_sample + j + 1; 360abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime = time2; 361da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber } 36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 363abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 364abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 365abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 366abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (sampleTime > req_time && *sample_index > 0) { 367abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --*sample_index; 368abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 369abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 370abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 371abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 372abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 373abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 374abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (sampleTime < req_time 375abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber && *sample_index + 1 < mNumSampleSizes) { 376abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++*sample_index; 377abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 378abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 379abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 380abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 381abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 382abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber time += delta * n; 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber cur_sample += n; 39020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 39120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_OUT_OF_RANGE; 39320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 39420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 395abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear( 396abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 397abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber Mutex::Autolock autoLock(mLock); 398abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = 0; 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset < 0) { 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // All samples are sync-samples. 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = start_sample_index; 40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 407abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mNumSyncSamples == 0) { 408abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 409abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return OK; 410abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 411da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 412abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t left = 0; 413abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber while (left < mNumSyncSamples) { 4148bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t x = mSyncSamples[left]; 41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 416abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x >= start_sample_index) { 41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 419abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 420abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++left; 421abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 422abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 423abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --left; 424abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t x; 425abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mDataSource->readAt( 426abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) { 427abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_IO; 428abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 429abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 430abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = ntohl(x); 431abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --x; 432abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 433abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (left + 1 < mNumSyncSamples) { 4348bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t y = mSyncSamples[left + 1]; 435abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 436abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // our sample lies between sync samples x and y. 437abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 438abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleIterator->seekTo(start_sample_index); 439abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 440abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 441abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 442abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 443abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sample_time = mSampleIterator->getSampleTime(); 444abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 445abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleIterator->seekTo(x); 446abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 447abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 448abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 449abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t x_time = mSampleIterator->getSampleTime(); 450abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 451abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleIterator->seekTo(y); 452abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 453abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 454abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 455abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 456abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t y_time = mSampleIterator->getSampleTime(); 457abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 458abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (abs_difference(x_time, sample_time) 459abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber > abs_difference(y_time, sample_time)) { 460abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // Pick the sync sample closest (timewise) to the start-sample. 461abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = y; 462abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++left; 463abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 464abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 465abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 466abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 467abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 468abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 469abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x > start_sample_index) { 470abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(left > 0); 471abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 472abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mDataSource->readAt( 473abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + (left - 1) * 4, &x, 4) != 4) { 474abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_IO; 475abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 476abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 477abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = ntohl(x); 478abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --x; 479abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 480abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(x <= start_sample_index); 481abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 482abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 483abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 484abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 485abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 486abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 487abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x < start_sample_index) { 488abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (left + 1 >= mNumSyncSamples) { 489abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_OUT_OF_RANGE; 490abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 491abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 4928bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber x = mSyncSamples[left + 1]; 493abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 494abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(x >= start_sample_index); 495abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 496abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 497abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 498abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 499abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 500abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 501abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 504abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = x; 50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5097e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 510c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 511c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 5127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (mSyncSampleOffset < 0) { 5137e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // All samples are sync-samples. 5147e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = 0; 5157e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 5167e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t bestSampleIndex = 0; 5197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t maxSampleSize = 0; 5207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 5227e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5237e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Consider the first kMaxNumSyncSamplesToScan sync samples and 5247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // pick the one with the largest (compressed) size as the thumbnail. 5257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t numSamplesToScan = mNumSyncSamples; 5277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 5287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber numSamplesToScan = kMaxNumSyncSamplesToScan; 5297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber for (size_t i = 0; i < numSamplesToScan; ++i) { 5328bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t x = mSyncSamples[i]; 5337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Now x is a sample index. 5357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t sampleSize; 536c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(x, &sampleSize); 5377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (err != OK) { 5387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return err; 5397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (i == 0 || sampleSize > maxSampleSize) { 5427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber bestSampleIndex = x; 5437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber maxSampleSize = sampleSize; 5447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = bestSampleIndex; 5487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 5507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber} 5517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 552c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l( 553c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, size_t *sampleSize) { 554c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return mSampleIterator->getSampleSizeDirect( 555c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, sampleSize); 556c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 557c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 558c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample( 559c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, 560c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t *offset, 561c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber size_t *size, 5628bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber uint32_t *decodingTime, 5638bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber bool *isSyncSample) { 564c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 565c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 566c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 567c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 568c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 569c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 570c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 571c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (offset) { 572c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = mSampleIterator->getSampleOffset(); 573c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 574c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 575c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (size) { 576c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = mSampleIterator->getSampleSize(); 577c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 578c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 579c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (decodingTime) { 580c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *decodingTime = mSampleIterator->getSampleTime(); 581c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 582c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 5838bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (isSyncSample) { 5848bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = false; 5858bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (mSyncSampleOffset < 0) { 5868bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber // Every sample is a sync sample. 5878bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 5888bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } else { 5898bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber size_t i = (mLastSyncSampleIndex < mNumSyncSamples) 5908bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex) 5918bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ? mLastSyncSampleIndex : 0; 5928bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 5938bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) { 5948bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber ++i; 5958bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 5968bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 5978bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) { 5988bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber *isSyncSample = true; 5998bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 6008bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 6018bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber mLastSyncSampleIndex = i; 6028bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 6038bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber } 6048bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber 605c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 606c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 607c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 610