1 // Copyright 2017 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.
5 #include "media/remoting/receiver.h"
9 #include "base/functional/bind.h"
10 #include "base/functional/callback.h"
11 #include "base/notreached.h"
12 #include "base/task/bind_post_task.h"
13 #include "base/task/sequenced_task_runner.h"
14 #include "base/task/single_thread_task_runner.h"
15 #include "media/base/decoder_buffer.h"
16 #include "media/base/renderer.h"
17 #include "media/cast/openscreen/remoting_message_factories.h"
18 #include "media/cast/openscreen/remoting_proto_enum_utils.h"
19 #include "media/cast/openscreen/remoting_proto_utils.h"
20 #include "media/remoting/receiver_controller.h"
21 #include "media/remoting/stream_provider.h"
23 using openscreen::cast::RpcMessenger;
29 // The period to send the TimeUpdate RPC message to update the media time on
31 constexpr base::TimeDelta kTimeUpdateInterval = base::Milliseconds(250);
38 ReceiverController* receiver_controller,
39 const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
40 std::unique_ptr<Renderer> renderer,
41 base::OnceCallback<void(int)> acquire_renderer_done_cb)
42 : rpc_handle_(rpc_handle),
43 remote_handle_(remote_handle),
44 receiver_controller_(receiver_controller),
45 rpc_messenger_(receiver_controller_->rpc_messenger()),
46 main_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
47 media_task_runner_(media_task_runner),
48 renderer_(std::move(renderer)),
49 acquire_renderer_done_cb_(std::move(acquire_renderer_done_cb)) {
50 DCHECK(rpc_handle_ != RpcMessenger::kInvalidHandle);
51 DCHECK(receiver_controller_);
52 DCHECK(rpc_messenger_);
55 // Note: The constructor is running on the main thread, but will be destroyed
56 // on the media thread. Therefore, all weak pointers must be dereferenced on
58 auto receive_callback = base::BindPostTask(
60 BindRepeating(&Receiver::OnReceivedRpc, weak_factory_.GetWeakPtr()));
62 // Listening all renderer rpc messages.
63 rpc_messenger_->RegisterMessageReceiverCallback(
64 rpc_handle_, [cb = std::move(receive_callback)](
65 std::unique_ptr<openscreen::cast::RpcMessage> message) {
66 cb.Run(std::move(message));
69 VerifyAcquireRendererDone();
72 Receiver::~Receiver() {
73 rpc_messenger_->UnregisterMessageReceiverCallback(rpc_handle_);
76 // Receiver::Initialize() will be called by the local pipeline, it would only
77 // keep the |init_cb| in order to continue the initialization once it receives
78 // RPC_R_INITIALIZE, which means Receiver::OnRpcInitialize() is called.
79 void Receiver::Initialize(MediaResource* media_resource,
80 RendererClient* client,
81 PipelineStatusCallback init_cb) {
82 demuxer_ = media_resource;
83 init_cb_ = std::move(init_cb);
84 ShouldInitializeRenderer();
87 /* CDM is not supported for remoting media */
88 void Receiver::SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) {
92 // No-op. Controlled by sender via RPC calls instead.
93 void Receiver::SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) {}
95 // No-op. Controlled by sender via RPC calls instead.
96 void Receiver::Flush(base::OnceClosure flush_cb) {}
98 // No-op. Controlled by sender via RPC calls instead.
99 void Receiver::StartPlayingFrom(base::TimeDelta time) {}
101 // No-op. Controlled by sender via RPC calls instead.
102 void Receiver::SetPlaybackRate(double playback_rate) {}
104 // No-op. Controlled by sender via RPC calls instead.
105 void Receiver::SetVolume(float volume) {}
107 // No-op. Controlled by sender via RPC calls instead.
108 base::TimeDelta Receiver::GetMediaTime() {
109 return base::TimeDelta();
112 RendererType Receiver::GetRendererType() {
113 return RendererType::kRemoting;
116 void Receiver::SendRpcMessageOnMainThread(
117 std::unique_ptr<openscreen::cast::RpcMessage> message) {
118 // |rpc_messenger_| is owned by |receiver_controller_| which is a singleton
119 // per process, so it's safe to use Unretained() here.
120 main_task_runner_->PostTask(
121 FROM_HERE, base::BindOnce(&RpcMessenger::SendMessageToRemote,
122 base::Unretained(rpc_messenger_), *message));
125 void Receiver::OnReceivedRpc(
126 std::unique_ptr<openscreen::cast::RpcMessage> message) {
127 DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
130 media::cast::DispatchRendererRpcCall(message.get(), this);
133 void Receiver::SetRemoteHandle(int remote_handle) {
134 DCHECK_NE(remote_handle, RpcMessenger::kInvalidHandle);
135 DCHECK_EQ(remote_handle_, RpcMessenger::kInvalidHandle);
136 remote_handle_ = remote_handle;
137 VerifyAcquireRendererDone();
140 void Receiver::VerifyAcquireRendererDone() {
141 if (remote_handle_ == RpcMessenger::kInvalidHandle)
144 DCHECK(acquire_renderer_done_cb_);
145 std::move(acquire_renderer_done_cb_).Run(rpc_handle_);
148 void Receiver::OnRpcInitialize() {
150 rpc_initialize_received_ = true;
151 ShouldInitializeRenderer();
154 void Receiver::ShouldInitializeRenderer() {
155 // ShouldInitializeRenderer() will be called from Initialize() and
156 // OnRpcInitialize() in different orders.
158 // |renderer_| must be initialized when both Initialize() and
159 // OnRpcInitialize() are called.
160 if (!rpc_initialize_received_ || !init_cb_)
163 DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
166 renderer_->Initialize(demuxer_, this,
167 base::BindOnce(&Receiver::OnRendererInitialized,
168 weak_factory_.GetWeakPtr()));
171 void Receiver::OnRendererInitialized(PipelineStatus status) {
172 DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
174 std::move(init_cb_).Run(status);
176 auto rpc = media::cast::CreateMessageForInitializationComplete(status ==
178 rpc->set_handle(remote_handle_);
179 SendRpcMessageOnMainThread(std::move(rpc));
182 void Receiver::OnRpcSetPlaybackRate(double playback_rate) {
183 DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
185 renderer_->SetPlaybackRate(playback_rate);
187 if (playback_rate == 0.0) {
188 if (time_update_timer_.IsRunning()) {
189 time_update_timer_.Stop();
190 // Send one final media time update since the sender will not get any
191 // until playback resumes.
192 SendMediaTimeUpdate();
195 ScheduleMediaTimeUpdates();
199 void Receiver::OnRpcFlush(uint32_t audio_count, uint32_t video_count) {
200 DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
202 receiver_controller_->OnRendererFlush(audio_count, video_count);
204 time_update_timer_.Stop();
206 base::BindOnce(&Receiver::OnFlushDone, weak_factory_.GetWeakPtr()));
209 void Receiver::OnFlushDone() {
210 auto rpc = media::cast::CreateMessageForFlushComplete();
211 rpc->set_handle(remote_handle_);
212 SendRpcMessageOnMainThread(std::move(rpc));
215 void Receiver::OnRpcStartPlayingFrom(base::TimeDelta time) {
216 DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
218 renderer_->StartPlayingFrom(time);
219 ScheduleMediaTimeUpdates();
222 void Receiver::ScheduleMediaTimeUpdates() {
223 if (time_update_timer_.IsRunning())
225 SendMediaTimeUpdate();
226 time_update_timer_.Start(FROM_HERE, kTimeUpdateInterval,
227 base::BindRepeating(&Receiver::SendMediaTimeUpdate,
228 weak_factory_.GetWeakPtr()));
231 void Receiver::OnRpcSetVolume(double volume) {
232 DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
233 renderer_->SetVolume(volume);
236 void Receiver::SendMediaTimeUpdate() {
237 // Issues RPC_RC_ONTIMEUPDATE RPC message.
239 media::cast::CreateMessageForMediaTimeUpdate(renderer_->GetMediaTime());
240 rpc->set_handle(remote_handle_);
241 SendRpcMessageOnMainThread(std::move(rpc));
244 void Receiver::OnError(PipelineStatus status) {
245 auto rpc = media::cast::CreateMessageForError();
246 rpc->set_handle(remote_handle_);
247 SendRpcMessageOnMainThread(std::move(rpc));
250 void Receiver::OnFallback(PipelineStatus status) {
254 void Receiver::OnEnded() {
255 auto rpc = media::cast::CreateMessageForMediaEnded();
256 rpc->set_handle(remote_handle_);
257 SendRpcMessageOnMainThread(std::move(rpc));
258 time_update_timer_.Stop();
261 void Receiver::OnStatisticsUpdate(const PipelineStatistics& stats) {
262 auto rpc = media::cast::CreateMessageForStatisticsUpdate(stats);
263 rpc->set_handle(remote_handle_);
264 SendRpcMessageOnMainThread(std::move(rpc));
267 void Receiver::OnBufferingStateChange(BufferingState state,
268 BufferingStateChangeReason reason) {
269 auto rpc = media::cast::CreateMessageForBufferingStateChange(state);
270 rpc->set_handle(remote_handle_);
271 SendRpcMessageOnMainThread(std::move(rpc));
274 void Receiver::OnWaiting(WaitingReason reason) {
275 // Media Remoting has not implemented this concept.
279 void Receiver::OnAudioConfigChange(const AudioDecoderConfig& config) {
280 auto rpc = media::cast::CreateMessageForAudioConfigChange(config);
281 rpc->set_handle(remote_handle_);
282 SendRpcMessageOnMainThread(std::move(rpc));
285 void Receiver::OnVideoConfigChange(const VideoDecoderConfig& config) {
286 auto rpc = media::cast::CreateMessageForVideoConfigChange(config);
287 rpc->set_handle(remote_handle_);
288 SendRpcMessageOnMainThread(std::move(rpc));
291 void Receiver::OnVideoNaturalSizeChange(const gfx::Size& size) {
292 auto rpc = media::cast::CreateMessageForVideoNaturalSizeChange(size);
293 rpc->set_handle(remote_handle_);
294 SendRpcMessageOnMainThread(std::move(rpc));
297 receiver_controller_->OnVideoNaturalSizeChange(size);
300 void Receiver::OnVideoOpacityChange(bool opaque) {
301 auto rpc = media::cast::CreateMessageForVideoOpacityChange(opaque);
302 rpc->set_handle(remote_handle_);
303 SendRpcMessageOnMainThread(std::move(rpc));
306 void Receiver::OnVideoFrameRateChange(absl::optional<int>) {}
308 } // namespace remoting