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