diff options
Diffstat (limited to 'cast/standalone_sender/remoting_sender.cc')
-rw-r--r-- | cast/standalone_sender/remoting_sender.cc | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/cast/standalone_sender/remoting_sender.cc b/cast/standalone_sender/remoting_sender.cc new file mode 100644 index 00000000..e28c9ae1 --- /dev/null +++ b/cast/standalone_sender/remoting_sender.cc @@ -0,0 +1,113 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cast/standalone_sender/remoting_sender.h" + +#include <utility> + +#include "cast/streaming/message_fields.h" + +namespace openscreen { +namespace cast { + +namespace { + +VideoDecoderConfig::Codec ToProtoCodec(VideoCodec value) { + switch (value) { + case VideoCodec::kHevc: + return VideoDecoderConfig_Codec_kCodecHEVC; + case VideoCodec::kH264: + return VideoDecoderConfig_Codec_kCodecH264; + case VideoCodec::kVp8: + return VideoDecoderConfig_Codec_kCodecVP8; + case VideoCodec::kVp9: + return VideoDecoderConfig_Codec_kCodecVP9; + case VideoCodec::kAv1: + return VideoDecoderConfig_Codec_kCodecAV1; + default: + return VideoDecoderConfig_Codec_kUnknownVideoCodec; + } +} + +AudioDecoderConfig::Codec ToProtoCodec(AudioCodec value) { + switch (value) { + case AudioCodec::kAac: + return AudioDecoderConfig_Codec_kCodecAAC; + case AudioCodec::kOpus: + return AudioDecoderConfig_Codec_kCodecOpus; + default: + return AudioDecoderConfig_Codec_kUnknownAudioCodec; + } +} + +} // namespace + +RemotingSender::Client::~Client() = default; + +RemotingSender::RemotingSender(RpcMessenger* messenger, + AudioCodec audio_codec, + VideoCodec video_codec, + Client* client) + : messenger_(messenger), + audio_codec_(audio_codec), + video_codec_(video_codec), + client_(client) { + OSP_DCHECK(client_); + messenger_->RegisterMessageReceiverCallback( + RpcMessenger::kAcquireRendererHandle, + [this](std::unique_ptr<RpcMessage> message) { + OSP_DCHECK(message); + this->OnMessage(*message); + }); +} + +RemotingSender::~RemotingSender() { + messenger_->UnregisterMessageReceiverCallback( + RpcMessenger::kAcquireRendererHandle); +} + +void RemotingSender::OnMessage(const RpcMessage& message) { + if (!message.has_proc()) { + return; + } + if (message.proc() == RpcMessage_RpcProc_RPC_DS_INITIALIZE) { + OSP_VLOG << "Received initialize message"; + OnInitializeMessage(message); + } else if (message.proc() == RpcMessage_RpcProc_RPC_R_SETPLAYBACKRATE) { + OSP_VLOG << "Received playback rate message: " << message.double_value(); + OnPlaybackRateMessage(message); + } +} + +void RemotingSender::OnInitializeMessage(const RpcMessage& message) { + receiver_handle_ = message.integer_value(); + + RpcMessage callback_message; + callback_message.set_handle(receiver_handle_); + callback_message.set_proc(RpcMessage::RPC_DS_INITIALIZE_CALLBACK); + + auto* callback_body = + callback_message.mutable_demuxerstream_initializecb_rpc(); + + // In Chrome, separate calls are used for the audio and video configs, but + // for simplicity's sake we combine them here. + callback_body->mutable_audio_decoder_config()->set_codec( + ToProtoCodec(audio_codec_)); + callback_body->mutable_video_decoder_config()->set_codec( + ToProtoCodec(video_codec_)); + + OSP_DLOG_INFO << "Initializing receiver handle " << receiver_handle_ + << " with audio codec " << CodecToString(audio_codec_) + << " and video codec " << CodecToString(video_codec_); + messenger_->SendMessageToRemote(callback_message); + + client_->OnReady(); +} + +void RemotingSender::OnPlaybackRateMessage(const RpcMessage& message) { + client_->OnPlaybackRateChange(message.double_value()); +} + +} // namespace cast +} // namespace openscreen |