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