1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SAMPLE_TABLE_H_
18
19#define SAMPLE_TABLE_H_
20
21#include <sys/types.h>
22#include <stdint.h>
23
24#include <media/stagefright/MediaErrors.h>
25#include <utils/RefBase.h>
26#include <utils/threads.h>
27#include <utils/Vector.h>
28
29namespace android {
30
31class DataSource;
32struct SampleIterator;
33
34class SampleTable : public RefBase {
35public:
36    SampleTable(const sp<DataSource> &source);
37
38    bool isValid() const;
39
40    // type can be 'stco' or 'co64'.
41    status_t setChunkOffsetParams(
42            uint32_t type, off64_t data_offset, size_t data_size);
43
44    status_t setSampleToChunkParams(off64_t data_offset, size_t data_size);
45
46    // type can be 'stsz' or 'stz2'.
47    status_t setSampleSizeParams(
48            uint32_t type, off64_t data_offset, size_t data_size);
49
50    status_t setTimeToSampleParams(off64_t data_offset, size_t data_size);
51
52    status_t setCompositionTimeToSampleParams(
53            off64_t data_offset, size_t data_size);
54
55    status_t setSyncSampleParams(off64_t data_offset, size_t data_size);
56
57    ////////////////////////////////////////////////////////////////////////////
58
59    uint32_t countChunkOffsets() const;
60
61    uint32_t countSamples() const;
62
63    status_t getMaxSampleSize(size_t *size);
64
65    status_t getMetaDataForSample(
66            uint32_t sampleIndex,
67            off64_t *offset,
68            size_t *size,
69            uint32_t *compositionTime,
70            bool *isSyncSample = NULL,
71            uint32_t *sampleDuration = NULL);
72
73    enum {
74        kFlagBefore,
75        kFlagAfter,
76        kFlagClosest
77    };
78    status_t findSampleAtTime(
79            uint64_t req_time, uint64_t scale_num, uint64_t scale_den,
80            uint32_t *sample_index, uint32_t flags);
81
82    status_t findSyncSampleNear(
83            uint32_t start_sample_index, uint32_t *sample_index,
84            uint32_t flags);
85
86    status_t findThumbnailSample(uint32_t *sample_index);
87
88protected:
89    ~SampleTable();
90
91private:
92    struct CompositionDeltaLookup;
93
94    static const uint32_t kChunkOffsetType32;
95    static const uint32_t kChunkOffsetType64;
96    static const uint32_t kSampleSizeType32;
97    static const uint32_t kSampleSizeTypeCompact;
98
99    sp<DataSource> mDataSource;
100    Mutex mLock;
101
102    off64_t mChunkOffsetOffset;
103    uint32_t mChunkOffsetType;
104    uint32_t mNumChunkOffsets;
105
106    off64_t mSampleToChunkOffset;
107    uint32_t mNumSampleToChunkOffsets;
108
109    off64_t mSampleSizeOffset;
110    uint32_t mSampleSizeFieldSize;
111    uint32_t mDefaultSampleSize;
112    uint32_t mNumSampleSizes;
113
114    bool mHasTimeToSample;
115    uint32_t mTimeToSampleCount;
116    Vector<uint32_t> mTimeToSample;
117
118    struct SampleTimeEntry {
119        uint32_t mSampleIndex;
120        uint32_t mCompositionTime;
121    };
122    SampleTimeEntry *mSampleTimeEntries;
123
124    int32_t *mCompositionTimeDeltaEntries;
125    size_t mNumCompositionTimeDeltaEntries;
126    CompositionDeltaLookup *mCompositionDeltaLookup;
127
128    off64_t mSyncSampleOffset;
129    uint32_t mNumSyncSamples;
130    uint32_t *mSyncSamples;
131    size_t mLastSyncSampleIndex;
132
133    SampleIterator *mSampleIterator;
134
135    struct SampleToChunkEntry {
136        uint32_t startChunk;
137        uint32_t samplesPerChunk;
138        uint32_t chunkDesc;
139    };
140    SampleToChunkEntry *mSampleToChunkEntries;
141
142    friend struct SampleIterator;
143
144    // normally we don't round
145    inline uint64_t getSampleTime(
146            size_t sample_index, uint64_t scale_num, uint64_t scale_den) const {
147        return (sample_index < (size_t)mNumSampleSizes && mSampleTimeEntries != NULL
148                && scale_den != 0)
149                ? (mSampleTimeEntries[sample_index].mCompositionTime * scale_num) / scale_den : 0;
150    }
151
152    status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);
153    int32_t getCompositionTimeOffset(uint32_t sampleIndex);
154
155    static int CompareIncreasingTime(const void *, const void *);
156
157    void buildSampleEntriesTable();
158
159    SampleTable(const SampleTable &);
160    SampleTable &operator=(const SampleTable &);
161};
162
163}  // namespace android
164
165#endif  // SAMPLE_TABLE_H_
166