SampleIterator.cpp revision 0386c91b8a910a134e5898ffa924c1b6c7560b13
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
174c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunkSampleIndex =
175c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                mFirstChunkSampleIndex
176c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    + (mStopChunk - mFirstChunk) * mSamplesPerChunk;
177c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        } else {
178c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunk = 0xffffffff;
179c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            mStopChunkSampleIndex = 0xffffffff;
180c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
181c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
182c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        ++mSampleToChunkIndex;
183c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
184c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
185c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
186c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
187c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
188c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleIterator::getChunkOffset(uint32_t chunk, off64_t *offset) {
189c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *offset = 0;
190c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
191c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (chunk >= mTable->mNumChunkOffsets) {
192c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
193c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
194c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
195c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mChunkOffsetType == SampleTable::kChunkOffsetType32) {
196c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t offset32;
197c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
198c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTable->mDataSource->readAt(
199c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mTable->mChunkOffsetOffset + 8 + 4 * chunk,
200c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    &offset32,
201c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    sizeof(offset32)) < (ssize_t)sizeof(offset32)) {
202c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
203c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
204c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
205c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = ntohl(offset32);
206c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    } else {
207c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK_EQ(mTable->mChunkOffsetType, SampleTable::kChunkOffsetType64);
208c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
209c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint64_t offset64;
210c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTable->mDataSource->readAt(
211c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mTable->mChunkOffsetOffset + 8 + 8 * chunk,
212c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    &offset64,
213c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    sizeof(offset64)) < (ssize_t)sizeof(offset64)) {
214c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
215c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
216c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
217c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = ntoh64(offset64);
218c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
219c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
220c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
221c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
222c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
223c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleIterator::getSampleSizeDirect(
224c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *size) {
225c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *size = 0;
226c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
227c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
228c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
229c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
230c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
231c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (mTable->mDefaultSampleSize > 0) {
232c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mTable->mDefaultSampleSize;
233c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return OK;
234c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
235c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
236c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    switch (mTable->mSampleSizeFieldSize) {
237c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 32:
238c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
239c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
240c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + 4 * sampleIndex,
241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        size, sizeof(*size)) < (ssize_t)sizeof(*size)) {
242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = ntohl(*size);
246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 16:
250c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint16_t x;
252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + 2 * sampleIndex,
254c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
255c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
256c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
257c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
258c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = ntohs(x);
259c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
260c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
261c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
262c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        case 8:
263c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
264c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint8_t x;
265c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
266c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + sampleIndex,
267c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
268c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
269c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
270c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
271c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = x;
272c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
273c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
274c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
275c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        default:
276c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        {
277c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            CHECK_EQ(mTable->mSampleSizeFieldSize, 4);
278c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
279c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            uint8_t x;
280c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            if (mTable->mDataSource->readAt(
281c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        mTable->mSampleSizeOffset + 12 + sampleIndex / 2,
282c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                        &x, sizeof(x)) < (ssize_t)sizeof(x)) {
283c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                return ERROR_IO;
284c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            }
285c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
286c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            *size = (sampleIndex & 1) ? x & 0x0f : x >> 4;
287c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            break;
288c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
289c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
290c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
291c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
292c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
293c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
294170056540e9ce65261b45efd15f67e72e2df1bedRobert Shihstatus_t SampleIterator::findSampleTimeAndDuration(
295170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        uint32_t sampleIndex, uint32_t *time, uint32_t *duration) {
296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (sampleIndex >= mTable->mNumSampleSizes) {
297c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return ERROR_OUT_OF_RANGE;
298c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
299c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
300c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    while (sampleIndex >= mTTSSampleIndex + mTTSCount) {
301c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mTimeToSampleIndex == mTable->mTimeToSampleCount) {
302c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_OUT_OF_RANGE;
303c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
304c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
305c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleIndex += mTTSCount;
306c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSSampleTime += mTTSCount * mTTSDuration;
307c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
308c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSCount = mTable->mTimeToSample[2 * mTimeToSampleIndex];
309c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mTTSDuration = mTable->mTimeToSample[2 * mTimeToSampleIndex + 1];
310c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
311c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        ++mTimeToSampleIndex;
312c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
313c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
314c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
315c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
3164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    *time += mTable->getCompositionTimeOffset(sampleIndex);
3174931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
318170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    *duration = mTTSDuration;
319170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih
320c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
321c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
322c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
323c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}  // namespace android
324c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
325