OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/remoting/remote_renderer_impl.h" | 5 #include "media/remoting/courier_renderer.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/numerics/safe_math.h" | 16 #include "base/numerics/safe_math.h" |
17 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
18 #include "base/time/time.h" | 18 #include "base/time/time.h" |
19 #include "media/base/bind_to_current_loop.h" | 19 #include "media/base/bind_to_current_loop.h" |
| 20 #include "media/base/buffering_state.h" |
20 #include "media/base/demuxer_stream_provider.h" | 21 #include "media/base/demuxer_stream_provider.h" |
21 #include "media/remoting/remote_demuxer_stream_adapter.h" | 22 #include "media/base/renderer_client.h" |
22 #include "media/remoting/remoting_renderer_controller.h" | 23 #include "media/remoting/demuxer_stream_adapter.h" |
23 #include "media/remoting/rpc/proto_enum_utils.h" | 24 #include "media/remoting/proto_enum_utils.h" |
24 #include "media/remoting/rpc/proto_utils.h" | 25 #include "media/remoting/proto_utils.h" |
| 26 #include "media/remoting/user_experience_controller.h" |
25 | 27 |
26 namespace { | 28 namespace { |
27 | 29 |
28 // The moving time window to track the media time and statistics updates. | 30 // The moving time window to track the media time and statistics updates. |
29 constexpr base::TimeDelta kTrackingWindow = base::TimeDelta::FromSeconds(5); | 31 constexpr base::TimeDelta kTrackingWindow = base::TimeDelta::FromSeconds(5); |
30 | 32 |
31 // The allowed delay for the remoting playback. When continuously exceeds this | 33 // The allowed delay for the remoting playback. When continuously exceeds this |
32 // limit for |kPlaybackDelayCountThreshold| times, the user experience is likely | 34 // limit for |kPlaybackDelayCountThreshold| times, the user experience is likely |
33 // poor and the controller is notified. | 35 // poor and the controller is notified. |
34 constexpr base::TimeDelta kMediaPlaybackDelayThreshold = | 36 constexpr base::TimeDelta kMediaPlaybackDelayThreshold = |
(...skipping 11 matching lines...) Expand all Loading... |
46 base::TimeDelta::FromSeconds(2); | 48 base::TimeDelta::FromSeconds(2); |
47 | 49 |
48 // The amount of time between polling the DemuxerStreamAdapters to measure their | 50 // The amount of time between polling the DemuxerStreamAdapters to measure their |
49 // data flow rates for metrics. | 51 // data flow rates for metrics. |
50 constexpr base::TimeDelta kDataFlowPollPeriod = | 52 constexpr base::TimeDelta kDataFlowPollPeriod = |
51 base::TimeDelta::FromSeconds(10); | 53 base::TimeDelta::FromSeconds(10); |
52 | 54 |
53 } // namespace | 55 } // namespace |
54 | 56 |
55 namespace media { | 57 namespace media { |
| 58 namespace remoting { |
56 | 59 |
57 RemoteRendererImpl::RemoteRendererImpl( | 60 CourierRenderer::CourierRenderer( |
58 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, | 61 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, |
59 const base::WeakPtr<RemotingRendererController>& | 62 const base::WeakPtr<UserExperienceController>& controller, |
60 remoting_renderer_controller, | |
61 VideoRendererSink* video_renderer_sink) | 63 VideoRendererSink* video_renderer_sink) |
62 : state_(STATE_UNINITIALIZED), | 64 : state_(STATE_UNINITIALIZED), |
63 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), | 65 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
64 media_task_runner_(std::move(media_task_runner)), | 66 media_task_runner_(std::move(media_task_runner)), |
65 demuxer_stream_provider_(nullptr), | 67 demuxer_stream_provider_(nullptr), |
66 client_(nullptr), | 68 client_(nullptr), |
67 remoting_renderer_controller_(remoting_renderer_controller), | 69 controller_(controller), |
68 rpc_broker_(remoting_renderer_controller_->GetRpcBroker()), | 70 rpc_broker_(controller_->GetRpcBroker()), |
69 rpc_handle_(rpc_broker_->GetUniqueHandle()), | 71 rpc_handle_(rpc_broker_->GetUniqueHandle()), |
70 remote_renderer_handle_(remoting::kInvalidHandle), | 72 remote_renderer_handle_(RpcBroker::kInvalidHandle), |
71 video_renderer_sink_(video_renderer_sink), | 73 video_renderer_sink_(video_renderer_sink), |
72 weak_factory_(this) { | 74 weak_factory_(this) { |
73 VLOG(2) << __func__; | 75 VLOG(2) << __func__; |
74 // The constructor is running on the main thread. | 76 // Note: The constructor is running on the main thread, but will be destroyed |
75 DCHECK(remoting_renderer_controller_); | 77 // on the media thread. Therefore, all weak pointers must be dereferenced on |
76 remoting_renderer_controller_->SetShowInterstitialCallback( | 78 // the media thread. |
77 base::Bind(&RemoteRendererImpl::RequestUpdateInterstitialOnMainThread, | 79 controller_->SetShowInterstitialCallback( |
| 80 base::Bind(&CourierRenderer::RequestUpdateInterstitialOnMainThread, |
78 media_task_runner_, weak_factory_.GetWeakPtr())); | 81 media_task_runner_, weak_factory_.GetWeakPtr())); |
79 | 82 const RpcBroker::ReceiveMessageCallback receive_callback = |
80 const remoting::RpcBroker::ReceiveMessageCallback receive_callback = | 83 base::Bind(&CourierRenderer::OnMessageReceivedOnMainThread, |
81 base::Bind(&RemoteRendererImpl::OnMessageReceivedOnMainThread, | |
82 media_task_runner_, weak_factory_.GetWeakPtr()); | 84 media_task_runner_, weak_factory_.GetWeakPtr()); |
83 rpc_broker_->RegisterMessageReceiverCallback(rpc_handle_, receive_callback); | 85 rpc_broker_->RegisterMessageReceiverCallback(rpc_handle_, receive_callback); |
84 } | 86 } |
85 | 87 |
86 RemoteRendererImpl::~RemoteRendererImpl() { | 88 CourierRenderer::~CourierRenderer() { |
87 VLOG(2) << __func__; | 89 VLOG(2) << __func__; |
88 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 90 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
89 | 91 |
90 UpdateInterstitial(interstitial_background_, canvas_size_, | 92 UpdateInterstitial(interstitial_background_, canvas_size_, |
91 RemotingInterstitialType::BETWEEN_SESSIONS); | 93 InterstitialType::BETWEEN_SESSIONS); |
92 | 94 |
93 // Post task on main thread to unset the interstial callback. | 95 // Post task on main thread to unset the interstial callback. |
94 main_task_runner_->PostTask( | 96 main_task_runner_->PostTask( |
95 FROM_HERE, | 97 FROM_HERE, |
96 base::Bind(&RemotingRendererController::SetShowInterstitialCallback, | 98 base::Bind(&UserExperienceController::SetShowInterstitialCallback, |
97 remoting_renderer_controller_, | 99 controller_, |
98 RemotingRendererController::ShowInterstitialCallback())); | 100 UserExperienceController::ShowInterstitialCallback())); |
99 | 101 |
100 // Post task on main thread to unregister message receiver. | 102 // Post task on main thread to unregister message receiver. |
101 main_task_runner_->PostTask( | 103 main_task_runner_->PostTask( |
102 FROM_HERE, | 104 FROM_HERE, base::Bind(&RpcBroker::UnregisterMessageReceiverCallback, |
103 base::Bind(&remoting::RpcBroker::UnregisterMessageReceiverCallback, | 105 rpc_broker_, rpc_handle_)); |
104 rpc_broker_, rpc_handle_)); | |
105 } | 106 } |
106 | 107 |
107 void RemoteRendererImpl::Initialize( | 108 void CourierRenderer::Initialize(DemuxerStreamProvider* demuxer_stream_provider, |
108 DemuxerStreamProvider* demuxer_stream_provider, | 109 RendererClient* client, |
109 media::RendererClient* client, | 110 const PipelineStatusCB& init_cb) { |
110 const PipelineStatusCB& init_cb) { | |
111 VLOG(2) << __func__; | 111 VLOG(2) << __func__; |
112 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 112 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
113 DCHECK(demuxer_stream_provider); | 113 DCHECK(demuxer_stream_provider); |
114 DCHECK(client); | 114 DCHECK(client); |
115 | 115 |
116 if (state_ != STATE_UNINITIALIZED) { | 116 if (state_ != STATE_UNINITIALIZED) { |
117 media_task_runner_->PostTask( | 117 media_task_runner_->PostTask( |
118 FROM_HERE, base::Bind(init_cb, PIPELINE_ERROR_INVALID_STATE)); | 118 FROM_HERE, base::Bind(init_cb, PIPELINE_ERROR_INVALID_STATE)); |
119 return; | 119 return; |
120 } | 120 } |
121 | 121 |
122 demuxer_stream_provider_ = demuxer_stream_provider; | 122 demuxer_stream_provider_ = demuxer_stream_provider; |
123 client_ = client; | 123 client_ = client; |
124 init_workflow_done_callback_ = init_cb; | 124 init_workflow_done_callback_ = init_cb; |
125 | 125 |
126 state_ = STATE_CREATE_PIPE; | 126 state_ = STATE_CREATE_PIPE; |
127 // Create audio mojo data pipe handles if audio is available. | 127 // Create audio mojo data pipe handles if audio is available. |
128 ::media::DemuxerStream* audio_demuxer_stream = | 128 DemuxerStream* audio_demuxer_stream = |
129 demuxer_stream_provider_->GetStream(::media::DemuxerStream::AUDIO); | 129 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); |
130 std::unique_ptr<mojo::DataPipe> audio_data_pipe; | 130 std::unique_ptr<mojo::DataPipe> audio_data_pipe; |
131 if (audio_demuxer_stream) { | 131 if (audio_demuxer_stream) { |
132 audio_data_pipe = base::WrapUnique(remoting::CreateDataPipe()); | 132 audio_data_pipe = base::WrapUnique(DemuxerStreamAdapter::CreateDataPipe()); |
133 } | 133 } |
134 | 134 |
135 // Create video mojo data pipe handles if video is available. | 135 // Create video mojo data pipe handles if video is available. |
136 ::media::DemuxerStream* video_demuxer_stream = | 136 DemuxerStream* video_demuxer_stream = |
137 demuxer_stream_provider_->GetStream(::media::DemuxerStream::VIDEO); | 137 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); |
138 std::unique_ptr<mojo::DataPipe> video_data_pipe; | 138 std::unique_ptr<mojo::DataPipe> video_data_pipe; |
139 if (video_demuxer_stream) { | 139 if (video_demuxer_stream) { |
140 video_data_pipe = base::WrapUnique(remoting::CreateDataPipe()); | 140 video_data_pipe = base::WrapUnique(DemuxerStreamAdapter::CreateDataPipe()); |
141 } | 141 } |
142 | 142 |
143 // Establish remoting data pipe connection using main thread. | 143 // Establish remoting data pipe connection using main thread. |
144 const RemotingSourceImpl::DataPipeStartCallback data_pipe_callback = | 144 const SharedSession::DataPipeStartCallback data_pipe_callback = |
145 base::Bind(&RemoteRendererImpl::OnDataPipeCreatedOnMainThread, | 145 base::Bind(&CourierRenderer::OnDataPipeCreatedOnMainThread, |
146 media_task_runner_, weak_factory_.GetWeakPtr(), rpc_broker_); | 146 media_task_runner_, weak_factory_.GetWeakPtr(), rpc_broker_); |
147 main_task_runner_->PostTask( | 147 main_task_runner_->PostTask( |
148 FROM_HERE, | 148 FROM_HERE, |
149 base::Bind(&RemotingRendererController::StartDataPipe, | 149 base::Bind(&UserExperienceController::StartDataPipe, controller_, |
150 remoting_renderer_controller_, base::Passed(&audio_data_pipe), | 150 base::Passed(&audio_data_pipe), base::Passed(&video_data_pipe), |
151 base::Passed(&video_data_pipe), data_pipe_callback)); | 151 data_pipe_callback)); |
152 } | 152 } |
153 | 153 |
154 void RemoteRendererImpl::SetCdm(CdmContext* cdm_context, | 154 void CourierRenderer::SetCdm(CdmContext* cdm_context, |
155 const CdmAttachedCB& cdm_attached_cb) { | 155 const CdmAttachedCB& cdm_attached_cb) { |
156 VLOG(2) << __func__ << " cdm_id:" << cdm_context->GetCdmId(); | 156 VLOG(2) << __func__ << " cdm_id:" << cdm_context->GetCdmId(); |
157 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 157 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
158 | 158 |
159 // TODO(erickung): add implementation once Remote CDM implementation is done. | 159 // TODO(erickung): add implementation once Remote CDM implementation is done. |
160 // Right now it returns callback immediately. | 160 // Right now it returns callback immediately. |
161 if (!cdm_attached_cb.is_null()) { | 161 if (!cdm_attached_cb.is_null()) { |
162 cdm_attached_cb.Run(false); | 162 cdm_attached_cb.Run(false); |
163 } | 163 } |
164 } | 164 } |
165 | 165 |
166 void RemoteRendererImpl::Flush(const base::Closure& flush_cb) { | 166 void CourierRenderer::Flush(const base::Closure& flush_cb) { |
167 VLOG(2) << __func__; | 167 VLOG(2) << __func__; |
168 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 168 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
169 DCHECK(flush_cb_.is_null()); | 169 DCHECK(flush_cb_.is_null()); |
170 | 170 |
171 if (state_ != STATE_PLAYING) { | 171 if (state_ != STATE_PLAYING) { |
172 DCHECK_EQ(state_, STATE_ERROR); | 172 DCHECK_EQ(state_, STATE_ERROR); |
173 // In the error state, this renderer will be shut down shortly. To prevent | 173 // In the error state, this renderer will be shut down shortly. To prevent |
174 // breaking the pipeline impl, just run the done callback (interface | 174 // breaking the pipeline impl, just run the done callback (interface |
175 // requirement). | 175 // requirement). |
176 media_task_runner_->PostTask(FROM_HERE, flush_cb); | 176 media_task_runner_->PostTask(FROM_HERE, flush_cb); |
(...skipping 13 matching lines...) Expand all Loading... |
190 (video_demuxer_stream_adapter_ && !flush_video_count.has_value()) || | 190 (video_demuxer_stream_adapter_ && !flush_video_count.has_value()) || |
191 (audio_demuxer_stream_adapter_ && video_demuxer_stream_adapter_ && | 191 (audio_demuxer_stream_adapter_ && video_demuxer_stream_adapter_ && |
192 flush_audio_count.has_value() != flush_video_count.has_value())) { | 192 flush_audio_count.has_value() != flush_video_count.has_value())) { |
193 VLOG(1) << "Ignoring flush request while under flushing operation"; | 193 VLOG(1) << "Ignoring flush request while under flushing operation"; |
194 return; | 194 return; |
195 } | 195 } |
196 | 196 |
197 flush_cb_ = flush_cb; | 197 flush_cb_ = flush_cb; |
198 | 198 |
199 // Issues RPC_R_FLUSHUNTIL RPC message. | 199 // Issues RPC_R_FLUSHUNTIL RPC message. |
200 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | 200 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); |
201 rpc->set_handle(remote_renderer_handle_); | 201 rpc->set_handle(remote_renderer_handle_); |
202 rpc->set_proc(remoting::pb::RpcMessage::RPC_R_FLUSHUNTIL); | 202 rpc->set_proc(pb::RpcMessage::RPC_R_FLUSHUNTIL); |
203 remoting::pb::RendererFlushUntil* message = | 203 pb::RendererFlushUntil* message = rpc->mutable_renderer_flushuntil_rpc(); |
204 rpc->mutable_renderer_flushuntil_rpc(); | |
205 if (flush_audio_count.has_value()) | 204 if (flush_audio_count.has_value()) |
206 message->set_audio_count(*flush_audio_count); | 205 message->set_audio_count(*flush_audio_count); |
207 if (flush_video_count.has_value()) | 206 if (flush_video_count.has_value()) |
208 message->set_video_count(*flush_video_count); | 207 message->set_video_count(*flush_video_count); |
209 message->set_callback_handle(rpc_handle_); | 208 message->set_callback_handle(rpc_handle_); |
210 VLOG(2) << __func__ << ": Sending RPC_R_FLUSHUNTIL to " << rpc->handle() | 209 VLOG(2) << __func__ << ": Sending RPC_R_FLUSHUNTIL to " << rpc->handle() |
211 << " with audio_count=" << message->audio_count() | 210 << " with audio_count=" << message->audio_count() |
212 << ", video_count=" << message->video_count() | 211 << ", video_count=" << message->video_count() |
213 << ", callback_handle=" << message->callback_handle(); | 212 << ", callback_handle=" << message->callback_handle(); |
214 SendRpcToRemote(std::move(rpc)); | 213 SendRpcToRemote(std::move(rpc)); |
215 } | 214 } |
216 | 215 |
217 void RemoteRendererImpl::StartPlayingFrom(base::TimeDelta time) { | 216 void CourierRenderer::StartPlayingFrom(base::TimeDelta time) { |
218 VLOG(2) << __func__ << ": " << time.InMicroseconds(); | 217 VLOG(2) << __func__ << ": " << time.InMicroseconds(); |
219 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 218 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
220 | 219 |
221 if (state_ != STATE_PLAYING) { | 220 if (state_ != STATE_PLAYING) { |
222 DCHECK_EQ(state_, STATE_ERROR); | 221 DCHECK_EQ(state_, STATE_ERROR); |
223 return; | 222 return; |
224 } | 223 } |
225 | 224 |
226 // Issues RPC_R_STARTPLAYINGFROM RPC message. | 225 // Issues RPC_R_STARTPLAYINGFROM RPC message. |
227 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | 226 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); |
228 rpc->set_handle(remote_renderer_handle_); | 227 rpc->set_handle(remote_renderer_handle_); |
229 rpc->set_proc(remoting::pb::RpcMessage::RPC_R_STARTPLAYINGFROM); | 228 rpc->set_proc(pb::RpcMessage::RPC_R_STARTPLAYINGFROM); |
230 rpc->set_integer64_value(time.InMicroseconds()); | 229 rpc->set_integer64_value(time.InMicroseconds()); |
231 VLOG(2) << __func__ << ": Sending RPC_R_STARTPLAYINGFROM to " << rpc->handle() | 230 VLOG(2) << __func__ << ": Sending RPC_R_STARTPLAYINGFROM to " << rpc->handle() |
232 << " with time_usec=" << rpc->integer64_value(); | 231 << " with time_usec=" << rpc->integer64_value(); |
233 SendRpcToRemote(std::move(rpc)); | 232 SendRpcToRemote(std::move(rpc)); |
234 | 233 |
235 { | 234 { |
236 base::AutoLock auto_lock(time_lock_); | 235 base::AutoLock auto_lock(time_lock_); |
237 current_media_time_ = time; | 236 current_media_time_ = time; |
238 } | 237 } |
239 ResetMeasurements(); | 238 ResetMeasurements(); |
240 } | 239 } |
241 | 240 |
242 void RemoteRendererImpl::SetPlaybackRate(double playback_rate) { | 241 void CourierRenderer::SetPlaybackRate(double playback_rate) { |
243 VLOG(2) << __func__ << ": " << playback_rate; | 242 VLOG(2) << __func__ << ": " << playback_rate; |
244 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 243 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
245 | 244 |
246 if (state_ != STATE_FLUSHING && state_ != STATE_PLAYING) { | 245 if (state_ != STATE_FLUSHING && state_ != STATE_PLAYING) { |
247 DCHECK_EQ(state_, STATE_ERROR); | 246 DCHECK_EQ(state_, STATE_ERROR); |
248 return; | 247 return; |
249 } | 248 } |
250 | 249 |
251 // Issues RPC_R_SETPLAYBACKRATE RPC message. | 250 // Issues RPC_R_SETPLAYBACKRATE RPC message. |
252 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | 251 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); |
253 rpc->set_handle(remote_renderer_handle_); | 252 rpc->set_handle(remote_renderer_handle_); |
254 rpc->set_proc(remoting::pb::RpcMessage::RPC_R_SETPLAYBACKRATE); | 253 rpc->set_proc(pb::RpcMessage::RPC_R_SETPLAYBACKRATE); |
255 rpc->set_double_value(playback_rate); | 254 rpc->set_double_value(playback_rate); |
256 VLOG(2) << __func__ << ": Sending RPC_R_SETPLAYBACKRATE to " << rpc->handle() | 255 VLOG(2) << __func__ << ": Sending RPC_R_SETPLAYBACKRATE to " << rpc->handle() |
257 << " with rate=" << rpc->double_value(); | 256 << " with rate=" << rpc->double_value(); |
258 SendRpcToRemote(std::move(rpc)); | 257 SendRpcToRemote(std::move(rpc)); |
259 playback_rate_ = playback_rate; | 258 playback_rate_ = playback_rate; |
260 ResetMeasurements(); | 259 ResetMeasurements(); |
261 } | 260 } |
262 | 261 |
263 void RemoteRendererImpl::SetVolume(float volume) { | 262 void CourierRenderer::SetVolume(float volume) { |
264 VLOG(2) << __func__ << ": " << volume; | 263 VLOG(2) << __func__ << ": " << volume; |
265 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 264 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
266 | 265 |
267 if (state_ != STATE_FLUSHING && state_ != STATE_PLAYING) { | 266 if (state_ != STATE_FLUSHING && state_ != STATE_PLAYING) { |
268 DCHECK_EQ(state_, STATE_ERROR); | 267 DCHECK_EQ(state_, STATE_ERROR); |
269 return; | 268 return; |
270 } | 269 } |
271 | 270 |
272 // Issues RPC_R_SETVOLUME RPC message. | 271 // Issues RPC_R_SETVOLUME RPC message. |
273 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | 272 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); |
274 rpc->set_handle(remote_renderer_handle_); | 273 rpc->set_handle(remote_renderer_handle_); |
275 rpc->set_proc(remoting::pb::RpcMessage::RPC_R_SETVOLUME); | 274 rpc->set_proc(pb::RpcMessage::RPC_R_SETVOLUME); |
276 rpc->set_double_value(volume); | 275 rpc->set_double_value(volume); |
277 VLOG(2) << __func__ << ": Sending RPC_R_SETVOLUME to " << rpc->handle() | 276 VLOG(2) << __func__ << ": Sending RPC_R_SETVOLUME to " << rpc->handle() |
278 << " with volume=" << rpc->double_value(); | 277 << " with volume=" << rpc->double_value(); |
279 SendRpcToRemote(std::move(rpc)); | 278 SendRpcToRemote(std::move(rpc)); |
280 } | 279 } |
281 | 280 |
282 base::TimeDelta RemoteRendererImpl::GetMediaTime() { | 281 base::TimeDelta CourierRenderer::GetMediaTime() { |
283 // No BelongsToCurrentThread() checking because this can be called from other | 282 // No BelongsToCurrentThread() checking because this can be called from other |
284 // threads. | 283 // threads. |
285 // TODO(erickung): Interpolate current media time using local system time. | 284 // TODO(erickung): Interpolate current media time using local system time. |
286 // Current receiver is to update |current_media_time_| every 250ms. But it | 285 // Current receiver is to update |current_media_time_| every 250ms. But it |
287 // needs to lower the update frequency in order to reduce network usage. Hence | 286 // needs to lower the update frequency in order to reduce network usage. Hence |
288 // the interpolation is needed after receiver implementation is changed. | 287 // the interpolation is needed after receiver implementation is changed. |
289 base::AutoLock auto_lock(time_lock_); | 288 base::AutoLock auto_lock(time_lock_); |
290 return current_media_time_; | 289 return current_media_time_; |
291 } | 290 } |
292 | 291 |
293 // static | 292 // static |
294 void RemoteRendererImpl::OnDataPipeCreatedOnMainThread( | 293 void CourierRenderer::OnDataPipeCreatedOnMainThread( |
295 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, | 294 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, |
296 base::WeakPtr<RemoteRendererImpl> self, | 295 base::WeakPtr<CourierRenderer> self, |
297 base::WeakPtr<remoting::RpcBroker> rpc_broker, | 296 base::WeakPtr<RpcBroker> rpc_broker, |
298 mojom::RemotingDataStreamSenderPtrInfo audio, | 297 mojom::RemotingDataStreamSenderPtrInfo audio, |
299 mojom::RemotingDataStreamSenderPtrInfo video, | 298 mojom::RemotingDataStreamSenderPtrInfo video, |
300 mojo::ScopedDataPipeProducerHandle audio_handle, | 299 mojo::ScopedDataPipeProducerHandle audio_handle, |
301 mojo::ScopedDataPipeProducerHandle video_handle) { | 300 mojo::ScopedDataPipeProducerHandle video_handle) { |
302 media_task_runner->PostTask( | 301 media_task_runner->PostTask( |
303 FROM_HERE, | 302 FROM_HERE, |
304 base::Bind( | 303 base::Bind(&CourierRenderer::OnDataPipeCreated, self, |
305 &RemoteRendererImpl::OnDataPipeCreated, self, base::Passed(&audio), | 304 base::Passed(&audio), base::Passed(&video), |
306 base::Passed(&video), base::Passed(&audio_handle), | 305 base::Passed(&audio_handle), base::Passed(&video_handle), |
307 base::Passed(&video_handle), | 306 rpc_broker ? rpc_broker->GetUniqueHandle() |
308 rpc_broker ? rpc_broker->GetUniqueHandle() : remoting::kInvalidHandle, | 307 : RpcBroker::kInvalidHandle, |
309 rpc_broker ? rpc_broker->GetUniqueHandle() | 308 rpc_broker ? rpc_broker->GetUniqueHandle() |
310 : remoting::kInvalidHandle)); | 309 : RpcBroker::kInvalidHandle)); |
311 } | 310 } |
312 | 311 |
313 void RemoteRendererImpl::OnDataPipeCreated( | 312 void CourierRenderer::OnDataPipeCreated( |
314 mojom::RemotingDataStreamSenderPtrInfo audio, | 313 mojom::RemotingDataStreamSenderPtrInfo audio, |
315 mojom::RemotingDataStreamSenderPtrInfo video, | 314 mojom::RemotingDataStreamSenderPtrInfo video, |
316 mojo::ScopedDataPipeProducerHandle audio_handle, | 315 mojo::ScopedDataPipeProducerHandle audio_handle, |
317 mojo::ScopedDataPipeProducerHandle video_handle, | 316 mojo::ScopedDataPipeProducerHandle video_handle, |
318 int audio_rpc_handle, | 317 int audio_rpc_handle, |
319 int video_rpc_handle) { | 318 int video_rpc_handle) { |
320 VLOG(2) << __func__; | 319 VLOG(2) << __func__; |
321 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 320 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
322 DCHECK(!init_workflow_done_callback_.is_null()); | 321 DCHECK(!init_workflow_done_callback_.is_null()); |
323 | 322 |
324 if (state_ == STATE_ERROR) | 323 if (state_ == STATE_ERROR) |
325 return; // Abort because something went wrong in the meantime. | 324 return; // Abort because something went wrong in the meantime. |
326 DCHECK_EQ(state_, STATE_CREATE_PIPE); | 325 DCHECK_EQ(state_, STATE_CREATE_PIPE); |
327 | 326 |
328 // Create audio demuxer stream adapter if audio is available. | 327 // Create audio demuxer stream adapter if audio is available. |
329 ::media::DemuxerStream* audio_demuxer_stream = | 328 DemuxerStream* audio_demuxer_stream = |
330 demuxer_stream_provider_->GetStream(::media::DemuxerStream::AUDIO); | 329 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); |
331 if (audio_demuxer_stream && audio.is_valid() && audio_handle.is_valid() && | 330 if (audio_demuxer_stream && audio.is_valid() && audio_handle.is_valid() && |
332 audio_rpc_handle != remoting::kInvalidHandle) { | 331 audio_rpc_handle != RpcBroker::kInvalidHandle) { |
333 VLOG(2) << "Initialize audio"; | 332 VLOG(2) << "Initialize audio"; |
334 audio_demuxer_stream_adapter_.reset( | 333 audio_demuxer_stream_adapter_.reset(new DemuxerStreamAdapter( |
335 new remoting::RemoteDemuxerStreamAdapter( | 334 main_task_runner_, media_task_runner_, "audio", audio_demuxer_stream, |
336 main_task_runner_, media_task_runner_, "audio", | 335 rpc_broker_, audio_rpc_handle, std::move(audio), |
337 audio_demuxer_stream, rpc_broker_, audio_rpc_handle, | 336 std::move(audio_handle), |
338 std::move(audio), std::move(audio_handle), | 337 base::Bind(&CourierRenderer::OnFatalError, base::Unretained(this)))); |
339 base::Bind(&RemoteRendererImpl::OnFatalError, | |
340 base::Unretained(this)))); | |
341 } | 338 } |
342 | 339 |
343 // Create video demuxer stream adapter if video is available. | 340 // Create video demuxer stream adapter if video is available. |
344 ::media::DemuxerStream* video_demuxer_stream = | 341 DemuxerStream* video_demuxer_stream = |
345 demuxer_stream_provider_->GetStream(::media::DemuxerStream::VIDEO); | 342 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); |
346 if (video_demuxer_stream && video.is_valid() && video_handle.is_valid() && | 343 if (video_demuxer_stream && video.is_valid() && video_handle.is_valid() && |
347 video_rpc_handle != remoting::kInvalidHandle) { | 344 video_rpc_handle != RpcBroker::kInvalidHandle) { |
348 VLOG(2) << "Initialize video"; | 345 VLOG(2) << "Initialize video"; |
349 video_demuxer_stream_adapter_.reset( | 346 video_demuxer_stream_adapter_.reset(new DemuxerStreamAdapter( |
350 new remoting::RemoteDemuxerStreamAdapter( | 347 main_task_runner_, media_task_runner_, "video", video_demuxer_stream, |
351 main_task_runner_, media_task_runner_, "video", | 348 rpc_broker_, video_rpc_handle, std::move(video), |
352 video_demuxer_stream, rpc_broker_, video_rpc_handle, | 349 std::move(video_handle), |
353 std::move(video), std::move(video_handle), | 350 base::Bind(&CourierRenderer::OnFatalError, base::Unretained(this)))); |
354 base::Bind(&RemoteRendererImpl::OnFatalError, | |
355 base::Unretained(this)))); | |
356 } | 351 } |
357 | 352 |
358 // Checks if data pipe is created successfully. | 353 // Checks if data pipe is created successfully. |
359 if (!audio_demuxer_stream_adapter_ && !video_demuxer_stream_adapter_) { | 354 if (!audio_demuxer_stream_adapter_ && !video_demuxer_stream_adapter_) { |
360 OnFatalError(remoting::DATA_PIPE_CREATE_ERROR); | 355 OnFatalError(DATA_PIPE_CREATE_ERROR); |
361 return; | 356 return; |
362 } | 357 } |
363 | 358 |
364 state_ = STATE_ACQUIRING; | 359 state_ = STATE_ACQUIRING; |
365 // Issues RPC_ACQUIRE_RENDERER RPC message. | 360 // Issues RPC_ACQUIRE_RENDERER RPC message. |
366 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | 361 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); |
367 rpc->set_handle(remoting::kReceiverHandle); | 362 rpc->set_handle(RpcBroker::kAcquireHandle); |
368 rpc->set_proc(remoting::pb::RpcMessage::RPC_ACQUIRE_RENDERER); | 363 rpc->set_proc(pb::RpcMessage::RPC_ACQUIRE_RENDERER); |
369 rpc->set_integer_value(rpc_handle_); | 364 rpc->set_integer_value(rpc_handle_); |
370 VLOG(2) << __func__ << ": Sending RPC_ACQUIRE_RENDERER to " << rpc->handle() | 365 VLOG(2) << __func__ << ": Sending RPC_ACQUIRE_RENDERER to " << rpc->handle() |
371 << " with rpc_handle=" << rpc->integer_value(); | 366 << " with rpc_handle=" << rpc->integer_value(); |
372 SendRpcToRemote(std::move(rpc)); | 367 SendRpcToRemote(std::move(rpc)); |
373 } | 368 } |
374 | 369 |
375 // static | 370 // static |
376 void RemoteRendererImpl::OnMessageReceivedOnMainThread( | 371 void CourierRenderer::OnMessageReceivedOnMainThread( |
377 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, | 372 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, |
378 base::WeakPtr<RemoteRendererImpl> self, | 373 base::WeakPtr<CourierRenderer> self, |
379 std::unique_ptr<remoting::pb::RpcMessage> message) { | 374 std::unique_ptr<pb::RpcMessage> message) { |
380 media_task_runner->PostTask( | 375 media_task_runner->PostTask(FROM_HERE, |
381 FROM_HERE, base::Bind(&RemoteRendererImpl::OnReceivedRpc, self, | 376 base::Bind(&CourierRenderer::OnReceivedRpc, self, |
382 base::Passed(&message))); | 377 base::Passed(&message))); |
383 } | 378 } |
384 | 379 |
385 void RemoteRendererImpl::OnReceivedRpc( | 380 void CourierRenderer::OnReceivedRpc(std::unique_ptr<pb::RpcMessage> message) { |
386 std::unique_ptr<remoting::pb::RpcMessage> message) { | |
387 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 381 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
388 DCHECK(message); | 382 DCHECK(message); |
389 switch (message->proc()) { | 383 switch (message->proc()) { |
390 case remoting::pb::RpcMessage::RPC_ACQUIRE_RENDERER_DONE: | 384 case pb::RpcMessage::RPC_ACQUIRE_RENDERER_DONE: |
391 AcquireRendererDone(std::move(message)); | 385 AcquireRendererDone(std::move(message)); |
392 break; | 386 break; |
393 case remoting::pb::RpcMessage::RPC_R_INITIALIZE_CALLBACK: | 387 case pb::RpcMessage::RPC_R_INITIALIZE_CALLBACK: |
394 InitializeCallback(std::move(message)); | 388 InitializeCallback(std::move(message)); |
395 break; | 389 break; |
396 case remoting::pb::RpcMessage::RPC_R_FLUSHUNTIL_CALLBACK: | 390 case pb::RpcMessage::RPC_R_FLUSHUNTIL_CALLBACK: |
397 FlushUntilCallback(); | 391 FlushUntilCallback(); |
398 break; | 392 break; |
399 case remoting::pb::RpcMessage::RPC_R_SETCDM_CALLBACK: | 393 case pb::RpcMessage::RPC_R_SETCDM_CALLBACK: |
400 SetCdmCallback(std::move(message)); | 394 SetCdmCallback(std::move(message)); |
401 break; | 395 break; |
402 case remoting::pb::RpcMessage::RPC_RC_ONTIMEUPDATE: | 396 case pb::RpcMessage::RPC_RC_ONTIMEUPDATE: |
403 OnTimeUpdate(std::move(message)); | 397 OnTimeUpdate(std::move(message)); |
404 break; | 398 break; |
405 case remoting::pb::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE: | 399 case pb::RpcMessage::RPC_RC_ONBUFFERINGSTATECHANGE: |
406 OnBufferingStateChange(std::move(message)); | 400 OnBufferingStateChange(std::move(message)); |
407 break; | 401 break; |
408 case remoting::pb::RpcMessage::RPC_RC_ONENDED: | 402 case pb::RpcMessage::RPC_RC_ONENDED: |
409 VLOG(2) << __func__ << ": Received RPC_RC_ONENDED."; | 403 VLOG(2) << __func__ << ": Received RPC_RC_ONENDED."; |
410 client_->OnEnded(); | 404 client_->OnEnded(); |
411 break; | 405 break; |
412 case remoting::pb::RpcMessage::RPC_RC_ONERROR: | 406 case pb::RpcMessage::RPC_RC_ONERROR: |
413 VLOG(2) << __func__ << ": Received RPC_RC_ONERROR."; | 407 VLOG(2) << __func__ << ": Received RPC_RC_ONERROR."; |
414 OnFatalError(remoting::RECEIVER_PIPELINE_ERROR); | 408 OnFatalError(RECEIVER_PIPELINE_ERROR); |
415 break; | 409 break; |
416 case remoting::pb::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE: | 410 case pb::RpcMessage::RPC_RC_ONVIDEONATURALSIZECHANGE: |
417 OnVideoNaturalSizeChange(std::move(message)); | 411 OnVideoNaturalSizeChange(std::move(message)); |
418 break; | 412 break; |
419 case remoting::pb::RpcMessage::RPC_RC_ONVIDEOOPACITYCHANGE: | 413 case pb::RpcMessage::RPC_RC_ONVIDEOOPACITYCHANGE: |
420 OnVideoOpacityChange(std::move(message)); | 414 OnVideoOpacityChange(std::move(message)); |
421 break; | 415 break; |
422 case remoting::pb::RpcMessage::RPC_RC_ONSTATISTICSUPDATE: | 416 case pb::RpcMessage::RPC_RC_ONSTATISTICSUPDATE: |
423 OnStatisticsUpdate(std::move(message)); | 417 OnStatisticsUpdate(std::move(message)); |
424 break; | 418 break; |
425 case remoting::pb::RpcMessage::RPC_RC_ONWAITINGFORDECRYPTIONKEY: | 419 case pb::RpcMessage::RPC_RC_ONWAITINGFORDECRYPTIONKEY: |
426 VLOG(2) << __func__ << ": Received RPC_RC_ONWAITINGFORDECRYPTIONKEY."; | 420 VLOG(2) << __func__ << ": Received RPC_RC_ONWAITINGFORDECRYPTIONKEY."; |
427 client_->OnWaitingForDecryptionKey(); | 421 client_->OnWaitingForDecryptionKey(); |
428 break; | 422 break; |
429 case remoting::pb::RpcMessage::RPC_RC_ONDURATIONCHANGE: | 423 case pb::RpcMessage::RPC_RC_ONDURATIONCHANGE: |
430 OnDurationChange(std::move(message)); | 424 OnDurationChange(std::move(message)); |
431 break; | 425 break; |
432 | 426 |
433 default: | 427 default: |
434 LOG(ERROR) << "Unknown rpc: " << message->proc(); | 428 VLOG(1) << "Unknown RPC: " << message->proc(); |
435 } | 429 } |
436 } | 430 } |
437 | 431 |
438 void RemoteRendererImpl::SendRpcToRemote( | 432 void CourierRenderer::SendRpcToRemote(std::unique_ptr<pb::RpcMessage> message) { |
439 std::unique_ptr<remoting::pb::RpcMessage> message) { | |
440 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 433 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
441 DCHECK(main_task_runner_); | 434 DCHECK(main_task_runner_); |
442 main_task_runner_->PostTask( | 435 main_task_runner_->PostTask( |
443 FROM_HERE, base::Bind(&remoting::RpcBroker::SendMessageToRemote, | 436 FROM_HERE, base::Bind(&RpcBroker::SendMessageToRemote, rpc_broker_, |
444 rpc_broker_, base::Passed(&message))); | 437 base::Passed(&message))); |
445 } | 438 } |
446 | 439 |
447 void RemoteRendererImpl::AcquireRendererDone( | 440 void CourierRenderer::AcquireRendererDone( |
448 std::unique_ptr<remoting::pb::RpcMessage> message) { | 441 std::unique_ptr<pb::RpcMessage> message) { |
449 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 442 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
450 DCHECK(message); | 443 DCHECK(message); |
451 | 444 |
452 remote_renderer_handle_ = message->integer_value(); | 445 remote_renderer_handle_ = message->integer_value(); |
453 VLOG(2) << __func__ | 446 VLOG(2) << __func__ |
454 << ": Received RPC_ACQUIRE_RENDERER_DONE with remote_renderer_handle=" | 447 << ": Received RPC_ACQUIRE_RENDERER_DONE with remote_renderer_handle=" |
455 << remote_renderer_handle_; | 448 << remote_renderer_handle_; |
456 | 449 |
457 if (state_ != STATE_ACQUIRING || init_workflow_done_callback_.is_null()) { | 450 if (state_ != STATE_ACQUIRING || init_workflow_done_callback_.is_null()) { |
458 LOG(WARNING) << "Unexpected acquire renderer done RPC."; | 451 LOG(WARNING) << "Unexpected acquire renderer done RPC."; |
459 OnFatalError(remoting::PEERS_OUT_OF_SYNC); | 452 OnFatalError(PEERS_OUT_OF_SYNC); |
460 return; | 453 return; |
461 } | 454 } |
462 state_ = STATE_INITIALIZING; | 455 state_ = STATE_INITIALIZING; |
463 | 456 |
464 // Issues RPC_R_INITIALIZE RPC message to initialize renderer. | 457 // Issues RPC_R_INITIALIZE RPC message to initialize renderer. |
465 std::unique_ptr<remoting::pb::RpcMessage> rpc(new remoting::pb::RpcMessage()); | 458 std::unique_ptr<pb::RpcMessage> rpc(new pb::RpcMessage()); |
466 rpc->set_handle(remote_renderer_handle_); | 459 rpc->set_handle(remote_renderer_handle_); |
467 rpc->set_proc(remoting::pb::RpcMessage::RPC_R_INITIALIZE); | 460 rpc->set_proc(pb::RpcMessage::RPC_R_INITIALIZE); |
468 remoting::pb::RendererInitialize* init = | 461 pb::RendererInitialize* init = rpc->mutable_renderer_initialize_rpc(); |
469 rpc->mutable_renderer_initialize_rpc(); | |
470 init->set_client_handle(rpc_handle_); | 462 init->set_client_handle(rpc_handle_); |
471 init->set_audio_demuxer_handle( | 463 init->set_audio_demuxer_handle( |
472 audio_demuxer_stream_adapter_ | 464 audio_demuxer_stream_adapter_ |
473 ? audio_demuxer_stream_adapter_->rpc_handle() | 465 ? audio_demuxer_stream_adapter_->rpc_handle() |
474 : remoting::kInvalidHandle); | 466 : RpcBroker::kInvalidHandle); |
475 init->set_video_demuxer_handle( | 467 init->set_video_demuxer_handle( |
476 video_demuxer_stream_adapter_ | 468 video_demuxer_stream_adapter_ |
477 ? video_demuxer_stream_adapter_->rpc_handle() | 469 ? video_demuxer_stream_adapter_->rpc_handle() |
478 : remoting::kInvalidHandle); | 470 : RpcBroker::kInvalidHandle); |
479 init->set_callback_handle(rpc_handle_); | 471 init->set_callback_handle(rpc_handle_); |
480 VLOG(2) << __func__ << ": Sending RPC_R_INITIALIZE to " << rpc->handle() | 472 VLOG(2) << __func__ << ": Sending RPC_R_INITIALIZE to " << rpc->handle() |
481 << " with client_handle=" << init->client_handle() | 473 << " with client_handle=" << init->client_handle() |
482 << ", audio_demuxer_handle=" << init->audio_demuxer_handle() | 474 << ", audio_demuxer_handle=" << init->audio_demuxer_handle() |
483 << ", video_demuxer_handle=" << init->video_demuxer_handle() | 475 << ", video_demuxer_handle=" << init->video_demuxer_handle() |
484 << ", callback_handle=" << init->callback_handle(); | 476 << ", callback_handle=" << init->callback_handle(); |
485 SendRpcToRemote(std::move(rpc)); | 477 SendRpcToRemote(std::move(rpc)); |
486 } | 478 } |
487 | 479 |
488 void RemoteRendererImpl::InitializeCallback( | 480 void CourierRenderer::InitializeCallback( |
489 std::unique_ptr<remoting::pb::RpcMessage> message) { | 481 std::unique_ptr<pb::RpcMessage> message) { |
490 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 482 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
491 DCHECK(message); | 483 DCHECK(message); |
492 | 484 |
493 const bool success = message->boolean_value(); | 485 const bool success = message->boolean_value(); |
494 VLOG(2) << __func__ | 486 VLOG(2) << __func__ |
495 << ": Received RPC_R_INITIALIZE_CALLBACK with success=" << success; | 487 << ": Received RPC_R_INITIALIZE_CALLBACK with success=" << success; |
496 | 488 |
497 if (state_ != STATE_INITIALIZING || init_workflow_done_callback_.is_null()) { | 489 if (state_ != STATE_INITIALIZING || init_workflow_done_callback_.is_null()) { |
498 LOG(WARNING) << "Unexpected initialize callback RPC."; | 490 LOG(WARNING) << "Unexpected initialize callback RPC."; |
499 OnFatalError(remoting::PEERS_OUT_OF_SYNC); | 491 OnFatalError(PEERS_OUT_OF_SYNC); |
500 return; | 492 return; |
501 } | 493 } |
502 | 494 |
503 if (!success) { | 495 if (!success) { |
504 OnFatalError(remoting::RECEIVER_INITIALIZE_FAILED); | 496 OnFatalError(RECEIVER_INITIALIZE_FAILED); |
505 return; | 497 return; |
506 } | 498 } |
507 | 499 |
508 metrics_recorder_.OnRendererInitialized(); | 500 metrics_recorder_.OnRendererInitialized(); |
509 | 501 |
510 state_ = STATE_PLAYING; | 502 state_ = STATE_PLAYING; |
511 base::ResetAndReturn(&init_workflow_done_callback_).Run(::media::PIPELINE_OK); | 503 base::ResetAndReturn(&init_workflow_done_callback_).Run(PIPELINE_OK); |
512 } | 504 } |
513 | 505 |
514 void RemoteRendererImpl::FlushUntilCallback() { | 506 void CourierRenderer::FlushUntilCallback() { |
515 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 507 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
516 VLOG(2) << __func__ << ": Received RPC_R_FLUSHUNTIL_CALLBACK"; | 508 VLOG(2) << __func__ << ": Received RPC_R_FLUSHUNTIL_CALLBACK"; |
517 | 509 |
518 if (state_ != STATE_FLUSHING || flush_cb_.is_null()) { | 510 if (state_ != STATE_FLUSHING || flush_cb_.is_null()) { |
519 LOG(WARNING) << "Unexpected flushuntil callback RPC."; | 511 LOG(WARNING) << "Unexpected flushuntil callback RPC."; |
520 OnFatalError(remoting::PEERS_OUT_OF_SYNC); | 512 OnFatalError(PEERS_OUT_OF_SYNC); |
521 return; | 513 return; |
522 } | 514 } |
523 | 515 |
524 state_ = STATE_PLAYING; | 516 state_ = STATE_PLAYING; |
525 if (audio_demuxer_stream_adapter_) | 517 if (audio_demuxer_stream_adapter_) |
526 audio_demuxer_stream_adapter_->SignalFlush(false); | 518 audio_demuxer_stream_adapter_->SignalFlush(false); |
527 if (video_demuxer_stream_adapter_) | 519 if (video_demuxer_stream_adapter_) |
528 video_demuxer_stream_adapter_->SignalFlush(false); | 520 video_demuxer_stream_adapter_->SignalFlush(false); |
529 base::ResetAndReturn(&flush_cb_).Run(); | 521 base::ResetAndReturn(&flush_cb_).Run(); |
530 ResetMeasurements(); | 522 ResetMeasurements(); |
531 } | 523 } |
532 | 524 |
533 void RemoteRendererImpl::SetCdmCallback( | 525 void CourierRenderer::SetCdmCallback(std::unique_ptr<pb::RpcMessage> message) { |
534 std::unique_ptr<remoting::pb::RpcMessage> message) { | |
535 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 526 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
536 DCHECK(message); | 527 DCHECK(message); |
537 VLOG(2) << __func__ << ": Received RPC_R_SETCDM_CALLBACK with cdm_id=" | 528 VLOG(2) << __func__ << ": Received RPC_R_SETCDM_CALLBACK with cdm_id=" |
538 << message->renderer_set_cdm_rpc().cdm_id() << ", callback_handle=" | 529 << message->renderer_set_cdm_rpc().cdm_id() << ", callback_handle=" |
539 << message->renderer_set_cdm_rpc().callback_handle(); | 530 << message->renderer_set_cdm_rpc().callback_handle(); |
540 // TODO(erickung): add implementation once Remote CDM implementation is done. | 531 // TODO(erickung): add implementation once Remote CDM implementation is done. |
541 NOTIMPLEMENTED(); | 532 NOTIMPLEMENTED(); |
542 } | 533 } |
543 | 534 |
544 void RemoteRendererImpl::OnTimeUpdate( | 535 void CourierRenderer::OnTimeUpdate(std::unique_ptr<pb::RpcMessage> message) { |
545 std::unique_ptr<remoting::pb::RpcMessage> message) { | |
546 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 536 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
547 DCHECK(message); | 537 DCHECK(message); |
548 // Shutdown remoting session if receiving malformed RPC message. | 538 // Shutdown remoting session if receiving malformed RPC message. |
549 if (!message->has_rendererclient_ontimeupdate_rpc()) { | 539 if (!message->has_rendererclient_ontimeupdate_rpc()) { |
550 VLOG(1) << __func__ << " missing required RPC message"; | 540 VLOG(1) << __func__ << " missing required RPC message"; |
551 OnFatalError(remoting::RPC_INVALID); | 541 OnFatalError(RPC_INVALID); |
552 return; | 542 return; |
553 } | 543 } |
554 const int64_t time_usec = | 544 const int64_t time_usec = |
555 message->rendererclient_ontimeupdate_rpc().time_usec(); | 545 message->rendererclient_ontimeupdate_rpc().time_usec(); |
556 const int64_t max_time_usec = | 546 const int64_t max_time_usec = |
557 message->rendererclient_ontimeupdate_rpc().max_time_usec(); | 547 message->rendererclient_ontimeupdate_rpc().max_time_usec(); |
558 VLOG(2) << __func__ | 548 VLOG(2) << __func__ |
559 << ": Received RPC_RC_ONTIMEUPDATE with time_usec=" << time_usec | 549 << ": Received RPC_RC_ONTIMEUPDATE with time_usec=" << time_usec |
560 << ", max_time_usec=" << max_time_usec; | 550 << ", max_time_usec=" << max_time_usec; |
561 // Ignores invalid time, such as negative value, or time larger than max value | 551 // Ignores invalid time, such as negative value, or time larger than max value |
562 // (usually the time stamp that all streams are pushed into AV pipeline). | 552 // (usually the time stamp that all streams are pushed into AV pipeline). |
563 if (time_usec < 0 || max_time_usec < 0 || time_usec > max_time_usec) | 553 if (time_usec < 0 || max_time_usec < 0 || time_usec > max_time_usec) |
564 return; | 554 return; |
565 | 555 |
566 { | 556 { |
567 // Updates current time information. | 557 // Updates current time information. |
568 base::AutoLock auto_lock(time_lock_); | 558 base::AutoLock auto_lock(time_lock_); |
569 current_media_time_ = base::TimeDelta::FromMicroseconds(time_usec); | 559 current_media_time_ = base::TimeDelta::FromMicroseconds(time_usec); |
570 current_max_time_ = base::TimeDelta::FromMicroseconds(max_time_usec); | 560 current_max_time_ = base::TimeDelta::FromMicroseconds(max_time_usec); |
571 } | 561 } |
572 | 562 |
573 metrics_recorder_.OnEvidenceOfPlayoutAtReceiver(); | 563 metrics_recorder_.OnEvidenceOfPlayoutAtReceiver(); |
574 OnMediaTimeUpdated(); | 564 OnMediaTimeUpdated(); |
575 } | 565 } |
576 | 566 |
577 void RemoteRendererImpl::OnBufferingStateChange( | 567 void CourierRenderer::OnBufferingStateChange( |
578 std::unique_ptr<remoting::pb::RpcMessage> message) { | 568 std::unique_ptr<pb::RpcMessage> message) { |
579 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 569 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
580 DCHECK(message); | 570 DCHECK(message); |
581 if (!message->has_rendererclient_onbufferingstatechange_rpc()) { | 571 if (!message->has_rendererclient_onbufferingstatechange_rpc()) { |
582 VLOG(1) << __func__ << " missing required RPC message"; | 572 VLOG(1) << __func__ << " missing required RPC message"; |
583 OnFatalError(remoting::RPC_INVALID); | 573 OnFatalError(RPC_INVALID); |
584 return; | 574 return; |
585 } | 575 } |
586 VLOG(2) << __func__ << ": Received RPC_RC_ONBUFFERINGSTATECHANGE with state=" | 576 VLOG(2) << __func__ << ": Received RPC_RC_ONBUFFERINGSTATECHANGE with state=" |
587 << message->rendererclient_onbufferingstatechange_rpc().state(); | 577 << message->rendererclient_onbufferingstatechange_rpc().state(); |
588 base::Optional<::media::BufferingState> state = | 578 base::Optional<BufferingState> state = ToMediaBufferingState( |
589 remoting::ToMediaBufferingState( | 579 message->rendererclient_onbufferingstatechange_rpc().state()); |
590 message->rendererclient_onbufferingstatechange_rpc().state()); | |
591 if (!state.has_value()) | 580 if (!state.has_value()) |
592 return; | 581 return; |
593 client_->OnBufferingStateChange(state.value()); | 582 client_->OnBufferingStateChange(state.value()); |
594 } | 583 } |
595 | 584 |
596 void RemoteRendererImpl::OnVideoNaturalSizeChange( | 585 void CourierRenderer::OnVideoNaturalSizeChange( |
597 std::unique_ptr<remoting::pb::RpcMessage> message) { | 586 std::unique_ptr<pb::RpcMessage> message) { |
598 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 587 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
599 DCHECK(message); | 588 DCHECK(message); |
600 // Shutdown remoting session if receiving malformed RPC message. | 589 // Shutdown remoting session if receiving malformed RPC message. |
601 if (!message->has_rendererclient_onvideonatualsizechange_rpc()) { | 590 if (!message->has_rendererclient_onvideonatualsizechange_rpc()) { |
602 VLOG(1) << __func__ << " missing required RPC message"; | 591 VLOG(1) << __func__ << " missing required RPC message"; |
603 OnFatalError(remoting::RPC_INVALID); | 592 OnFatalError(RPC_INVALID); |
604 return; | 593 return; |
605 } | 594 } |
606 const auto& size_change = | 595 const auto& size_change = |
607 message->rendererclient_onvideonatualsizechange_rpc(); | 596 message->rendererclient_onvideonatualsizechange_rpc(); |
608 VLOG(2) << __func__ << ": Received RPC_RC_ONVIDEONATURALSIZECHANGE with size=" | 597 VLOG(2) << __func__ << ": Received RPC_RC_ONVIDEONATURALSIZECHANGE with size=" |
609 << size_change.width() << 'x' << size_change.height(); | 598 << size_change.width() << 'x' << size_change.height(); |
610 if (size_change.width() <= 0 || size_change.height() <= 0) | 599 if (size_change.width() <= 0 || size_change.height() <= 0) |
611 return; | 600 return; |
612 client_->OnVideoNaturalSizeChange( | 601 client_->OnVideoNaturalSizeChange( |
613 gfx::Size(size_change.width(), size_change.height())); | 602 gfx::Size(size_change.width(), size_change.height())); |
614 } | 603 } |
615 | 604 |
616 void RemoteRendererImpl::OnVideoOpacityChange( | 605 void CourierRenderer::OnVideoOpacityChange( |
617 std::unique_ptr<remoting::pb::RpcMessage> message) { | 606 std::unique_ptr<pb::RpcMessage> message) { |
618 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 607 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
619 DCHECK(message); | 608 DCHECK(message); |
620 const bool opaque = message->boolean_value(); | 609 const bool opaque = message->boolean_value(); |
621 VLOG(2) << __func__ | 610 VLOG(2) << __func__ |
622 << ": Received RPC_RC_ONVIDEOOPACITYCHANGE with opaque=" << opaque; | 611 << ": Received RPC_RC_ONVIDEOOPACITYCHANGE with opaque=" << opaque; |
623 client_->OnVideoOpacityChange(opaque); | 612 client_->OnVideoOpacityChange(opaque); |
624 } | 613 } |
625 | 614 |
626 void RemoteRendererImpl::OnStatisticsUpdate( | 615 void CourierRenderer::OnStatisticsUpdate( |
627 std::unique_ptr<remoting::pb::RpcMessage> message) { | 616 std::unique_ptr<pb::RpcMessage> message) { |
628 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 617 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
629 DCHECK(message); | 618 DCHECK(message); |
630 // Shutdown remoting session if receiving malformed RPC message. | 619 // Shutdown remoting session if receiving malformed RPC message. |
631 if (!message->has_rendererclient_onstatisticsupdate_rpc()) { | 620 if (!message->has_rendererclient_onstatisticsupdate_rpc()) { |
632 VLOG(1) << __func__ << " missing required RPC message"; | 621 VLOG(1) << __func__ << " missing required RPC message"; |
633 OnFatalError(remoting::RPC_INVALID); | 622 OnFatalError(RPC_INVALID); |
634 return; | 623 return; |
635 } | 624 } |
636 const auto& rpc_message = message->rendererclient_onstatisticsupdate_rpc(); | 625 PipelineStatistics stats; |
637 ::media::PipelineStatistics stats; | 626 ConvertProtoToPipelineStatistics( |
638 // Note: Each |stats| value is a delta, not the aggregate amount. | 627 message->rendererclient_onstatisticsupdate_rpc(), &stats); |
639 stats.audio_bytes_decoded = rpc_message.audio_bytes_decoded(); | 628 // Note: Each field in |stats| is a delta, not the aggregate amount. |
640 stats.video_bytes_decoded = rpc_message.video_bytes_decoded(); | |
641 stats.video_frames_decoded = rpc_message.video_frames_decoded(); | |
642 stats.video_frames_dropped = rpc_message.video_frames_dropped(); | |
643 stats.audio_memory_usage = rpc_message.audio_memory_usage(); | |
644 stats.video_memory_usage = rpc_message.video_memory_usage(); | |
645 VLOG(2) << __func__ | 629 VLOG(2) << __func__ |
646 << ": Received RPC_RC_ONSTATISTICSUPDATE with audio_bytes_decoded=" | 630 << ": Received RPC_RC_ONSTATISTICSUPDATE with audio_bytes_decoded=" |
647 << stats.audio_bytes_decoded | 631 << stats.audio_bytes_decoded |
648 << ", video_bytes_decoded=" << stats.video_bytes_decoded | 632 << ", video_bytes_decoded=" << stats.video_bytes_decoded |
649 << ", video_frames_decoded=" << stats.video_frames_decoded | 633 << ", video_frames_decoded=" << stats.video_frames_decoded |
650 << ", video_frames_dropped=" << stats.video_frames_dropped | 634 << ", video_frames_dropped=" << stats.video_frames_dropped |
651 << ", audio_memory_usage=" << stats.audio_memory_usage | 635 << ", audio_memory_usage=" << stats.audio_memory_usage |
652 << ", video_memory_usage=" << stats.video_memory_usage; | 636 << ", video_memory_usage=" << stats.video_memory_usage; |
653 | 637 |
654 if (stats.audio_bytes_decoded > 0 || stats.video_frames_decoded > 0 || | 638 if (stats.audio_bytes_decoded > 0 || stats.video_frames_decoded > 0 || |
655 stats.video_frames_dropped > 0) { | 639 stats.video_frames_dropped > 0) { |
656 metrics_recorder_.OnEvidenceOfPlayoutAtReceiver(); | 640 metrics_recorder_.OnEvidenceOfPlayoutAtReceiver(); |
657 } | 641 } |
658 UpdateVideoStatsQueue(stats.video_frames_decoded, stats.video_frames_dropped); | 642 UpdateVideoStatsQueue(stats.video_frames_decoded, stats.video_frames_dropped); |
659 client_->OnStatisticsUpdate(stats); | 643 client_->OnStatisticsUpdate(stats); |
660 } | 644 } |
661 | 645 |
662 void RemoteRendererImpl::OnDurationChange( | 646 void CourierRenderer::OnDurationChange( |
663 std::unique_ptr<remoting::pb::RpcMessage> message) { | 647 std::unique_ptr<pb::RpcMessage> message) { |
664 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 648 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
665 DCHECK(message); | 649 DCHECK(message); |
666 VLOG(2) << __func__ << ": Received RPC_RC_ONDURATIONCHANGE with usec=" | 650 VLOG(2) << __func__ << ": Received RPC_RC_ONDURATIONCHANGE with usec=" |
667 << message->integer64_value(); | 651 << message->integer64_value(); |
668 if (message->integer64_value() < 0) | 652 if (message->integer64_value() < 0) |
669 return; | 653 return; |
670 client_->OnDurationChange( | 654 client_->OnDurationChange( |
671 base::TimeDelta::FromMicroseconds(message->integer64_value())); | 655 base::TimeDelta::FromMicroseconds(message->integer64_value())); |
672 } | 656 } |
673 | 657 |
674 void RemoteRendererImpl::OnFatalError(remoting::StopTrigger stop_trigger) { | 658 void CourierRenderer::OnFatalError(StopTrigger stop_trigger) { |
675 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 659 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
676 DCHECK_NE(remoting::UNKNOWN_STOP_TRIGGER, stop_trigger); | 660 DCHECK_NE(UNKNOWN_STOP_TRIGGER, stop_trigger); |
677 | 661 |
678 VLOG(2) << __func__ << " with StopTrigger " << stop_trigger; | 662 VLOG(2) << __func__ << " with StopTrigger " << stop_trigger; |
679 | 663 |
680 // If this is the first error, notify the controller. It is expected the | 664 // If this is the first error, notify the controller. It is expected the |
681 // controller will shut down this renderer shortly. | 665 // controller will cause this renderer to shut down shortly. |
682 if (state_ != STATE_ERROR) { | 666 if (state_ != STATE_ERROR) { |
683 state_ = STATE_ERROR; | 667 state_ = STATE_ERROR; |
684 main_task_runner_->PostTask( | 668 main_task_runner_->PostTask( |
685 FROM_HERE, base::Bind(&RemotingRendererController::OnRendererFatalError, | 669 FROM_HERE, base::Bind(&UserExperienceController::OnRendererFatalError, |
686 remoting_renderer_controller_, stop_trigger)); | 670 controller_, stop_trigger)); |
687 } | 671 } |
688 | 672 |
689 data_flow_poll_timer_.Stop(); | 673 data_flow_poll_timer_.Stop(); |
690 | 674 |
691 if (!init_workflow_done_callback_.is_null()) { | 675 if (!init_workflow_done_callback_.is_null()) { |
692 base::ResetAndReturn(&init_workflow_done_callback_) | 676 base::ResetAndReturn(&init_workflow_done_callback_) |
693 .Run(PIPELINE_ERROR_INITIALIZATION_FAILED); | 677 .Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
694 return; | 678 return; |
695 } | 679 } |
696 | 680 |
697 if (!flush_cb_.is_null()) | 681 if (!flush_cb_.is_null()) |
698 base::ResetAndReturn(&flush_cb_).Run(); | 682 base::ResetAndReturn(&flush_cb_).Run(); |
699 } | 683 } |
700 | 684 |
701 // static | 685 // static |
702 void RemoteRendererImpl::RequestUpdateInterstitialOnMainThread( | 686 void CourierRenderer::RequestUpdateInterstitialOnMainThread( |
703 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, | 687 scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, |
704 base::WeakPtr<RemoteRendererImpl> remote_renderer_impl, | 688 base::WeakPtr<CourierRenderer> remote_renderer_impl, |
705 const base::Optional<SkBitmap>& background_image, | 689 const base::Optional<SkBitmap>& background_image, |
706 const gfx::Size& canvas_size, | 690 const gfx::Size& canvas_size, |
707 RemotingInterstitialType interstitial_type) { | 691 InterstitialType interstitial_type) { |
708 media_task_runner->PostTask( | 692 media_task_runner->PostTask( |
709 FROM_HERE, | 693 FROM_HERE, |
710 base::Bind(&RemoteRendererImpl::UpdateInterstitial, remote_renderer_impl, | 694 base::Bind(&CourierRenderer::UpdateInterstitial, remote_renderer_impl, |
711 background_image, canvas_size, interstitial_type)); | 695 background_image, canvas_size, interstitial_type)); |
712 } | 696 } |
713 | 697 |
714 void RemoteRendererImpl::UpdateInterstitial( | 698 void CourierRenderer::UpdateInterstitial( |
715 const base::Optional<SkBitmap>& background_image, | 699 const base::Optional<SkBitmap>& background_image, |
716 const gfx::Size& canvas_size, | 700 const gfx::Size& canvas_size, |
717 RemotingInterstitialType interstitial_type) { | 701 InterstitialType interstitial_type) { |
718 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 702 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
719 if (background_image.has_value()) | 703 if (background_image.has_value()) |
720 interstitial_background_ = background_image.value(); | 704 interstitial_background_ = background_image.value(); |
721 canvas_size_ = canvas_size; | 705 canvas_size_ = canvas_size; |
722 PaintRemotingInterstitial(interstitial_background_, canvas_size_, | 706 PaintInterstitial(interstitial_background_, canvas_size_, interstitial_type, |
723 interstitial_type, video_renderer_sink_); | 707 video_renderer_sink_); |
724 } | 708 } |
725 | 709 |
726 void RemoteRendererImpl::OnMediaTimeUpdated() { | 710 void CourierRenderer::OnMediaTimeUpdated() { |
727 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 711 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
728 if (!flush_cb_.is_null()) | 712 if (!flush_cb_.is_null()) |
729 return; // Don't manage and check the queue when Flush() is on-going. | 713 return; // Don't manage and check the queue when Flush() is on-going. |
730 | 714 |
731 base::TimeTicks current_time = base::TimeTicks::Now(); | 715 base::TimeTicks current_time = base::TimeTicks::Now(); |
732 if (current_time < ignore_updates_until_time_) | 716 if (current_time < ignore_updates_until_time_) |
733 return; // Not stable yet. | 717 return; // Not stable yet. |
734 | 718 |
735 media_time_queue_.push_back( | 719 media_time_queue_.push_back( |
736 std::make_pair(current_time, current_media_time_)); | 720 std::make_pair(current_time, current_media_time_)); |
737 base::TimeDelta window_duration = | 721 base::TimeDelta window_duration = |
738 current_time - media_time_queue_.front().first; | 722 current_time - media_time_queue_.front().first; |
739 if (window_duration < kTrackingWindow) | 723 if (window_duration < kTrackingWindow) |
740 return; // Not enough data to make a reliable decision. | 724 return; // Not enough data to make a reliable decision. |
741 | 725 |
742 base::TimeDelta media_duration = | 726 base::TimeDelta media_duration = |
743 media_time_queue_.back().second - media_time_queue_.front().second; | 727 media_time_queue_.back().second - media_time_queue_.front().second; |
744 base::TimeDelta update_duration = | 728 base::TimeDelta update_duration = |
745 (media_time_queue_.back().first - media_time_queue_.front().first) * | 729 (media_time_queue_.back().first - media_time_queue_.front().first) * |
746 playback_rate_; | 730 playback_rate_; |
747 if ((media_duration - update_duration).magnitude() >= | 731 if ((media_duration - update_duration).magnitude() >= |
748 kMediaPlaybackDelayThreshold) { | 732 kMediaPlaybackDelayThreshold) { |
749 VLOG(1) << "Irregular playback detected: Media playback delayed." | 733 VLOG(1) << "Irregular playback detected: Media playback delayed." |
750 << " media_duration = " << media_duration | 734 << " media_duration = " << media_duration |
751 << " update_duration = " << update_duration; | 735 << " update_duration = " << update_duration; |
752 ++times_playback_delayed_; | 736 ++times_playback_delayed_; |
753 if (times_playback_delayed_ == kPlaybackDelayCountThreshold) | 737 if (times_playback_delayed_ == kPlaybackDelayCountThreshold) |
754 OnFatalError(remoting::PACING_TOO_SLOWLY); | 738 OnFatalError(PACING_TOO_SLOWLY); |
755 } else { | 739 } else { |
756 times_playback_delayed_ = 0; | 740 times_playback_delayed_ = 0; |
757 } | 741 } |
758 | 742 |
759 // Prune |media_time_queue_|. | 743 // Prune |media_time_queue_|. |
760 while (media_time_queue_.back().first - media_time_queue_.front().first >= | 744 while (media_time_queue_.back().first - media_time_queue_.front().first >= |
761 kTrackingWindow) | 745 kTrackingWindow) |
762 media_time_queue_.pop_front(); | 746 media_time_queue_.pop_front(); |
763 } | 747 } |
764 | 748 |
765 void RemoteRendererImpl::UpdateVideoStatsQueue(int video_frames_decoded, | 749 void CourierRenderer::UpdateVideoStatsQueue(int video_frames_decoded, |
766 int video_frames_dropped) { | 750 int video_frames_dropped) { |
767 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 751 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
768 if (!flush_cb_.is_null()) | 752 if (!flush_cb_.is_null()) |
769 return; // Don't manage and check the queue when Flush() is on-going. | 753 return; // Don't manage and check the queue when Flush() is on-going. |
770 | 754 |
771 if (!stats_updated_) { | 755 if (!stats_updated_) { |
772 if (video_frames_decoded) | 756 if (video_frames_decoded) |
773 stats_updated_ = true; | 757 stats_updated_ = true; |
774 // Ignore the first stats since it may include the information during | 758 // Ignore the first stats since it may include the information during |
775 // unstable period. | 759 // unstable period. |
776 return; | 760 return; |
(...skipping 11 matching lines...) Expand all Loading... |
788 current_time - std::get<0>(video_stats_queue_.front()); | 772 current_time - std::get<0>(video_stats_queue_.front()); |
789 if (window_duration < kTrackingWindow) | 773 if (window_duration < kTrackingWindow) |
790 return; // Not enough data to make a reliable decision. | 774 return; // Not enough data to make a reliable decision. |
791 | 775 |
792 if (sum_video_frames_decoded_ && | 776 if (sum_video_frames_decoded_ && |
793 sum_video_frames_dropped_ * 100 > | 777 sum_video_frames_dropped_ * 100 > |
794 sum_video_frames_decoded_ * kMaxNumVideoFramesDroppedPercentage) { | 778 sum_video_frames_decoded_ * kMaxNumVideoFramesDroppedPercentage) { |
795 VLOG(1) << "Irregular playback detected: Too many video frames dropped." | 779 VLOG(1) << "Irregular playback detected: Too many video frames dropped." |
796 << " video_frames_decoded= " << sum_video_frames_decoded_ | 780 << " video_frames_decoded= " << sum_video_frames_decoded_ |
797 << " video_frames_dropped= " << sum_video_frames_dropped_; | 781 << " video_frames_dropped= " << sum_video_frames_dropped_; |
798 OnFatalError(remoting::FRAME_DROP_RATE_HIGH); | 782 OnFatalError(FRAME_DROP_RATE_HIGH); |
799 } | 783 } |
800 // Prune |video_stats_queue_|. | 784 // Prune |video_stats_queue_|. |
801 while (std::get<0>(video_stats_queue_.back()) - | 785 while (std::get<0>(video_stats_queue_.back()) - |
802 std::get<0>(video_stats_queue_.front()) >= | 786 std::get<0>(video_stats_queue_.front()) >= |
803 kTrackingWindow) { | 787 kTrackingWindow) { |
804 sum_video_frames_decoded_ -= std::get<1>(video_stats_queue_.front()); | 788 sum_video_frames_decoded_ -= std::get<1>(video_stats_queue_.front()); |
805 sum_video_frames_dropped_ -= std::get<2>(video_stats_queue_.front()); | 789 sum_video_frames_dropped_ -= std::get<2>(video_stats_queue_.front()); |
806 video_stats_queue_.pop_front(); | 790 video_stats_queue_.pop_front(); |
807 } | 791 } |
808 } | 792 } |
809 | 793 |
810 void RemoteRendererImpl::ResetMeasurements() { | 794 void CourierRenderer::ResetMeasurements() { |
811 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 795 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
812 media_time_queue_.clear(); | 796 media_time_queue_.clear(); |
813 video_stats_queue_.clear(); | 797 video_stats_queue_.clear(); |
814 sum_video_frames_dropped_ = 0; | 798 sum_video_frames_dropped_ = 0; |
815 sum_video_frames_decoded_ = 0; | 799 sum_video_frames_decoded_ = 0; |
816 stats_updated_ = false; | 800 stats_updated_ = false; |
817 ignore_updates_until_time_ = base::TimeTicks::Now() + kStabilizationPeriod; | 801 ignore_updates_until_time_ = base::TimeTicks::Now() + kStabilizationPeriod; |
818 | 802 |
819 if (state_ != STATE_ERROR && | 803 if (state_ != STATE_ERROR && |
820 (audio_demuxer_stream_adapter_ || video_demuxer_stream_adapter_)) { | 804 (audio_demuxer_stream_adapter_ || video_demuxer_stream_adapter_)) { |
821 data_flow_poll_timer_.Start(FROM_HERE, kDataFlowPollPeriod, this, | 805 data_flow_poll_timer_.Start(FROM_HERE, kDataFlowPollPeriod, this, |
822 &RemoteRendererImpl::MeasureAndRecordDataRates); | 806 &CourierRenderer::MeasureAndRecordDataRates); |
823 } | 807 } |
824 } | 808 } |
825 | 809 |
826 void RemoteRendererImpl::MeasureAndRecordDataRates() { | 810 void CourierRenderer::MeasureAndRecordDataRates() { |
827 DCHECK(media_task_runner_->BelongsToCurrentThread()); | 811 DCHECK(media_task_runner_->BelongsToCurrentThread()); |
828 | 812 |
829 // Whenever media is first started or flushed/seeked, there is a "burst | 813 // Whenever media is first started or flushed/seeked, there is a "burst |
830 // bufferring" period as the remote device rapidly fills its buffer before | 814 // bufferring" period as the remote device rapidly fills its buffer before |
831 // resuming playback. Since the goal here is to measure the sustained content | 815 // resuming playback. Since the goal here is to measure the sustained content |
832 // bitrates, ignore the byte counts the first time since the last | 816 // bitrates, ignore the byte counts the first time since the last |
833 // ResetMeasurements() call. | 817 // ResetMeasurements() call. |
834 const base::TimeTicks current_time = base::TimeTicks::Now(); | 818 const base::TimeTicks current_time = base::TimeTicks::Now(); |
835 if (current_time < ignore_updates_until_time_ + kDataFlowPollPeriod) { | 819 if (current_time < ignore_updates_until_time_ + kDataFlowPollPeriod) { |
836 if (audio_demuxer_stream_adapter_) | 820 if (audio_demuxer_stream_adapter_) |
(...skipping 19 matching lines...) Expand all Loading... |
856 (video_demuxer_stream_adapter_->GetBytesWrittenAndReset() / | 840 (video_demuxer_stream_adapter_->GetBytesWrittenAndReset() / |
857 kDataFlowPollPeriod.InSecondsF()) / | 841 kDataFlowPollPeriod.InSecondsF()) / |
858 kBytesPerKilobit; | 842 kBytesPerKilobit; |
859 DCHECK_GE(kilobits_per_second, 0); | 843 DCHECK_GE(kilobits_per_second, 0); |
860 const base::CheckedNumeric<int> checked_kbps = kilobits_per_second; | 844 const base::CheckedNumeric<int> checked_kbps = kilobits_per_second; |
861 metrics_recorder_.OnVideoRateEstimate( | 845 metrics_recorder_.OnVideoRateEstimate( |
862 checked_kbps.ValueOrDefault(std::numeric_limits<int>::max())); | 846 checked_kbps.ValueOrDefault(std::numeric_limits<int>::max())); |
863 } | 847 } |
864 } | 848 } |
865 | 849 |
| 850 } // namespace remoting |
866 } // namespace media | 851 } // namespace media |
OLD | NEW |