1/*
2 * Copyright (C) 2012 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 PARSER_H_
18
19#define PARSER_H_
20
21#include <media/stagefright/foundation/AHandler.h>
22#include <media/stagefright/DataSource.h>
23#include <utils/Vector.h>
24
25namespace android {
26
27struct ABuffer;
28
29struct FragmentedMP4Parser : public AHandler {
30    struct Source : public RefBase {
31        Source() {}
32
33        virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0;
34        virtual bool isSeekable() = 0;
35
36        protected:
37        virtual ~Source() {}
38
39        private:
40        DISALLOW_EVIL_CONSTRUCTORS(Source);
41    };
42
43    FragmentedMP4Parser();
44
45    void start(const char *filename);
46    void start(const sp<Source> &source);
47    void start(sp<DataSource> &source);
48
49    sp<AMessage> getFormat(bool audio, bool synchronous = false);
50    status_t dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit, bool synchronous = false);
51    status_t seekTo(bool audio, int64_t timeUs);
52    bool isSeekable() const;
53
54    virtual void onMessageReceived(const sp<AMessage> &msg);
55
56protected:
57    virtual ~FragmentedMP4Parser();
58
59private:
60    enum {
61        kWhatStart,
62        kWhatProceed,
63        kWhatReadMore,
64        kWhatGetFormat,
65        kWhatDequeueAccessUnit,
66        kWhatSeekTo,
67    };
68
69    struct TrackFragment;
70    struct DynamicTrackFragment;
71    struct StaticTrackFragment;
72
73    struct DispatchEntry {
74        uint32_t mType;
75        uint32_t mParentType;
76        status_t (FragmentedMP4Parser::*mHandler)(uint32_t, size_t, uint64_t);
77    };
78
79    struct Container {
80        uint64_t mOffset;
81        uint64_t mBytesRemaining;
82        uint32_t mType;
83        bool mExtendsToEOF;
84    };
85
86    struct SampleDescription {
87        uint32_t mType;
88        uint16_t mDataRefIndex;
89
90        sp<AMessage> mFormat;
91    };
92
93    struct SampleInfo {
94        off64_t mOffset;
95        size_t mSize;
96        uint32_t mPresentationTime;
97        size_t mSampleDescIndex;
98        uint32_t mFlags;
99    };
100
101    struct MediaDataInfo {
102        sp<ABuffer> mBuffer;
103        off64_t mOffset;
104    };
105
106    struct SidxEntry {
107        size_t mSize;
108        uint32_t mDurationUs;
109    };
110
111    struct TrackInfo {
112        enum Flags {
113            kTrackEnabled     = 0x01,
114            kTrackInMovie     = 0x02,
115            kTrackInPreview   = 0x04,
116        };
117
118        uint32_t mTrackID;
119        uint32_t mFlags;
120        uint32_t mDuration;  // This is the duration in terms of movie timescale!
121        uint64_t mSidxDuration; // usec, from sidx box, which can use a different timescale
122
123        uint32_t mMediaTimeScale;
124
125        uint32_t mMediaHandlerType;
126        Vector<SampleDescription> mSampleDescs;
127
128        // from track extends:
129        uint32_t mDefaultSampleDescriptionIndex;
130        uint32_t mDefaultSampleDuration;
131        uint32_t mDefaultSampleSize;
132        uint32_t mDefaultSampleFlags;
133
134        uint32_t mDecodingTime;
135
136        Vector<SidxEntry> mSidx;
137        sp<StaticTrackFragment> mStaticFragment;
138        List<sp<TrackFragment> > mFragments;
139    };
140
141    struct TrackFragmentHeaderInfo {
142        enum Flags {
143            kBaseDataOffsetPresent         = 0x01,
144            kSampleDescriptionIndexPresent = 0x02,
145            kDefaultSampleDurationPresent  = 0x08,
146            kDefaultSampleSizePresent      = 0x10,
147            kDefaultSampleFlagsPresent     = 0x20,
148            kDurationIsEmpty               = 0x10000,
149        };
150
151        uint32_t mTrackID;
152        uint32_t mFlags;
153        uint64_t mBaseDataOffset;
154        uint32_t mSampleDescriptionIndex;
155        uint32_t mDefaultSampleDuration;
156        uint32_t mDefaultSampleSize;
157        uint32_t mDefaultSampleFlags;
158
159        uint64_t mDataOffset;
160    };
161
162    static const DispatchEntry kDispatchTable[];
163
164    sp<Source> mSource;
165    off_t mBufferPos;
166    bool mSuspended;
167    bool mDoneWithMoov;
168    off_t mFirstMoofOffset; // used as the starting point for offsets calculated from the sidx box
169    sp<ABuffer> mBuffer;
170    Vector<Container> mStack;
171    KeyedVector<uint32_t, TrackInfo> mTracks;  // TrackInfo by trackID
172    Vector<MediaDataInfo> mMediaData;
173
174    uint32_t mCurrentTrackID;
175
176    status_t mFinalResult;
177
178    TrackFragmentHeaderInfo mTrackFragmentHeaderInfo;
179
180    status_t onProceed();
181    status_t onDequeueAccessUnit(size_t trackIndex, sp<ABuffer> *accessUnit);
182    status_t onSeekTo(bool wantAudio, int64_t position);
183
184    void enter(off64_t offset, uint32_t type, uint64_t size);
185
186    uint16_t readU16(size_t offset);
187    uint32_t readU32(size_t offset);
188    uint64_t readU64(size_t offset);
189    void skip(off_t distance);
190    status_t need(size_t size);
191    bool fitsContainer(uint64_t size) const;
192
193    status_t parseTrackHeader(
194            uint32_t type, size_t offset, uint64_t size);
195
196    status_t parseMediaHeader(
197            uint32_t type, size_t offset, uint64_t size);
198
199    status_t parseMediaHandler(
200            uint32_t type, size_t offset, uint64_t size);
201
202    status_t parseTrackExtends(
203            uint32_t type, size_t offset, uint64_t size);
204
205    status_t parseTrackFragmentHeader(
206            uint32_t type, size_t offset, uint64_t size);
207
208    status_t parseTrackFragmentRun(
209            uint32_t type, size_t offset, uint64_t size);
210
211    status_t parseVisualSampleEntry(
212            uint32_t type, size_t offset, uint64_t size);
213
214    status_t parseAudioSampleEntry(
215            uint32_t type, size_t offset, uint64_t size);
216
217    status_t parseSampleSizes(
218            uint32_t type, size_t offset, uint64_t size);
219
220    status_t parseCompactSampleSizes(
221            uint32_t type, size_t offset, uint64_t size);
222
223    status_t parseSampleToChunk(
224            uint32_t type, size_t offset, uint64_t size);
225
226    status_t parseChunkOffsets(
227            uint32_t type, size_t offset, uint64_t size);
228
229    status_t parseChunkOffsets64(
230            uint32_t type, size_t offset, uint64_t size);
231
232    status_t parseAVCCodecSpecificData(
233            uint32_t type, size_t offset, uint64_t size);
234
235    status_t parseESDSCodecSpecificData(
236            uint32_t type, size_t offset, uint64_t size);
237
238    status_t parseMediaData(
239            uint32_t type, size_t offset, uint64_t size);
240
241    status_t parseSegmentIndex(
242            uint32_t type, size_t offset, uint64_t size);
243
244    TrackInfo *editTrack(uint32_t trackID, bool createIfNecessary = false);
245
246    ssize_t findTrack(bool wantAudio) const;
247
248    status_t makeAccessUnit(
249            TrackInfo *info,
250            const SampleInfo &sample,
251            const MediaDataInfo &mdatInfo,
252            sp<ABuffer> *accessUnit);
253
254    status_t getSample(
255            TrackInfo *info,
256            sp<TrackFragment> *fragment,
257            SampleInfo *sampleInfo);
258
259    static int CompareSampleLocation(
260        const SampleInfo &sample, const MediaDataInfo &mdatInfo);
261
262    void resumeIfNecessary();
263
264    void copyBuffer(
265            sp<ABuffer> *dst,
266            size_t offset, uint64_t size, size_t extra = 0) const;
267
268    DISALLOW_EVIL_CONSTRUCTORS(FragmentedMP4Parser);
269};
270
271}  // namespace android
272
273#endif  // PARSER_H_
274
275