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 |