From 4ecce5026fe3235e783766dcb9fc2b59405da08f Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Fri, 31 Aug 2012 11:07:37 -0700 Subject: Move fragmented mp4 parser to libstagefright and rename it from Parser to FragmentedMP4Parser Change-Id: I986f50d0c5c93648aac675d6160e18623b031541 --- media/libstagefright/include/FragmentedMP4Parser.h | 255 +++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 media/libstagefright/include/FragmentedMP4Parser.h (limited to 'media/libstagefright/include') diff --git a/media/libstagefright/include/FragmentedMP4Parser.h b/media/libstagefright/include/FragmentedMP4Parser.h new file mode 100644 index 0000000..bd8fe32 --- /dev/null +++ b/media/libstagefright/include/FragmentedMP4Parser.h @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PARSER_H_ + +#define PARSER_H_ + +#include +#include + +namespace android { + +struct ABuffer; + +struct FragmentedMP4Parser : public AHandler { + struct Source : public RefBase { + Source() {} + + virtual ssize_t readAt(off64_t offset, void *data, size_t size) = 0; + + protected: + virtual ~Source() {} + + private: + DISALLOW_EVIL_CONSTRUCTORS(Source); + }; + + FragmentedMP4Parser(); + + void start(const char *filename); + void start(const sp &source); + + sp getFormat(bool audio); + status_t dequeueAccessUnit(bool audio, sp *accessUnit); + + virtual void onMessageReceived(const sp &msg); + +protected: + virtual ~FragmentedMP4Parser(); + +private: + enum { + kWhatStart, + kWhatProceed, + kWhatReadMore, + kWhatGetFormat, + kWhatDequeueAccessUnit, + }; + + struct TrackFragment; + struct DynamicTrackFragment; + struct StaticTrackFragment; + + struct DispatchEntry { + uint32_t mType; + uint32_t mParentType; + status_t (FragmentedMP4Parser::*mHandler)(uint32_t, size_t, uint64_t); + }; + + struct Container { + uint64_t mOffset; + uint64_t mBytesRemaining; + uint32_t mType; + bool mExtendsToEOF; + }; + + struct SampleDescription { + uint32_t mType; + uint16_t mDataRefIndex; + + sp mFormat; + }; + + struct SampleInfo { + off64_t mOffset; + size_t mSize; + uint32_t mPresentationTime; + size_t mSampleDescIndex; + uint32_t mFlags; + }; + + struct MediaDataInfo { + sp mBuffer; + off64_t mOffset; + }; + + struct TrackInfo { + enum Flags { + kTrackEnabled = 0x01, + kTrackInMovie = 0x02, + kTrackInPreview = 0x04, + }; + + uint32_t mTrackID; + uint32_t mFlags; + uint32_t mDuration; // This is the duration in terms of movie timescale! + + uint32_t mMediaTimeScale; + + uint32_t mMediaHandlerType; + Vector mSampleDescs; + + // from track extends: + uint32_t mDefaultSampleDescriptionIndex; + uint32_t mDefaultSampleDuration; + uint32_t mDefaultSampleSize; + uint32_t mDefaultSampleFlags; + + uint32_t mDecodingTime; + + sp mStaticFragment; + List > mFragments; + }; + + struct TrackFragmentHeaderInfo { + enum Flags { + kBaseDataOffsetPresent = 0x01, + kSampleDescriptionIndexPresent = 0x02, + kDefaultSampleDurationPresent = 0x08, + kDefaultSampleSizePresent = 0x10, + kDefaultSampleFlagsPresent = 0x20, + kDurationIsEmpty = 0x10000, + }; + + uint32_t mTrackID; + uint32_t mFlags; + uint64_t mBaseDataOffset; + uint32_t mSampleDescriptionIndex; + uint32_t mDefaultSampleDuration; + uint32_t mDefaultSampleSize; + uint32_t mDefaultSampleFlags; + + uint64_t mDataOffset; + }; + + static const DispatchEntry kDispatchTable[]; + + sp mSource; + off_t mBufferPos; + bool mSuspended; + sp mBuffer; + Vector mStack; + KeyedVector mTracks; // TrackInfo by trackID + Vector mMediaData; + + uint32_t mCurrentTrackID; + + status_t mFinalResult; + + TrackFragmentHeaderInfo mTrackFragmentHeaderInfo; + + status_t onProceed(); + status_t onDequeueAccessUnit(size_t trackIndex, sp *accessUnit); + + void enter(off64_t offset, uint32_t type, uint64_t size); + + uint16_t readU16(size_t offset); + uint32_t readU32(size_t offset); + uint64_t readU64(size_t offset); + void skip(off_t distance); + status_t need(size_t size); + bool fitsContainer(uint64_t size) const; + + status_t parseTrackHeader( + uint32_t type, size_t offset, uint64_t size); + + status_t parseMediaHeader( + uint32_t type, size_t offset, uint64_t size); + + status_t parseMediaHandler( + uint32_t type, size_t offset, uint64_t size); + + status_t parseTrackExtends( + uint32_t type, size_t offset, uint64_t size); + + status_t parseTrackFragmentHeader( + uint32_t type, size_t offset, uint64_t size); + + status_t parseTrackFragmentRun( + uint32_t type, size_t offset, uint64_t size); + + status_t parseVisualSampleEntry( + uint32_t type, size_t offset, uint64_t size); + + status_t parseAudioSampleEntry( + uint32_t type, size_t offset, uint64_t size); + + status_t parseSampleSizes( + uint32_t type, size_t offset, uint64_t size); + + status_t parseCompactSampleSizes( + uint32_t type, size_t offset, uint64_t size); + + status_t parseSampleToChunk( + uint32_t type, size_t offset, uint64_t size); + + status_t parseChunkOffsets( + uint32_t type, size_t offset, uint64_t size); + + status_t parseChunkOffsets64( + uint32_t type, size_t offset, uint64_t size); + + status_t parseAVCCodecSpecificData( + uint32_t type, size_t offset, uint64_t size); + + status_t parseESDSCodecSpecificData( + uint32_t type, size_t offset, uint64_t size); + + status_t parseMediaData( + uint32_t type, size_t offset, uint64_t size); + + TrackInfo *editTrack(uint32_t trackID, bool createIfNecessary = false); + + ssize_t findTrack(bool wantAudio) const; + + status_t makeAccessUnit( + TrackInfo *info, + const SampleInfo &sample, + const MediaDataInfo &mdatInfo, + sp *accessUnit); + + status_t getSample( + TrackInfo *info, + sp *fragment, + SampleInfo *sampleInfo); + + static int CompareSampleLocation( + const SampleInfo &sample, const MediaDataInfo &mdatInfo); + + void resumeIfNecessary(); + + void copyBuffer( + sp *dst, + size_t offset, uint64_t size, size_t extra = 0) const; + + DISALLOW_EVIL_CONSTRUCTORS(FragmentedMP4Parser); +}; + +} // namespace android + +#endif // PARSER_H_ + -- cgit v1.1