aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cast/standalone_receiver/cast_service.cc41
-rw-r--r--cast/standalone_receiver/cast_service.h26
-rw-r--r--cast/standalone_receiver/main.cc41
-rw-r--r--cast/standalone_receiver/mirroring_application.cc12
-rw-r--r--cast/standalone_receiver/streaming_playback_controller.cc8
-rw-r--r--cast/standalone_receiver/streaming_playback_controller.h5
-rw-r--r--cast/standalone_sender/looping_file_cast_agent.cc26
-rw-r--r--cast/standalone_sender/looping_file_cast_agent.h7
-rw-r--r--cast/standalone_sender/main.cc14
-rw-r--r--cast/streaming/receiver_session.cc72
-rw-r--r--cast/streaming/receiver_session.h45
-rw-r--r--cast/streaming/sender_session.h5
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