SampleTable.cpp revision abd1f4f870925d6776dbe4b930b759a1ab6595ca
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "SampleTable"
18c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//#define LOG_NDEBUG 0
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h"
22c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include "include/SampleIterator.h"
2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h>
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h>
270c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
33c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o');
34c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
35c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4');
36c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z');
38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2');
40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber////////////////////////////////////////////////////////////////////////////////
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source)
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mDataSource(source),
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetOffset(-1),
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetType(0),
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumChunkOffsets(0),
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleToChunkOffset(-1),
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleToChunkOffsets(0),
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeOffset(-1),
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeFieldSize(0),
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDefaultSampleSize(0),
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleSizes(0),
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSampleCount(0),
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSample(NULL),
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSyncSampleOffset(-1),
57c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mNumSyncSamples(0),
58c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mSampleToChunkEntries(NULL) {
59c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = new SampleIterator(this);
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() {
63c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete[] mSampleToChunkEntries;
64c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries = NULL;
65c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete[] mTimeToSample;
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = NULL;
68c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
69c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete mSampleIterator;
70c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = NULL;
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams(
74549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber        uint32_t type, off_t data_offset, size_t data_size) {
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetOffset >= 0) {
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
790c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64);
8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetOffset = data_offset;
8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetType = type;
8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
8934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumChunkOffsets = U32_AT(&header[4]);
10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetType == kChunkOffsetType32) {
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 4) {
10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 8) {
10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams(
115549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber        off_t data_offset, size_t data_size) {
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleToChunkOffset >= 0) {
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleToChunkOffset = data_offset;
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
12734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleToChunkOffsets = U32_AT(&header[4]);
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8 + mNumSampleToChunkOffsets * 12) {
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
143c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries =
144c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        new SampleToChunkEntry[mNumSampleToChunkOffsets];
145c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
146c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
147c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint8_t buffer[12];
148c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mDataSource->readAt(
149c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer))
150c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                != (ssize_t)sizeof(buffer)) {
151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
154c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK(U32_AT(buffer) >= 1);  // chunk index is 1 based in the spec.
155c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        // We want the chunk index to be 0-based.
157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1;
158c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]);
159c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]);
160c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
161c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams(
166549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber        uint32_t type, off_t data_offset, size_t data_size) {
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleSizeOffset >= 0) {
16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1710c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact);
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleSizeOffset = data_offset;
17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 12) {
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[12];
18034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mDefaultSampleSize = U32_AT(&header[4]);
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleSizes = U32_AT(&header[8]);
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (type == kSampleSizeType32) {
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = 32;
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mDefaultSampleSize != 0) {
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return OK;
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + mNumSampleSizes * 4) {
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if ((mDefaultSampleSize & 0xffffff00) != 0) {
20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            // The high 24 bits are reserved and must be 0.
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = mDefaultSampleSize & 0xf;
21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mDefaultSampleSize = 0;
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            && mSampleSizeFieldSize != 16) {
21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams(
226549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huber        off_t data_offset, size_t data_size) {
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mTimeToSample != NULL || data_size < 8) {
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
23234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
23320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
23820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
23920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
24020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
24120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
24220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSampleCount = U32_AT(&header[4]);
24320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = new uint32_t[mTimeToSampleCount * 2];
24420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
24520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
24634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
24720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
24820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
24920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
25020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) {
25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mTimeToSample[i] = ntohl(mTimeToSample[i]);
25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
25620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
258549aa3741725ea2fd75c5fb717ff5a9316a5a55dAndreas Huberstatus_t SampleTable::setSyncSampleParams(off_t data_offset, size_t data_size) {
25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset >= 0 || data_size < 8) {
26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
26120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSyncSampleOffset = data_offset;
26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
26634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSyncSamples = U32_AT(&header[4]);
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mNumSyncSamples < 2) {
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        LOGW("Table of sync samples is empty or has only a single entry!");
28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const {
28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumChunkOffsets;
28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const {
28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumSampleSizes;
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) {
29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *max_size = 0;
29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t sample_size;
299c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(i, &sample_size);
300da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (sample_size > *max_size) {
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *max_size = sample_size;
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
313da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) {
314da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber    return time1 > time2 ? time1 - time2 : time2 - time1;
315da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber}
316da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
317abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSampleAtTime(
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
319abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    *sample_index = 0;
320abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t cur_sample = 0;
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint32_t time = 0;
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t n = mTimeToSample[2 * i];
32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t delta = mTimeToSample[2 * i + 1];
32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (req_time < time + n * delta) {
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            int j = (req_time - time) / delta;
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
332da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber            uint32_t time1 = time + j * delta;
333da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber            uint32_t time2 = time1 + delta;
334da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
335abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            uint32_t sampleTime;
336da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber            if (i+1 == mTimeToSampleCount
337da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber                    || (abs_difference(req_time, time1)
338da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber                        < abs_difference(req_time, time2))) {
339da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber                *sample_index = cur_sample + j;
340abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                sampleTime = time1;
341da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber            } else {
342da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber                *sample_index = cur_sample + j + 1;
343abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                sampleTime = time2;
344da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber            }
34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
346abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            switch (flags) {
347abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                case kFlagBefore:
348abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                {
349abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    if (sampleTime > req_time && *sample_index > 0) {
350abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                        --*sample_index;
351abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    }
352abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    break;
353abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
354abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
355abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                case kFlagAfter:
356abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                {
357abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    if (sampleTime < req_time
358abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                            && *sample_index + 1 < mNumSampleSizes) {
359abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                        ++*sample_index;
360abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    }
361abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    break;
362abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
363abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
364abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                default:
365abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    break;
36620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return OK;
36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
37120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        time += delta * n;
37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        cur_sample += n;
37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return ERROR_OUT_OF_RANGE;
37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
378abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear(
379abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) {
380abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    Mutex::Autolock autoLock(mLock);
381abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
38220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *sample_index = 0;
38320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset < 0) {
38520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // All samples are sync-samples.
38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *sample_index = start_sample_index;
38720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
38820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
38920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
390abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mNumSyncSamples == 0) {
391abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        *sample_index = 0;
392abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return OK;
393abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
394da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
395abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t left = 0;
396abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    while (left < mNumSyncSamples) {
397abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t x;
39834769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber        if (mDataSource->readAt(
399abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) {
40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_IO;
40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        x = ntohl(x);
404abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        --x;
40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
406abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (x >= start_sample_index) {
40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
409abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
410abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        ++left;
411abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
412abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
413abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    --left;
414abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t x;
415abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mDataSource->readAt(
416abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                mSyncSampleOffset + 8 + left * 4, &x, 4) != 4) {
417abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return ERROR_IO;
418abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
419abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
420abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    x = ntohl(x);
421abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    --x;
422abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
423abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (left + 1 < mNumSyncSamples) {
424abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t y;
425abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (mDataSource->readAt(
426abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    mSyncSampleOffset + 8 + (left + 1) * 4, &y, 4) != 4) {
427abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return ERROR_IO;
428abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
429abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
430abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        y = ntohl(y);
431abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        --y;
432abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
433abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        // our sample lies between sync samples x and y.
434abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
435abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        status_t err = mSampleIterator->seekTo(start_sample_index);
436abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
437abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
438abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
439abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
440abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t sample_time = mSampleIterator->getSampleTime();
441abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
442abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        err = mSampleIterator->seekTo(x);
443abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
444abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
445abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
446abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t x_time = mSampleIterator->getSampleTime();
447abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
448abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        err = mSampleIterator->seekTo(y);
449abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
450abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
451abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
452abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
453abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t y_time = mSampleIterator->getSampleTime();
454abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
455abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (abs_difference(x_time, sample_time)
456abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                > abs_difference(y_time, sample_time)) {
457abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // Pick the sync sample closest (timewise) to the start-sample.
458abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            x = y;
459abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            ++left;
460abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
461abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
462abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
463abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    switch (flags) {
464abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagBefore:
465abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
466abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (x > start_sample_index) {
467abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(left > 0);
468abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
469abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                if (mDataSource->readAt(
470abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                            mSyncSampleOffset + 8 + (left - 1) * 4, &x, 4) != 4) {
471abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    return ERROR_IO;
472abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
473abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
474abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                x = ntohl(x);
475abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                --x;
476abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
477abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(x <= start_sample_index);
478abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
479abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
480abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
481abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
482abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagAfter:
483abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
484abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (x < start_sample_index) {
485abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                if (left + 1 >= mNumSyncSamples) {
486abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    return ERROR_OUT_OF_RANGE;
487abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
488abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
489abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                if (mDataSource->readAt(
490abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                            mSyncSampleOffset + 8 + (left + 1) * 4, &x, 4) != 4) {
491abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    return ERROR_IO;
492abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
493abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
494abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                x = ntohl(x);
495abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                --x;
496abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
497abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(x >= start_sample_index);
498abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
499abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
500abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
501abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
502abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
503abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        default:
504abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
50620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
507abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    *sample_index = x;
50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5127e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
513c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
514c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
5157e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (mSyncSampleOffset < 0) {
5167e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // All samples are sync-samples.
5177e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        *sample_index = 0;
5187e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        return OK;
5197e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
5207e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5217e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    uint32_t bestSampleIndex = 0;
5227e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t maxSampleSize = 0;
5237e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5247e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    static const size_t kMaxNumSyncSamplesToScan = 20;
5257e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5267e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // Consider the first kMaxNumSyncSamplesToScan sync samples and
5277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // pick the one with the largest (compressed) size as the thumbnail.
5287e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5297e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t numSamplesToScan = mNumSyncSamples;
5307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (numSamplesToScan > kMaxNumSyncSamplesToScan) {
5317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        numSamplesToScan = kMaxNumSyncSamplesToScan;
5327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
5337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    for (size_t i = 0; i < numSamplesToScan; ++i) {
5357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        uint32_t x;
53634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber        if (mDataSource->readAt(
5377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber                    mSyncSampleOffset + 8 + i * 4, &x, 4) != 4) {
5387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            return ERROR_IO;
5397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
5407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        x = ntohl(x);
5417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        --x;
5427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // Now x is a sample index.
5447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t sampleSize;
545c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(x, &sampleSize);
5467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (err != OK) {
5477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            return err;
5487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
5497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (i == 0 || sampleSize > maxSampleSize) {
5517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            bestSampleIndex = x;
5527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            maxSampleSize = sampleSize;
5537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
5547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
5557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    *sample_index = bestSampleIndex;
5577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
5587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    return OK;
5597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber}
5607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
561c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l(
562c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *sampleSize) {
563c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return mSampleIterator->getSampleSizeDirect(
564c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            sampleIndex, sampleSize);
565c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
566c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
567c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample(
568c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex,
569c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        off_t *offset,
570c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        size_t *size,
571c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t *decodingTime) {
572c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
573c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
574c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
575c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) {
576c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
577c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
578c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
579c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (offset) {
580c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = mSampleIterator->getSampleOffset();
581c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
582c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
583c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (size) {
584c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mSampleIterator->getSampleSize();
585c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
586c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
587c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (decodingTime) {
588c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *decodingTime = mSampleIterator->getSampleTime();
589c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
590c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
591c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
592c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
593c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
59420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
59520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
596