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
2175226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen#include "SampleIterator.h"
22c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
23c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include <arpa/inet.h>
24c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
252a243f08193fe9ff1afe018e9953f01c44ced9deMarco Nelissen#include <media/DataSourceBase.h>
26f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
27607612858f3afad1ade51a098aafa2a41523b5f7Dongwon Kang#include <media/stagefright/foundation/ByteUtils.h>
28c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
2975226177f20a176d50e3e53bbb34067cb49112c3Marco Nelissen#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        status_t err;
98c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if ((err = getChunkOffset(chunk, &mCurrentChunkOffset)) != OK) {
9929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("getChunkOffset return error");
100c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return err;
101c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
102c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
103c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mCurrentChunkSampleSizes.clear();
104c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
105c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t firstChunkSampleIndex =
106c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mFirstChunkSampleIndex
10703237ce0f9584c98ccda76c2474a4ae84c763f5bRobert Shih                + mSamplesPerChunk * (chunk - mFirstChunk);
108c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
109c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        for (uint32_t i = 0; i < mSamplesPerChunk; ++i) {
110c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            size_t sampleSize;
111c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if ((err = getSampleSizeDirect(
112c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                            firstChunkSampleIndex + i, &sampleSize)) != OK) {
11329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("getSampleSizeDirect return error");
11403237ce0f9584c98ccda76c2474a4ae84c763f5bRobert Shih                mCurrentChunkSampleSizes.clear();
115c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return err;
116c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
117c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
118c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mCurrentChunkSampleSizes.push(sampleSize);
119c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
12003237ce0f9584c98ccda76c2474a4ae84c763f5bRobert Shih
12103237ce0f9584c98ccda76c2474a4ae84c763f5bRobert Shih        mCurrentChunkIndex = chunk;
122c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
123c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
124c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    uint32_t chunkRelativeSampleIndex =
125c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        (sampleIndex - mFirstChunkSampleIndex) % mSamplesPerChunk;
126c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
127c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleOffset = mCurrentChunkOffset;
128c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < chunkRelativeSampleIndex; ++i) {
129c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mCurrentSampleOffset += mCurrentChunkSampleSizes[i];
130c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
131c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
132c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleSize = mCurrentChunkSampleSizes[chunkRelativeSampleIndex];
133c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex < mTTSSampleIndex) {
134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTimeToSampleIndex = 0;
135c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleIndex = 0;
136c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleTime = 0;
137c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSCount = 0;
138c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSDuration = 0;
139c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
140c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
141c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
142170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    if ((err = findSampleTimeAndDuration(
143170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih            sampleIndex, &mCurrentSampleTime, &mCurrentSampleDuration)) != OK) {
14429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("findSampleTime return error");
145c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
146c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
147c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
148c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleIndex = sampleIndex;
149c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
150c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mInitialized = true;
151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::findChunkRange(uint32_t sampleIndex) {
156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    CHECK(sampleIndex >= mFirstChunkSampleIndex);
157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    while (sampleIndex >= mStopChunkSampleIndex) {
159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mSampleToChunkIndex == mTable->mNumSampleToChunkOffsets) {
160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_OUT_OF_RANGE;
161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
162c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
163c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mFirstChunkSampleIndex = mStopChunkSampleIndex;
164c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
165c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        const SampleTable::SampleToChunkEntry *entry =
166c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            &mTable->mSampleToChunkEntries[mSampleToChunkIndex];
167c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
168c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mFirstChunk = entry->startChunk;
169c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSamplesPerChunk = entry->samplesPerChunk;
170c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mChunkDesc = entry->chunkDesc;
171c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
172c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mSampleToChunkIndex + 1 < mTable->mNumSampleToChunkOffsets) {
173c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunk = entry[1].startChunk;
174c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
175b0ed640b15b57b7262a34e549e76d44db5b155dbMarco Nelissen            if (mSamplesPerChunk == 0 || mStopChunk < mFirstChunk ||
176cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker                (mStopChunk - mFirstChunk) > UINT32_MAX / mSamplesPerChunk ||
177cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker                ((mStopChunk - mFirstChunk) * mSamplesPerChunk >
178cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker                 UINT32_MAX - mFirstChunkSampleIndex)) {
179cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker
180cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker                return ERROR_OUT_OF_RANGE;
181cbcd8dd1967af30ff035132328002c0ec9a8872eChad Brubaker            }
182c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunkSampleIndex =
183c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                mFirstChunkSampleIndex
184c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    + (mStopChunk - mFirstChunk) * mSamplesPerChunk;
185c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        } else {
186c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunk = 0xffffffff;
187c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunkSampleIndex = 0xffffffff;
188c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
189c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
190c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        ++mSampleToChunkIndex;
191c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
192c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
193c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
194c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
195c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
196c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleIterator::getChunkOffset(uint32_t chunk, off64_t *offset) {
197c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *offset = 0;
198c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
199c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (chunk >= mTable->mNumChunkOffsets) {
200c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
201c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
202c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
203c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mChunkOffsetType == SampleTable::kChunkOffsetType32) {
204c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t offset32;
205c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
206c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTable->mDataSource->readAt(
207c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mTable->mChunkOffsetOffset + 8 + 4 * chunk,
208c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    &offset32,
209c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    sizeof(offset32)) < (ssize_t)sizeof(offset32)) {
210c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
211c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
212c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
213c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = ntohl(offset32);
214c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    } else {
215c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK_EQ(mTable->mChunkOffsetType, SampleTable::kChunkOffsetType64);
216c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
217c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint64_t offset64;
218c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTable->mDataSource->readAt(
219c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mTable->mChunkOffsetOffset + 8 + 8 * chunk,
220c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    &offset64,
221c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    sizeof(offset64)) < (ssize_t)sizeof(offset64)) {
222c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
223c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
224c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
225c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = ntoh64(offset64);
226c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
227c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
228c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
229c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
230c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
231c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::getSampleSizeDirect(
232c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *size) {
233c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *size = 0;
234c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
235c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
236c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
237c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
238c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
239c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mDefaultSampleSize > 0) {
240c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mTable->mDefaultSampleSize;
241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return OK;
242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    switch (mTable->mSampleSizeFieldSize) {
245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 32:
246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
24716c8f0ddb60293a694c39aec90aeb0a8663234cashaohongsheng            uint32_t x;
248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + 4 * sampleIndex,
25016c8f0ddb60293a694c39aec90aeb0a8663234cashaohongsheng                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
25416c8f0ddb60293a694c39aec90aeb0a8663234cashaohongsheng            *size = ntohl(x);
255c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
256c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
257c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
258c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 16:
259c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
260c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint16_t x;
261c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
262c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + 2 * sampleIndex,
263c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
264c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
265c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
266c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
267c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = ntohs(x);
268c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
269c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
270c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
271c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 8:
272c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
273c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint8_t x;
274c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
275c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + sampleIndex,
276c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
277c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
278c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
279c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
280c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = x;
281c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
282c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
283c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
284c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        default:
285c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
2860bdcf66bf30dfe60b44ea2d69bc846cca33fc3f3Colin Cross            CHECK_EQ(mTable->mSampleSizeFieldSize, 4u);
287c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
288c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint8_t x;
289c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
290c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + sampleIndex / 2,
291c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
292c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
293c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
294c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
295c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = (sampleIndex & 1) ? x & 0x0f : x >> 4;
296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
297c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
298c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
299c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
300c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
301c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
302c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
303170056540e9ce65261b45efd15f67e72e2df1bedRobert Shihstatus_t SampleIterator::findSampleTimeAndDuration(
304170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        uint32_t sampleIndex, uint32_t *time, uint32_t *duration) {
305c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
306c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
307c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
308c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
309833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen    while (true) {
310833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen        if (mTTSSampleIndex > UINT32_MAX - mTTSCount) {
311833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen            return ERROR_OUT_OF_RANGE;
312833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen        }
313833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen        if(sampleIndex < mTTSSampleIndex + mTTSCount) {
314833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen            break;
315833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen        }
316833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen        if (mTimeToSampleIndex == mTable->mTimeToSampleCount ||
317bbc0c8bb5478ee59970977033802185cccf10b48Marco Nelissen            (mTTSDuration != 0 && mTTSCount > UINT32_MAX / mTTSDuration) ||
318833fb390dcdfa4da31640dd3210e568d141960c4Marco Nelissen            mTTSSampleTime > UINT32_MAX - (mTTSCount * mTTSDuration)) {
319c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_OUT_OF_RANGE;
320c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
321c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
322c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleIndex += mTTSCount;
323c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleTime += mTTSCount * mTTSDuration;
324c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
325c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSCount = mTable->mTimeToSample[2 * mTimeToSampleIndex];
326c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSDuration = mTable->mTimeToSample[2 * mTimeToSampleIndex + 1];
327c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
328c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        ++mTimeToSampleIndex;
329c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
330c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
331c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
332c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
333b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    int32_t offset = mTable->getCompositionTimeOffset(sampleIndex);
334b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    if ((offset < 0 && *time < (offset == INT32_MIN ?
335b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen            INT32_MAX : uint32_t(-offset))) ||
336b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen            (offset > 0 && *time > UINT32_MAX - offset)) {
337b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen        ALOGE("%u + %d would overflow", *time, offset);
338b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen        return ERROR_OUT_OF_RANGE;
339b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    }
340b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    if (offset > 0) {
341b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen        *time += offset;
342b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    } else {
343b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen        *time -= (offset == INT32_MIN ? INT32_MAX : (-offset));
344b1dc9e07c084d0df17de71b54f8340c0b8917824Marco Nelissen    }
3454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
346170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    *duration = mTTSDuration;
347170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih
348c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
349c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
350c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
351c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}  // namespace android
352c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
353