aboutsummaryrefslogtreecommitdiff
path: root/cast/standalone_receiver/main.cc
diff options
context:
space:
mode:
authorYuri Wiitala <miu@chromium.org>2020-03-11 17:13:54 -0700
committerCommit Bot <commit-bot@chromium.org>2020-03-13 01:37:33 +0000
commit341085a69375757298fa77187a6dbcd0d7d9bfdd (patch)
tree4b53c44bbc92ee290ecdde9de593ec2121c95343 /cast/standalone_receiver/main.cc
parent81d24dbc25c2fbb17626ea1c9383e8bad7d0d806 (diff)
downloadopenscreen-341085a69375757298fa77187a6dbcd0d7d9bfdd.tar.gz
Cast Streaming Standalone Sender (3 of 3): main.cc
Glues everything together, providing a command-line interface for sending a media file to a Cast Streaming Receiver. Also, consistency and bug fixes to the standalone receiver's main.cc This provides audio-only streaming at this time. Both bandwidth estimation and libvpx encoding need to be in-place before video streaming can be enabled. Change-Id: I79282cfca103f09c35b4bcebaebc28559a06f914 Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/2087739 Reviewed-by: Max Yakimakha <yakimakha@chromium.org> Commit-Queue: Yuri Wiitala <miu@chromium.org>
Diffstat (limited to 'cast/standalone_receiver/main.cc')
-rw-r--r--cast/standalone_receiver/main.cc106
1 files changed, 68 insertions, 38 deletions
diff --git a/cast/standalone_receiver/main.cc b/cast/standalone_receiver/main.cc
index 1dc8b6f5..0320f7c7 100644
--- a/cast/standalone_receiver/main.cc
+++ b/cast/standalone_receiver/main.cc
@@ -6,7 +6,6 @@
#include <array>
#include <chrono> // NOLINT
-#include <thread> // NOLINT
#include "cast/standalone_receiver/simple_message_port.h"
#include "cast/standalone_receiver/streaming_playback_controller.h"
@@ -41,8 +40,8 @@ namespace {
// application as: 1) the TYPE of the content changes (interactive, low-latency
// versus smooth, higher-latency buffered video watching); and 2) the networking
// environment reliability changes.
-
-constexpr std::chrono::milliseconds kDemoTargetPlayoutDelay{400};
+constexpr std::chrono::milliseconds kTargetPlayoutDelay =
+ kDefaultTargetPlayoutDelay;
const Offer kDemoOffer{
/* .cast_mode = */ CastMode{},
@@ -53,7 +52,7 @@ const Offer kDemoOffer{
/* .codec_name = */ "opus",
/* .rtp_payload_type = */ RtpPayloadType::kAudioOpus,
/* .ssrc = */ 1,
- /* .target_delay */ kDemoTargetPlayoutDelay,
+ /* .target_delay */ kTargetPlayoutDelay,
/* .aes_key = */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
@@ -73,7 +72,7 @@ const Offer kDemoOffer{
/* .codec_name = */ "vp8",
/* .rtp_payload_type = */ RtpPayloadType::kVideoVp8,
/* .ssrc = */ 50001,
- /* .target_delay */ kDemoTargetPlayoutDelay,
+ /* .target_delay */ kTargetPlayoutDelay,
/* .aes_key = */
{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f},
@@ -94,23 +93,21 @@ const Offer kDemoOffer{
/* .resolutions = */ {},
/* .error_recovery_mode = */ ""}}};
-// The UDP socket port receiving packets from the Sender.
-constexpr int kCastStreamingPort = 2344;
-
// End of Receiver Configuration.
////////////////////////////////////////////////////////////////////////////////
void RunStandaloneReceiver(TaskRunnerImpl* task_runner,
- const IPAddress& address) {
+ const IPEndpoint& receive_endpoint) {
// Create the Environment that holds the required injected dependencies
// (clock, task runner) used throughout the system, and owns the UDP socket
// over which all communication occurs with the Sender.
- const IPEndpoint receive_endpoint{address, kCastStreamingPort};
-
auto env =
std::make_unique<Environment>(&Clock::now, task_runner, receive_endpoint);
auto port = std::make_unique<SimpleMessagePort>();
auto* raw_port = port.get();
+
+ // This may differ from the receive_endpoint (e.g., if the OS auto-assigned
+ // the address and/or port).
const auto endpoint = env->GetBoundLocalEndpoint();
ReceiverSession::Preferences preferences{
@@ -136,61 +133,94 @@ void RunStandaloneReceiver(TaskRunnerImpl* task_runner,
<< "...";
// Run the event loop until an exit is requested (e.g., the video player GUI
- // window is closed, a SIGTERM is intercepted, or whatever other appropriate
- // user indication that shutdown is requested).
- task_runner->RunUntilStopped();
+ // window is closed, a SIGINT or SIGTERM is received, or whatever other
+ // appropriate user indication that shutdown is requested).
+ task_runner->RunUntilSignaled();
}
} // namespace
} // namespace cast
} // namespace openscreen
+namespace {
+
+void LogUsage(const char* argv0) {
+ constexpr char kExecutableTag[] = "argv[0]";
+ constexpr char kUsageMessage[] = R"(
+ usage: argv[0] <options>
+
+ --address=addr[:port]
+ Specify the LOCAL IPv4 or IPv6 address and port to bind to (e.g.,
+ 192.168.1.22:9999 or [::1]:12345). This is used to bind to a specific
+ network interface. Or, use the ANY address (0.0.0.0) to attempt to
+ bind to all interfaces (but this mode does not work reliably on some
+ platforms).
+
+ Default if not set: 127.0.0.1 (and default Cast Streaming port 2344)
+
+ --tracing: Enable performance tracing logging.
+ )";
+ std::string message = kUsageMessage;
+ message.replace(message.find(kExecutableTag), strlen(kExecutableTag), argv0);
+ OSP_LOG_ERROR << message;
+}
+
+} // namespace
+
int main(int argc, char* argv[]) {
using openscreen::Clock;
+ using openscreen::ErrorOr;
+ using openscreen::IPAddress;
+ using openscreen::IPEndpoint;
using openscreen::PlatformClientPosix;
- using openscreen::TaskRunner;
using openscreen::TaskRunnerImpl;
- struct option argument_options[] = {
- {"address", required_argument, nullptr, 'a'},
- {"tracing", no_argument, nullptr, 't'}};
+ openscreen::SetLogLevel(openscreen::LogLevel::kInfo);
- struct Arguments {
- openscreen::IPAddress address;
- bool is_tracing_enabled = false;
- };
+ const struct option argument_options[] = {
+ {"address", required_argument, nullptr, 'a'},
+ {"tracing", no_argument, nullptr, 't'},
+ {"help", no_argument, nullptr, 'h'},
+ {nullptr, 0, nullptr, 0}};
- Arguments arguments;
+ IPEndpoint receive_endpoint{IPAddress::kV4LoopbackAddress,
+ openscreen::cast::kDefaultCastStreamingPort};
+ std::unique_ptr<openscreen::TextTraceLoggingPlatform> trace_logger;
int ch = -1;
- while ((ch = getopt_long(argc, argv, "a:t", argument_options, nullptr)) !=
+ while ((ch = getopt_long(argc, argv, "a:th", argument_options, nullptr)) !=
-1) {
switch (ch) {
case 'a': {
- auto error_or_address = openscreen::IPAddress::Parse(optarg);
- if (error_or_address.is_error()) {
- OSP_LOG_ERROR << "Invalid IP address given, exiting...";
- return -1;
+ const ErrorOr<IPEndpoint> parsed_endpoint = IPEndpoint::Parse(optarg);
+ if (parsed_endpoint.is_value()) {
+ receive_endpoint = parsed_endpoint.value();
+ } else {
+ const ErrorOr<IPAddress> parsed_address = IPAddress::Parse(optarg);
+ if (parsed_address.is_value()) {
+ receive_endpoint.address = parsed_address.value();
+ } else {
+ OSP_LOG_ERROR << "Invalid --address specified: " << optarg;
+ return 1;
+ }
}
- arguments.address = std::move(error_or_address.value());
- } break;
+ break;
+ }
case 't':
- arguments.is_tracing_enabled = true;
+ trace_logger = std::make_unique<openscreen::TextTraceLoggingPlatform>();
+ break;
+ case 'h':
+ LogUsage(argv[0]);
+ return 1;
}
}
- std::unique_ptr<openscreen::TextTraceLoggingPlatform> platform;
- if (arguments.is_tracing_enabled) {
- platform = std::make_unique<openscreen::TextTraceLoggingPlatform>();
- }
-
- openscreen::SetLogLevel(openscreen::LogLevel::kInfo);
auto* const task_runner = new TaskRunnerImpl(&Clock::now);
PlatformClientPosix::Create(Clock::duration{50}, Clock::duration{50},
std::unique_ptr<TaskRunnerImpl>(task_runner));
// Runs until the process is interrupted. Safe to pass |task_runner| as it
// will not be destroyed by ShutDown() until this exits.
- openscreen::cast::RunStandaloneReceiver(task_runner, arguments.address);
+ openscreen::cast::RunStandaloneReceiver(task_runner, receive_endpoint);
PlatformClientPosix::ShutDown();
return 0;
}