SampleTable.cpp revision dafa42d49dd70d745697662750bb6040429ee76c
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
303564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia/* TODO: remove after being merged into other branches */
313564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#ifndef UINT32_MAX
323564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#define UINT32_MAX       (4294967295U)
333564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia#endif
343564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei 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
238ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    if (SIZE_MAX / sizeof(SampleToChunkEntry) <= (size_t)mNumSampleToChunkOffsets)
239c24607c29c96f939aed9e33bfa702b1dd79da4b7Joshua J. Drake        return ERROR_OUT_OF_RANGE;
240c24607c29c96f939aed9e33bfa702b1dd79da4b7Joshua J. Drake
241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries =
242ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets];
243ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mSampleToChunkEntries)
244ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return ERROR_OUT_OF_RANGE;
245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint8_t buffer[12];
248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mDataSource->readAt(
249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer))
250c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                != (ssize_t)sizeof(buffer)) {
251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
252c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
253dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen        // chunk index is 1 based in the spec.
254dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen        if (U32_AT(buffer) < 1) {
255dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen            ALOGE("b/23534160");
256dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen            return ERROR_OUT_OF_RANGE;
257dafa42d49dd70d745697662750bb6040429ee76cMarco Nelissen        }
258c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
259c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        // We want the chunk index to be 0-based.
260c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1;
261c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]);
262c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]);
263c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
264c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams(
269c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleSizeOffset >= 0) {
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2740c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact);
27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleSizeOffset = data_offset;
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 12) {
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[12];
28334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mDefaultSampleSize = U32_AT(&header[4]);
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleSizes = U32_AT(&header[8]);
2953564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia    if (mNumSampleSizes > (UINT32_MAX - 12) / 16) {
2963564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia        return ERROR_MALFORMED;
2973564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia    }
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (type == kSampleSizeType32) {
30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = 32;
30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mDefaultSampleSize != 0) {
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return OK;
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + mNumSampleSizes * 4) {
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if ((mDefaultSampleSize & 0xffffff00) != 0) {
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            // The high 24 bits are reserved and must be 0.
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3159f753df58a70f20db220af31cb202bbd21b30f36Andreas Huber        mSampleSizeFieldSize = mDefaultSampleSize & 0xff;
31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mDefaultSampleSize = 0;
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            && mSampleSizeFieldSize != 16) {
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams(
332c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mTimeToSample != NULL || data_size < 8) {
33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
33834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSampleCount = U32_AT(&header[4]);
349a105482ae577852ffd08ce88ae5d1ba81db875acWei Jia    uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
3502c5fb0c7249ba7e5d79236c61a1c94a489041e65Wei Jia    if (allocSize > UINT32_MAX) {
351edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
352edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
353ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2];
354ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mTimeToSample)
355ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return ERROR_OUT_OF_RANGE;
35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
35834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) {
36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mTimeToSample[i] = ntohl(mTimeToSample[i]);
36520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams(
3714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        off64_t data_offset, size_t data_size) {
372df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("There are reordered frames present.");
3734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
3754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    uint8_t header[8];
3794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
3804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset, header, sizeof(header))
3814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)sizeof(header)) {
3824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
3834931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (U32_AT(header) != 0) {
3864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        // Expected version = 0, flags = 0.
3874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3904931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    size_t numEntries = U32_AT(&header[4]);
3914931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (data_size != (numEntries + 1) * 8) {
3934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3944931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3954931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3964931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mNumCompositionTimeDeltaEntries = numEntries;
397a105482ae577852ffd08ce88ae5d1ba81db875acWei Jia    uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t);
3982c5fb0c7249ba7e5d79236c61a1c94a489041e65Wei Jia    if (allocSize > UINT32_MAX) {
399edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
400edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
401edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih
402ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries];
403ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mCompositionTimeDeltaEntries)
404ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return ERROR_OUT_OF_RANGE;
4054931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4064931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
4074931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
4084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)numEntries * 8) {
4094931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        delete[] mCompositionTimeDeltaEntries;
4104931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries = NULL;
4114931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4124931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
4134931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4144931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4154931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    for (size_t i = 0; i < 2 * numEntries; ++i) {
4164931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
4174931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4184931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
41989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup->setEntries(
42089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries);
42189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4224931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    return OK;
4234931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
4244931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
425c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
42620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset >= 0 || data_size < 8) {
42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSyncSampleOffset = data_offset;
43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
43334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSyncSamples = U32_AT(&header[4]);
44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mNumSyncSamples < 2) {
4463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Table of sync samples is empty or has only a single entry!");
44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
4488bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
449e2e812e58e8d2716b00d7d82db99b08d3afb4b32Joshua J. Drake    uint64_t allocSize = mNumSyncSamples * (uint64_t)sizeof(uint32_t);
450edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    if (allocSize > SIZE_MAX) {
451edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
452edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
453edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih
454ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    mSyncSamples = new (std::nothrow) uint32_t[mNumSyncSamples];
455ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mSyncSamples)
456ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return ERROR_OUT_OF_RANGE;
457ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake
4588bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    size_t size = mNumSyncSamples * sizeof(uint32_t);
4598bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
4608bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            != (ssize_t)size) {
4618bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        return ERROR_IO;
4628bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
4638bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4648bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    for (size_t i = 0; i < mNumSyncSamples; ++i) {
4658bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
4668bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
4678bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
46820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
46920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
47020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const {
47220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumChunkOffsets;
47320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
47420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const {
47620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumSampleSizes;
47720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
47820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
47920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) {
48020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
48120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *max_size = 0;
48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
48420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
48520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t sample_size;
486c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(i, &sample_size);
487da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
48820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
48920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
49020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
49120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
49220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (sample_size > *max_size) {
49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *max_size = sample_size;
49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
49720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
49820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
49920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
500da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) {
501da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber    return time1 > time2 ? time1 - time2 : time2 - time1;
502da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber}
503da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
5044678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static
5054678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
5064678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
5074678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
5084931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
5094678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (a->mCompositionTime < b->mCompositionTime) {
5104678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return -1;
5114678a6dc5f09008481524949a9667af5a6190374Andreas Huber    } else if (a->mCompositionTime > b->mCompositionTime) {
5124678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return 1;
5134678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
514abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
5154678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return 0;
5164678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
5174678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5184678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() {
51920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5213564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia    if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) {
5224678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return;
5234678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5244678a6dc5f09008481524949a9667af5a6190374Andreas Huber
525ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes];
526ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake    if (!mSampleTimeEntries)
527ad435371a4b95e16ceb49ab28efc04da8b3680e1Joshua J. Drake        return;
5284678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5294678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleIndex = 0;
5304678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleTime = 0;
5314678a6dc5f09008481524949a9667af5a6190374Andreas Huber
53220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
53320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t n = mTimeToSample[2 * i];
53420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t delta = mTimeToSample[2 * i + 1];
53520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5364678a6dc5f09008481524949a9667af5a6190374Andreas Huber        for (uint32_t j = 0; j < n; ++j) {
53765a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            if (sampleIndex < mNumSampleSizes) {
53865a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // Technically this should always be the case if the file
53965a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // is well-formed, but you know... there's (gasp) malformed
54065a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // content out there.
54120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
54265a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
543abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
54489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                uint32_t compTimeDelta =
54589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    mCompositionDeltaLookup->getCompositionTimeOffset(
54689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                            sampleIndex);
54789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
54865a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mCompositionTime =
54989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    sampleTime + compTimeDelta;
55065a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            }
5514678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5524678a6dc5f09008481524949a9667af5a6190374Andreas Huber            ++sampleIndex;
5534678a6dc5f09008481524949a9667af5a6190374Andreas Huber            sampleTime += delta;
5544678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
5554678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5564678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5574678a6dc5f09008481524949a9667af5a6190374Andreas Huber    qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
5584678a6dc5f09008481524949a9667af5a6190374Andreas Huber          CompareIncreasingTime);
5594678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
5604678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5614678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime(
562599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint64_t req_time, uint64_t scale_num, uint64_t scale_den,
563599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint32_t *sample_index, uint32_t flags) {
5644678a6dc5f09008481524949a9667af5a6190374Andreas Huber    buildSampleEntriesTable();
5654678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5663564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia    if (mSampleTimeEntries == NULL) {
5673564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia        return ERROR_OUT_OF_RANGE;
5683564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia    }
5693564c4562f46bede6ef1ea716c4fd4f77e470ae8Wei Jia
5704678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t left = 0;
571225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    uint32_t right_plus_one = mNumSampleSizes;
572225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    while (left < right_plus_one) {
573225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar        uint32_t center = left + (right_plus_one - left) / 2;
574599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint64_t centerTime =
575599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            getSampleTime(center, scale_num, scale_den);
5764678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5774678a6dc5f09008481524949a9667af5a6190374Andreas Huber        if (req_time < centerTime) {
578225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar            right_plus_one = center;
5794678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else if (req_time > centerTime) {
5804678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center + 1;
5814678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else {
582599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            *sample_index = mSampleTimeEntries[center].mSampleIndex;
583599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            return OK;
5844678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
5854678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5864678a6dc5f09008481524949a9667af5a6190374Andreas Huber
587599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    uint32_t closestIndex = left;
588599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
589599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    if (closestIndex == mNumSampleSizes) {
590a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        if (flags == kFlagAfter) {
591a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber            return ERROR_OUT_OF_RANGE;
592a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        }
593599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagBefore;
594599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    } else if (closestIndex == 0) {
595599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        if (flags == kFlagBefore) {
596599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // normally we should return out of range, but that is
597599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // treated as end-of-stream.  instead return first sample
598599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            //
599599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // return ERROR_OUT_OF_RANGE;
600599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        }
601599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagAfter;
6024678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
6034678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6044678a6dc5f09008481524949a9667af5a6190374Andreas Huber    switch (flags) {
6054678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagBefore:
6064678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
607599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            --closestIndex;
6084678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
6094678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6114678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagAfter:
6124678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
613599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // nothing to do
6144678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
61520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
61620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6174678a6dc5f09008481524949a9667af5a6190374Andreas Huber        default:
6184678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
6194678a6dc5f09008481524949a9667af5a6190374Andreas Huber            CHECK(flags == kFlagClosest);
620599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // pick closest based on timestamp. use abs_difference for safety
621599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (abs_difference(
622599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                    getSampleTime(closestIndex, scale_num, scale_den), req_time) >
623599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                abs_difference(
624599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                    req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) {
625599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                --closestIndex;
6264678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
6274678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
6284678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
62920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
63020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6314678a6dc5f09008481524949a9667af5a6190374Andreas Huber    *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
6324678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return OK;
63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
63420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
635abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear(
636abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) {
637abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    Mutex::Autolock autoLock(mLock);
638abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
63920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *sample_index = 0;
64020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
64120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset < 0) {
64220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // All samples are sync-samples.
64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *sample_index = start_sample_index;
64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
647abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mNumSyncSamples == 0) {
648abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        *sample_index = 0;
649abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return OK;
650abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
651da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
652abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t left = 0;
653225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    uint32_t right_plus_one = mNumSyncSamples;
654225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    while (left < right_plus_one) {
655225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar        uint32_t center = left + (right_plus_one - left) / 2;
6568f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        uint32_t x = mSyncSamples[center];
65720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6588f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        if (start_sample_index < x) {
659225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar            right_plus_one = center;
6608f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else if (start_sample_index > x) {
6618f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            left = center + 1;
6628f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else {
663599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            *sample_index = x;
664599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            return OK;
66520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
666f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong    }
667599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
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        }
673599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagBefore;
6748d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    }
675599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    else if (left == 0) {
676599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        if (flags == kFlagBefore) {
677599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            ALOGE("tried to find a sync frame before the first one: %d", left);
678abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
679599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // normally we should return out of range, but that is
680599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // treated as end-of-stream.  instead seek to first sync
681599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            //
682599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // return ERROR_OUT_OF_RANGE;
683abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
684599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagAfter;
685abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
686abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
687599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    // Now ssi[left - 1] <(=) start_sample_index <= ssi[left]
688abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    switch (flags) {
689abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagBefore:
690abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
691599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            --left;
692abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
693abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
694abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagAfter:
695abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
696599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // nothing to do
697abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
698abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
699abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        default:
700599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        {
701599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // this route is not used, but implement it nonetheless
702599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            CHECK(flags == kFlagClosest);
703599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
704599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            status_t err = mSampleIterator->seekTo(start_sample_index);
705599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
706599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
707599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
708599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t sample_time = mSampleIterator->getSampleTime();
709599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
710599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            err = mSampleIterator->seekTo(mSyncSamples[left]);
711599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
712599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
713599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
714599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t upper_time = mSampleIterator->getSampleTime();
715599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
716599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            err = mSampleIterator->seekTo(mSyncSamples[left - 1]);
717599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
718599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
719599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
720599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t lower_time = mSampleIterator->getSampleTime();
721599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
722599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // use abs_difference for safety
723599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (abs_difference(upper_time, sample_time) >
724599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                abs_difference(sample_time, lower_time)) {
725599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                --left;
726599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
727abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
728599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        }
72920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
73020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
731599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    *sample_index = mSyncSamples[left];
73220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
73320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
73420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
736c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
737c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (mSyncSampleOffset < 0) {
7397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // All samples are sync-samples.
7407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        *sample_index = 0;
7417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        return OK;
7427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    uint32_t bestSampleIndex = 0;
7457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t maxSampleSize = 0;
7467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    static const size_t kMaxNumSyncSamplesToScan = 20;
7487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // Consider the first kMaxNumSyncSamplesToScan sync samples and
7507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // pick the one with the largest (compressed) size as the thumbnail.
7517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t numSamplesToScan = mNumSyncSamples;
7537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (numSamplesToScan > kMaxNumSyncSamplesToScan) {
7547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        numSamplesToScan = kMaxNumSyncSamplesToScan;
7557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    for (size_t i = 0; i < numSamplesToScan; ++i) {
7588bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t x = mSyncSamples[i];
7597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // Now x is a sample index.
7617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t sampleSize;
762c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(x, &sampleSize);
7637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (err != OK) {
7647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            return err;
7657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
7667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (i == 0 || sampleSize > maxSampleSize) {
7687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            bestSampleIndex = x;
7697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            maxSampleSize = sampleSize;
7707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
7717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7737e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    *sample_index = bestSampleIndex;
7747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7757e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    return OK;
7767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber}
7777e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
778c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l(
779c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *sampleSize) {
780c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return mSampleIterator->getSampleSizeDirect(
781c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            sampleIndex, sampleSize);
782c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
783c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
784c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample(
785c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex,
786c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t *offset,
787c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        size_t *size,
7884678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t *compositionTime,
789170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        bool *isSyncSample,
790170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        uint32_t *sampleDuration) {
791c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
792c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
793c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
794c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) {
795c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
796c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
797c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
798c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (offset) {
799c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = mSampleIterator->getSampleOffset();
800c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
801c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
802c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (size) {
803c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mSampleIterator->getSampleSize();
804c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
805c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
8064678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (compositionTime) {
8074678a6dc5f09008481524949a9667af5a6190374Andreas Huber        *compositionTime = mSampleIterator->getSampleTime();
808c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
809c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
8108bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (isSyncSample) {
8118bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        *isSyncSample = false;
8128bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (mSyncSampleOffset < 0) {
8138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            // Every sample is a sync sample.
8148bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            *isSyncSample = true;
8158bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        } else {
8168bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            size_t i = (mLastSyncSampleIndex < mNumSyncSamples)
8178bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                    && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex)
8188bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ? mLastSyncSampleIndex : 0;
8198bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8208bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) {
8218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ++i;
8228bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
8238bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8248bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) {
8258bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                *isSyncSample = true;
8268bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
8278bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8288bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mLastSyncSampleIndex = i;
8298bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
8308bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
8318bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
832170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    if (sampleDuration) {
833170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        *sampleDuration = mSampleIterator->getSampleDuration();
834170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    }
835170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih
836c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
837c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
838c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
83989aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
84089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
8414931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
8424931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
84320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
84420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
845