SampleTable.cpp revision cccd2e5e3aa015d6ce96ba0245b7161c077cdba2
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
2689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia/* TODO: remove after being merged into other branches */
31108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia#ifndef UINT32_MAX
32108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia#define UINT32_MAX       (4294967295U)
33108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia#endif
34108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o');
39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4');
41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
42c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z');
43c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
44c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2');
45c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
46c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber////////////////////////////////////////////////////////////////////////////////
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4889aa8fe4cb00d2f24260005b008602232d678684Andreas Huberstruct SampleTable::CompositionDeltaLookup {
4989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    CompositionDeltaLookup();
5089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    void setEntries(
5289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            const uint32_t *deltaEntries, size_t numDeltaEntries);
5389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
5589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5689aa8fe4cb00d2f24260005b008602232d678684Andreas Huberprivate:
5789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex mLock;
5889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    const uint32_t *mDeltaEntries;
6089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mNumDeltaEntries;
6189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mCurrentDeltaEntry;
6389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mCurrentEntrySampleIndex;
6489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup);
6689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber};
6789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6889aa8fe4cb00d2f24260005b008602232d678684Andreas HuberSampleTable::CompositionDeltaLookup::CompositionDeltaLookup()
6989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    : mDeltaEntries(NULL),
7089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mNumDeltaEntries(0),
7189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCurrentDeltaEntry(0),
7289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCurrentEntrySampleIndex(0) {
7389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
7489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
7589aa8fe4cb00d2f24260005b008602232d678684Andreas Hubervoid SampleTable::CompositionDeltaLookup::setEntries(
7689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        const uint32_t *deltaEntries, size_t numDeltaEntries) {
7789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex::Autolock autolock(mLock);
7889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
7989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mDeltaEntries = deltaEntries;
8089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mNumDeltaEntries = numDeltaEntries;
8189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCurrentDeltaEntry = 0;
8289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCurrentEntrySampleIndex = 0;
8389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
8489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8589aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
8689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        uint32_t sampleIndex) {
8789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex::Autolock autolock(mLock);
8889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    if (mDeltaEntries == NULL) {
9089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        return 0;
9189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
9289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
9389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    if (sampleIndex < mCurrentEntrySampleIndex) {
9489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentDeltaEntry = 0;
9589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentEntrySampleIndex = 0;
9689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
9789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
9889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    while (mCurrentDeltaEntry < mNumDeltaEntries) {
9989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry];
10089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) {
10189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            return mDeltaEntries[2 * mCurrentDeltaEntry + 1];
10289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        }
10389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentEntrySampleIndex += sampleCount;
10589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        ++mCurrentDeltaEntry;
10689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
10789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return 0;
10989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
11089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
11189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber////////////////////////////////////////////////////////////////////////////////
11289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
113693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source)
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mDataSource(source),
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetOffset(-1),
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetType(0),
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumChunkOffsets(0),
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleToChunkOffset(-1),
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleToChunkOffsets(0),
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeOffset(-1),
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeFieldSize(0),
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDefaultSampleSize(0),
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleSizes(0),
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSampleCount(0),
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSample(NULL),
1264678a6dc5f09008481524949a9667af5a6190374Andreas Huber      mSampleTimeEntries(NULL),
1274931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mCompositionTimeDeltaEntries(NULL),
1284931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mNumCompositionTimeDeltaEntries(0),
12989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCompositionDeltaLookup(new CompositionDeltaLookup),
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSyncSampleOffset(-1),
131c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mNumSyncSamples(0),
1328bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mSyncSamples(NULL),
1338bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mLastSyncSampleIndex(0),
134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mSampleToChunkEntries(NULL) {
135c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = new SampleIterator(this);
13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() {
139c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete[] mSampleToChunkEntries;
140c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries = NULL;
141c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
1428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    delete[] mSyncSamples;
1438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    mSyncSamples = NULL;
1448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
14589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    delete mCompositionDeltaLookup;
14689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup = NULL;
14789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
1484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    delete[] mCompositionTimeDeltaEntries;
1494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mCompositionTimeDeltaEntries = NULL;
1504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
1514678a6dc5f09008481524949a9667af5a6190374Andreas Huber    delete[] mSampleTimeEntries;
1524678a6dc5f09008481524949a9667af5a6190374Andreas Huber    mSampleTimeEntries = NULL;
1534678a6dc5f09008481524949a9667af5a6190374Andreas Huber
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete[] mTimeToSample;
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = NULL;
156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete mSampleIterator;
158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = NULL;
15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
161169c286ed166499c5099d2b336967e0bf3d25551Andreas Huberbool SampleTable::isValid() const {
162169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber    return mChunkOffsetOffset >= 0
163169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mSampleToChunkOffset >= 0
164169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mSampleSizeOffset >= 0
165169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mTimeToSample != NULL;
166169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber}
167169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber
16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams(
169c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetOffset >= 0) {
17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1740c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64);
17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetOffset = data_offset;
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetType = type;
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
18434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumChunkOffsets = U32_AT(&header[4]);
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetType == kChunkOffsetType32) {
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 4) {
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 8) {
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams(
210c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleToChunkOffset >= 0) {
21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleToChunkOffset = data_offset;
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
22234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleToChunkOffsets = U32_AT(&header[4]);
23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8 + mNumSampleToChunkOffsets * 12) {
23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2385c4428f6391478ae983e1fcf7c42c832aa1a5e69Joshua J. Drake    if (SIZE_MAX / sizeof(SampleToChunkEntry) <= mNumSampleToChunkOffsets)
2395c4428f6391478ae983e1fcf7c42c832aa1a5e69Joshua J. Drake        return ERROR_OUT_OF_RANGE;
2405c4428f6391478ae983e1fcf7c42c832aa1a5e69Joshua J. Drake
241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries =
242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        new SampleToChunkEntry[mNumSampleToChunkOffsets];
243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint8_t buffer[12];
246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mDataSource->readAt(
247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer))
248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                != (ssize_t)sizeof(buffer)) {
249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
250c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK(U32_AT(buffer) >= 1);  // chunk index is 1 based in the spec.
253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
254c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        // We want the chunk index to be 0-based.
255c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1;
256c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]);
257c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]);
258c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
259c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams(
264c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleSizeOffset >= 0) {
26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2690c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact);
27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleSizeOffset = data_offset;
27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 12) {
27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[12];
27834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mDefaultSampleSize = U32_AT(&header[4]);
28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleSizes = U32_AT(&header[8]);
290108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia    if (mNumSampleSizes > (UINT32_MAX - 12) / 16) {
291c27cee30d9359fa83e33b4f87f88e6bb9ef66341Wei Jia        ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
292108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia        return ERROR_MALFORMED;
293108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia    }
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (type == kSampleSizeType32) {
29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = 32;
29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mDefaultSampleSize != 0) {
29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return OK;
30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + mNumSampleSizes * 4) {
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if ((mDefaultSampleSize & 0xffffff00) != 0) {
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            // The high 24 bits are reserved and must be 0.
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3119f753df58a70f20db220af31cb202bbd21b30f36Andreas Huber        mSampleSizeFieldSize = mDefaultSampleSize & 0xff;
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mDefaultSampleSize = 0;
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            && mSampleSizeFieldSize != 16) {
31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams(
328c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mTimeToSample != NULL || data_size < 8) {
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
33434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSampleCount = U32_AT(&header[4]);
345738a753a3ca7bf8f9f608ca941575626265294e4Wei Jia    uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
346f106b1993143df44282777253244ce67974c9d4aRobert Shih    if (allocSize > SIZE_MAX) {
347f106b1993143df44282777253244ce67974c9d4aRobert Shih        return ERROR_OUT_OF_RANGE;
348f106b1993143df44282777253244ce67974c9d4aRobert Shih    }
34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = new uint32_t[mTimeToSampleCount * 2];
35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
35234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) {
35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mTimeToSample[i] = ntohl(mTimeToSample[i]);
35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3644931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams(
3654931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        off64_t data_offset, size_t data_size) {
366df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("There are reordered frames present.");
3674931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
3694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3724931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    uint8_t header[8];
3734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
3744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset, header, sizeof(header))
3754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)sizeof(header)) {
3764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
3774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (U32_AT(header) != 0) {
3804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        // Expected version = 0, flags = 0.
3814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3834931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    size_t numEntries = U32_AT(&header[4]);
3854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (data_size != (numEntries + 1) * 8) {
3874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3904931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mNumCompositionTimeDeltaEntries = numEntries;
391738a753a3ca7bf8f9f608ca941575626265294e4Wei Jia    uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t);
392f106b1993143df44282777253244ce67974c9d4aRobert Shih    if (allocSize > SIZE_MAX) {
393f106b1993143df44282777253244ce67974c9d4aRobert Shih        return ERROR_OUT_OF_RANGE;
394f106b1993143df44282777253244ce67974c9d4aRobert Shih    }
395f106b1993143df44282777253244ce67974c9d4aRobert Shih
3964931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];
3974931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3984931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
3994931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
4004931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)numEntries * 8) {
4014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        delete[] mCompositionTimeDeltaEntries;
4024931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries = NULL;
4034931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4044931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
4054931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4064931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4074931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    for (size_t i = 0; i < 2 * numEntries; ++i) {
4084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
4094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
41189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup->setEntries(
41289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries);
41389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4144931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    return OK;
4154931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
4164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
417c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset >= 0 || data_size < 8) {
41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSyncSampleOffset = data_offset;
42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
42534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSyncSamples = U32_AT(&header[4]);
43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mNumSyncSamples < 2) {
4383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Table of sync samples is empty or has only a single entry!");
43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
4408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4413cc11bfc00cbb3ed87a4464777a75606b4973b51Joshua J. Drake    uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t);
442f106b1993143df44282777253244ce67974c9d4aRobert Shih    if (allocSize > SIZE_MAX) {
443f106b1993143df44282777253244ce67974c9d4aRobert Shih        return ERROR_OUT_OF_RANGE;
444f106b1993143df44282777253244ce67974c9d4aRobert Shih    }
445f106b1993143df44282777253244ce67974c9d4aRobert Shih
4468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    mSyncSamples = new uint32_t[mNumSyncSamples];
4478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    size_t size = mNumSyncSamples * sizeof(uint32_t);
4488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
4498bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            != (ssize_t)size) {
4508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        return ERROR_IO;
4518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
4528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    for (size_t i = 0; i < mNumSyncSamples; ++i) {
4548bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
4558bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
4568bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const {
46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumChunkOffsets;
46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const {
46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumSampleSizes;
46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) {
46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *max_size = 0;
47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t sample_size;
475c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(i, &sample_size);
476da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (sample_size > *max_size) {
48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *max_size = sample_size;
48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
48620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
48720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
489da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) {
490da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber    return time1 > time2 ? time1 - time2 : time2 - time1;
491da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber}
492da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
4934678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static
4944678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
4954678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
4964678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
4974931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4984678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (a->mCompositionTime < b->mCompositionTime) {
4994678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return -1;
5004678a6dc5f09008481524949a9667af5a6190374Andreas Huber    } else if (a->mCompositionTime > b->mCompositionTime) {
5014678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return 1;
5024678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
503abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
5044678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return 0;
5054678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
5064678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5074678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() {
50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
510108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia    if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) {
511cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia        if (mNumSampleSizes == 0) {
512cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia            ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
513cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia        }
5144678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return;
5154678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5164678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5174678a6dc5f09008481524949a9667af5a6190374Andreas Huber    mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes];
5184678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5194678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleIndex = 0;
5204678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleTime = 0;
5214678a6dc5f09008481524949a9667af5a6190374Andreas Huber
52220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
52320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t n = mTimeToSample[2 * i];
52420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t delta = mTimeToSample[2 * i + 1];
52520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5264678a6dc5f09008481524949a9667af5a6190374Andreas Huber        for (uint32_t j = 0; j < n; ++j) {
52765a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            if (sampleIndex < mNumSampleSizes) {
52865a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // Technically this should always be the case if the file
52965a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // is well-formed, but you know... there's (gasp) malformed
53065a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // content out there.
53120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
53265a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
533abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
53489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                uint32_t compTimeDelta =
53589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    mCompositionDeltaLookup->getCompositionTimeOffset(
53689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                            sampleIndex);
53789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
53865a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mCompositionTime =
53989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    sampleTime + compTimeDelta;
54065a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            }
5414678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5424678a6dc5f09008481524949a9667af5a6190374Andreas Huber            ++sampleIndex;
5434678a6dc5f09008481524949a9667af5a6190374Andreas Huber            sampleTime += delta;
5444678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
5454678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5464678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5474678a6dc5f09008481524949a9667af5a6190374Andreas Huber    qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
5484678a6dc5f09008481524949a9667af5a6190374Andreas Huber          CompareIncreasingTime);
5494678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
5504678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5514678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime(
5524678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
5534678a6dc5f09008481524949a9667af5a6190374Andreas Huber    buildSampleEntriesTable();
5544678a6dc5f09008481524949a9667af5a6190374Andreas Huber
555108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia    if (mSampleTimeEntries == NULL) {
556108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia        return ERROR_OUT_OF_RANGE;
557108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia    }
558108cd2dc8df55f3f2ecdfbb4bb0ae981a74b6860Wei Jia
5594678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t left = 0;
5604678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t right = mNumSampleSizes;
5614678a6dc5f09008481524949a9667af5a6190374Andreas Huber    while (left < right) {
5624678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t center = (left + right) / 2;
5634678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime;
5644678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5654678a6dc5f09008481524949a9667af5a6190374Andreas Huber        if (req_time < centerTime) {
5664678a6dc5f09008481524949a9667af5a6190374Andreas Huber            right = center;
5674678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else if (req_time > centerTime) {
5684678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center + 1;
5694678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else {
5704678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center;
5714678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
5724678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
5734678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5744678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5754678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (left == mNumSampleSizes) {
576a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        if (flags == kFlagAfter) {
577a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber            return ERROR_OUT_OF_RANGE;
578a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        }
579a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber
5804678a6dc5f09008481524949a9667af5a6190374Andreas Huber        --left;
5814678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5824678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5834678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t closestIndex = left;
584abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
5854678a6dc5f09008481524949a9667af5a6190374Andreas Huber    switch (flags) {
5864678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagBefore:
5874678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
5884678a6dc5f09008481524949a9667af5a6190374Andreas Huber            while (closestIndex > 0
5894678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    && mSampleTimeEntries[closestIndex].mCompositionTime
5904678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            > req_time) {
5914678a6dc5f09008481524949a9667af5a6190374Andreas Huber                --closestIndex;
59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
5934678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
5944678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5964678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagAfter:
5974678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
5984678a6dc5f09008481524949a9667af5a6190374Andreas Huber            while (closestIndex + 1 < mNumSampleSizes
5994678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    && mSampleTimeEntries[closestIndex].mCompositionTime
6004678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            < req_time) {
6014678a6dc5f09008481524949a9667af5a6190374Andreas Huber                ++closestIndex;
6024678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
6034678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
60420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
60520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6064678a6dc5f09008481524949a9667af5a6190374Andreas Huber        default:
6074678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
6084678a6dc5f09008481524949a9667af5a6190374Andreas Huber            CHECK(flags == kFlagClosest);
6094678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6104678a6dc5f09008481524949a9667af5a6190374Andreas Huber            if (closestIndex > 0) {
6114678a6dc5f09008481524949a9667af5a6190374Andreas Huber                // Check left neighbour and pick closest.
6124678a6dc5f09008481524949a9667af5a6190374Andreas Huber                uint32_t absdiff1 =
6134678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    abs_difference(
6144678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            mSampleTimeEntries[closestIndex].mCompositionTime,
6154678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            req_time);
6164678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6174678a6dc5f09008481524949a9667af5a6190374Andreas Huber                uint32_t absdiff2 =
6184678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    abs_difference(
6194678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            mSampleTimeEntries[closestIndex - 1].mCompositionTime,
6204678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            req_time);
6214678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6224678a6dc5f09008481524949a9667af5a6190374Andreas Huber                if (absdiff1 > absdiff2) {
6234678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    closestIndex = closestIndex - 1;
6244678a6dc5f09008481524949a9667af5a6190374Andreas Huber                }
6254678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
6264678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6274678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
6284678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6314678a6dc5f09008481524949a9667af5a6190374Andreas Huber    *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
6324678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6334678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return OK;
63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
63520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
636abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear(
637abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) {
638abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    Mutex::Autolock autoLock(mLock);
639abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *sample_index = 0;
64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset < 0) {
64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // All samples are sync-samples.
64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *sample_index = start_sample_index;
64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
648abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mNumSyncSamples == 0) {
649abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        *sample_index = 0;
650abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return OK;
651abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
652da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
653abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t left = 0;
6548f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    uint32_t right = mNumSyncSamples;
6558f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    while (left < right) {
6568f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        uint32_t center = left + (right - left) / 2;
6578f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        uint32_t x = mSyncSamples[center];
65820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6598f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        if (start_sample_index < x) {
6608f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            right = center;
6618f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else if (start_sample_index > x) {
6628f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            left = center + 1;
6638f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else {
6648f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            left = center;
66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
66620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
667f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong    }
6688d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    if (left == mNumSyncSamples) {
6698d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        if (flags == kFlagAfter) {
67029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("tried to find a sync frame after the last one: %d", left);
6718d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng            return ERROR_OUT_OF_RANGE;
6728d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        }
6738d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        left = left - 1;
6748d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    }
675abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
6768f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    // Now ssi[left] is the sync sample index just before (or at)
6778f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    // start_sample_index.
6788f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    // Also start_sample_index < ssi[left + 1], if left + 1 < mNumSyncSamples.
679abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
6808f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    uint32_t x = mSyncSamples[left];
681abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
682abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (left + 1 < mNumSyncSamples) {
6838bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t y = mSyncSamples[left + 1];
684abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
685abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        // our sample lies between sync samples x and y.
686abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
687abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        status_t err = mSampleIterator->seekTo(start_sample_index);
688abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
689abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
690abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
691abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
692abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t sample_time = mSampleIterator->getSampleTime();
693abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
694abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        err = mSampleIterator->seekTo(x);
695abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
696abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
697abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
698abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t x_time = mSampleIterator->getSampleTime();
699abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
700abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        err = mSampleIterator->seekTo(y);
701abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
702abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
703abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
704abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
705abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t y_time = mSampleIterator->getSampleTime();
706abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
707abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (abs_difference(x_time, sample_time)
708abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                > abs_difference(y_time, sample_time)) {
709abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // Pick the sync sample closest (timewise) to the start-sample.
710abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            x = y;
711abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            ++left;
712abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
713abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
714abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
715abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    switch (flags) {
716abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagBefore:
717abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
718abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (x > start_sample_index) {
719abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(left > 0);
720abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
7218f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                x = mSyncSamples[left - 1];
722abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
7238f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                if (x > start_sample_index) {
7248f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    // The table of sync sample indices was not sorted
7258f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    // properly.
7268f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    return ERROR_MALFORMED;
7278f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                }
728abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
729abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
730abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
731abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
732abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagAfter:
733abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
734abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (x < start_sample_index) {
735abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                if (left + 1 >= mNumSyncSamples) {
736abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    return ERROR_OUT_OF_RANGE;
737abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
738abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
7398bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                x = mSyncSamples[left + 1];
740abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
7418f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                if (x < start_sample_index) {
7428f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    // The table of sync sample indices was not sorted
7438f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    // properly.
7448f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    return ERROR_MALFORMED;
7458f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                }
746abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
747abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
748abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
749abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
750abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
751abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        default:
752abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
755abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    *sample_index = x;
75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
75820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
75920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
761c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
762c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (mSyncSampleOffset < 0) {
7647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // All samples are sync-samples.
7657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        *sample_index = 0;
7667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        return OK;
7677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    uint32_t bestSampleIndex = 0;
7707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t maxSampleSize = 0;
7717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    static const size_t kMaxNumSyncSamplesToScan = 20;
7737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // Consider the first kMaxNumSyncSamplesToScan sync samples and
7757e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // pick the one with the largest (compressed) size as the thumbnail.
7767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7777e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t numSamplesToScan = mNumSyncSamples;
7787e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (numSamplesToScan > kMaxNumSyncSamplesToScan) {
7797e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        numSamplesToScan = kMaxNumSyncSamplesToScan;
7807e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7817e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7827e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    for (size_t i = 0; i < numSamplesToScan; ++i) {
7838bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t x = mSyncSamples[i];
7847e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7857e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // Now x is a sample index.
7867e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t sampleSize;
787c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(x, &sampleSize);
7887e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (err != OK) {
7897e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            return err;
7907e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
7917e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7927e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (i == 0 || sampleSize > maxSampleSize) {
7937e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            bestSampleIndex = x;
7947e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            maxSampleSize = sampleSize;
7957e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
7967e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7977e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7987e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    *sample_index = bestSampleIndex;
7997e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8007e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    return OK;
8017e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber}
8027e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
803c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l(
804c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *sampleSize) {
805c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return mSampleIterator->getSampleSizeDirect(
806c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            sampleIndex, sampleSize);
807c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
808c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
809c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample(
810c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex,
811c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t *offset,
812c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        size_t *size,
8134678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t *compositionTime,
8148bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        bool *isSyncSample) {
815c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
816c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
817c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
818c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) {
819c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
820c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
821c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
822c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (offset) {
823c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = mSampleIterator->getSampleOffset();
824c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
825c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
826c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (size) {
827c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mSampleIterator->getSampleSize();
828c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
829c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
8304678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (compositionTime) {
8314678a6dc5f09008481524949a9667af5a6190374Andreas Huber        *compositionTime = mSampleIterator->getSampleTime();
832c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
833c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
8348bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (isSyncSample) {
8358bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        *isSyncSample = false;
8368bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (mSyncSampleOffset < 0) {
8378bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            // Every sample is a sync sample.
8388bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            *isSyncSample = true;
8398bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        } else {
8408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            size_t i = (mLastSyncSampleIndex < mNumSyncSamples)
8418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                    && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex)
8428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ? mLastSyncSampleIndex : 0;
8438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) {
8458bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ++i;
8468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
8478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) {
8498bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                *isSyncSample = true;
8508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
8518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mLastSyncSampleIndex = i;
8538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
8548bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
8558bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
856c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
857c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
858c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
85989aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
86089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
8614931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
8624931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
86320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
86420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
865