LCOV - code coverage report
Current view: top level - dom/media - MediaDecoderReader.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 56 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 37 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : #if !defined(MediaDecoderReader_h_)
       7             : #define MediaDecoderReader_h_
       8             : 
       9             : #include "AbstractMediaDecoder.h"
      10             : #include "AudioCompactor.h"
      11             : #include "Intervals.h"
      12             : #include "MediaData.h"
      13             : #include "MediaInfo.h"
      14             : #include "MediaMetadataManager.h"
      15             : #include "MediaQueue.h"
      16             : #include "MediaResult.h"
      17             : #include "MediaTimer.h"
      18             : #include "SeekTarget.h"
      19             : #include "TimeUnits.h"
      20             : #include "mozilla/EnumSet.h"
      21             : #include "mozilla/MozPromise.h"
      22             : #include "nsAutoPtr.h"
      23             : 
      24             : namespace mozilla {
      25             : 
      26             : class CDMProxy;
      27             : class MediaDecoderReader;
      28             : class TaskQueue;
      29             : class VideoFrameContainer;
      30             : 
      31             : struct WaitForDataRejectValue
      32             : {
      33             :   enum Reason
      34             :   {
      35             :     SHUTDOWN,
      36             :     CANCELED
      37             :   };
      38             : 
      39           0 :   WaitForDataRejectValue(MediaData::Type aType, Reason aReason)
      40           0 :     :mType(aType), mReason(aReason)
      41             :   {
      42           0 :   }
      43             :   MediaData::Type mType;
      44             :   Reason mReason;
      45             : };
      46             : 
      47           0 : struct SeekRejectValue
      48             : {
      49             :   MOZ_IMPLICIT SeekRejectValue(const MediaResult& aError)
      50             :     : mType(MediaData::NULL_DATA), mError(aError) { }
      51           0 :   MOZ_IMPLICIT SeekRejectValue(nsresult aResult)
      52           0 :     : mType(MediaData::NULL_DATA), mError(aResult) { }
      53           0 :   SeekRejectValue(MediaData::Type aType, const MediaResult& aError)
      54           0 :     : mType(aType), mError(aError) { }
      55             :   MediaData::Type mType;
      56             :   MediaResult mError;
      57             : };
      58             : 
      59           0 : struct MetadataHolder
      60             : {
      61             :   UniquePtr<MediaInfo> mInfo;
      62             :   UniquePtr<MetadataTags> mTags;
      63             : };
      64             : 
      65             : struct MOZ_STACK_CLASS MediaDecoderReaderInit
      66             : {
      67             :   AbstractMediaDecoder* const mDecoder;
      68             :   MediaResource* mResource = nullptr;
      69             :   VideoFrameContainer* mVideoFrameContainer = nullptr;
      70             : 
      71           0 :   explicit MediaDecoderReaderInit(AbstractMediaDecoder* aDecoder)
      72           0 :     : mDecoder(aDecoder)
      73             :   {
      74           0 :   }
      75             : };
      76             : 
      77             : // Encapsulates the decoding and reading of media data. Reading can either
      78             : // synchronous and done on the calling "decode" thread, or asynchronous and
      79             : // performed on a background thread, with the result being returned by
      80             : // callback.
      81             : // Unless otherwise specified, methods and fields of this class can only
      82             : // be accessed on the decode task queue.
      83             : class MediaDecoderReader
      84             : {
      85             :   friend class ReRequestVideoWithSkipTask;
      86             :   friend class ReRequestAudioTask;
      87             : 
      88             :   static const bool IsExclusive = true;
      89             : 
      90             : public:
      91             :   using TrackSet = EnumSet<TrackInfo::TrackType>;
      92             : 
      93             :   using MetadataPromise = MozPromise<MetadataHolder, MediaResult, IsExclusive>;
      94             : 
      95             :   template <typename Type>
      96             :   using DataPromise = MozPromise<RefPtr<Type>, MediaResult, IsExclusive>;
      97             :   using AudioDataPromise = DataPromise<AudioData>;
      98             :   using VideoDataPromise = DataPromise<VideoData>;
      99             : 
     100             :   using SeekPromise = MozPromise<media::TimeUnit, SeekRejectValue, IsExclusive>;
     101             : 
     102             :   // Note that, conceptually, WaitForData makes sense in a non-exclusive sense.
     103             :   // But in the current architecture it's only ever used exclusively (by MDSM),
     104             :   // so we mark it that way to verify our assumptions. If you have a use-case
     105             :   // for multiple WaitForData consumers, feel free to flip the exclusivity here.
     106             :   using WaitForDataPromise =
     107             :     MozPromise<MediaData::Type, WaitForDataRejectValue, IsExclusive>;
     108             : 
     109           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReader)
     110             : 
     111             :   // The caller must ensure that Shutdown() is called before aDecoder is
     112             :   // destroyed.
     113             :   explicit MediaDecoderReader(const MediaDecoderReaderInit& aInit);
     114             : 
     115             :   // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
     116             :   // on failure.
     117             :   nsresult Init();
     118             : 
     119             :   // Called by MDSM in dormant state to release resources allocated by this
     120             :   // reader. The reader can resume decoding by calling Seek() to a specific
     121             :   // position.
     122           0 :   virtual void ReleaseResources() { }
     123             : 
     124             :   // Destroys the decoding state. The reader cannot be made usable again.
     125             :   // This is different from ReleaseMediaResources() as it is irreversable,
     126             :   // whereas ReleaseMediaResources() is.  Must be called on the decode
     127             :   // thread.
     128             :   virtual RefPtr<ShutdownPromise> Shutdown();
     129             : 
     130           0 :   virtual bool OnTaskQueue() const
     131             :   {
     132           0 :     return OwnerThread()->IsCurrentThreadIn();
     133             :   }
     134             : 
     135             :   void UpdateDuration(const media::TimeUnit& aDuration);
     136             : 
     137             :   // Resets all state related to decoding, emptying all buffers etc.
     138             :   // Cancels all pending Request*Data() request callbacks, rejects any
     139             :   // outstanding seek promises, and flushes the decode pipeline. The
     140             :   // decoder must not call any of the callbacks for outstanding
     141             :   // Request*Data() calls after this is called. Calls to Request*Data()
     142             :   // made after this should be processed as usual.
     143             :   //
     144             :   // Normally this call preceedes a Seek() call, or shutdown.
     145             :   //
     146             :   // aParam is a set of TrackInfo::TrackType enums specifying which
     147             :   // queues need to be reset, defaulting to both audio and video tracks.
     148             :   virtual nsresult ResetDecode(
     149             :     TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,
     150             :                                 TrackInfo::kVideoTrack));
     151             : 
     152             :   // Requests one audio sample from the reader.
     153             :   //
     154             :   // The decode should be performed asynchronously, and the promise should
     155             :   // be resolved when it is complete.
     156             :   virtual RefPtr<AudioDataPromise> RequestAudioData();
     157             : 
     158             :   // Requests one video sample from the reader.
     159             :   virtual RefPtr<VideoDataPromise>
     160             :   RequestVideoData(const media::TimeUnit& aTimeThreshold);
     161             : 
     162             :   // By default, the state machine polls the reader once per second when it's
     163             :   // in buffering mode. Some readers support a promise-based mechanism by which
     164             :   // they notify the state machine when the data arrives.
     165           0 :   virtual bool IsWaitForDataSupported() const { return false; }
     166             : 
     167           0 :   virtual RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType)
     168             :   {
     169           0 :     MOZ_CRASH();
     170             :   }
     171             : 
     172             :   // The default implementation of AsyncReadMetadata is implemented in terms of
     173             :   // synchronous ReadMetadata() calls. Implementations may also
     174             :   // override AsyncReadMetadata to create a more proper async implementation.
     175             :   virtual RefPtr<MetadataPromise> AsyncReadMetadata();
     176             : 
     177             :   // Fills aInfo with the latest cached data required to present the media,
     178             :   // ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
     179           0 :   virtual void ReadUpdatedMetadata(MediaInfo* aInfo) {}
     180             : 
     181             :   // Moves the decode head to aTime microseconds.
     182             :   virtual RefPtr<SeekPromise> Seek(const SeekTarget& aTarget) = 0;
     183             : 
     184           0 :   virtual void SetCDMProxy(CDMProxy* aProxy) {}
     185             : 
     186             :   // Tell the reader that the data decoded are not for direct playback, so it
     187             :   // can accept more files, in particular those which have more channels than
     188             :   // available in the audio output.
     189           0 :   void SetIgnoreAudioOutputFormat()
     190             :   {
     191           0 :     mIgnoreAudioOutputFormat = true;
     192           0 :   }
     193             : 
     194             :   // The MediaDecoderStateMachine uses various heuristics that assume that
     195             :   // raw media data is arriving sequentially from a network channel. This
     196             :   // makes sense in the <video src="foo"> case, but not for more advanced use
     197             :   // cases like MSE.
     198           0 :   virtual bool UseBufferingHeuristics() const { return true; }
     199             : 
     200             :   // Returns the number of bytes of memory allocated by structures/frames in
     201             :   // the video queue.
     202             :   size_t SizeOfVideoQueueInBytes() const;
     203             : 
     204             :   // Returns the number of bytes of memory allocated by structures/frames in
     205             :   // the audio queue.
     206             :   size_t SizeOfAudioQueueInBytes() const;
     207             : 
     208             :   virtual size_t SizeOfVideoQueueInFrames();
     209             :   virtual size_t SizeOfAudioQueueInFrames();
     210             : 
     211             :   // Called once new data has been cached by the MediaResource.
     212             :   // mBuffered should be recalculated and updated accordingly.
     213           0 :   virtual void NotifyDataArrived()
     214             :   {
     215           0 :     MOZ_ASSERT(OnTaskQueue());
     216           0 :     NS_ENSURE_TRUE_VOID(!mShutdown);
     217           0 :     UpdateBuffered();
     218             :   }
     219             : 
     220           0 :   virtual MediaQueue<AudioData>& AudioQueue() { return mAudioQueue; }
     221           0 :   virtual MediaQueue<VideoData>& VideoQueue() { return mVideoQueue; }
     222             : 
     223           0 :   AbstractCanonical<media::TimeIntervals>* CanonicalBuffered()
     224             :   {
     225           0 :     return &mBuffered;
     226             :   }
     227             : 
     228           0 :   TaskQueue* OwnerThread() const
     229             :   {
     230           0 :     return mTaskQueue;
     231             :   }
     232             : 
     233             :   // Returns true if the reader implements RequestAudioData()
     234             :   // and RequestVideoData() asynchronously, rather than using the
     235             :   // implementation in this class to adapt the old synchronous to
     236             :   // the newer async model.
     237           0 :   virtual bool IsAsync() const { return false; }
     238             : 
     239             :   // Returns true if this decoder reader uses hardware accelerated video
     240             :   // decoding.
     241           0 :   virtual bool VideoIsHardwareAccelerated() const { return false; }
     242             : 
     243           0 :   TimedMetadataEventSource& TimedMetadataEvent()
     244             :   {
     245           0 :     return mTimedMetadataEvent;
     246             :   }
     247             : 
     248             :   // Notified by the OggDemuxer during playback when chained ogg is detected.
     249           0 :   MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; }
     250             : 
     251           0 :   TimedMetadataEventProducer& TimedMetadataProducer()
     252             :   {
     253           0 :     return mTimedMetadataEvent;
     254             :   }
     255             : 
     256           0 :   MediaEventProducer<void>& MediaNotSeekableProducer()
     257             :   {
     258           0 :     return mOnMediaNotSeekable;
     259             :   }
     260             : 
     261             :   // Notified if the reader can't decode a sample due to a missing decryption
     262             :   // key.
     263           0 :   MediaEventSource<TrackInfo::TrackType>& OnTrackWaitingForKey()
     264             :   {
     265           0 :     return mOnTrackWaitingForKey;
     266             :   }
     267             : 
     268           0 :   MediaEventProducer<TrackInfo::TrackType>& OnTrackWaitingForKeyProducer()
     269             :   {
     270           0 :     return mOnTrackWaitingForKey;
     271             :   }
     272             : 
     273             :   // Switch the video decoder to NullDecoderModule. It might takes effective
     274             :   // since a few samples later depends on how much demuxed samples are already
     275             :   // queued in the original video decoder.
     276           0 :   virtual void SetVideoNullDecode(bool aIsNullDecode) { }
     277             : 
     278             : protected:
     279             :   virtual ~MediaDecoderReader();
     280             : 
     281             :   // Recomputes mBuffered.
     282             :   virtual void UpdateBuffered();
     283             : 
     284             :   RefPtr<VideoDataPromise> DecodeToFirstVideoData();
     285             : 
     286             :   // Queue of audio frames. This queue is threadsafe, and is accessed from
     287             :   // the audio, decoder, state machine, and main threads.
     288             :   MediaQueue<AudioData> mAudioQueue;
     289             : 
     290             :   // Queue of video frames. This queue is threadsafe, and is accessed from
     291             :   // the decoder, state machine, and main threads.
     292             :   MediaQueue<VideoData> mVideoQueue;
     293             : 
     294             :   // An adapter to the audio queue which first copies data to buffers with
     295             :   // minimal allocation slop and then pushes them to the queue.  This is
     296             :   // useful for decoders working with formats that give awkward numbers of
     297             :   // frames such as mp3.
     298             :   AudioCompactor mAudioCompactor;
     299             : 
     300             :   // Reference to the owning decoder object.
     301             :   AbstractMediaDecoder* mDecoder;
     302             : 
     303             :   // Decode task queue.
     304             :   RefPtr<TaskQueue> mTaskQueue;
     305             : 
     306             :   // Buffered range.
     307             :   Canonical<media::TimeIntervals> mBuffered;
     308             : 
     309             :   // Stores presentation info required for playback.
     310             :   MediaInfo mInfo;
     311             : 
     312             :   media::NullableTimeUnit mDuration;
     313             : 
     314             :   // Whether we should accept media that we know we can't play
     315             :   // directly, because they have a number of channel higher than
     316             :   // what we support.
     317             :   bool mIgnoreAudioOutputFormat;
     318             : 
     319             :   // This is a quick-and-dirty way for DecodeAudioData implementations to
     320             :   // communicate the presence of a decoding error to RequestAudioData. We should
     321             :   // replace this with a promise-y mechanism as we make this stuff properly
     322             :   // async.
     323             :   bool mHitAudioDecodeError;
     324             :   bool mShutdown;
     325             : 
     326             :   // Used to send TimedMetadata to the listener.
     327             :   TimedMetadataEventProducer mTimedMetadataEvent;
     328             : 
     329             :   // Notify if this media is not seekable.
     330             :   MediaEventProducer<void> mOnMediaNotSeekable;
     331             : 
     332             :   // Notify if we are waiting for a decryption key.
     333             :   MediaEventProducer<TrackInfo::TrackType> mOnTrackWaitingForKey;
     334             : 
     335             :   RefPtr<MediaResource> mResource;
     336             : 
     337             : private:
     338           0 :   virtual nsresult InitInternal() { return NS_OK; }
     339             : 
     340             :   // Read header data for all bitstreams in the file. Fills aInfo with
     341             :   // the data required to present the media, and optionally fills *aTags
     342             :   // with tag metadata from the file.
     343             :   // Returns NS_OK on success, or NS_ERROR_FAILURE on failure.
     344           0 :   virtual nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
     345             :   {
     346           0 :     MOZ_CRASH();
     347             :   }
     348             : 
     349             :   virtual void VisibilityChanged();
     350             : 
     351             :   // Overrides of this function should decodes an unspecified amount of
     352             :   // audio data, enqueuing the audio data in mAudioQueue. Returns true
     353             :   // when there's more audio to decode, false if the audio is finished,
     354             :   // end of file has been reached, or an un-recoverable read error has
     355             :   // occured. This function blocks until the decode is complete.
     356           0 :   virtual bool DecodeAudioData()
     357             :   {
     358           0 :     return false;
     359             :   }
     360             : 
     361             :   // Overrides of this function should read and decodes one video frame.
     362             :   // Packets with a timestamp less than aTimeThreshold will be decoded
     363             :   // (unless they're not keyframes and aKeyframeSkip is true), but will
     364             :   // not be added to the queue. This function blocks until the decode
     365             :   // is complete.
     366           0 :   virtual bool DecodeVideoFrame(bool& aKeyframeSkip,
     367             :                                 const media::TimeUnit& aTimeThreshold)
     368             :   {
     369           0 :     return false;
     370             :   }
     371             : 
     372             :   // GetBuffered estimates the time ranges buffered by interpolating the cached
     373             :   // byte ranges with the duration of the media. Reader subclasses should
     374             :   // override this method if they can quickly calculate the buffered ranges more
     375             :   // accurately.
     376             :   //
     377             :   // The primary advantage of this implementation in the reader base class is
     378             :   // that it's a fast approximation, which does not perform any I/O.
     379             :   media::TimeIntervals GetBuffered();
     380             : 
     381             :   // Promises used only for the base-class (sync->async adapter) implementation
     382             :   // of Request{Audio,Video}Data.
     383             :   MozPromiseHolder<AudioDataPromise> mBaseAudioPromise;
     384             :   MozPromiseHolder<VideoDataPromise> mBaseVideoPromise;
     385             : };
     386             : 
     387             : } // namespace mozilla
     388             : 
     389             : #endif

Generated by: LCOV version 1.13