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