OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "media/remoting/remote_receiver.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/callback.h" | |
9 #include "media/base/decoder_buffer.h" | |
10 #include "media/base/renderer.h" | |
11 #include "media/remoting/proto_enum_utils.h" | |
12 #include "media/remoting/remote_stream_provider.h" | |
13 | |
14 namespace media { | |
15 namespace remoting { | |
16 namespace { | |
17 | |
18 // The period to send the TimeUpdate RPC message to update the media time on | |
19 // sender side. | |
20 constexpr base::TimeDelta kTimeUpdateInterval = | |
21 base::TimeDelta::FromMilliseconds(250); | |
22 | |
23 } // namespace | |
24 | |
25 RemoteReceiver::RemoteReceiver(std::unique_ptr<Renderer> renderer, | |
26 RpcBroker* rpc_broker) | |
27 : renderer_(std::move(renderer)), | |
28 rpc_broker_(rpc_broker), | |
29 rpc_handle_(rpc_broker_->GetUniqueHandle()), | |
30 weak_factory_(this) { | |
31 DCHECK(renderer_); | |
32 DCHECK(rpc_broker_); | |
33 rpc_broker_->RegisterMessageReceiverCallback( | |
34 rpc_handle_, | |
35 base::Bind(&RemoteReceiver::OnReceivedRpc, weak_factory_.GetWeakPtr())); | |
36 rpc_broker_->RegisterMessageReceiverCallback( | |
37 RpcBroker::kAcquireHandle, | |
38 base::Bind(&RemoteReceiver::OnReceivedRpc, weak_factory_.GetWeakPtr())); | |
39 } | |
40 | |
41 RemoteReceiver::~RemoteReceiver() { | |
42 rpc_broker_->UnregisterMessageReceiverCallback(rpc_handle_); | |
43 rpc_broker_->UnregisterMessageReceiverCallback(RpcBroker::kAcquireHandle); | |
44 } | |
45 | |
46 void RemoteReceiver::OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message) { | |
47 DCHECK(message); | |
48 switch (message->proc()) { | |
49 case pb::RpcMessage::RPC_ACQUIRE_RENDERER: | |
50 AcquireRenderer(std::move(message)); | |
51 break; | |
52 case pb::RpcMessage::RPC_R_FLUSHUNTIL: | |
53 FlushUntil(std::move(message)); | |
54 break; | |
55 case pb::RpcMessage::RPC_R_STARTPLAYINGFROM: | |
56 StartPlayingFrom(std::move(message)); | |
57 break; | |
58 case pb::RpcMessage::RPC_R_SETPLAYBACKRATE: | |
59 SetPlaybackRate(std::move(message)); | |
60 break; | |
61 case pb::RpcMessage::RPC_R_SETVOLUME: | |
62 SetVolume(std::move(message)); | |
63 break; | |
64 case pb::RpcMessage::RPC_R_INITIALIZE: | |
65 Initialize(std::move(message)); | |
66 break; | |
67 default: | |
68 VLOG(1) << __func__ << ": Unknow RPC message. proc=" << message->proc(); | |
69 } | |
70 } | |
71 | |
72 void RemoteReceiver::AcquireRenderer(std::unique_ptr<pb::RpcMessage> message) { | |
73 DVLOG(3) << __func__ << ": Receives RPC_ACQUIRE_RENDERER with remote_handle= " | |
74 << message->integer_value(); | |
75 | |
76 remote_handle_ = message->integer_value(); | |
77 stream_provider_.reset(new RemoteStreamProvider(rpc_broker_)); | |
miu
2017/03/29 01:39:13
if (stream_provider_) {
return acquire renderer
xjz
2017/03/30 23:21:30
We don't have a RPC for acquire failure. Called On
| |
78 | |
79 DVLOG(3) << __func__ | |
80 << ": Issues RPC_ACQUIRE_RENDERER_DONE RPC message. remote_handle=" | |
81 << remote_handle_ << " rpc_handle=" << rpc_handle_; | |
82 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
83 rpc->set_handle(remote_handle_); | |
84 rpc->set_proc(pb::RpcMessage::RPC_ACQUIRE_RENDERER_DONE); | |
85 rpc->set_integer_value(rpc_handle_); | |
86 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
87 } | |
88 | |
89 void RemoteReceiver::Initialize(std::unique_ptr<pb::RpcMessage> message) { | |
90 DCHECK(stream_provider_); | |
91 DVLOG(3) << __func__ << ": Receives RPC_R_INITIALIZE with callback handle= " | |
92 << message->renderer_initialize_rpc().callback_handle(); | |
93 DCHECK(message->renderer_initialize_rpc().callback_handle() == | |
94 remote_handle_); | |
95 stream_provider_->Initialize( | |
miu
2017/03/29 01:39:14
if (!stream_provider_) {
return initialize faile
xjz
2017/03/30 23:21:30
Done.
| |
96 message->renderer_initialize_rpc().audio_demuxer_handle(), | |
97 message->renderer_initialize_rpc().video_demuxer_handle(), | |
98 base::Bind(&RemoteReceiver::OnStreamInitialized, | |
99 weak_factory_.GetWeakPtr())); | |
100 } | |
101 | |
102 void RemoteReceiver::OnStreamInitialized() { | |
103 renderer_->Initialize(stream_provider_.get(), this, | |
miu
2017/03/29 01:39:13
DCHECK(stream_provider_);
xjz
2017/03/30 23:21:30
Done.
| |
104 base::Bind(&RemoteReceiver::OnRendererInitialized, | |
105 weak_factory_.GetWeakPtr())); | |
106 } | |
107 | |
108 void RemoteReceiver::OnRendererInitialized(PipelineStatus status) { | |
109 DVLOG(3) << __func__ << ": Issues RPC_R_INITIALIZE_CALLBACK RPC message." | |
110 << "remote_handle=" << remote_handle_; | |
111 | |
112 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
113 rpc->set_handle(remote_handle_); | |
114 rpc->set_proc(pb::RpcMessage::RPC_R_INITIALIZE_CALLBACK); | |
115 rpc->set_boolean_value(status == PIPELINE_OK); | |
116 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
117 } | |
118 | |
119 void RemoteReceiver::SetPlaybackRate(std::unique_ptr<pb::RpcMessage> message) { | |
120 playback_rate_ = message->double_value(); | |
miu
2017/03/29 01:39:14
Per comment in header file, instead of this, how a
xjz
2017/03/30 23:21:30
Done.
| |
121 DVLOG(3) << __func__ | |
122 << ": Receives RPC_R_SETPLAYBACKRATE with rate=" << playback_rate_; | |
123 renderer_->SetPlaybackRate(playback_rate_); | |
124 } | |
125 | |
126 void RemoteReceiver::FlushUntil(std::unique_ptr<pb::RpcMessage> message) { | |
127 DVLOG(3) << __func__ << ": Receives RPC_R_FLUSHUNTIL RPC message."; | |
128 | |
129 const pb::RendererFlushUntil flush_message = | |
130 message->renderer_flushuntil_rpc(); | |
131 DCHECK_EQ(flush_message.callback_handle(), remote_handle_); | |
132 if (flush_message.has_audio_count()) { | |
miu
2017/03/29 01:39:13
if (stream_provider_) {
if (flush_message.has_au
xjz
2017/03/30 23:21:30
Done.
| |
133 stream_provider_->FlushUntil(DemuxerStream::AUDIO, | |
134 flush_message.audio_count()); | |
135 } | |
136 if (flush_message.has_video_count()) { | |
137 stream_provider_->FlushUntil(DemuxerStream::VIDEO, | |
138 flush_message.video_count()); | |
139 } | |
140 time_update_timer_.Stop(); | |
141 renderer_->Flush( | |
142 base::Bind(&RemoteReceiver::OnFlushDone, weak_factory_.GetWeakPtr())); | |
143 } | |
144 | |
145 void RemoteReceiver::OnFlushDone() { | |
146 DVLOG(3) << __func__ << ": Issues RPC_R_FLUSHUNTIL_CALLBACK RPC message."; | |
147 | |
148 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
149 rpc->set_handle(remote_handle_); | |
150 rpc->set_proc(pb::RpcMessage::RPC_R_FLUSHUNTIL_CALLBACK); | |
151 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
152 } | |
153 | |
154 void RemoteReceiver::StartPlayingFrom(std::unique_ptr<pb::RpcMessage> message) { | |
155 DVLOG(3) << __func__ << ": Receives RPC_R_STARTPLAYINGFROM message."; | |
156 base::TimeDelta time = | |
157 base::TimeDelta::FromMicroseconds(message->integer64_value()); | |
158 renderer_->StartPlayingFrom(time); | |
159 // Schedule period report timer. | |
miu
2017/03/29 01:39:14
Per above suggestions, the rest of the method is j
xjz
2017/03/30 23:21:30
Done.
| |
160 UpdateMediaTime(); | |
161 time_update_timer_.Start( | |
162 FROM_HERE, kTimeUpdateInterval, | |
163 base::Bind(&RemoteReceiver::UpdateMediaTime, weak_factory_.GetWeakPtr())); | |
164 } | |
165 | |
166 void RemoteReceiver::SetVolume(std::unique_ptr<pb::RpcMessage> message) { | |
167 DVLOG(3) << __func__ << ": Receives RPC_R_SETVOLUME message."; | |
168 renderer_->SetVolume(message->double_value()); | |
169 } | |
170 | |
171 void RemoteReceiver::UpdateMediaTime() { | |
172 // Issues RPC_RC_ONTIMEUPDATE RPC message. | |
173 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
174 rpc->set_handle(remote_handle_); | |
175 rpc->set_proc(pb::RpcMessage::RPC_RC_ONTIMEUPDATE); | |
176 auto* message = rpc->mutable_rendererclient_ontimeupdate_rpc(); | |
177 base::TimeDelta media_time = renderer_->GetMediaTime(); | |
178 message->set_time_usec(media_time.InMicroseconds()); | |
179 base::TimeDelta max_time = media_time; | |
180 // Allow some slop to account for delays in scheduling time update tasks. | |
181 if (time_update_timer_.IsRunning() && (playback_rate_ > 0)) { | |
182 max_time += kTimeUpdateInterval; | |
183 max_time += kTimeUpdateInterval; | |
184 } | |
185 message->set_max_time_usec(max_time.InMicroseconds()); | |
186 DVLOG(3) << __func__ << ": Issues RPC_RC_ONTIMEUPDATE message." | |
187 << " media_time = " << media_time.InMicroseconds() | |
188 << " max_time= " << max_time.InMicroseconds(); | |
189 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
190 } | |
191 | |
192 void RemoteReceiver::OnReceivedBuffer(DemuxerStream::Type type, | |
193 scoped_refptr<DecoderBuffer> buffer) { | |
194 DVLOG(3) << __func__; | |
195 DCHECK(stream_provider_); | |
196 stream_provider_->AppendBuffer(type, buffer); | |
197 } | |
198 | |
199 void RemoteReceiver::OnError(PipelineStatus status) { | |
200 DVLOG(3) << __func__ << ": Issues RPC_RC_ONERROR message."; | |
201 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
202 rpc->set_handle(remote_handle_); | |
203 rpc->set_proc(pb::RpcMessage::RPC_RC_ONERROR); | |
204 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
205 } | |
206 | |
207 void RemoteReceiver::OnEnded() { | |
208 DVLOG(3) << __func__ << ": Issues RPC_RC_ONENDED message."; | |
209 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
210 rpc->set_handle(remote_handle_); | |
211 rpc->set_proc(pb::RpcMessage::RPC_RC_ONENDED); | |
212 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
213 time_update_timer_.Stop(); | |
214 } | |
215 | |
216 void RemoteReceiver::OnStatisticsUpdate(const PipelineStatistics& stats) { | |
217 DVLOG(3) << __func__ << ": Issues RPC_RC_ONSTATISTICSUPDATE message."; | |
218 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
219 rpc->set_handle(remote_handle_); | |
220 rpc->set_proc(pb::RpcMessage::RPC_RC_ONSTATISTICSUPDATE); | |
221 auto* message = rpc->mutable_rendererclient_onstatisticsupdate_rpc(); | |
222 message->set_audio_bytes_decoded(stats.audio_bytes_decoded); | |
223 message->set_video_bytes_decoded(stats.video_bytes_decoded); | |
224 message->set_video_frames_decoded(stats.video_frames_decoded); | |
225 message->set_video_frames_dropped(stats.video_frames_dropped); | |
226 message->set_audio_memory_usage(stats.audio_memory_usage); | |
227 message->set_video_memory_usage(stats.video_memory_usage); | |
228 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
229 } | |
230 | |
231 void RemoteReceiver::OnBufferingStateChange(BufferingState state) { | |
232 DVLOG(3) << __func__ << ": Issues RPC_RC_ONBUFFERINGSTATECHANGE message."; | |
233 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
234 rpc->set_handle(remote_handle_); | |
235 rpc->set_proc(pb::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE); | |
236 auto* message = rpc->mutable_rendererclient_onbufferingstatechange_rpc(); | |
237 message->set_state(ToProtoMediaBufferingState(state).value()); | |
238 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
239 } | |
240 | |
241 void RemoteReceiver::OnWaitingForDecryptionKey() { | |
242 DVLOG(3) << __func__ << ": Issues RPC_RC_ONWAITINGFORDECRYPTIONKEY message."; | |
243 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
244 rpc->set_handle(remote_handle_); | |
245 rpc->set_proc(pb::RpcMessage::RPC_RC_ONWAITINGFORDECRYPTIONKEY); | |
246 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
247 } | |
248 | |
249 void RemoteReceiver::OnVideoNaturalSizeChange(const gfx::Size& size) { | |
250 DVLOG(3) << __func__ << ": Issues RPC_RC_ONVIDEONATURALSIZECHANGE message."; | |
251 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
252 rpc->set_handle(remote_handle_); | |
253 rpc->set_proc(pb::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE); | |
254 auto* message = rpc->mutable_rendererclient_onvideonatualsizechange_rpc(); | |
255 message->set_width(size.width()); | |
256 message->set_height(size.height()); | |
257 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
258 } | |
259 | |
260 void RemoteReceiver::OnVideoOpacityChange(bool opaque) { | |
261 DVLOG(3) << __func__ << ": Issues RPC_RC_ONVIDEOOPACITYCHANGE message."; | |
262 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
263 rpc->set_handle(remote_handle_); | |
264 rpc->set_proc(pb::RpcMessage::RPC_RC_ONVIDEOOPACITYCHANGE); | |
265 rpc->set_boolean_value(opaque); | |
266 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
267 } | |
268 | |
269 void RemoteReceiver::OnDurationChange(base::TimeDelta duration) { | |
270 DVLOG(3) << __func__ << ": Issues RPC_RC_ONDURATIONCHANGE message."; | |
271 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
272 rpc->set_handle(remote_handle_); | |
273 rpc->set_proc(pb::RpcMessage::RPC_RC_ONDURATIONCHANGE); | |
274 rpc->set_integer_value(duration.InMicroseconds()); | |
275 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
276 } | |
277 | |
278 } // namespace remoting | |
279 } // namespace media | |
OLD | NEW |