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