SampleTable.cpp revision ad435371a4b95e16ceb49ab28efc04da8b3680e1
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
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
4389aa8fe4cb00d2f24260005b008602232d678684Andreas Huberstruct SampleTable::CompositionDeltaLookup {
4489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    CompositionDeltaLookup();
4589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    void setEntries(
4789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            const uint32_t *deltaEntries, size_t numDeltaEntries);
4889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
5089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5189aa8fe4cb00d2f24260005b008602232d678684Andreas Huberprivate:
5289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex mLock;
5389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    const uint32_t *mDeltaEntries;
5589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mNumDeltaEntries;
5689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mCurrentDeltaEntry;
5889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mCurrentEntrySampleIndex;
5989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup);
6189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber};
6289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6389aa8fe4cb00d2f24260005b008602232d678684Andreas HuberSampleTable::CompositionDeltaLookup::CompositionDeltaLookup()
6489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    : mDeltaEntries(NULL),
6589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mNumDeltaEntries(0),
6689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCurrentDeltaEntry(0),
6789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCurrentEntrySampleIndex(0) {
6889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
6989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
7089aa8fe4cb00d2f24260005b008602232d678684Andreas Hubervoid SampleTable::CompositionDeltaLookup::setEntries(
7189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        const uint32_t *deltaEntries, size_t numDeltaEntries) {
7289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex::Autolock autolock(mLock);
7389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
7489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mDeltaEntries = deltaEntries;
7589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mNumDeltaEntries = numDeltaEntries;
7689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCurrentDeltaEntry = 0;
7789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCurrentEntrySampleIndex = 0;
7889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
7989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8089aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
8189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        uint32_t sampleIndex) {
8289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex::Autolock autolock(mLock);
8389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    if (mDeltaEntries == NULL) {
8589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        return 0;
8689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
8789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    if (sampleIndex < mCurrentEntrySampleIndex) {
8989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentDeltaEntry = 0;
9089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentEntrySampleIndex = 0;
9189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
9289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
9389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    while (mCurrentDeltaEntry < mNumDeltaEntries) {
9489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry];
9589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) {
9689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            return mDeltaEntries[2 * mCurrentDeltaEntry + 1];
9789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        }
9889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
9989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentEntrySampleIndex += sampleCount;
10089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        ++mCurrentDeltaEntry;
10189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
10289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return 0;
10489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
10589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber////////////////////////////////////////////////////////////////////////////////
10789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
108693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source)
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mDataSource(source),
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetOffset(-1),
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetType(0),
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumChunkOffsets(0),
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleToChunkOffset(-1),
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleToChunkOffsets(0),
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeOffset(-1),
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeFieldSize(0),
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDefaultSampleSize(0),
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleSizes(0),
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSampleCount(0),
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSample(NULL),
1214678a6dc5f09008481524949a9667af5a6190374Andreas Huber      mSampleTimeEntries(NULL),
1224931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mCompositionTimeDeltaEntries(NULL),
1234931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mNumCompositionTimeDeltaEntries(0),
12489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCompositionDeltaLookup(new CompositionDeltaLookup),
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSyncSampleOffset(-1),
126c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mNumSyncSamples(0),
1278bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mSyncSamples(NULL),
1288bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mLastSyncSampleIndex(0),
129c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mSampleToChunkEntries(NULL) {
130c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = new SampleIterator(this);
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() {
134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete[] mSampleToChunkEntries;
135c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries = NULL;
136c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
1378bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    delete[] mSyncSamples;
1388bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    mSyncSamples = NULL;
1398bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
14089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    delete mCompositionDeltaLookup;
14189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup = NULL;
14289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
1434931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    delete[] mCompositionTimeDeltaEntries;
1444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mCompositionTimeDeltaEntries = NULL;
1454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
1464678a6dc5f09008481524949a9667af5a6190374Andreas Huber    delete[] mSampleTimeEntries;
1474678a6dc5f09008481524949a9667af5a6190374Andreas Huber    mSampleTimeEntries = NULL;
1484678a6dc5f09008481524949a9667af5a6190374Andreas Huber
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete[] mTimeToSample;
15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = NULL;
151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete mSampleIterator;
153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = NULL;
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
156169c286ed166499c5099d2b336967e0bf3d25551Andreas Huberbool SampleTable::isValid() const {
157169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber    return mChunkOffsetOffset >= 0
158169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mSampleToChunkOffset >= 0
159169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mSampleSizeOffset >= 0
160169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mTimeToSample != NULL;
161169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber}
162169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber
16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams(
164c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetOffset >= 0) {
16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1690c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64);
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetOffset = data_offset;
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetType = type;
17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
17934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumChunkOffsets = U32_AT(&header[4]);
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetType == kChunkOffsetType32) {
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 4) {
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 8) {
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams(
205c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleToChunkOffset >= 0) {
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleToChunkOffset = data_offset;
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
21734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleToChunkOffsets = U32_AT(&header[4]);
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8 + mNumSampleToChunkOffsets * 12) {
23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
233c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries =
234ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets];
235ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mSampleToChunkEntries)
236ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return ERROR_OUT_OF_RANGE;
237c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
238c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
239c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint8_t buffer[12];
240c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mDataSource->readAt(
241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer))
242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                != (ssize_t)sizeof(buffer)) {
243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK(U32_AT(buffer) >= 1);  // chunk index is 1 based in the spec.
247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        // We want the chunk index to be 0-based.
249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1;
250c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]);
251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]);
252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
253c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams(
258c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleSizeOffset >= 0) {
26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2630c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact);
26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleSizeOffset = data_offset;
26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 12) {
26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[12];
27234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mDefaultSampleSize = U32_AT(&header[4]);
28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleSizes = U32_AT(&header[8]);
28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (type == kSampleSizeType32) {
28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = 32;
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mDefaultSampleSize != 0) {
28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return OK;
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + mNumSampleSizes * 4) {
29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if ((mDefaultSampleSize & 0xffffff00) != 0) {
29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            // The high 24 bits are reserved and must be 0.
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3019f753df58a70f20db220af31cb202bbd21b30f36Andreas Huber        mSampleSizeFieldSize = mDefaultSampleSize & 0xff;
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mDefaultSampleSize = 0;
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            && mSampleSizeFieldSize != 16) {
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams(
318c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mTimeToSample != NULL || data_size < 8) {
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
32434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSampleCount = U32_AT(&header[4]);
335e2e812e58e8d2716b00d7d82db99b08d3afb4b32Joshua J. Drake    uint64_t allocSize = mTimeToSampleCount * 2 * (uint64_t)sizeof(uint32_t);
336edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    if (allocSize > SIZE_MAX) {
337edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
338edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
339ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2];
340ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mTimeToSample)
341ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return ERROR_OUT_OF_RANGE;
34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
34434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) {
35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mTimeToSample[i] = ntohl(mTimeToSample[i]);
35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3564931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams(
3574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        off64_t data_offset, size_t data_size) {
358df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("There are reordered frames present.");
3594931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3604931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
3614931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3624931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3634931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3644931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    uint8_t header[8];
3654931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
3664931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset, header, sizeof(header))
3674931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)sizeof(header)) {
3684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
3694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (U32_AT(header) != 0) {
3724931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        // Expected version = 0, flags = 0.
3734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    size_t numEntries = U32_AT(&header[4]);
3774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (data_size != (numEntries + 1) * 8) {
3794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mNumCompositionTimeDeltaEntries = numEntries;
383e2e812e58e8d2716b00d7d82db99b08d3afb4b32Joshua J. Drake    uint64_t allocSize = numEntries * 2 * (uint64_t)sizeof(uint32_t);
384edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    if (allocSize > SIZE_MAX) {
385edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
386edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
387edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih
388ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries];
389ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mCompositionTimeDeltaEntries)
390ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return ERROR_OUT_OF_RANGE;
3914931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
3934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
3944931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)numEntries * 8) {
3954931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        delete[] mCompositionTimeDeltaEntries;
3964931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries = NULL;
3974931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3984931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
3994931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4004931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    for (size_t i = 0; i < 2 * numEntries; ++i) {
4024931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
4034931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4044931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
40589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup->setEntries(
40689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries);
40789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    return OK;
4094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
4104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
411c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
41220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset >= 0 || data_size < 8) {
41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSyncSampleOffset = data_offset;
41720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
41934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
42220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
42320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
42520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSyncSamples = U32_AT(&header[4]);
43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mNumSyncSamples < 2) {
4323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Table of sync samples is empty or has only a single entry!");
43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
4348bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
435e2e812e58e8d2716b00d7d82db99b08d3afb4b32Joshua J. Drake    uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t);
436edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    if (allocSize > SIZE_MAX) {
437edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
438edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
439edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih
440ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    mSyncSamples = new (std::nothrow) uint32_t[mNumSyncSamples];
441ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mSyncSamples)
442ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return ERROR_OUT_OF_RANGE;
443ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake
4448bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    size_t size = mNumSyncSamples * sizeof(uint32_t);
4458bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
4468bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            != (ssize_t)size) {
4478bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        return ERROR_IO;
4488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
4498bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    for (size_t i = 0; i < mNumSyncSamples; ++i) {
4518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
4528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
4538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const {
45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumChunkOffsets;
45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const {
46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumSampleSizes;
46320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
46420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) {
46620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
46720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *max_size = 0;
46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t sample_size;
472c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(i, &sample_size);
473da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (sample_size > *max_size) {
47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *max_size = sample_size;
48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
486da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) {
487da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber    return time1 > time2 ? time1 - time2 : time2 - time1;
488da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber}
489da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
4904678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static
4914678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
4924678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
4934678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
4944931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4954678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (a->mCompositionTime < b->mCompositionTime) {
4964678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return -1;
4974678a6dc5f09008481524949a9667af5a6190374Andreas Huber    } else if (a->mCompositionTime > b->mCompositionTime) {
4984678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return 1;
4994678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
500abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
5014678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return 0;
5024678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
5034678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5044678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() {
50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5074678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (mSampleTimeEntries != NULL) {
5084678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return;
5094678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5104678a6dc5f09008481524949a9667af5a6190374Andreas Huber
511ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes];
512ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mSampleTimeEntries)
513ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return;
5144678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5154678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleIndex = 0;
5164678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleTime = 0;
5174678a6dc5f09008481524949a9667af5a6190374Andreas Huber
51820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t n = mTimeToSample[2 * i];
52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t delta = mTimeToSample[2 * i + 1];
52120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5224678a6dc5f09008481524949a9667af5a6190374Andreas Huber        for (uint32_t j = 0; j < n; ++j) {
52365a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            if (sampleIndex < mNumSampleSizes) {
52465a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // Technically this should always be the case if the file
52565a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // is well-formed, but you know... there's (gasp) malformed
52665a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // content out there.
52720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
52865a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
529abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
53089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                uint32_t compTimeDelta =
53189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    mCompositionDeltaLookup->getCompositionTimeOffset(
53289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                            sampleIndex);
53389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
53465a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mCompositionTime =
53589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    sampleTime + compTimeDelta;
53665a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            }
5374678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5384678a6dc5f09008481524949a9667af5a6190374Andreas Huber            ++sampleIndex;
5394678a6dc5f09008481524949a9667af5a6190374Andreas Huber            sampleTime += delta;
5404678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
5414678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5424678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5434678a6dc5f09008481524949a9667af5a6190374Andreas Huber    qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
5444678a6dc5f09008481524949a9667af5a6190374Andreas Huber          CompareIncreasingTime);
5454678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
5464678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5474678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime(
548599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint64_t req_time, uint64_t scale_num, uint64_t scale_den,
549599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint32_t *sample_index, uint32_t flags) {
5504678a6dc5f09008481524949a9667af5a6190374Andreas Huber    buildSampleEntriesTable();
5514678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5524678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t left = 0;
553225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    uint32_t right_plus_one = mNumSampleSizes;
554225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    while (left < right_plus_one) {
555225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar        uint32_t center = left + (right_plus_one - left) / 2;
556599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint64_t centerTime =
557599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            getSampleTime(center, scale_num, scale_den);
5584678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5594678a6dc5f09008481524949a9667af5a6190374Andreas Huber        if (req_time < centerTime) {
560225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar            right_plus_one = center;
5614678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else if (req_time > centerTime) {
5624678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center + 1;
5634678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else {
564599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            *sample_index = mSampleTimeEntries[center].mSampleIndex;
565599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            return OK;
5664678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
5674678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5684678a6dc5f09008481524949a9667af5a6190374Andreas Huber
569599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    uint32_t closestIndex = left;
570599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
571599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    if (closestIndex == mNumSampleSizes) {
572a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        if (flags == kFlagAfter) {
573a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber            return ERROR_OUT_OF_RANGE;
574a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        }
575599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagBefore;
576599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    } else if (closestIndex == 0) {
577599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        if (flags == kFlagBefore) {
578599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // normally we should return out of range, but that is
579599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // treated as end-of-stream.  instead return first sample
580599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            //
581599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // return ERROR_OUT_OF_RANGE;
582599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        }
583599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagAfter;
5844678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5854678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5864678a6dc5f09008481524949a9667af5a6190374Andreas Huber    switch (flags) {
5874678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagBefore:
5884678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
589599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            --closestIndex;
5904678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
5914678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5934678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagAfter:
5944678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
595599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // nothing to do
5964678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
59820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5994678a6dc5f09008481524949a9667af5a6190374Andreas Huber        default:
6004678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
6014678a6dc5f09008481524949a9667af5a6190374Andreas Huber            CHECK(flags == kFlagClosest);
602599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // pick closest based on timestamp. use abs_difference for safety
603599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (abs_difference(
604599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                    getSampleTime(closestIndex, scale_num, scale_den), req_time) >
605599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                abs_difference(
606599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                    req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) {
607599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                --closestIndex;
6084678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
6094678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
6104678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6134678a6dc5f09008481524949a9667af5a6190374Andreas Huber    *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
6144678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return OK;
61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
617abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear(
618abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) {
619abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    Mutex::Autolock autoLock(mLock);
620abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
62120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *sample_index = 0;
62220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
62320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset < 0) {
62420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // All samples are sync-samples.
62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *sample_index = start_sample_index;
62620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
62720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
62820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
629abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mNumSyncSamples == 0) {
630abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        *sample_index = 0;
631abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return OK;
632abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
633da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
634abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t left = 0;
635225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    uint32_t right_plus_one = mNumSyncSamples;
636225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    while (left < right_plus_one) {
637225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar        uint32_t center = left + (right_plus_one - left) / 2;
6388f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        uint32_t x = mSyncSamples[center];
63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6408f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        if (start_sample_index < x) {
641225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar            right_plus_one = center;
6428f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else if (start_sample_index > x) {
6438f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            left = center + 1;
6448f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else {
645599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            *sample_index = x;
646599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            return OK;
64720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
648f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong    }
649599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
6508d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    if (left == mNumSyncSamples) {
6518d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        if (flags == kFlagAfter) {
65229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("tried to find a sync frame after the last one: %d", left);
6538d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng            return ERROR_OUT_OF_RANGE;
6548d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        }
655599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagBefore;
6568d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    }
657599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    else if (left == 0) {
658599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        if (flags == kFlagBefore) {
659599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            ALOGE("tried to find a sync frame before the first one: %d", left);
660abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
661599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // normally we should return out of range, but that is
662599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // treated as end-of-stream.  instead seek to first sync
663599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            //
664599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // return ERROR_OUT_OF_RANGE;
665abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
666599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagAfter;
667abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
668abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
669599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    // Now ssi[left - 1] <(=) start_sample_index <= ssi[left]
670abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    switch (flags) {
671abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagBefore:
672abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
673599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            --left;
674abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
675abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
676abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagAfter:
677abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
678599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // nothing to do
679abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
680abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
681abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        default:
682599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        {
683599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // this route is not used, but implement it nonetheless
684599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            CHECK(flags == kFlagClosest);
685599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
686599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            status_t err = mSampleIterator->seekTo(start_sample_index);
687599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
688599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
689599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
690599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t sample_time = mSampleIterator->getSampleTime();
691599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
692599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            err = mSampleIterator->seekTo(mSyncSamples[left]);
693599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
694599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
695599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
696599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t upper_time = mSampleIterator->getSampleTime();
697599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
698599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            err = mSampleIterator->seekTo(mSyncSamples[left - 1]);
699599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
700599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
701599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
702599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t lower_time = mSampleIterator->getSampleTime();
703599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
704599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // use abs_difference for safety
705599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (abs_difference(upper_time, sample_time) >
706599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                abs_difference(sample_time, lower_time)) {
707599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                --left;
708599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
709abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
710599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        }
71120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
71220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
713599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    *sample_index = mSyncSamples[left];
71420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
71520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
71620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
718c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
719c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (mSyncSampleOffset < 0) {
7217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // All samples are sync-samples.
7227e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        *sample_index = 0;
7237e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        return OK;
7247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    uint32_t bestSampleIndex = 0;
7277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t maxSampleSize = 0;
7287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    static const size_t kMaxNumSyncSamplesToScan = 20;
7307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // Consider the first kMaxNumSyncSamplesToScan sync samples and
7327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // pick the one with the largest (compressed) size as the thumbnail.
7337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t numSamplesToScan = mNumSyncSamples;
7357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (numSamplesToScan > kMaxNumSyncSamplesToScan) {
7367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        numSamplesToScan = kMaxNumSyncSamplesToScan;
7377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    for (size_t i = 0; i < numSamplesToScan; ++i) {
7408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t x = mSyncSamples[i];
7417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // Now x is a sample index.
7437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t sampleSize;
744c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(x, &sampleSize);
7457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (err != OK) {
7467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            return err;
7477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
7487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (i == 0 || sampleSize > maxSampleSize) {
7507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            bestSampleIndex = x;
7517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            maxSampleSize = sampleSize;
7527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
7537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    *sample_index = bestSampleIndex;
7567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    return OK;
7587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber}
7597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
760c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l(
761c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *sampleSize) {
762c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return mSampleIterator->getSampleSizeDirect(
763c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            sampleIndex, sampleSize);
764c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
765c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
766c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample(
767c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex,
768c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t *offset,
769c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        size_t *size,
7704678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t *compositionTime,
771170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        bool *isSyncSample,
772170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        uint32_t *sampleDuration) {
773c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
774c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
775c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
776c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) {
777c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
778c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
779c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
780c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (offset) {
781c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = mSampleIterator->getSampleOffset();
782c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
783c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
784c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (size) {
785c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mSampleIterator->getSampleSize();
786c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
787c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7884678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (compositionTime) {
7894678a6dc5f09008481524949a9667af5a6190374Andreas Huber        *compositionTime = mSampleIterator->getSampleTime();
790c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
791c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7928bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (isSyncSample) {
7938bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        *isSyncSample = false;
7948bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (mSyncSampleOffset < 0) {
7958bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            // Every sample is a sync sample.
7968bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            *isSyncSample = true;
7978bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        } else {
7988bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            size_t i = (mLastSyncSampleIndex < mNumSyncSamples)
7998bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                    && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex)
8008bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ? mLastSyncSampleIndex : 0;
8018bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8028bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) {
8038bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ++i;
8048bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
8058bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8068bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) {
8078bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                *isSyncSample = true;
8088bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
8098bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8108bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mLastSyncSampleIndex = i;
8118bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
8128bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
8138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
814170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    if (sampleDuration) {
815170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        *sampleDuration = mSampleIterator->getSampleDuration();
816170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    }
817170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih
818c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
819c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
820c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
82189aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
82289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
8234931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
8244931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
82520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
82620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
827