SampleTable.cpp revision abd1f4f870925d6776dbe4b930b759a1ab6595ca
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), 58c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries(NULL) { 59c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = new SampleIterator(this); 6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 6220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() { 63c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete[] mSampleToChunkEntries; 64c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = NULL; 65c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete[] mTimeToSample; 6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = NULL; 68c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 69c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber delete mSampleIterator; 70c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleIterator = NULL; 7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams( 74549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber uint32_t type, off_t data_offset, size_t data_size) { 7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetOffset >= 0) { 7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 790c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64); 8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetOffset = data_offset; 8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mChunkOffsetType = type; 8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 8934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumChunkOffsets = U32_AT(&header[4]); 10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mChunkOffsetType == kChunkOffsetType32) { 10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 4) { 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumChunkOffsets * 8) { 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams( 115549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber off_t data_offset, size_t data_size) { 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleToChunkOffset >= 0) { 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleToChunkOffset = data_offset; 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8) { 12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 12734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleToChunkOffsets = U32_AT(&header[4]); 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 8 + mNumSampleToChunkOffsets * 12) { 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 143c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries = 144c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber new SampleToChunkEntry[mNumSampleToChunkOffsets]; 145c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 146c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) { 147c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint8_t buffer[12]; 148c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (mDataSource->readAt( 149c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer)) 150c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber != (ssize_t)sizeof(buffer)) { 151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return ERROR_IO; 152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber CHECK(U32_AT(buffer) >= 1); // chunk index is 1 based in the spec. 155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber // We want the chunk index to be 0-based. 157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1; 158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]); 159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]); 160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams( 166549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber uint32_t type, off_t data_offset, size_t data_size) { 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeOffset >= 0) { 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1710c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact); 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeOffset = data_offset; 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12) { 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[12]; 18034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = U32_AT(&header[4]); 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSampleSizes = U32_AT(&header[8]); 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (type == kSampleSizeType32) { 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = 32; 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mDefaultSampleSize != 0) { 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + mNumSampleSizes * 4) { 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } else { 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if ((mDefaultSampleSize & 0xffffff00) != 0) { 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // The high 24 bits are reserved and must be 0. 20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSampleSizeFieldSize = mDefaultSampleSize & 0xf; 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mDefaultSampleSize = 0; 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber && mSampleSizeFieldSize != 16) { 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) { 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams( 226549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber off_t data_offset, size_t data_size) { 22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mTimeToSample != NULL || data_size < 8) { 22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 23234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSampleCount = U32_AT(&header[4]); 24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample = new uint32_t[mTimeToSampleCount * 2]; 24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2; 24634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset + 8, mTimeToSample, size) < (ssize_t)size) { 24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) { 25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mTimeToSample[i] = ntohl(mTimeToSample[i]); 25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 258549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huberstatus_t SampleTable::setSyncSampleParams(off_t data_offset, size_t data_size) { 25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset >= 0 || data_size < 8) { 26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSyncSampleOffset = data_offset; 26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint8_t header[8]; 26634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) { 26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (U32_AT(header) != 0) { 27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // Expected version = 0, flags = 0. 27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_MALFORMED; 27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNumSyncSamples = U32_AT(&header[4]); 27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mNumSyncSamples < 2) { 27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber LOGW("Table of sync samples is empty or has only a single entry!"); 28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const { 28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumChunkOffsets; 28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const { 28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNumSampleSizes; 29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) { 29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = 0; 29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mNumSampleSizes; ++i) { 29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber size_t sample_size; 299c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(i, &sample_size); 300da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (err != OK) { 30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return err; 30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (sample_size > *max_size) { 30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *max_size = sample_size; 30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 313da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) { 314da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber return time1 > time2 ? time1 - time2 : time2 - time1; 315da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber} 316da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 317abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSampleAtTime( 31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t req_time, uint32_t *sample_index, uint32_t flags) { 319abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 320abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber Mutex::Autolock autoLock(mLock); 32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t cur_sample = 0; 32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t time = 0; 32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber for (uint32_t i = 0; i < mTimeToSampleCount; ++i) { 32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t n = mTimeToSample[2 * i]; 32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber uint32_t delta = mTimeToSample[2 * i + 1]; 32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (req_time < time + n * delta) { 33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber int j = (req_time - time) / delta; 33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 332da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber uint32_t time1 = time + j * delta; 333da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber uint32_t time2 = time1 + delta; 334da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 335abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sampleTime; 336da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber if (i+1 == mTimeToSampleCount 337da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber || (abs_difference(req_time, time1) 338da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber < abs_difference(req_time, time2))) { 339da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber *sample_index = cur_sample + j; 340abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime = time1; 341da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber } else { 342da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber *sample_index = cur_sample + j + 1; 343abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber sampleTime = time2; 344da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber } 34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 346abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 347abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 348abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 349abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (sampleTime > req_time && *sample_index > 0) { 350abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --*sample_index; 351abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 352abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 353abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 354abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 355abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 356abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 357abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (sampleTime < req_time 358abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber && *sample_index + 1 < mNumSampleSizes) { 359abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++*sample_index; 360abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 361abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 362abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 363abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 364abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 365abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber time += delta * n; 37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber cur_sample += n; 37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_OUT_OF_RANGE; 37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 378abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear( 379abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) { 380abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber Mutex::Autolock autoLock(mLock); 381abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = 0; 38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mSyncSampleOffset < 0) { 38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber // All samples are sync-samples. 38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *sample_index = start_sample_index; 38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 390abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mNumSyncSamples == 0) { 391abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = 0; 392abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return OK; 393abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 394da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber 395abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t left = 0; 396abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber while (left < mNumSyncSamples) { 397abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t x; 39834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 399abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) { 40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return ERROR_IO; 40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber x = ntohl(x); 404abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --x; 40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 406abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x >= start_sample_index) { 40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber break; 40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 409abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 410abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++left; 411abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 412abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 413abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --left; 414abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t x; 415abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mDataSource->readAt( 416abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) { 417abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_IO; 418abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 419abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 420abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = ntohl(x); 421abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --x; 422abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 423abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (left + 1 < mNumSyncSamples) { 424abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t y; 425abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mDataSource->readAt( 426abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + (left + 1) * 4, &y, 4) != 4) { 427abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_IO; 428abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 429abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 430abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber y = ntohl(y); 431abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --y; 432abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 433abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // our sample lies between sync samples x and y. 434abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 435abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber status_t err = mSampleIterator->seekTo(start_sample_index); 436abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 437abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 438abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 439abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 440abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t sample_time = mSampleIterator->getSampleTime(); 441abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 442abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleIterator->seekTo(x); 443abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 444abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 445abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 446abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t x_time = mSampleIterator->getSampleTime(); 447abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 448abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber err = mSampleIterator->seekTo(y); 449abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (err != OK) { 450abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return err; 451abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 452abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 453abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber uint32_t y_time = mSampleIterator->getSampleTime(); 454abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 455abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (abs_difference(x_time, sample_time) 456abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber > abs_difference(y_time, sample_time)) { 457abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber // Pick the sync sample closest (timewise) to the start-sample. 458abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = y; 459abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ++left; 460abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 461abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 462abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 463abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber switch (flags) { 464abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagBefore: 465abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 466abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x > start_sample_index) { 467abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(left > 0); 468abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 469abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mDataSource->readAt( 470abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + (left - 1) * 4, &x, 4) != 4) { 471abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_IO; 472abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 473abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 474abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = ntohl(x); 475abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --x; 476abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 477abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(x <= start_sample_index); 478abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 479abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 480abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 481abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 482abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber case kFlagAfter: 483abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber { 484abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (x < start_sample_index) { 485abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (left + 1 >= mNumSyncSamples) { 486abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_OUT_OF_RANGE; 487abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 488abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 489abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber if (mDataSource->readAt( 490abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber mSyncSampleOffset + 8 + (left + 1) * 4, &x, 4) != 4) { 491abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber return ERROR_IO; 492abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 493abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 494abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber x = ntohl(x); 495abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber --x; 496abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 497abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(x >= start_sample_index); 498abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 499abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 500abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 501abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber } 502abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber 503abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber default: 504abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber break; 50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 507abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber *sample_index = x; 50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return OK; 51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 5127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) { 513c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 514c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 5157e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (mSyncSampleOffset < 0) { 5167e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // All samples are sync-samples. 5177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = 0; 5187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 5197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t bestSampleIndex = 0; 5227e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t maxSampleSize = 0; 5237e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber static const size_t kMaxNumSyncSamplesToScan = 20; 5257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Consider the first kMaxNumSyncSamplesToScan sync samples and 5277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // pick the one with the largest (compressed) size as the thumbnail. 5287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t numSamplesToScan = mNumSyncSamples; 5307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (numSamplesToScan > kMaxNumSyncSamplesToScan) { 5317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber numSamplesToScan = kMaxNumSyncSamplesToScan; 5327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber for (size_t i = 0; i < numSamplesToScan; ++i) { 5357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber uint32_t x; 53634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber if (mDataSource->readAt( 5377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber mSyncSampleOffset + 8 + i * 4, &x, 4) != 4) { 5387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return ERROR_IO; 5397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber x = ntohl(x); 5417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber --x; 5427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber // Now x is a sample index. 5447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber size_t sampleSize; 545c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err = getSampleSize_l(x, &sampleSize); 5467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (err != OK) { 5477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return err; 5487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber if (i == 0 || sampleSize > maxSampleSize) { 5517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber bestSampleIndex = x; 5527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber maxSampleSize = sampleSize; 5537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber } 5557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber *sample_index = bestSampleIndex; 5577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 5587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber return OK; 5597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber} 5607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber 561c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l( 562c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, size_t *sampleSize) { 563c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return mSampleIterator->getSampleSizeDirect( 564c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber sampleIndex, sampleSize); 565c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 566c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 567c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample( 568c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t sampleIndex, 569c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber off_t *offset, 570c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber size_t *size, 571c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber uint32_t *decodingTime) { 572c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber Mutex::Autolock autoLock(mLock); 573c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 574c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber status_t err; 575c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) { 576c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return err; 577c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 578c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 579c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (offset) { 580c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *offset = mSampleIterator->getSampleOffset(); 581c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 582c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 583c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (size) { 584c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *size = mSampleIterator->getSampleSize(); 585c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 586c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 587c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber if (decodingTime) { 588c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *decodingTime = mSampleIterator->getSampleTime(); 589c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber } 590c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 591c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber return OK; 592c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber} 593c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber 59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 596