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
87c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    uint32_t chunk =
88c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        (sampleIndex - mFirstChunkSampleIndex) / mSamplesPerChunk
89c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        + mFirstChunk;
90c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
91c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (!mInitialized || chunk != mCurrentChunkIndex) {
92c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mCurrentChunkIndex = chunk;
93c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
94c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err;
95c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if ((err = getChunkOffset(chunk, &mCurrentChunkOffset)) != OK) {
9629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("getChunkOffset return error");
97c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return err;
98c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
99c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
100c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mCurrentChunkSampleSizes.clear();
101c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
102c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t firstChunkSampleIndex =
103c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mFirstChunkSampleIndex
104c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                + mSamplesPerChunk * (mCurrentChunkIndex - mFirstChunk);
105c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
106c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        for (uint32_t i = 0; i < mSamplesPerChunk; ++i) {
107c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            size_t sampleSize;
108c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if ((err = getSampleSizeDirect(
109c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                            firstChunkSampleIndex + i, &sampleSize)) != OK) {
11029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("getSampleSizeDirect return error");
111c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return err;
112c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
113c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
114c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mCurrentChunkSampleSizes.push(sampleSize);
115c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
116c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
117c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
118c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    uint32_t chunkRelativeSampleIndex =
119c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        (sampleIndex - mFirstChunkSampleIndex) % mSamplesPerChunk;
120c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
121c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleOffset = mCurrentChunkOffset;
122c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < chunkRelativeSampleIndex; ++i) {
123c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mCurrentSampleOffset += mCurrentChunkSampleSizes[i];
124c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
125c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
126c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleSize = mCurrentChunkSampleSizes[chunkRelativeSampleIndex];
127c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex < mTTSSampleIndex) {
128c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTimeToSampleIndex = 0;
129c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleIndex = 0;
130c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleTime = 0;
131c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSCount = 0;
132c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSDuration = 0;
133c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
135c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
136c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if ((err = findSampleTime(sampleIndex, &mCurrentSampleTime)) != OK) {
13729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("findSampleTime return error");
138c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
139c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
140c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
141c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mCurrentSampleIndex = sampleIndex;
142c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
143c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mInitialized = true;
144c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
145c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
146c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
147c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
148c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::findChunkRange(uint32_t sampleIndex) {
149c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    CHECK(sampleIndex >= mFirstChunkSampleIndex);
150c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    while (sampleIndex >= mStopChunkSampleIndex) {
152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mSampleToChunkIndex == mTable->mNumSampleToChunkOffsets) {
153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_OUT_OF_RANGE;
154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mFirstChunkSampleIndex = mStopChunkSampleIndex;
157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        const SampleTable::SampleToChunkEntry *entry =
159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            &mTable->mSampleToChunkEntries[mSampleToChunkIndex];
160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mFirstChunk = entry->startChunk;
162c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSamplesPerChunk = entry->samplesPerChunk;
163c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mChunkDesc = entry->chunkDesc;
164c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
165c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mSampleToChunkIndex + 1 < mTable->mNumSampleToChunkOffsets) {
166c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunk = entry[1].startChunk;
167c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
168c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunkSampleIndex =
169c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                mFirstChunkSampleIndex
170c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    + (mStopChunk - mFirstChunk) * mSamplesPerChunk;
171c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        } else {
172c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunk = 0xffffffff;
173c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunkSampleIndex = 0xffffffff;
174c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
175c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
176c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        ++mSampleToChunkIndex;
177c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
178c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
179c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
180c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
181c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
182c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleIterator::getChunkOffset(uint32_t chunk, off64_t *offset) {
183c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *offset = 0;
184c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
185c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (chunk >= mTable->mNumChunkOffsets) {
186c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
187c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
188c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
189c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mChunkOffsetType == SampleTable::kChunkOffsetType32) {
190c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t offset32;
191c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
192c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTable->mDataSource->readAt(
193c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mTable->mChunkOffsetOffset + 8 + 4 * chunk,
194c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    &offset32,
195c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    sizeof(offset32)) < (ssize_t)sizeof(offset32)) {
196c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
197c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
198c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
199c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = ntohl(offset32);
200c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    } else {
201c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK_EQ(mTable->mChunkOffsetType, SampleTable::kChunkOffsetType64);
202c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
203c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint64_t offset64;
204c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTable->mDataSource->readAt(
205c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mTable->mChunkOffsetOffset + 8 + 8 * chunk,
206c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    &offset64,
207c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    sizeof(offset64)) < (ssize_t)sizeof(offset64)) {
208c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
209c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
210c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
211c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = ntoh64(offset64);
212c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
213c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
214c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
215c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
216c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
217c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::getSampleSizeDirect(
218c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *size) {
219c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *size = 0;
220c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
221c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
222c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
223c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
224c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
225c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mDefaultSampleSize > 0) {
226c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mTable->mDefaultSampleSize;
227c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return OK;
228c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
229c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
230c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    switch (mTable->mSampleSizeFieldSize) {
231c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 32:
232c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
233c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
234c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + 4 * sampleIndex,
235c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        size, sizeof(*size)) < (ssize_t)sizeof(*size)) {
236c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
237c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
238c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
239c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = ntohl(*size);
240c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 16:
244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint16_t x;
246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + 2 * sampleIndex,
248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
250c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = ntohs(x);
253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
254c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
255c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
256c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 8:
257c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
258c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint8_t x;
259c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
260c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + sampleIndex,
261c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
262c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
263c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
264c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
265c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = x;
266c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
267c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
268c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
269c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        default:
270c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
271c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            CHECK_EQ(mTable->mSampleSizeFieldSize, 4);
272c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
273c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint8_t x;
274c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
275c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + sampleIndex / 2,
276c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
277c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
278c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
279c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
280c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = (sampleIndex & 1) ? x & 0x0f : x >> 4;
281c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
282c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
283c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
284c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
285c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
286c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
287c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
288c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::findSampleTime(
289c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, uint32_t *time) {
290c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
291c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
292c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
293c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
294c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    while (sampleIndex >= mTTSSampleIndex + mTTSCount) {
295c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTimeToSampleIndex == mTable->mTimeToSampleCount) {
296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_OUT_OF_RANGE;
297c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
298c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
299c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleIndex += mTTSCount;
300c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleTime += mTTSCount * mTTSDuration;
301c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
302c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSCount = mTable->mTimeToSample[2 * mTimeToSampleIndex];
303c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSDuration = mTable->mTimeToSample[2 * mTimeToSampleIndex + 1];
304c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
305c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        ++mTimeToSampleIndex;
306c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
307c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
308c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
309c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
3104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    *time += mTable->getCompositionTimeOffset(sampleIndex);
3114931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
312c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
313c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
314c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
315c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}  // namespace android
316c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
317