diff options
-rw-r--r-- | cast/standalone_receiver/cast_service.cc | 41 | ||||
-rw-r--r-- | cast/standalone_receiver/cast_service.h | 26 | ||||
-rw-r--r-- | cast/standalone_receiver/main.cc | 41 | ||||
-rw-r--r-- | cast/standalone_receiver/mirroring_application.cc | 12 | ||||
-rw-r--r-- | cast/standalone_receiver/streaming_playback_controller.cc | 8 | ||||
-rw-r--r-- | cast/standalone_receiver/streaming_playback_controller.h | 5 | ||||
-rw-r--r-- | cast/standalone_sender/looping_file_cast_agent.cc | 26 | ||||
-rw-r--r-- | cast/standalone_sender/looping_file_cast_agent.h | 7 | ||||
-rw-r--r-- | cast/standalone_sender/main.cc | 14 | ||||
-rw-r--r-- | cast/streaming/receiver_session.cc | 72 | ||||
-rw-r--r-- | cast/streaming/receiver_session.h | 45 | ||||
-rw-r--r-- | cast/streaming/sender_session.h | 5 |
12 files changed, 217 insertions, 85 deletions
diff --git a/cast/standalone_receiver/cast_service.cc b/cast/standalone_receiver/cast_service.cc index efab229b..28e6c65c 100644 --- a/cast/standalone_receiver/cast_service.cc +++ b/cast/standalone_receiver/cast_service.cc @@ -37,28 +37,27 @@ discovery::Config MakeDiscoveryConfig(const InterfaceInfo& interface) { } // namespace -CastService::CastService(TaskRunner* task_runner, - const InterfaceInfo& interface, - GeneratedCredentials credentials, - const std::string& friendly_name, - const std::string& model_name, - bool enable_discovery) - : local_endpoint_(DetermineEndpoint(interface)), - credentials_(std::move(credentials)), - agent_(task_runner, credentials_.provider.get()), - mirroring_application_(task_runner, local_endpoint_.address, &agent_), +CastService::CastService(CastService::Configuration config) + : local_endpoint_(DetermineEndpoint(config.interface)), + credentials_(std::move(config.credentials)), + agent_(config.task_runner, credentials_.provider.get()), + mirroring_application_(config.task_runner, + local_endpoint_.address, + &agent_), socket_factory_(&agent_, agent_.cast_socket_client()), connection_factory_( - TlsConnectionFactory::CreateFactory(&socket_factory_, task_runner)), - discovery_service_(enable_discovery ? discovery::CreateDnsSdService( - task_runner, - this, - MakeDiscoveryConfig(interface)) - : LazyDeletedDiscoveryService()), + TlsConnectionFactory::CreateFactory(&socket_factory_, + config.task_runner)), + discovery_service_(config.enable_discovery + ? discovery::CreateDnsSdService( + config.task_runner, + this, + MakeDiscoveryConfig(config.interface)) + : LazyDeletedDiscoveryService()), discovery_publisher_( discovery_service_ ? MakeSerialDelete<discovery::DnsSdServicePublisher<ServiceInfo>>( - task_runner, + config.task_runner, discovery_service_.get(), kCastV2ServiceId, ServiceInfoToDnsSdInstance) @@ -69,11 +68,11 @@ CastService::CastService(TaskRunner* task_runner, if (discovery_publisher_) { ServiceInfo info; info.port = local_endpoint_.port; - info.unique_id = HexEncode(interface.hardware_address); - info.friendly_name = friendly_name; - info.model_name = model_name; + info.unique_id = HexEncode(config.interface.hardware_address); + info.friendly_name = config.friendly_name; + info.model_name = config.model_name; info.capabilities = kHasVideoOutput | kHasAudioOutput; - Error error = discovery_publisher_->Register(info); + const Error error = discovery_publisher_->Register(info); if (!error.ok()) { OnFatalError(std::move(error)); } diff --git a/cast/standalone_receiver/cast_service.h b/cast/standalone_receiver/cast_service.h index 99137de2..c210b433 100644 --- a/cast/standalone_receiver/cast_service.h +++ b/cast/standalone_receiver/cast_service.h @@ -41,13 +41,27 @@ namespace cast { // * Publishes over mDNS to be discoverable to all senders on the same LAN. class CastService final : public discovery::ReportingClient { public: - CastService(TaskRunner* task_runner, - const InterfaceInfo& interface, - GeneratedCredentials credentials, - const std::string& friendly_name, - const std::string& model_name, - bool enable_discovery = true); + struct Configuration { + // The task runner to be used for async calls. + TaskRunner* task_runner; + // The interface the cast service is running on. + InterfaceInfo interface; + + // The credentials that the cast service should use for TLS. + GeneratedCredentials credentials; + + // The friendly name to be used for broadcasting. + std::string friendly_name; + + // The model name to be used for broadcasting. + std::string model_name; + + // Whether we should broadcast over mDNS/DNS-SD. + bool enable_discovery = true; + }; + + explicit CastService(Configuration config); ~CastService() final; private: diff --git a/cast/standalone_receiver/main.cc b/cast/standalone_receiver/main.cc index 8dd0f37a..d66d70e6 100644 --- a/cast/standalone_receiver/main.cc +++ b/cast/standalone_receiver/main.cc @@ -67,6 +67,11 @@ options: -v, --verbose: Enable verbose logging. -h, --help: Show this help message. + + -x, --disable-discovery: Disable discovery, useful for platforms like Mac OS + where our implementation is incompatible with + the native Bonjour service. + )"; std::cerr << StringPrintf(kTemplate, argv0); @@ -95,30 +100,22 @@ InterfaceInfo GetInterfaceInfoFromName(const char* name) { return interface_info; } -void RunCastService(TaskRunnerImpl* task_runner, - const InterfaceInfo& interface, - GeneratedCredentials creds, - const std::string& friendly_name, - const std::string& model_name, - bool discovery_enabled) { +void RunCastService(TaskRunnerImpl* runner, CastService::Configuration config) { std::unique_ptr<CastService> service; - task_runner->PostTask([&] { - service = std::make_unique<CastService>(task_runner, interface, - std::move(creds), friendly_name, - model_name, discovery_enabled); - }); + runner->PostTask( + [&] { service = std::make_unique<CastService>(std::move(config)); }); OSP_LOG_INFO << "CastService is running. CTRL-C (SIGINT), or send a " "SIGTERM to exit."; - task_runner->RunUntilSignaled(); + runner->RunUntilSignaled(); // Spin the TaskRunner to execute destruction/shutdown tasks. OSP_LOG_INFO << "Shutting down..."; - task_runner->PostTask([&] { + runner->PostTask([&] { service.reset(); - task_runner->RequestStopSoon(); + runner->RequestStopSoon(); }); - task_runner->RunUntilStopped(); + runner->RunUntilStopped(); OSP_LOG_INFO << "Bye!"; } @@ -160,7 +157,7 @@ int RunStandaloneReceiver(int argc, char* argv[]) { {nullptr, 0, nullptr, 0}}; bool is_verbose = false; - bool discovery_enabled = true; + bool enable_discovery = true; std::string private_key_path; std::string developer_certificate_path; std::string friendly_name = "Cast Standalone Receiver"; @@ -168,7 +165,7 @@ int RunStandaloneReceiver(int argc, char* argv[]) { bool should_generate_credentials = false; std::unique_ptr<TextTraceLoggingPlatform> trace_logger; int ch = -1; - while ((ch = getopt_long(argc, argv, "p:d:f:m:gtvhx", kArgumentOptions, + while ((ch = getopt_long(argc, argv, "p:d:f:m:grtvhx", kArgumentOptions, nullptr)) != -1) { switch (ch) { case 'p': @@ -193,7 +190,7 @@ int RunStandaloneReceiver(int argc, char* argv[]) { is_verbose = true; break; case 'x': - discovery_enabled = false; + enable_discovery = false; break; case 'h': LogUsage(argv[0]); @@ -234,14 +231,16 @@ int RunStandaloneReceiver(int argc, char* argv[]) { << "Hardware address is empty. Either you are on a loopback device " "or getting the network interface information failed somehow. " "Discovery publishing will be disabled."; - discovery_enabled = false; + enable_discovery = false; } auto* const task_runner = new TaskRunnerImpl(&Clock::now); PlatformClientPosix::Create(milliseconds(50), std::unique_ptr<TaskRunnerImpl>(task_runner)); - RunCastService(task_runner, interface, std::move(creds.value()), - friendly_name, model_name, discovery_enabled); + RunCastService(task_runner, + CastService::Configuration{ + task_runner, interface, std::move(creds.value()), + friendly_name, model_name, enable_discovery}); PlatformClientPosix::ShutDown(); return 0; diff --git a/cast/standalone_receiver/mirroring_application.cc b/cast/standalone_receiver/mirroring_application.cc index b654e010..83921d76 100644 --- a/cast/standalone_receiver/mirroring_application.cc +++ b/cast/standalone_receiver/mirroring_application.cc @@ -4,6 +4,8 @@ #include "cast/standalone_receiver/mirroring_application.h" +#include <utility> + #include "cast/common/public/message_port.h" #include "cast/streaming/constants.h" #include "cast/streaming/environment.h" @@ -53,9 +55,13 @@ bool MirroringApplication::Launch(const std::string& app_id, IPEndpoint{interface_address_, kDefaultCastStreamingPort}); controller_ = std::make_unique<StreamingPlaybackController>(task_runner_, this); - current_session_ = std::make_unique<ReceiverSession>( - controller_.get(), environment_.get(), message_port, - ReceiverSession::Preferences{}); + + ReceiverSession::Preferences preferences; + preferences.remoting = + std::make_unique<ReceiverSession::RemotingPreferences>(); + current_session_ = + std::make_unique<ReceiverSession>(controller_.get(), environment_.get(), + message_port, std::move(preferences)); return true; } diff --git a/cast/standalone_receiver/streaming_playback_controller.cc b/cast/standalone_receiver/streaming_playback_controller.cc index 4c3f627b..918653f5 100644 --- a/cast/standalone_receiver/streaming_playback_controller.cc +++ b/cast/standalone_receiver/streaming_playback_controller.cc @@ -83,6 +83,14 @@ void StreamingPlaybackController::OnNegotiated( #endif // defined(CAST_STANDALONE_RECEIVER_HAVE_EXTERNAL_LIBS) } +void StreamingPlaybackController::OnRemotingNegotiated( + const ReceiverSession* session, + ReceiverSession::RemotingNegotiation negotiation) { + // TODO(issuetracker.google.com/190078859): need ability to initialize + // remoting codecs. + OSP_UNIMPLEMENTED(); +} + void StreamingPlaybackController::OnReceiversDestroying( const ReceiverSession* session, ReceiversDestroyingReason reason) { diff --git a/cast/standalone_receiver/streaming_playback_controller.h b/cast/standalone_receiver/streaming_playback_controller.h index d2ab72f2..5a743bf6 100644 --- a/cast/standalone_receiver/streaming_playback_controller.h +++ b/cast/standalone_receiver/streaming_playback_controller.h @@ -35,10 +35,11 @@ class StreamingPlaybackController final : public ReceiverSession::Client { // ReceiverSession::Client overrides. void OnNegotiated(const ReceiverSession* session, ReceiverSession::ConfiguredReceivers receivers) override; - + void OnRemotingNegotiated( + const ReceiverSession* session, + ReceiverSession::RemotingNegotiation negotiation) override; void OnReceiversDestroying(const ReceiverSession* session, ReceiversDestroyingReason reason) override; - void OnError(const ReceiverSession* session, Error error) override; private: diff --git a/cast/standalone_sender/looping_file_cast_agent.cc b/cast/standalone_sender/looping_file_cast_agent.cc index e26d4f5e..70d489de 100644 --- a/cast/standalone_sender/looping_file_cast_agent.cc +++ b/cast/standalone_sender/looping_file_cast_agent.cc @@ -268,8 +268,14 @@ void LoopingFileCastAgent::CreateAndStartSession() { video_config.resolutions.emplace_back(Resolution{1920, 1080}); OSP_VLOG << "Starting session negotiation."; - const Error negotiation_error = - current_session_->Negotiate({audio_config}, {video_config}); + Error negotiation_error; + if (connection_settings_->use_remoting) { + negotiation_error = + current_session_->NegotiateRemoting(audio_config, video_config); + } else { + negotiation_error = + current_session_->Negotiate({audio_config}, {video_config}); + } if (!negotiation_error.ok()) { OSP_LOG_ERROR << "Failed to negotiate a session: " << negotiation_error; } @@ -289,6 +295,22 @@ void LoopingFileCastAgent::OnNegotiated( std::move(senders), connection_settings_->max_bitrate); } +void LoopingFileCastAgent::OnRemotingNegotiated( + const SenderSession* session, + SenderSession::RemotingNegotiation negotiation) { + // TODO(jophba): this needs to be hashed out as part of + // figuring out the embedder workflow. + if (negotiation.senders.audio_sender == nullptr && + negotiation.senders.video_sender == nullptr) { + OSP_LOG_ERROR << "Missing both audio and video, so exiting..."; + return; + } + + file_sender_ = std::make_unique<LoopingFileSender>( + environment_.get(), connection_settings_->path_to_file.c_str(), session, + std::move(negotiation.senders), connection_settings_->max_bitrate); +} + void LoopingFileCastAgent::OnError(const SenderSession* session, Error error) { OSP_LOG_ERROR << "SenderSession fatal error: " << error; Shutdown(); diff --git a/cast/standalone_sender/looping_file_cast_agent.h b/cast/standalone_sender/looping_file_cast_agent.h index 74ca7f3a..d1d6b6ce 100644 --- a/cast/standalone_sender/looping_file_cast_agent.h +++ b/cast/standalone_sender/looping_file_cast_agent.h @@ -95,6 +95,10 @@ class LoopingFileCastAgent final // Whether we should use the hacky RTP stream IDs for legacy android // receivers, or if we should use the proper values. bool use_android_rtp_hack = true; + + // Whether we should use remoting for the video, instead of the default of + // mirroring. + bool use_remoting = false; }; // Connect to a Cast Receiver, and start the workflow to establish a @@ -147,6 +151,9 @@ class LoopingFileCastAgent final SenderSession::ConfiguredSenders senders, capture_recommendations::Recommendations capture_recommendations) override; + void OnRemotingNegotiated( + const SenderSession* session, + SenderSession::RemotingNegotiation negotiation) override; void OnError(const SenderSession* session, Error error) override; // Helper for stopping the current session, and/or unwinding a remote diff --git a/cast/standalone_sender/main.cc b/cast/standalone_sender/main.cc index c6680cd5..27ff3287 100644 --- a/cast/standalone_sender/main.cc +++ b/cast/standalone_sender/main.cc @@ -70,6 +70,8 @@ usage: %s <options> addr[:port] media_file Use the wrong RTP payload types, for compatibility with older Android TV receivers. See https://crbug.com/631828. + -r, --remoting: Enable remoting content instead of mirroring. + -t, --tracing: Enable performance tracing logging. -v, --verbose: Enable verbose logging. @@ -111,6 +113,7 @@ int StandaloneSenderMain(int argc, char* argv[]) { {"developer-certificate", required_argument, nullptr, 'd'}, #endif {"android-hack", no_argument, nullptr, 'a'}, + {"remoting", no_argument, nullptr, 'r'}, {"tracing", no_argument, nullptr, 't'}, {"verbose", no_argument, nullptr, 'v'}, {"help", no_argument, nullptr, 'h'}, @@ -120,10 +123,11 @@ int StandaloneSenderMain(int argc, char* argv[]) { bool is_verbose = false; std::string developer_certificate_path; bool use_android_rtp_hack = false; + bool use_remoting = false; int max_bitrate = kDefaultMaxBitrate; std::unique_ptr<TextTraceLoggingPlatform> trace_logger; int ch = -1; - while ((ch = getopt_long(argc, argv, "m:d:atvh", kArgumentOptions, + while ((ch = getopt_long(argc, argv, "m:d:artvh", kArgumentOptions, nullptr)) != -1) { switch (ch) { case 'm': @@ -143,6 +147,9 @@ int StandaloneSenderMain(int argc, char* argv[]) { case 'a': use_android_rtp_hack = true; break; + case 'r': + use_remoting = true; + break; case 't': trace_logger = std::make_unique<TextTraceLoggingPlatform>(); break; @@ -206,8 +213,9 @@ int StandaloneSenderMain(int argc, char* argv[]) { cast_agent = new LoopingFileCastAgent( task_runner, [&] { task_runner->RequestStopSoon(); }); cast_agent->Connect({remote_endpoint, path, max_bitrate, - true /* should_include_video */, - use_android_rtp_hack}); + .should_include_video = true, + .use_android_rtp_hack = use_android_rtp_hack, + .use_remoting = use_remoting}); }); // Run the event loop until SIGINT (e.g., CTRL-C at the console) or diff --git a/cast/streaming/receiver_session.cc b/cast/streaming/receiver_session.cc index c2a06d01..9d267ada 100644 --- a/cast/streaming/receiver_session.cc +++ b/cast/streaming/receiver_session.cc @@ -74,6 +74,14 @@ MediaCapability ToCapability(VideoCodec codec) { ReceiverSession::Client::~Client() = default; +using RemotingPreferences = ReceiverSession::RemotingPreferences; + +RemotingPreferences::RemotingPreferences() = default; +RemotingPreferences::RemotingPreferences(RemotingPreferences&&) noexcept = + default; +RemotingPreferences& RemotingPreferences::operator=( + RemotingPreferences&&) noexcept = default; + using Preferences = ReceiverSession::Preferences; Preferences::Preferences() = default; @@ -172,25 +180,17 @@ void ReceiverSession::OnOffer(SenderMessage message) { auto properties = std::make_unique<SessionProperties>(); properties->sequence_number = message.sequence_number; - // TODO(issuetracker.google.com/184186390): ReceiverSession needs to support - // fielding remoting offers. const Offer& offer = absl::get<Offer>(message.body); if (offer.cast_mode == CastMode::kRemoting) { - SendErrorAnswerReply(message.sequence_number, - "Remoting support is not complete in libcast"); - return; - } - - if (!offer.audio_streams.empty() && !preferences_.audio_codecs.empty()) { - properties->selected_audio = - SelectStream(preferences_.audio_codecs, offer.audio_streams); - } - - if (!offer.video_streams.empty() && !preferences_.video_codecs.empty()) { - properties->selected_video = - SelectStream(preferences_.video_codecs, offer.video_streams); + if (!preferences_.remoting) { + SendErrorAnswerReply(message.sequence_number, + "This receiver does not have remoting enabled."); + return; + } } + properties->mode = offer.cast_mode; + SelectStreams(offer, properties.get()); if (!properties->IsValid()) { SendErrorAnswerReply(message.sequence_number, "Failed to select any streams from OFFER"); @@ -243,6 +243,31 @@ void ReceiverSession::OnCapabilitiesRequest(SenderMessage message) { } } +void ReceiverSession::SelectStreams(const Offer& offer, + SessionProperties* properties) { + if (offer.cast_mode == CastMode::kMirroring) { + if (!offer.audio_streams.empty() && !preferences_.audio_codecs.empty()) { + properties->selected_audio = + SelectStream(preferences_.audio_codecs, offer.audio_streams); + } + if (!offer.video_streams.empty() && !preferences_.video_codecs.empty()) { + properties->selected_video = + SelectStream(preferences_.video_codecs, offer.video_streams); + } + } else { + OSP_DCHECK(offer.cast_mode == CastMode::kRemoting); + + if (offer.audio_streams.size() == 1) { + properties->selected_audio = + std::make_unique<AudioStream>(offer.audio_streams[0]); + } + if (offer.video_streams.size() == 1) { + properties->selected_video = + std::make_unique<VideoStream>(offer.video_streams[0]); + } + } +} + void ReceiverSession::InitializeSession(const SessionProperties& properties) { Answer answer = ConstructAnswer(properties); if (!answer.IsValid()) { @@ -255,7 +280,22 @@ void ReceiverSession::InitializeSession(const SessionProperties& properties) { // Only spawn receivers if we know we have a valid answer message. ConfiguredReceivers receivers = SpawnReceivers(properties); - client_->OnNegotiated(this, std::move(receivers)); + if (properties.mode == CastMode::kMirroring) { + client_->OnNegotiated(this, std::move(receivers)); + } else { + // TODO(jophba): cleanup sequence number usage. + broker_ = std::make_unique<RpcBroker>([this](std::vector<uint8_t> message) { + Error error = this->messenger_.SendMessage( + ReceiverMessage{ReceiverMessage::Type::kRpc, -1, true /* valid */, + std::move(message)}); + + if (!error.ok()) { + OSP_LOG_WARN << "Failed to send RPC message: " << error; + } + }); + client_->OnRemotingNegotiated( + this, RemotingNegotiation{std::move(receivers), broker_.get()}); + } const Error result = messenger_.SendMessage(ReceiverMessage{ ReceiverMessage::Type::kAnswer, properties.sequence_number, true /* valid */, std::move(answer)}); diff --git a/cast/streaming/receiver_session.h b/cast/streaming/receiver_session.h index 3c341279..0f9f00cf 100644 --- a/cast/streaming/receiver_session.h +++ b/cast/streaming/receiver_session.h @@ -16,6 +16,7 @@ #include "cast/streaming/offer_messages.h" #include "cast/streaming/receiver_packet_router.h" #include "cast/streaming/resolution.h" +#include "cast/streaming/rpc_broker.h" #include "cast/streaming/sender_message.h" #include "cast/streaming/session_config.h" #include "cast/streaming/session_messenger.h" @@ -26,9 +27,9 @@ namespace cast { class Environment; class Receiver; -// This class is responsible for listening for streaming (both mirroring and -// remoting) requests from Cast Sender devices, then negotiating capture -// constraints and instantiating audio and video Receiver objects. +// This class is responsible for listening for streaming requests from Cast +// Sender devices, then negotiating capture constraints and instantiating audio +// and video Receiver objects. // The owner of this session is expected to provide a client for // updates, an environment for getting UDP socket information (as well as // other OS dependencies), and a set of preferences to be used for @@ -62,17 +63,33 @@ class ReceiverSession final : public Environment::SocketSubscriber { VideoCaptureConfig video_config; }; + // This struct contains all of the information necessary to begin remoting + // once we get a remoting request from a Sender. + struct RemotingNegotiation { + ConfiguredReceivers receivers; + + // The RPC broker to be used for subscribing to remoting proto messages. + RpcBroker* broker; + }; + // The embedder should provide a client for handling connections. // When a connection is established, the OnNegotiated callback is called. class Client { public: enum ReceiversDestroyingReason { kEndOfSession, kRenegotiated }; - // Called when a new set of receivers has been negotiated. This may be - // called multiple times during a session, as renegotiations occur. + // Called when a set of streaming receivers has been negotiated. Both this + // and |OnRemotingNegotiated| may be called repeatedly as negotiations occur + // through the life of a session. virtual void OnNegotiated(const ReceiverSession* session, ConfiguredReceivers receivers) = 0; + // Called when a set of remoting receivers has been negotiated. This will + // only be called if |RemotingPreferences| are provided as part of + // constructing the ReceiverSession object. + virtual void OnRemotingNegotiated(const ReceiverSession* session, + RemotingNegotiation negotiation) {} + // Called immediately preceding the destruction of this session's receivers. // If |reason| is |kEndOfSession|, OnNegotiated() will never be called // again; if it is |kRenegotiated|, OnNegotiated() will be called again @@ -92,7 +109,7 @@ class ReceiverSession final : public Environment::SocketSubscriber { // Information about the display the receiver is attached to. struct Display { // The display limitations of the actual screen, used to provide upper - // bounds on mirroring and remoting streams. For example, we will never + // bounds on streams. For example, we will never // send 60FPS if it is going to be displayed on a 30FPS screen. // Note that we may exceed the display width and height for standard // content sizes like 720p or 1080p. @@ -166,6 +183,12 @@ class ReceiverSession final : public Environment::SocketSubscriber { // TODO(issuetracker.google.com/184429130): the mirroring control // protocol needs to be updated to allow more discrete support. struct RemotingPreferences { + RemotingPreferences(); + RemotingPreferences(RemotingPreferences&&) noexcept; + RemotingPreferences(const RemotingPreferences&) = delete; + RemotingPreferences& operator=(RemotingPreferences&&) noexcept; + RemotingPreferences& operator=(const RemotingPreferences&) = delete; + // Current remoting senders take an "all or nothing" support for audio // codec support. While Opus and AAC support is handled in our Preferences' // |audio_codecs| property, support for the following codecs must be @@ -219,7 +242,7 @@ class ReceiverSession final : public Environment::SocketSubscriber { // Libcast remoting support is opt-in: embedders wishing to field remoting // offers may provide a set of remoting preferences, or leave nullptr for - // all remoting OFFERs to be rejected in favor of continuing mirroring. + // all remoting OFFERs to be rejected in favor of continuing streaming. std::unique_ptr<RemotingPreferences> remoting; }; @@ -263,6 +286,10 @@ class ReceiverSession final : public Environment::SocketSubscriber { void OnOffer(SenderMessage message); void OnCapabilitiesRequest(SenderMessage message); + // Selects streams from an offer based on its configuration, and sets + // them in the session properties. + void SelectStreams(const Offer& offer, SessionProperties* properties); + // Creates receivers and sends an appropriate Answer message using the // session properties. void InitializeSession(const SessionProperties& properties); @@ -307,6 +334,10 @@ class ReceiverSession final : public Environment::SocketSubscriber { // through |Client::OnReceiversDestroying|. std::unique_ptr<Receiver> current_audio_receiver_; std::unique_ptr<Receiver> current_video_receiver_; + + // If remoting, we store the RpcBroker used by the embedder to send RPC + // messages from the remoting protobuf specification. + std::unique_ptr<RpcBroker> broker_; }; } // namespace cast diff --git a/cast/streaming/sender_session.h b/cast/streaming/sender_session.h index 7702b490..d95c61aa 100644 --- a/cast/streaming/sender_session.h +++ b/cast/streaming/sender_session.h @@ -50,8 +50,6 @@ class SenderSession final { // This struct contains all of the information necessary to begin remoting // after we receive the capabilities from the receiver. - // TODO(issuetracker.google.com/184189241): capture recommendations should be - // exposed as part of the remoting negotiation. struct RemotingNegotiation { ConfiguredSenders senders; @@ -258,8 +256,7 @@ class SenderSession final { std::unique_ptr<Sender> current_video_sender_; // If remoting, we store the RpcBroker used by the embedder to send RPC - // messages from the remoting protobuf specification. For more information, - // see //cast/streaming/remoting.proto. + // messages from the remoting protobuf specification. std::unique_ptr<RpcBroker> broker_; }; // namespace cast |