1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/fmp4/MP4Reader.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,154 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#if !defined(MP4Reader_h_) 1.11 +#define MP4Reader_h_ 1.12 + 1.13 +#include "MediaDecoderReader.h" 1.14 +#include "nsAutoPtr.h" 1.15 +#include "PlatformDecoderModule.h" 1.16 +#include "mp4_demuxer/mp4_demuxer.h" 1.17 +#include "mp4_demuxer/box_definitions.h" 1.18 +#include "MediaTaskQueue.h" 1.19 + 1.20 +#include <deque> 1.21 +#include "mozilla/Monitor.h" 1.22 + 1.23 +namespace mozilla { 1.24 + 1.25 +namespace dom { 1.26 +class TimeRanges; 1.27 +} 1.28 + 1.29 +typedef std::deque<mp4_demuxer::MP4Sample*> MP4SampleQueue; 1.30 + 1.31 +class MP4Stream; 1.32 + 1.33 +class MP4Reader : public MediaDecoderReader 1.34 +{ 1.35 +public: 1.36 + MP4Reader(AbstractMediaDecoder* aDecoder); 1.37 + 1.38 + virtual ~MP4Reader(); 1.39 + 1.40 + virtual nsresult Init(MediaDecoderReader* aCloneDonor) MOZ_OVERRIDE; 1.41 + 1.42 + virtual bool DecodeAudioData() MOZ_OVERRIDE; 1.43 + virtual bool DecodeVideoFrame(bool &aKeyframeSkip, 1.44 + int64_t aTimeThreshold) MOZ_OVERRIDE; 1.45 + 1.46 + virtual bool HasAudio() MOZ_OVERRIDE; 1.47 + virtual bool HasVideo() MOZ_OVERRIDE; 1.48 + 1.49 + virtual nsresult ReadMetadata(MediaInfo* aInfo, 1.50 + MetadataTags** aTags) MOZ_OVERRIDE; 1.51 + 1.52 + virtual nsresult Seek(int64_t aTime, 1.53 + int64_t aStartTime, 1.54 + int64_t aEndTime, 1.55 + int64_t aCurrentTime) MOZ_OVERRIDE; 1.56 +private: 1.57 + 1.58 + // Destroys all decoder resources. 1.59 + void Shutdown(); 1.60 + 1.61 + // Initializes mLayersBackendType if possible. 1.62 + void InitLayersBackendType(); 1.63 + 1.64 + // Blocks until the demuxer produces an sample of specified type. 1.65 + // Returns nullptr on error on EOS. Caller must delete sample. 1.66 + mp4_demuxer::MP4Sample* PopSample(mp4_demuxer::TrackType aTrack); 1.67 + 1.68 + bool SkipVideoDemuxToNextKeyFrame(int64_t aTimeThreshold, uint32_t& parsed); 1.69 + 1.70 + void Output(mp4_demuxer::TrackType aType, MediaData* aSample); 1.71 + void InputExhausted(mp4_demuxer::TrackType aTrack); 1.72 + void Error(mp4_demuxer::TrackType aTrack); 1.73 + bool Decode(mp4_demuxer::TrackType aTrack); 1.74 + void Flush(mp4_demuxer::TrackType aTrack); 1.75 + 1.76 + nsAutoPtr<mp4_demuxer::MP4Demuxer> mDemuxer; 1.77 + nsAutoPtr<MP4Stream> mMP4Stream; 1.78 + nsAutoPtr<PlatformDecoderModule> mPlatform; 1.79 + 1.80 + class DecoderCallback : public MediaDataDecoderCallback { 1.81 + public: 1.82 + DecoderCallback(MP4Reader* aReader, 1.83 + mp4_demuxer::TrackType aType) 1.84 + : mReader(aReader) 1.85 + , mType(aType) 1.86 + { 1.87 + } 1.88 + virtual void Output(MediaData* aSample) MOZ_OVERRIDE { 1.89 + mReader->Output(mType, aSample); 1.90 + } 1.91 + virtual void InputExhausted() MOZ_OVERRIDE { 1.92 + mReader->InputExhausted(mType); 1.93 + } 1.94 + virtual void Error() MOZ_OVERRIDE { 1.95 + mReader->Error(mType); 1.96 + } 1.97 + private: 1.98 + MP4Reader* mReader; 1.99 + mp4_demuxer::TrackType mType; 1.100 + }; 1.101 + 1.102 + struct DecoderData { 1.103 + DecoderData(const char* aMonitorName, 1.104 + uint32_t aDecodeAhead) 1.105 + : mMonitor(aMonitorName) 1.106 + , mNumSamplesInput(0) 1.107 + , mNumSamplesOutput(0) 1.108 + , mDecodeAhead(aDecodeAhead) 1.109 + , mActive(false) 1.110 + , mInputExhausted(false) 1.111 + , mError(false) 1.112 + , mIsFlushing(false) 1.113 + { 1.114 + } 1.115 + 1.116 + // The platform decoder. 1.117 + RefPtr<MediaDataDecoder> mDecoder; 1.118 + // Queue of input extracted by the demuxer, but not yet sent to the 1.119 + // platform decoder. 1.120 + MP4SampleQueue mDemuxedSamples; 1.121 + // TaskQueue on which decoder can choose to decode. 1.122 + // Only non-null up until the decoder is created. 1.123 + RefPtr<MediaTaskQueue> mTaskQueue; 1.124 + // Callback that receives output and error notifications from the decoder. 1.125 + nsAutoPtr<DecoderCallback> mCallback; 1.126 + // Monitor that protects all non-threadsafe state; the primitives 1.127 + // that follow. 1.128 + Monitor mMonitor; 1.129 + uint64_t mNumSamplesInput; 1.130 + uint64_t mNumSamplesOutput; 1.131 + uint32_t mDecodeAhead; 1.132 + // Whether this stream exists in the media. 1.133 + bool mActive; 1.134 + bool mInputExhausted; 1.135 + bool mError; 1.136 + bool mIsFlushing; 1.137 + }; 1.138 + DecoderData mAudio; 1.139 + DecoderData mVideo; 1.140 + 1.141 + // The last number of decoded output frames that we've reported to 1.142 + // MediaDecoder::NotifyDecoded(). We diff the number of output video 1.143 + // frames every time that DecodeVideoData() is called, and report the 1.144 + // delta there. 1.145 + uint64_t mLastReportedNumDecodedFrames; 1.146 + 1.147 + DecoderData& GetDecoderData(mp4_demuxer::TrackType aTrack); 1.148 + MP4SampleQueue& SampleQueue(mp4_demuxer::TrackType aTrack); 1.149 + MediaDataDecoder* Decoder(mp4_demuxer::TrackType aTrack); 1.150 + 1.151 + layers::LayersBackend mLayersBackendType; 1.152 + 1.153 +}; 1.154 + 1.155 +} // namespace mozilla 1.156 + 1.157 +#endif