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