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 7 #ifndef VideoSink_h_ 8 #define VideoSink_h_ 9 10 #include "FrameStatistics.h" 11 #include "ImageContainer.h" 12 #include "MediaEventSource.h" 13 #include "MediaSink.h" 14 #include "MediaTimer.h" 15 #include "mozilla/AbstractThread.h" 16 #include "mozilla/MozPromise.h" 17 #include "mozilla/RefPtr.h" 18 #include "mozilla/TimeStamp.h" 19 #include "VideoFrameContainer.h" 20 21 namespace mozilla { 22 23 class VideoFrameContainer; 24 template <class T> class MediaQueue; 25 26 namespace media { 27 28 class VideoSink : public MediaSink 29 { 30 typedef mozilla::layers::ImageContainer::ProducerID ProducerID; 31 public: 32 VideoSink(AbstractThread* aThread, 33 MediaSink* aAudioSink, 34 MediaQueue<MediaData>& aVideoQueue, 35 VideoFrameContainer* aContainer, 36 FrameStatistics& aFrameStats, 37 uint32_t aVQueueSentToCompositerSize); 38 39 const PlaybackParams& GetPlaybackParams() const override; 40 41 void SetPlaybackParams(const PlaybackParams& aParams) override; 42 43 RefPtr<GenericPromise> OnEnded(TrackType aType) override; 44 45 int64_t GetEndTime(TrackType aType) const override; 46 47 int64_t GetPosition(TimeStamp* aTimeStamp = nullptr) const override; 48 49 bool HasUnplayedFrames(TrackType aType) const override; 50 51 void SetPlaybackRate(double aPlaybackRate) override; 52 53 void SetVolume(double aVolume) override; 54 55 void SetPreservesPitch(bool aPreservesPitch) override; 56 57 void SetPlaying(bool aPlaying) override; 58 59 void Redraw(const VideoInfo& aInfo) override; 60 61 void Start(int64_t aStartTime, const MediaInfo& aInfo) override; 62 63 void Stop() override; 64 65 bool IsStarted() const override; 66 67 bool IsPlaying() const override; 68 69 void Shutdown() override; 70 71 void DumpDebugInfo() override; 72 73 private: 74 virtual ~VideoSink(); 75 76 // VideoQueue listener related. 77 void OnVideoQueuePushed(RefPtr<MediaData>&& aSample); 78 void OnVideoQueueFinished(); 79 void ConnectListener(); 80 void DisconnectListener(); 81 82 // Sets VideoQueue images into the VideoFrameContainer. Called on the shared 83 // state machine thread. The first aMaxFrames (at most) are set. 84 // aClockTime and aClockTimeStamp are used as the baseline for deriving 85 // timestamps for the frames; when omitted, aMaxFrames must be 1 and 86 // a null timestamp is passed to the VideoFrameContainer. 87 // If the VideoQueue is empty, this does nothing. 88 void RenderVideoFrames(int32_t aMaxFrames, int64_t aClockTime = 0, 89 const TimeStamp& aClickTimeStamp = TimeStamp()); 90 91 // Triggered while videosink is started, videosink becomes "playing" status, 92 // or VideoQueue event arrived. 93 void TryUpdateRenderedVideoFrames(); 94 95 // If we have video, display a video frame if it's time for display has 96 // arrived, otherwise sleep until it's time for the next frame. Update the 97 // current frame time as appropriate, and trigger ready state update. 98 // Called on the shared state machine thread. 99 void UpdateRenderedVideoFrames(); 100 void UpdateRenderedVideoFramesByTimer(); 101 102 void MaybeResolveEndPromise(); 103 AssertOwnerThread()104 void AssertOwnerThread() const 105 { 106 MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn()); 107 } 108 VideoQueue()109 MediaQueue<MediaData>& VideoQueue() const { 110 return mVideoQueue; 111 } 112 113 const RefPtr<AbstractThread> mOwnerThread; 114 RefPtr<MediaSink> mAudioSink; 115 MediaQueue<MediaData>& mVideoQueue; 116 VideoFrameContainer* mContainer; 117 118 // Producer ID to help ImageContainer distinguish different streams of 119 // FrameIDs. A unique and immutable value per VideoSink. 120 const ProducerID mProducerID; 121 122 // Used to notify MediaDecoder's frame statistics 123 FrameStatistics& mFrameStats; 124 125 RefPtr<GenericPromise> mEndPromise; 126 MozPromiseHolder<GenericPromise> mEndPromiseHolder; 127 MozPromiseRequestHolder<GenericPromise> mVideoSinkEndRequest; 128 129 // The presentation end time of the last video frame which has been displayed 130 // in microseconds. 131 int64_t mVideoFrameEndTime; 132 133 // Event listeners for VideoQueue 134 MediaEventListener mPushListener; 135 MediaEventListener mFinishListener; 136 137 // True if this sink is going to handle video track. 138 bool mHasVideo; 139 140 // Used to trigger another update of rendered frames in next round. 141 DelayedScheduler mUpdateScheduler; 142 143 // Max frame number sent to compositor at a time. 144 // Based on the pref value obtained in MDSM. 145 const uint32_t mVideoQueueSendToCompositorSize; 146 147 // Talos tests for the compositor require at least one frame in the 148 // video queue so that the compositor has something to composit during 149 // the talos test when the decode is stressed. We have a minimum size 150 // on the video queue in order to facilitate this talos test. 151 // Note: Normal playback should not have a queue size of more than 0, 152 // otherwise A/V sync will be ruined! *Only* make this non-zero for 153 // testing purposes. 154 const uint32_t mMinVideoQueueSize; 155 }; 156 157 } // namespace media 158 } // namespace mozilla 159 160 #endif 161