SampleIterator.cpp revision b1dc9e07c084d0df17de71b54f8340c0b8917824
1c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber/*
2c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * Copyright (C) 2010 The Android Open Source Project
3c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *
4c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * you may not use this file except in compliance with the License.
6c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * You may obtain a copy of the License at
7c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *
8c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber *
10c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * Unless required by applicable law or agreed to in writing, software
11c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * See the License for the specific language governing permissions and
14c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber * limitations under the License.
15c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber */
16c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
17c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#define LOG_TAG "SampleIterator"
18c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//#define LOG_NDEBUG 0
19c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include <utils/Log.h>
20c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
21c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include "include/SampleIterator.h"
22c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
23c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include <arpa/inet.h>
24c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
25f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
26c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include <media/stagefright/DataSource.h>
27c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include <media/stagefright/Utils.h>
28c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
29c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include "include/SampleTable.h"
30c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
31c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Hubernamespace android {
32c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
33c57b67905c2128ddadfeca96785ee1f593b6605aAndreas HuberSampleIterator::SampleIterator(SampleTable *table)
34c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    : mTable(table),
35c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mInitialized(false),
36c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mTimeToSampleIndex(0),
37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mTTSSampleIndex(0),
38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mTTSSampleTime(0),
39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mTTSCount(0),
40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mTTSDuration(0) {
41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    reset();
42c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
43c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
44c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Hubervoid SampleIterator::reset() {
45c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkIndex = 0;
46c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mFirstChunk = 0;
47c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mFirstChunkSampleIndex = 0;
48c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mStopChunk = 0;
49c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mStopChunkSampleIndex = 0;
50c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSamplesPerChunk = 0;
51c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mChunkDesc = 0;
52c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
53c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
54c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::seekTo(uint32_t sampleIndex) {
553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("seekTo(%d)", sampleIndex);
56c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
57213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
58213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber        return ERROR_END_OF_STREAM;
59213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber    }
60213addfaf4b359c69da4e9b4490c511d116845bbAndreas Huber
61c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mSampleToChunkOffset < 0
62c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            || mTable->mChunkOffsetOffset < 0
63c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            || mTable->mSampleSizeOffset < 0
64c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            || mTable->mTimeToSampleCount == 0) {
65c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
66c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_MALFORMED;
67c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
68c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
69c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mInitialized && mCurrentSampleIndex == sampleIndex) {
70c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return OK;
71c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
72c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
73c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (!mInitialized || sampleIndex < mFirstChunkSampleIndex) {
74c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        reset();
75c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
76c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
77c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mStopChunkSampleIndex) {
78c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err;
79c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if ((err = findChunkRange(sampleIndex)) != OK) {
8029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("findChunkRange failed");
81c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return err;
82c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
83c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
84c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
85c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    CHECK(sampleIndex < mStopChunkSampleIndex);
86c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
870386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia    if (mSamplesPerChunk == 0) {
880386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        ALOGE("b/22802344");
890386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia        return ERROR_MALFORMED;
900386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia    }
910386c91b8a910a134e5898ffa924c1b6c7560b13Wei Jia
92c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    uint32_t chunk =
93c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        (sampleIndex - mFirstChunkSampleIndex) / mSamplesPerChunk
94c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        + mFirstChunk;
95c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
96c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (!mInitialized || chunk != mCurrentChunkIndex) {
97c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mCurrentChunkIndex = chunk;
98c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
99c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err;
100c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if ((err = getChunkOffset(chunk, &mCurrentChunkOffset)) != OK) {
10129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("getChunkOffset return error");
102c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return err;
103c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
104c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
105c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mCurrentChunkSampleSizes.clear();
106c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
107c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t firstChunkSampleIndex =
108c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mFirstChunkSampleIndex
109c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                + mSamplesPerChunk * (mCurrentChunkIndex - mFirstChunk);
110c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
111c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        for (uint32_t i = 0; i < mSamplesPerChunk; ++i) {
112c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            size_t sampleSize;
113c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if ((err = getSampleSizeDirect(
114c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                            firstChunkSampleIndex + i, &sampleSize)) != OK) {
11529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("getSampleSizeDirect return error");
116c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return err;
117c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
118c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
119c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mCurrentChunkSampleSizes.push(sampleSize);
120c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
121c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
122c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
123c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    uint32_t chunkRelativeSampleIndex =
124c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        (sampleIndex - mFirstChunkSampleIndex) % mSamplesPerChunk;
125c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
126c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleOffset = mCurrentChunkOffset;
127c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < chunkRelativeSampleIndex; ++i) {
128c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mCurrentSampleOffset += mCurrentChunkSampleSizes[i];
129c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
130c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
131c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleSize = mCurrentChunkSampleSizes[chunkRelativeSampleIndex];
132c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex < mTTSSampleIndex) {
133c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTimeToSampleIndex = 0;
134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleIndex = 0;
135c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleTime = 0;
136c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSCount = 0;
137c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSDuration = 0;
138c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
139c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
140c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
141170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    if ((err = findSampleTimeAndDuration(
142170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih            sampleIndex, &mCurrentSampleTime, &mCurrentSampleDuration)) != OK) {
14329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("findSampleTime return error");
144c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
145c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
146c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
147c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleIndex = sampleIndex;
148c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
149c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mInitialized = true;
150c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::findChunkRange(uint32_t sampleIndex) {
155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    CHECK(sampleIndex >= mFirstChunkSampleIndex);
156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    while (sampleIndex >= mStopChunkSampleIndex) {
158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mSampleToChunkIndex == mTable->mNumSampleToChunkOffsets) {
159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_OUT_OF_RANGE;
160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
162c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mFirstChunkSampleIndex = mStopChunkSampleIndex;
163c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
164c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        const SampleTable::SampleToChunkEntry *entry =
165c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            &mTable->mSampleToChunkEntries[mSampleToChunkIndex];
166c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
167c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mFirstChunk = entry->startChunk;
168c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSamplesPerChunk = entry->samplesPerChunk;
169c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mChunkDesc = entry->chunkDesc;
170c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
171c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mSampleToChunkIndex + 1 < mTable->mNumSampleToChunkOffsets) {
172c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunk = entry[1].startChunk;
173c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
174cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker            if (mStopChunk < mFirstChunk ||
175cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker                (mStopChunk - mFirstChunk) > UINT32_MAX / mSamplesPerChunk ||
176cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker                ((mStopChunk - mFirstChunk) * mSamplesPerChunk >
177cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker                 UINT32_MAX - mFirstChunkSampleIndex)) {
178cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker
179cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker                return ERROR_OUT_OF_RANGE;
180cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker            }
181c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunkSampleIndex =
182c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                mFirstChunkSampleIndex
183c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    + (mStopChunk - mFirstChunk) * mSamplesPerChunk;
184c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        } else {
185c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunk = 0xffffffff;
186c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunkSampleIndex = 0xffffffff;
187c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
188c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
189c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        ++mSampleToChunkIndex;
190c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
191c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
192c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
193c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
194c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
195c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleIterator::getChunkOffset(uint32_t chunk, off64_t *offset) {
196c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *offset = 0;
197c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
198c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (chunk >= mTable->mNumChunkOffsets) {
199c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
200c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
201c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
202c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mChunkOffsetType == SampleTable::kChunkOffsetType32) {
203c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t offset32;
204c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
205c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTable->mDataSource->readAt(
206c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mTable->mChunkOffsetOffset + 8 + 4 * chunk,
207c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    &offset32,
208c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    sizeof(offset32)) < (ssize_t)sizeof(offset32)) {
209c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
210c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
211c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
212c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = ntohl(offset32);
213c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    } else {
214c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK_EQ(mTable->mChunkOffsetType, SampleTable::kChunkOffsetType64);
215c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
216c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint64_t offset64;
217c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTable->mDataSource->readAt(
218c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mTable->mChunkOffsetOffset + 8 + 8 * chunk,
219c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    &offset64,
220c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    sizeof(offset64)) < (ssize_t)sizeof(offset64)) {
221c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
222c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
223c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
224c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = ntoh64(offset64);
225c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
226c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
227c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
228c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
229c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
230c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::getSampleSizeDirect(
231c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *size) {
232c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *size = 0;
233c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
234c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
235c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
236c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
237c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
238c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mDefaultSampleSize > 0) {
239c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mTable->mDefaultSampleSize;
240c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return OK;
241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    switch (mTable->mSampleSizeFieldSize) {
244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 32:
245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + 4 * sampleIndex,
248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        size, sizeof(*size)) < (ssize_t)sizeof(*size)) {
249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
250c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = ntohl(*size);
253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
254c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
255c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
256c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 16:
257c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
258c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint16_t x;
259c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
260c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + 2 * sampleIndex,
261c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
262c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
263c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
264c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
265c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = ntohs(x);
266c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
267c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
268c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
269c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 8:
270c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
271c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint8_t x;
272c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
273c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + sampleIndex,
274c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
275c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
276c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
277c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
278c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = x;
279c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
280c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
281c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
282c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        default:
283c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
284c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            CHECK_EQ(mTable->mSampleSizeFieldSize, 4);
285c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
286c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint8_t x;
287c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
288c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + sampleIndex / 2,
289c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
290c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
291c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
292c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
293c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = (sampleIndex & 1) ? x & 0x0f : x >> 4;
294c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
295c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
297c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
298c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
299c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
300c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
301170056540e9ce65261b45efd15f67e72e2df1bedRobert Shihstatus_t SampleIterator::findSampleTimeAndDuration(
302170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        uint32_t sampleIndex, uint32_t *time, uint32_t *duration) {
303c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
304c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
305c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
306c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
307c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    while (sampleIndex >= mTTSSampleIndex + mTTSCount) {
308c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTimeToSampleIndex == mTable->mTimeToSampleCount) {
309c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_OUT_OF_RANGE;
310c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
311c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
312c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleIndex += mTTSCount;
313c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleTime += mTTSCount * mTTSDuration;
314c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
315c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSCount = mTable->mTimeToSample[2 * mTimeToSampleIndex];
316c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSDuration = mTable->mTimeToSample[2 * mTimeToSampleIndex + 1];
317c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
318c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        ++mTimeToSampleIndex;
319c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
320c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
321c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
322c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
323b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    int32_t offset = mTable->getCompositionTimeOffset(sampleIndex);
324b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    if ((offset < 0 && *time < (offset == INT32_MIN ?
325b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen            INT32_MAX : uint32_t(-offset))) ||
326b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen            (offset > 0 && *time > UINT32_MAX - offset)) {
327b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen        ALOGE("%u + %d would overflow", *time, offset);
328b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen        return ERROR_OUT_OF_RANGE;
329b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    }
330b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    if (offset > 0) {
331b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen        *time += offset;
332b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    } else {
333b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen        *time -= (offset == INT32_MIN ? INT32_MAX : (-offset));
334b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    }
3354931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
336170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    *duration = mTTSDuration;
337170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih
338c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
339c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
340c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
341c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}  // namespace android
342c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
343