SampleTable.cpp revision a488c7daf91357611fcdbff7a32e5a73ec630070
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "SampleTable"
18c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//#define LOG_NDEBUG 0
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h"
22c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include "include/SampleIterator.h"
2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h>
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h>
270c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
33c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o');
34c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
35c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4');
36c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z');
38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2');
40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber////////////////////////////////////////////////////////////////////////////////
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source)
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mDataSource(source),
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetOffset(-1),
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetType(0),
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumChunkOffsets(0),
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleToChunkOffset(-1),
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleToChunkOffsets(0),
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeOffset(-1),
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeFieldSize(0),
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDefaultSampleSize(0),
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleSizes(0),
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSampleCount(0),
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSample(NULL),
564678a6dc5f09008481524949a9667af5a6190374Andreas Huber      mSampleTimeEntries(NULL),
574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mCompositionTimeDeltaEntries(NULL),
584931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mNumCompositionTimeDeltaEntries(0),
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSyncSampleOffset(-1),
60c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mNumSyncSamples(0),
618bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mSyncSamples(NULL),
628bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mLastSyncSampleIndex(0),
63c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mSampleToChunkEntries(NULL) {
64c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = new SampleIterator(this);
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() {
68c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete[] mSampleToChunkEntries;
69c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries = NULL;
70c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
718bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    delete[] mSyncSamples;
728bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    mSyncSamples = NULL;
738bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    delete[] mCompositionTimeDeltaEntries;
754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mCompositionTimeDeltaEntries = NULL;
764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
774678a6dc5f09008481524949a9667af5a6190374Andreas Huber    delete[] mSampleTimeEntries;
784678a6dc5f09008481524949a9667af5a6190374Andreas Huber    mSampleTimeEntries = NULL;
794678a6dc5f09008481524949a9667af5a6190374Andreas Huber
8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete[] mTimeToSample;
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = NULL;
82c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
83c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete mSampleIterator;
84c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = NULL;
8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams(
88c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetOffset >= 0) {
9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
930c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64);
9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetOffset = data_offset;
9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetType = type;
9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
10334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumChunkOffsets = U32_AT(&header[4]);
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetType == kChunkOffsetType32) {
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 4) {
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 8) {
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams(
129c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleToChunkOffset >= 0) {
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleToChunkOffset = data_offset;
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
14134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleToChunkOffsets = U32_AT(&header[4]);
15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8 + mNumSampleToChunkOffsets * 12) {
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries =
158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        new SampleToChunkEntry[mNumSampleToChunkOffsets];
159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint8_t buffer[12];
162c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mDataSource->readAt(
163c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer))
164c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                != (ssize_t)sizeof(buffer)) {
165c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
166c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
167c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
168c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK(U32_AT(buffer) >= 1);  // chunk index is 1 based in the spec.
169c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
170c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        // We want the chunk index to be 0-based.
171c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1;
172c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]);
173c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]);
174c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
175c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams(
180c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleSizeOffset >= 0) {
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1850c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact);
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleSizeOffset = data_offset;
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 12) {
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[12];
19434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mDefaultSampleSize = U32_AT(&header[4]);
20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleSizes = U32_AT(&header[8]);
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (type == kSampleSizeType32) {
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = 32;
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mDefaultSampleSize != 0) {
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return OK;
21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + mNumSampleSizes * 4) {
21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if ((mDefaultSampleSize & 0xffffff00) != 0) {
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            // The high 24 bits are reserved and must be 0.
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = mDefaultSampleSize & 0xf;
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mDefaultSampleSize = 0;
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            && mSampleSizeFieldSize != 16) {
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams(
240c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mTimeToSample != NULL || data_size < 8) {
24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
24634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSampleCount = U32_AT(&header[4]);
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = new uint32_t[mTimeToSampleCount * 2];
25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
26034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) {
26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mTimeToSample[i] = ntohl(mTimeToSample[i]);
26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2724931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams(
2734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        off64_t data_offset, size_t data_size) {
2744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    LOGI("There are reordered frames present.");
2754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
2764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
2774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
2784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
2794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
2804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    uint8_t header[8];
2814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
2824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset, header, sizeof(header))
2834931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)sizeof(header)) {
2844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
2854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
2864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
2874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (U32_AT(header) != 0) {
2884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        // Expected version = 0, flags = 0.
2894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
2904931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
2914931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
2924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    size_t numEntries = U32_AT(&header[4]);
2934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
2944931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (data_size != (numEntries + 1) * 8) {
2954931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
2964931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
2974931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
2984931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mNumCompositionTimeDeltaEntries = numEntries;
2994931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];
3004931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
3024931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
3034931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)numEntries * 8) {
3044931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        delete[] mCompositionTimeDeltaEntries;
3054931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries = NULL;
3064931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3074931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
3084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    for (size_t i = 0; i < 2 * numEntries; ++i) {
3114931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
3124931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3134931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3144931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    return OK;
3154931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
3164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
317c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset >= 0 || data_size < 8) {
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSyncSampleOffset = data_offset;
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
32534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSyncSamples = U32_AT(&header[4]);
33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mNumSyncSamples < 2) {
33875fc7654280ac2a72fa8124b88e616219a3e61e2Andreas Huber        LOGV("Table of sync samples is empty or has only a single entry!");
33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
3408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
3418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    mSyncSamples = new uint32_t[mNumSyncSamples];
3428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    size_t size = mNumSyncSamples * sizeof(uint32_t);
3438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
3448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            != (ssize_t)size) {
3458bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        return ERROR_IO;
3468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
3478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
3488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    for (size_t i = 0; i < mNumSyncSamples; ++i) {
3498bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
3508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
3518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const {
35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumChunkOffsets;
35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const {
36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumSampleSizes;
36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) {
36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *max_size = 0;
36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t sample_size;
370c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(i, &sample_size);
371da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (sample_size > *max_size) {
37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *max_size = sample_size;
37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
384da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) {
385da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber    return time1 > time2 ? time1 - time2 : time2 - time1;
386da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber}
387da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
3884678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static
3894678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
3904678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
3914678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
3924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3934678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (a->mCompositionTime < b->mCompositionTime) {
3944678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return -1;
3954678a6dc5f09008481524949a9667af5a6190374Andreas Huber    } else if (a->mCompositionTime > b->mCompositionTime) {
3964678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return 1;
3974678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
398abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
3994678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return 0;
4004678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
4014678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4024678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() {
40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
40420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4054678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (mSampleTimeEntries != NULL) {
4064678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return;
4074678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
4084678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4094678a6dc5f09008481524949a9667af5a6190374Andreas Huber    mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes];
4104678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4114678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleIndex = 0;
4124678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleTime = 0;
4134678a6dc5f09008481524949a9667af5a6190374Andreas Huber
41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t n = mTimeToSample[2 * i];
41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t delta = mTimeToSample[2 * i + 1];
41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4184678a6dc5f09008481524949a9667af5a6190374Andreas Huber        for (uint32_t j = 0; j < n; ++j) {
4194678a6dc5f09008481524949a9667af5a6190374Andreas Huber            CHECK(sampleIndex < mNumSampleSizes);
42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4214678a6dc5f09008481524949a9667af5a6190374Andreas Huber            mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
422abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4234678a6dc5f09008481524949a9667af5a6190374Andreas Huber            mSampleTimeEntries[sampleIndex].mCompositionTime =
4244678a6dc5f09008481524949a9667af5a6190374Andreas Huber                sampleTime + getCompositionTimeOffset(sampleIndex);
4254678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4264678a6dc5f09008481524949a9667af5a6190374Andreas Huber            ++sampleIndex;
4274678a6dc5f09008481524949a9667af5a6190374Andreas Huber            sampleTime += delta;
4284678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
4294678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
4304678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4314678a6dc5f09008481524949a9667af5a6190374Andreas Huber    qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
4324678a6dc5f09008481524949a9667af5a6190374Andreas Huber          CompareIncreasingTime);
4334678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
4344678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4354678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime(
4364678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
4374678a6dc5f09008481524949a9667af5a6190374Andreas Huber    buildSampleEntriesTable();
4384678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4394678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t left = 0;
4404678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t right = mNumSampleSizes;
4414678a6dc5f09008481524949a9667af5a6190374Andreas Huber    while (left < right) {
4424678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t center = (left + right) / 2;
4434678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime;
4444678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4454678a6dc5f09008481524949a9667af5a6190374Andreas Huber        if (req_time < centerTime) {
4464678a6dc5f09008481524949a9667af5a6190374Andreas Huber            right = center;
4474678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else if (req_time > centerTime) {
4484678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center + 1;
4494678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else {
4504678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center;
4514678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
4524678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
4534678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
4544678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4554678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (left == mNumSampleSizes) {
456a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        if (flags == kFlagAfter) {
457a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber            return ERROR_OUT_OF_RANGE;
458a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        }
459a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber
4604678a6dc5f09008481524949a9667af5a6190374Andreas Huber        --left;
4614678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
4624678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4634678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t closestIndex = left;
464abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4654678a6dc5f09008481524949a9667af5a6190374Andreas Huber    switch (flags) {
4664678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagBefore:
4674678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
4684678a6dc5f09008481524949a9667af5a6190374Andreas Huber            while (closestIndex > 0
4694678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    && mSampleTimeEntries[closestIndex].mCompositionTime
4704678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            > req_time) {
4714678a6dc5f09008481524949a9667af5a6190374Andreas Huber                --closestIndex;
47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
4734678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
4744678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4764678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagAfter:
4774678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
4784678a6dc5f09008481524949a9667af5a6190374Andreas Huber            while (closestIndex + 1 < mNumSampleSizes
4794678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    && mSampleTimeEntries[closestIndex].mCompositionTime
4804678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            < req_time) {
4814678a6dc5f09008481524949a9667af5a6190374Andreas Huber                ++closestIndex;
4824678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
4834678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4864678a6dc5f09008481524949a9667af5a6190374Andreas Huber        default:
4874678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
4884678a6dc5f09008481524949a9667af5a6190374Andreas Huber            CHECK(flags == kFlagClosest);
4894678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4904678a6dc5f09008481524949a9667af5a6190374Andreas Huber            if (closestIndex > 0) {
4914678a6dc5f09008481524949a9667af5a6190374Andreas Huber                // Check left neighbour and pick closest.
4924678a6dc5f09008481524949a9667af5a6190374Andreas Huber                uint32_t absdiff1 =
4934678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    abs_difference(
4944678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            mSampleTimeEntries[closestIndex].mCompositionTime,
4954678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            req_time);
4964678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4974678a6dc5f09008481524949a9667af5a6190374Andreas Huber                uint32_t absdiff2 =
4984678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    abs_difference(
4994678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            mSampleTimeEntries[closestIndex - 1].mCompositionTime,
5004678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            req_time);
5014678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5024678a6dc5f09008481524949a9667af5a6190374Andreas Huber                if (absdiff1 > absdiff2) {
5034678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    closestIndex = closestIndex - 1;
5044678a6dc5f09008481524949a9667af5a6190374Andreas Huber                }
5054678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
5064678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5074678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
5084678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5114678a6dc5f09008481524949a9667af5a6190374Andreas Huber    *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
5124678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5134678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return OK;
51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
516abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear(
517abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) {
518abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    Mutex::Autolock autoLock(mLock);
519abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *sample_index = 0;
52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset < 0) {
52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // All samples are sync-samples.
52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *sample_index = start_sample_index;
52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
528abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mNumSyncSamples == 0) {
529abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        *sample_index = 0;
530abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return OK;
531abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
532da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
533abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t left = 0;
534abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    while (left < mNumSyncSamples) {
5358bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t x = mSyncSamples[left];
53620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
537abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (x >= start_sample_index) {
53820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
53920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
540abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
541abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        ++left;
542abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
543f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong    if (left > 0) {
544f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong        --left;
545f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong    }
546abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
547abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t x;
548abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mDataSource->readAt(
549abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) {
550abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return ERROR_IO;
551abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
552abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
553abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    x = ntohl(x);
554abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    --x;
555abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
556abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (left + 1 < mNumSyncSamples) {
5578bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t y = mSyncSamples[left + 1];
558abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
559abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        // our sample lies between sync samples x and y.
560abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
561abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        status_t err = mSampleIterator->seekTo(start_sample_index);
562abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
563abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
564abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
565abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
566abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t sample_time = mSampleIterator->getSampleTime();
567abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
568abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        err = mSampleIterator->seekTo(x);
569abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
570abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
571abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
572abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t x_time = mSampleIterator->getSampleTime();
573abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
574abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        err = mSampleIterator->seekTo(y);
575abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
576abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
577abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
578abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
579abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t y_time = mSampleIterator->getSampleTime();
580abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
581abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (abs_difference(x_time, sample_time)
582abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                > abs_difference(y_time, sample_time)) {
583abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // Pick the sync sample closest (timewise) to the start-sample.
584abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            x = y;
585abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            ++left;
586abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
587abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
588abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
589abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    switch (flags) {
590abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagBefore:
591abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
592abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (x > start_sample_index) {
593abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(left > 0);
594abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
595abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                if (mDataSource->readAt(
596abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                            mSyncSampleOffset + 8 + (left - 1) * 4, &x, 4) != 4) {
597abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    return ERROR_IO;
598abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
599abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
600abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                x = ntohl(x);
601abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                --x;
602abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
603abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(x <= start_sample_index);
604abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
605abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
606abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
607abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
608abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagAfter:
609abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
610abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (x < start_sample_index) {
611abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                if (left + 1 >= mNumSyncSamples) {
612abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    return ERROR_OUT_OF_RANGE;
613abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
614abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
6158bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                x = mSyncSamples[left + 1];
616abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
617abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(x >= start_sample_index);
618abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
619abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
620abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
621abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
622abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
623abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        default:
624abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
627abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    *sample_index = x;
62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
63120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
633c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
634c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
6357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (mSyncSampleOffset < 0) {
6367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // All samples are sync-samples.
6377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        *sample_index = 0;
6387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        return OK;
6397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
6407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    uint32_t bestSampleIndex = 0;
6427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t maxSampleSize = 0;
6437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    static const size_t kMaxNumSyncSamplesToScan = 20;
6457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // Consider the first kMaxNumSyncSamplesToScan sync samples and
6477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // pick the one with the largest (compressed) size as the thumbnail.
6487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t numSamplesToScan = mNumSyncSamples;
6507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (numSamplesToScan > kMaxNumSyncSamplesToScan) {
6517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        numSamplesToScan = kMaxNumSyncSamplesToScan;
6527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
6537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    for (size_t i = 0; i < numSamplesToScan; ++i) {
6558bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t x = mSyncSamples[i];
6567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // Now x is a sample index.
6587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t sampleSize;
659c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(x, &sampleSize);
6607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (err != OK) {
6617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            return err;
6627e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
6637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (i == 0 || sampleSize > maxSampleSize) {
6657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            bestSampleIndex = x;
6667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            maxSampleSize = sampleSize;
6677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
6687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
6697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    *sample_index = bestSampleIndex;
6717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
6727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    return OK;
6737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber}
6747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
675c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l(
676c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *sampleSize) {
677c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return mSampleIterator->getSampleSizeDirect(
678c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            sampleIndex, sampleSize);
679c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
680c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
681c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample(
682c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex,
683c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t *offset,
684c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        size_t *size,
6854678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t *compositionTime,
6868bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        bool *isSyncSample) {
687c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
688c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
689c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
690c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) {
691c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
692c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
693c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
694c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (offset) {
695c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = mSampleIterator->getSampleOffset();
696c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
697c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
698c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (size) {
699c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mSampleIterator->getSampleSize();
700c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
701c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7024678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (compositionTime) {
7034678a6dc5f09008481524949a9667af5a6190374Andreas Huber        *compositionTime = mSampleIterator->getSampleTime();
704c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
705c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7068bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (isSyncSample) {
7078bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        *isSyncSample = false;
7088bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (mSyncSampleOffset < 0) {
7098bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            // Every sample is a sync sample.
7108bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            *isSyncSample = true;
7118bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        } else {
7128bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            size_t i = (mLastSyncSampleIndex < mNumSyncSamples)
7138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                    && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex)
7148bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ? mLastSyncSampleIndex : 0;
7158bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
7168bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) {
7178bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ++i;
7188bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
7198bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
7208bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) {
7218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                *isSyncSample = true;
7228bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
7238bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
7248bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mLastSyncSampleIndex = i;
7258bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
7268bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
7278bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
728c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
729c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
730c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7314931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) const {
7324931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mCompositionTimeDeltaEntries == NULL) {
7334931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return 0;
7344931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
7354931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
7364931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    uint32_t curSample = 0;
7374931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    for (size_t i = 0; i < mNumCompositionTimeDeltaEntries; ++i) {
7384931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        uint32_t sampleCount = mCompositionTimeDeltaEntries[2 * i];
7394931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
7404931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        if (sampleIndex < curSample + sampleCount) {
7414931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            uint32_t sampleDelta = mCompositionTimeDeltaEntries[2 * i + 1];
7424931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
7434931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            return sampleDelta;
7444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        }
7454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
7464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        curSample += sampleCount;
7474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
7484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
7494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    return 0;
7504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
7514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
754