VideoSink.h (5667B)
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 "VideoFrameContainer.h" 16 #include "mozilla/AbstractThread.h" 17 #include "mozilla/MozPromise.h" 18 #include "mozilla/RefPtr.h" 19 #include "mozilla/TimeStamp.h" 20 21 namespace mozilla { 22 23 class VideoFrameContainer; 24 template <class T> 25 class MediaQueue; 26 27 class VideoSink : public MediaSink { 28 typedef mozilla::layers::ImageContainer::ProducerID ProducerID; 29 30 public: 31 VideoSink(AbstractThread* aThread, MediaSink* aAudioSink, 32 MediaQueue<VideoData>& aVideoQueue, VideoFrameContainer* aContainer, 33 FrameStatistics& aFrameStats, uint32_t aVQueueSentToCompositerSize); 34 35 RefPtr<EndedPromise> OnEnded(TrackType aType) override; 36 37 media::TimeUnit GetEndTime(TrackType aType) const override; 38 39 media::TimeUnit GetPosition(TimeStamp* aTimeStamp = nullptr) override; 40 41 bool HasUnplayedFrames(TrackType aType) const override; 42 media::TimeUnit UnplayedDuration(TrackType aType) const override; 43 44 void SetPlaybackRate(double aPlaybackRate) override; 45 46 void SetVolume(double aVolume) override; 47 48 void SetStreamName(const nsAString& aStreamName) override; 49 50 void SetPreservesPitch(bool aPreservesPitch) override; 51 52 void SetPlaying(bool aPlaying) override; 53 54 RefPtr<GenericPromise> SetAudioDevice( 55 RefPtr<AudioDeviceInfo> aDevice) override; 56 57 double PlaybackRate() const override; 58 59 void Redraw(const VideoInfo& aInfo) override; 60 61 nsresult Start(const media::TimeUnit& aStartTime, 62 const MediaInfo& aInfo) override; 63 64 void Stop() override; 65 66 bool IsStarted() const override; 67 68 bool IsPlaying() const override; 69 70 void Shutdown() override; 71 72 void SetSecondaryVideoContainer(VideoFrameContainer* aSecondary) override; 73 74 void GetDebugInfo(dom::MediaSinkDebugInfo& aInfo) override; 75 76 void SetVideoQueueSendToCompositorSize(const uint32_t aSize) override { 77 mVideoQueueSendToCompositorSize = aSize; 78 } 79 80 private: 81 virtual ~VideoSink(); 82 83 // VideoQueue listener related. 84 void OnVideoQueuePushed(const RefPtr<VideoData>& aSample); 85 void OnVideoQueueFinished(); 86 void ConnectListener(); 87 void DisconnectListener(); 88 89 void EnsureHighResTimersOnOnlyIfPlaying(); 90 91 // Sets images and frame dimensions into the VideoFrameContainer. Called on 92 // the shared state machine thread. 93 // aClockTime and aClockTimeStamp are used as the baseline for deriving 94 // timestamps for the frames. 95 // If aFrames is empty, this does nothing. 96 void RenderVideoFrames(Span<const RefPtr<VideoData>> aFrames, 97 int64_t aClockTime, const TimeStamp& aClockTimeStamp); 98 99 // Triggered while videosink is started, videosink becomes "playing" status, 100 // or VideoQueue event arrived. 101 void TryUpdateRenderedVideoFrames(); 102 103 // If we have video, display a video frame if it's time for display has 104 // arrived, otherwise sleep until it's time for the next frame. Update the 105 // current frame time as appropriate, and trigger ready state update. 106 // Called on the shared state machine thread. 107 void UpdateRenderedVideoFrames(); 108 void UpdateRenderedVideoFramesByTimer(); 109 110 void MaybeResolveEndPromise(); 111 112 void AssertOwnerThread() const { 113 MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn()); 114 } 115 116 MediaQueue<VideoData>& VideoQueue() const { return mVideoQueue; } 117 118 const RefPtr<AbstractThread> mOwnerThread; 119 const RefPtr<MediaSink> mAudioSink; 120 MediaQueue<VideoData>& mVideoQueue; 121 VideoFrameContainer* mContainer; 122 RefPtr<VideoFrameContainer> mSecondaryContainer; 123 124 // Producer ID to help ImageContainer distinguish different streams of 125 // FrameIDs. A unique and immutable value per VideoSink. 126 const ProducerID mProducerID; 127 128 // Used to notify MediaDecoder's frame statistics 129 FrameStatistics& mFrameStats; 130 131 RefPtr<EndedPromise> mEndPromise; 132 MozPromiseHolder<EndedPromise> mEndPromiseHolder; 133 MozPromiseRequestHolder<EndedPromise> mVideoSinkEndRequest; 134 135 // The presentation end time of the last video frame which has been displayed. 136 media::TimeUnit mVideoFrameEndTime; 137 138 // Total duration of sequential frames that have been dropped in this sink 139 // without any sent to the compositor 140 media::TimeUnit mDroppedInSinkSequenceDuration; 141 // Accounting for frames dropped in the compositor 142 uint32_t mOldCompositorDroppedCount; 143 uint32_t mPendingDroppedCount; 144 145 // Event listeners for VideoQueue 146 MediaEventListener mPushListener; 147 MediaEventListener mFinishListener; 148 149 // True if this sink is going to handle video track. 150 bool mHasVideo; 151 152 // Used to trigger another update of rendered frames in next round. 153 DelayedScheduler<TimeStamp> mUpdateScheduler; 154 155 // Max frame number sent to compositor at a time. 156 // Based on the value obtained in MDSM. 157 uint32_t mVideoQueueSendToCompositorSize; 158 159 #ifdef XP_WIN 160 // Whether we've called timeBeginPeriod(1) to request high resolution 161 // timers. We request high resolution timers when playback starts, and 162 // turn them off when playback is paused. Enabling high resolution 163 // timers can cause higher CPU usage and battery drain on Windows 7, 164 // but reduces our frame drop rate. 165 bool mHiResTimersRequested; 166 #endif 167 168 RefPtr<layers::Image> mBlankImage; 169 bool InitializeBlankImage(); 170 }; 171 172 } // namespace mozilla 173 174 #endif