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 Receiver::Receiver(std::unique_ptr<Renderer> renderer, RpcBroker* rpc_broker) | |
26 : renderer_(std::move(renderer)), | |
27 rpc_broker_(rpc_broker), | |
28 rpc_handle_(rpc_broker_->GetUniqueHandle()), | |
29 weak_factory_(this) { | |
30 DCHECK(renderer_); | |
31 DCHECK(rpc_broker_); | |
32 rpc_broker_->RegisterMessageReceiverCallback( | |
33 rpc_handle_, | |
34 base::Bind(&Receiver::OnReceivedRpc, weak_factory_.GetWeakPtr())); | |
35 rpc_broker_->RegisterMessageReceiverCallback( | |
36 RpcBroker::kAcquireHandle, | |
37 base::Bind(&Receiver::OnReceivedRpc, weak_factory_.GetWeakPtr())); | |
38 } | |
39 | |
40 Receiver::~Receiver() { | |
41 rpc_broker_->UnregisterMessageReceiverCallback(rpc_handle_); | |
42 rpc_broker_->UnregisterMessageReceiverCallback(RpcBroker::kAcquireHandle); | |
43 } | |
44 | |
45 void Receiver::OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message) { | |
46 DCHECK(message); | |
47 switch (message->proc()) { | |
48 case pb::RpcMessage::RPC_ACQUIRE_RENDERER: | |
49 AcquireRenderer(std::move(message)); | |
50 break; | |
51 case pb::RpcMessage::RPC_R_FLUSHUNTIL: | |
52 FlushUntil(std::move(message)); | |
53 break; | |
54 case pb::RpcMessage::RPC_R_STARTPLAYINGFROM: | |
55 StartPlayingFrom(std::move(message)); | |
56 break; | |
57 case pb::RpcMessage::RPC_R_SETPLAYBACKRATE: | |
58 SetPlaybackRate(std::move(message)); | |
59 break; | |
60 case pb::RpcMessage::RPC_R_SETVOLUME: | |
61 SetVolume(std::move(message)); | |
62 break; | |
63 case pb::RpcMessage::RPC_R_INITIALIZE: | |
64 Initialize(std::move(message)); | |
65 break; | |
66 default: | |
67 VLOG(1) << __func__ << ": Unknow RPC message. proc=" << message->proc(); | |
68 } | |
69 } | |
70 | |
71 void Receiver::AcquireRenderer(std::unique_ptr<pb::RpcMessage> message) { | |
72 DVLOG(3) << __func__ << ": Receives RPC_ACQUIRE_RENDERER with remote_handle= " | |
73 << message->integer_value(); | |
74 | |
75 remote_handle_ = message->integer_value(); | |
76 if (stream_provider_) { | |
77 VLOG(1) << "Acquire renderer error: Already aquired."; | |
78 OnError(PipelineStatus::PIPELINE_ERROR_DECODE); | |
79 return; | |
80 } | |
81 | |
82 stream_provider_.reset(new StreamProvider( | |
83 rpc_broker_, base::Bind(&Receiver::OnError, weak_factory_.GetWeakPtr(), | |
84 PipelineStatus::PIPELINE_ERROR_DECODE))); | |
85 | |
86 DVLOG(3) << __func__ | |
87 << ": Issues RPC_ACQUIRE_RENDERER_DONE RPC message. remote_handle=" | |
88 << remote_handle_ << " rpc_handle=" << rpc_handle_; | |
89 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
90 rpc->set_handle(remote_handle_); | |
91 rpc->set_proc(pb::RpcMessage::RPC_ACQUIRE_RENDERER_DONE); | |
92 rpc->set_integer_value(rpc_handle_); | |
93 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
94 } | |
95 | |
96 void Receiver::Initialize(std::unique_ptr<pb::RpcMessage> message) { | |
97 DCHECK(stream_provider_); | |
98 DVLOG(3) << __func__ << ": Receives RPC_R_INITIALIZE with callback handle= " | |
99 << message->renderer_initialize_rpc().callback_handle(); | |
100 DCHECK(message->renderer_initialize_rpc().callback_handle() == | |
101 remote_handle_); | |
102 if (!stream_provider_) | |
103 OnRendererInitialized(PipelineStatus::PIPELINE_ERROR_INITIALIZATION_FAILED); | |
104 | |
105 stream_provider_->Initialize( | |
106 message->renderer_initialize_rpc().audio_demuxer_handle(), | |
107 message->renderer_initialize_rpc().video_demuxer_handle(), | |
108 base::Bind(&Receiver::OnStreamInitialized, weak_factory_.GetWeakPtr())); | |
109 } | |
110 | |
111 void Receiver::OnStreamInitialized() { | |
112 DCHECK(stream_provider_); | |
113 renderer_->Initialize( | |
114 stream_provider_.get(), this, | |
115 base::Bind(&Receiver::OnRendererInitialized, weak_factory_.GetWeakPtr())); | |
116 } | |
117 | |
118 void Receiver::OnRendererInitialized(PipelineStatus status) { | |
119 DVLOG(3) << __func__ << ": Issues RPC_R_INITIALIZE_CALLBACK RPC message." | |
120 << "remote_handle=" << remote_handle_; | |
121 | |
122 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
123 rpc->set_handle(remote_handle_); | |
124 rpc->set_proc(pb::RpcMessage::RPC_R_INITIALIZE_CALLBACK); | |
125 rpc->set_boolean_value(status == PIPELINE_OK); | |
126 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
127 } | |
128 | |
129 void Receiver::SetPlaybackRate(std::unique_ptr<pb::RpcMessage> message) { | |
130 const double playback_rate = message->double_value(); | |
131 DVLOG(3) << __func__ | |
132 << ": Receives RPC_R_SETPLAYBACKRATE with rate=" << playback_rate; | |
133 renderer_->SetPlaybackRate(playback_rate); | |
134 | |
135 if (playback_rate == 0.0) { | |
136 if (time_update_timer_.IsRunning()) { | |
137 time_update_timer_.Stop(); | |
138 // Send one final media time update since the sender will not get any | |
139 // until playback resumes. | |
140 SendMediaTimeUpdate(); | |
141 } | |
142 } else { | |
143 ScheduleMediaTimeUpdates(); | |
144 } | |
145 } | |
146 | |
147 void Receiver::FlushUntil(std::unique_ptr<pb::RpcMessage> message) { | |
148 DVLOG(3) << __func__ << ": Receives RPC_R_FLUSHUNTIL RPC message."; | |
149 | |
150 const pb::RendererFlushUntil flush_message = | |
151 message->renderer_flushuntil_rpc(); | |
152 DCHECK_EQ(flush_message.callback_handle(), remote_handle_); | |
153 if (stream_provider_) { | |
154 if (flush_message.has_audio_count()) { | |
155 stream_provider_->FlushUntil(DemuxerStream::AUDIO, | |
156 flush_message.audio_count()); | |
157 } | |
158 if (flush_message.has_video_count()) { | |
159 stream_provider_->FlushUntil(DemuxerStream::VIDEO, | |
160 flush_message.video_count()); | |
161 } | |
162 } | |
163 time_update_timer_.Stop(); | |
164 renderer_->Flush( | |
165 base::Bind(&Receiver::OnFlushDone, weak_factory_.GetWeakPtr())); | |
166 } | |
167 | |
168 void Receiver::OnFlushDone() { | |
169 DVLOG(3) << __func__ << ": Issues RPC_R_FLUSHUNTIL_CALLBACK RPC message."; | |
170 | |
171 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
172 rpc->set_handle(remote_handle_); | |
173 rpc->set_proc(pb::RpcMessage::RPC_R_FLUSHUNTIL_CALLBACK); | |
174 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
175 } | |
176 | |
177 void Receiver::StartPlayingFrom(std::unique_ptr<pb::RpcMessage> message) { | |
178 DVLOG(3) << __func__ << ": Receives RPC_R_STARTPLAYINGFROM message."; | |
179 base::TimeDelta time = | |
180 base::TimeDelta::FromMicroseconds(message->integer64_value()); | |
181 renderer_->StartPlayingFrom(time); | |
182 ScheduleMediaTimeUpdates(); | |
183 } | |
184 | |
185 void Receiver::ScheduleMediaTimeUpdates() { | |
186 if (time_update_timer_.IsRunning()) | |
187 return; | |
188 SendMediaTimeUpdate(); | |
189 time_update_timer_.Start( | |
190 FROM_HERE, kTimeUpdateInterval, | |
191 base::Bind(&Receiver::SendMediaTimeUpdate, weak_factory_.GetWeakPtr())); | |
192 } | |
193 | |
194 void Receiver::SetVolume(std::unique_ptr<pb::RpcMessage> message) { | |
195 DVLOG(3) << __func__ << ": Receives RPC_R_SETVOLUME message."; | |
196 renderer_->SetVolume(message->double_value()); | |
197 } | |
198 | |
199 void Receiver::SendMediaTimeUpdate() { | |
200 // Issues RPC_RC_ONTIMEUPDATE RPC 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_ONTIMEUPDATE); | |
204 auto* message = rpc->mutable_rendererclient_ontimeupdate_rpc(); | |
205 base::TimeDelta media_time = renderer_->GetMediaTime(); | |
206 message->set_time_usec(media_time.InMicroseconds()); | |
207 base::TimeDelta max_time = media_time; | |
miu
2017/04/03 21:05:01
Isn't max_time supposed to be the total time for t
xjz
2017/04/04 01:07:55
Actually, this is now only used to check that it s
| |
208 // Allow some slop to account for delays in scheduling time update tasks. | |
miu
2017/04/03 21:05:01
Now that I look at this again, I'm confused. Why i
xjz
2017/04/04 01:07:55
Removed the slop. As explained above, it is not ne
| |
209 max_time += kTimeUpdateInterval; | |
210 max_time += kTimeUpdateInterval; | |
211 message->set_max_time_usec(max_time.InMicroseconds()); | |
212 DVLOG(3) << __func__ << ": Issues RPC_RC_ONTIMEUPDATE message." | |
213 << " media_time = " << media_time.InMicroseconds() | |
214 << " max_time= " << max_time.InMicroseconds(); | |
215 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
216 } | |
217 | |
218 void Receiver::OnReceivedBuffer(DemuxerStream::Type type, | |
219 scoped_refptr<DecoderBuffer> buffer) { | |
220 DVLOG(3) << __func__ | |
221 << ": type=" << (type == DemuxerStream::AUDIO ? "Audio" : "Video"); | |
222 DCHECK(stream_provider_); | |
223 stream_provider_->AppendBuffer(type, buffer); | |
224 } | |
225 | |
226 void Receiver::OnError(PipelineStatus status) { | |
227 VLOG(1) << __func__ << ": Issues RPC_RC_ONERROR message."; | |
228 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
229 rpc->set_handle(remote_handle_); | |
230 rpc->set_proc(pb::RpcMessage::RPC_RC_ONERROR); | |
231 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
232 } | |
233 | |
234 void Receiver::OnEnded() { | |
235 DVLOG(3) << __func__ << ": Issues RPC_RC_ONENDED message."; | |
236 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
237 rpc->set_handle(remote_handle_); | |
238 rpc->set_proc(pb::RpcMessage::RPC_RC_ONENDED); | |
239 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
240 time_update_timer_.Stop(); | |
241 } | |
242 | |
243 void Receiver::OnStatisticsUpdate(const PipelineStatistics& stats) { | |
244 DVLOG(3) << __func__ << ": Issues RPC_RC_ONSTATISTICSUPDATE message."; | |
245 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
246 rpc->set_handle(remote_handle_); | |
247 rpc->set_proc(pb::RpcMessage::RPC_RC_ONSTATISTICSUPDATE); | |
248 auto* message = rpc->mutable_rendererclient_onstatisticsupdate_rpc(); | |
249 message->set_audio_bytes_decoded(stats.audio_bytes_decoded); | |
250 message->set_video_bytes_decoded(stats.video_bytes_decoded); | |
251 message->set_video_frames_decoded(stats.video_frames_decoded); | |
252 message->set_video_frames_dropped(stats.video_frames_dropped); | |
253 message->set_audio_memory_usage(stats.audio_memory_usage); | |
254 message->set_video_memory_usage(stats.video_memory_usage); | |
255 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
256 } | |
257 | |
258 void Receiver::OnBufferingStateChange(BufferingState state) { | |
259 DVLOG(3) << __func__ | |
260 << ": Issues RPC_RC_ONBUFFERINGSTATECHANGE message: state=" << state; | |
261 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
262 rpc->set_handle(remote_handle_); | |
263 rpc->set_proc(pb::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE); | |
264 auto* message = rpc->mutable_rendererclient_onbufferingstatechange_rpc(); | |
265 message->set_state(ToProtoMediaBufferingState(state).value()); | |
266 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
267 } | |
268 | |
269 void Receiver::OnWaitingForDecryptionKey() { | |
270 DVLOG(3) << __func__ << ": Issues RPC_RC_ONWAITINGFORDECRYPTIONKEY 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_ONWAITINGFORDECRYPTIONKEY); | |
274 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
275 } | |
276 | |
277 void Receiver::OnVideoNaturalSizeChange(const gfx::Size& size) { | |
278 DVLOG(3) << __func__ << ": Issues RPC_RC_ONVIDEONATURALSIZECHANGE message."; | |
279 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
280 rpc->set_handle(remote_handle_); | |
281 rpc->set_proc(pb::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE); | |
282 auto* message = rpc->mutable_rendererclient_onvideonatualsizechange_rpc(); | |
283 message->set_width(size.width()); | |
284 message->set_height(size.height()); | |
285 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
286 } | |
287 | |
288 void Receiver::OnVideoOpacityChange(bool opaque) { | |
289 DVLOG(3) << __func__ << ": Issues RPC_RC_ONVIDEOOPACITYCHANGE message."; | |
290 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
291 rpc->set_handle(remote_handle_); | |
292 rpc->set_proc(pb::RpcMessage::RPC_RC_ONVIDEOOPACITYCHANGE); | |
293 rpc->set_boolean_value(opaque); | |
294 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
295 } | |
296 | |
297 void Receiver::OnDurationChange(base::TimeDelta duration) { | |
298 DVLOG(3) << __func__ << ": Issues RPC_RC_ONDURATIONCHANGE message."; | |
299 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); | |
300 rpc->set_handle(remote_handle_); | |
301 rpc->set_proc(pb::RpcMessage::RPC_RC_ONDURATIONCHANGE); | |
302 rpc->set_integer_value(duration.InMicroseconds()); | |
303 rpc_broker_->SendMessageToRemote(std::move(rpc)); | |
304 } | |
305 | |
306 } // namespace remoting | |
307 } // namespace media | |
OLD | NEW |