Fix FullScreen crash in Webapp
[platform/framework/web/chromium-efl.git] / media / remoting / courier_renderer.h
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MEDIA_REMOTING_COURIER_RENDERER_H_
6 #define MEDIA_REMOTING_COURIER_RENDERER_H_
7
8 #include <memory>
9 #include <tuple>
10 #include <utility>
11
12 #include "base/containers/circular_deque.h"
13 #include "base/functional/callback.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/memory/scoped_refptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/synchronization/lock.h"
18 #include "base/task/sequenced_task_runner.h"
19 #include "base/task/single_thread_task_runner.h"
20 #include "base/time/time.h"
21 #include "base/timer/timer.h"
22 #include "media/base/pipeline_status.h"
23 #include "media/base/renderer.h"
24 #include "media/mojo/mojom/remoting.mojom.h"
25 #include "media/remoting/metrics.h"
26 #include "mojo/public/cpp/bindings/pending_remote.h"
27 #include "mojo/public/cpp/system/data_pipe.h"
28 #include "third_party/abseil-cpp/absl/types/optional.h"
29 #include "third_party/openscreen/src/cast/streaming/remoting.pb.h"
30 #include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
31 #include "third_party/openscreen/src/util/weak_ptr.h"
32
33 namespace media {
34
35 class RendererClient;
36 class VideoRendererSink;
37
38 namespace remoting {
39
40 class DemuxerStreamAdapter;
41 class RendererController;
42
43 // A media::Renderer implementation that proxies all operations to a remote
44 // renderer via RPCs. The CourierRenderer is instantiated by
45 // AdaptiveRendererFactory when media remoting is meant to take place.
46 class CourierRenderer final : public Renderer {
47  public:
48   // The whole class except for constructor and GetMediaTime() runs on
49   // |media_task_runner|. The constructor and GetMediaTime() run on render main
50   // thread.
51   CourierRenderer(scoped_refptr<base::SequencedTaskRunner> media_task_runner,
52                   const base::WeakPtr<RendererController>& controller,
53                   VideoRendererSink* video_renderer_sink);
54
55   CourierRenderer(const CourierRenderer&) = delete;
56   CourierRenderer& operator=(const CourierRenderer&) = delete;
57
58   ~CourierRenderer() final;
59
60  private:
61   // Callback when attempting to establish data pipe. The function is set to
62   // static in order to post task to media thread in order to avoid threading
63   // race condition.
64   static void OnDataPipeCreatedOnMainThread(
65       scoped_refptr<base::SequencedTaskRunner> media_task_runner,
66       base::WeakPtr<CourierRenderer> self,
67       openscreen::WeakPtr<openscreen::cast::RpcMessenger> rpc_messenger,
68       mojo::PendingRemote<mojom::RemotingDataStreamSender> audio,
69       mojo::PendingRemote<mojom::RemotingDataStreamSender> video,
70       mojo::ScopedDataPipeProducerHandle audio_handle,
71       mojo::ScopedDataPipeProducerHandle video_handle);
72
73   // Callback function when RPC message is received. The function is set to
74   // static in order to post task to media thread in order to avoid threading
75   // race condition.
76   static void OnMessageReceivedOnMainThread(
77       scoped_refptr<base::SequencedTaskRunner> media_task_runner,
78       base::WeakPtr<CourierRenderer> self,
79       std::unique_ptr<openscreen::cast::RpcMessage> message);
80
81  public:
82   // media::Renderer implementation.
83   void Initialize(MediaResource* media_resource,
84                   RendererClient* client,
85                   PipelineStatusCallback init_cb) final;
86   void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) final;
87   void Flush(base::OnceClosure flush_cb) final;
88   void StartPlayingFrom(base::TimeDelta time) final;
89   void SetPlaybackRate(double playback_rate) final;
90   void SetVolume(float volume) final;
91   base::TimeDelta GetMediaTime() final;
92   RendererType GetRendererType() final;
93
94  private:
95   friend class CourierRendererTest;
96
97   enum State {
98     STATE_UNINITIALIZED,
99     STATE_CREATE_PIPE,
100     STATE_ACQUIRING,
101     STATE_INITIALIZING,
102     STATE_FLUSHING,
103     STATE_PLAYING,
104     STATE_ERROR
105   };
106
107   // Callback when attempting to establish data pipe. Runs on media thread only.
108   void OnDataPipeCreated(
109       mojo::PendingRemote<mojom::RemotingDataStreamSender> audio,
110       mojo::PendingRemote<mojom::RemotingDataStreamSender> video,
111       mojo::ScopedDataPipeProducerHandle audio_handle,
112       mojo::ScopedDataPipeProducerHandle video_handle,
113       int audio_rpc_handle,
114       int video_rpc_handle);
115
116   // Callback function when RPC message is received. Runs on media thread only.
117   void OnReceivedRpc(std::unique_ptr<openscreen::cast::RpcMessage> message);
118
119   // Function to post task to main thread in order to send RPC message.
120   void SendRpcToRemote(std::unique_ptr<openscreen::cast::RpcMessage> message);
121
122   // Functions when RPC message is received.
123   void AcquireRendererDone(
124       std::unique_ptr<openscreen::cast::RpcMessage> message);
125   void InitializeCallback(
126       std::unique_ptr<openscreen::cast::RpcMessage> message);
127   void FlushUntilCallback();
128   void OnTimeUpdate(std::unique_ptr<openscreen::cast::RpcMessage> message);
129   void OnBufferingStateChange(
130       std::unique_ptr<openscreen::cast::RpcMessage> message);
131   void OnAudioConfigChange(
132       std::unique_ptr<openscreen::cast::RpcMessage> message);
133   void OnVideoConfigChange(
134       std::unique_ptr<openscreen::cast::RpcMessage> message);
135   void OnVideoNaturalSizeChange(
136       std::unique_ptr<openscreen::cast::RpcMessage> message);
137   void OnVideoOpacityChange(
138       std::unique_ptr<openscreen::cast::RpcMessage> message);
139   void OnStatisticsUpdate(
140       std::unique_ptr<openscreen::cast::RpcMessage> message);
141
142   // Called when |current_media_time_| is updated.
143   void OnMediaTimeUpdated();
144
145   // Called to update the |video_stats_queue_|.
146   void UpdateVideoStatsQueue(int video_frames_decoded,
147                              int video_frames_dropped);
148
149   // Called to clear all recent measurements history and schedule resuming after
150   // a stabilization period elapses.
151   void ResetMeasurements();
152
153   // Called when a fatal runtime error occurs. |stop_trigger| is the error code
154   // handed to the RendererController.
155   void OnFatalError(StopTrigger stop_trigger);
156
157   // Called periodically to measure the data flows from the
158   // DemuxerStreamAdapters and record this information in the metrics.
159   void MeasureAndRecordDataRates();
160
161   // Helper to check whether is waiting for data from the Demuxers while
162   // receiver is waiting for buffering. If yes, remoting will be continued even
163   // though the playback might be delayed or paused.
164   bool IsWaitingForDataFromDemuxers() const;
165
166   // Helpers to register/deregister the renderer with the RPC messenger. These
167   // must be called on the media thread to dereference the weak pointer to
168   // this, which if contains a valid RPC messenger pointer will result in a
169   // jump to the main thread.
170   void RegisterForRpcMessaging();
171   void DeregisterFromRpcMessaging();
172
173   State state_;
174   const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
175   const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
176
177   // Current renderer playback time information.
178   base::TimeDelta current_media_time_;
179   base::TimeDelta current_max_time_;
180   // Both |current_media_time_| and |current_max_time_| should be protected by
181   // lock because it can be accessed from both media and render main thread.
182   base::Lock time_lock_;
183
184   raw_ptr<MediaResource> media_resource_;
185   raw_ptr<RendererClient> client_;
186   std::unique_ptr<DemuxerStreamAdapter> audio_demuxer_stream_adapter_;
187   std::unique_ptr<DemuxerStreamAdapter> video_demuxer_stream_adapter_;
188
189   // Component to establish mojo remoting service on browser process.
190   const base::WeakPtr<RendererController> controller_;
191
192   // Broker class to process incoming and outgoing RPC messages.
193   // Only accessed on |main_task_runner_|. NOTE: the messenger is wrapped
194   // in an |openscreen::WeakPtr| instead of |base|'s implementation due to
195   // it being defined in the third_party/openscreen repository.
196   const openscreen::WeakPtr<openscreen::cast::RpcMessenger> rpc_messenger_;
197
198   // RPC handle value for CourierRenderer component.
199   const int rpc_handle_;
200
201   // RPC handle value for render on receiver endpoint.
202   int remote_renderer_handle_;
203
204   // Callbacks.
205   PipelineStatusCallback init_workflow_done_callback_;
206   base::OnceClosure flush_cb_;
207
208   const raw_ptr<VideoRendererSink>
209       video_renderer_sink_;  // Outlives this class.
210
211   // Current playback rate.
212   double playback_rate_ = 0;
213
214   // Current volume.
215   float volume_ = 1.0f;
216
217   // Ignores updates until this time.
218   base::TimeTicks ignore_updates_until_time_;
219
220   // Indicates whether stats has been updated.
221   bool stats_updated_ = false;
222
223   // Stores all |current_media_time_| and the local time when updated in the
224   // moving time window. This is used to check whether the playback duration
225   // matches the update duration in the window.
226   base::circular_deque<std::pair<base::TimeTicks, base::TimeDelta>>
227       media_time_queue_;
228
229   // Stores all updates on the number of video frames decoded/dropped, and the
230   // local time when updated in the moving time window. This is used to check
231   // whether too many video frames were dropped.
232   base::circular_deque<std::tuple<base::TimeTicks, int, int>>
233       video_stats_queue_;
234
235   // The total number of frames decoded/dropped in the time window.
236   int sum_video_frames_decoded_ = 0;
237   int sum_video_frames_dropped_ = 0;
238
239   // Records the number of consecutive times that remoting playback was delayed.
240   int times_playback_delayed_ = 0;
241
242   // Records events and measurements of interest.
243   RendererMetricsRecorder metrics_recorder_;
244
245   raw_ptr<const base::TickClock> clock_;
246
247   // A timer that polls the DemuxerStreamAdapters periodically to measure
248   // the data flow rates for metrics.
249   base::RepeatingTimer data_flow_poll_timer_;
250
251   // Indicates whether is waiting for data from the Demuxers while receiver
252   // reported buffer underflow.
253   bool receiver_is_blocked_on_local_demuxers_ = true;
254
255   base::WeakPtrFactory<CourierRenderer> weak_factory_{this};
256 };
257
258 }  // namespace remoting
259 }  // namespace media
260
261 #endif  // MEDIA_REMOTING_COURIER_RENDERER_H_