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/MediaExtractorPluginHelper.h>
25 #include <media/stagefright/MediaErrors.h>
26 #include <utils/RefBase.h>
27 #include <utils/threads.h>
28 
29 namespace android {
30 
31 class DataSourceHelper;
32 struct SampleIterator;
33 
34 class SampleTable : public RefBase {
35 public:
36     explicit SampleTable(DataSourceHelper *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             uint64_t *compositionTime,
70             bool *isSyncSample = NULL,
71             uint64_t *sampleDuration = NULL);
72 
73     // call only after getMetaDataForSample has been called successfully.
74     uint32_t getLastSampleIndexInChunk();
75 
76     enum {
77         kFlagBefore,
78         kFlagAfter,
79         kFlagClosest,
80         kFlagFrameIndex,
81     };
82     status_t findSampleAtTime(
83             uint64_t req_time, uint64_t scale_num, uint64_t scale_den,
84             uint32_t *sample_index, uint32_t flags);
85 
86     status_t findSyncSampleNear(
87             uint32_t start_sample_index, uint32_t *sample_index,
88             uint32_t flags);
89 
90     status_t findThumbnailSample(uint32_t *sample_index);
91 
setPredictSampleSize(uint32_t sampleSize)92     void setPredictSampleSize(uint32_t sampleSize) {
93         mDefaultSampleSize = sampleSize;
94     }
95 
96 protected:
97     ~SampleTable();
98 
99 private:
100     struct CompositionDeltaLookup;
101 
102     static const uint32_t kChunkOffsetType32;
103     static const uint32_t kChunkOffsetType64;
104     static const uint32_t kSampleSizeType32;
105     static const uint32_t kSampleSizeTypeCompact;
106 
107     // Limit the total size of all internal tables to 200MiB.
108     static const size_t kMaxTotalSize = 200 * (1 << 20);
109 
110     DataSourceHelper *mDataSource;
111     Mutex mLock;
112 
113     off64_t mChunkOffsetOffset;
114     uint32_t mChunkOffsetType;
115     uint32_t mNumChunkOffsets;
116 
117     off64_t mSampleToChunkOffset;
118     uint32_t mNumSampleToChunkOffsets;
119 
120     off64_t mSampleSizeOffset;
121     uint32_t mSampleSizeFieldSize;
122     uint32_t mDefaultSampleSize;
123     uint32_t mNumSampleSizes;
124 
125     bool mHasTimeToSample;
126     uint32_t mTimeToSampleCount;
127     uint32_t* mTimeToSample;
128 
129     struct SampleTimeEntry {
130         uint32_t mSampleIndex;
131         uint64_t mCompositionTime;
132     };
133     SampleTimeEntry *mSampleTimeEntries;
134 
135     int32_t *mCompositionTimeDeltaEntries;
136     size_t mNumCompositionTimeDeltaEntries;
137     CompositionDeltaLookup *mCompositionDeltaLookup;
138 
139     off64_t mSyncSampleOffset;
140     uint32_t mNumSyncSamples;
141     uint32_t *mSyncSamples;
142     size_t mLastSyncSampleIndex;
143 
144     SampleIterator *mSampleIterator;
145 
146     struct SampleToChunkEntry {
147         uint32_t startChunk;
148         uint32_t samplesPerChunk;
149         uint32_t chunkDesc;
150     };
151     SampleToChunkEntry *mSampleToChunkEntries;
152 
153     // Approximate size of all tables combined.
154     uint64_t mTotalSize;
155 
156     friend struct SampleIterator;
157 
158     // normally we don't round
getSampleTime(size_t sample_index,uint64_t scale_num,uint64_t scale_den)159     inline uint64_t getSampleTime(
160             size_t sample_index, uint64_t scale_num, uint64_t scale_den) const {
161         return (sample_index < (size_t)mNumSampleSizes && mSampleTimeEntries != NULL
162                 && scale_den != 0)
163                 ? (mSampleTimeEntries[sample_index].mCompositionTime * scale_num) / scale_den : 0;
164     }
165 
166     status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);
167     int32_t getCompositionTimeOffset(uint32_t sampleIndex);
168 
169     static int CompareIncreasingTime(const void *, const void *);
170 
171     void buildSampleEntriesTable();
172 
173     SampleTable(const SampleTable &);
174     SampleTable &operator=(const SampleTable &);
175 };
176 
177 }  // namespace android
178 
179 #endif  // SAMPLE_TABLE_H_
180