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