Home | History | Annotate | Download | only in include
      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 
     25 namespace android {
     26 
     27 struct ABuffer;
     28 
     29 struct 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 
     56 protected:
     57     virtual ~FragmentedMP4Parser();
     58 
     59 private:
     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) const;
    267 
    268     DISALLOW_EVIL_CONSTRUCTORS(FragmentedMP4Parser);
    269 };
    270 
    271 }  // namespace android
    272 
    273 #endif  // PARSER_H_
    274 
    275