diff options
Diffstat (limited to 'cast/standalone_sender/looping_file_sender.cc')
-rw-r--r-- | cast/standalone_sender/looping_file_sender.cc | 91 |
1 files changed, 69 insertions, 22 deletions
diff --git a/cast/standalone_sender/looping_file_sender.cc b/cast/standalone_sender/looping_file_sender.cc index 9fae8439..4362add6 100644 --- a/cast/standalone_sender/looping_file_sender.cc +++ b/cast/standalone_sender/looping_file_sender.cc @@ -4,36 +4,46 @@ #include "cast/standalone_sender/looping_file_sender.h" +#include <utility> + +#if defined(CAST_STANDALONE_SENDER_HAVE_LIBAOM) +#include "cast/standalone_sender/streaming_av1_encoder.h" +#endif +#include "cast/standalone_sender/streaming_vpx_encoder.h" +#include "util/osp_logging.h" #include "util/trace_logging.h" namespace openscreen { namespace cast { LoopingFileSender::LoopingFileSender(Environment* environment, - const char* path, + ConnectionSettings settings, const SenderSession* session, SenderSession::ConfiguredSenders senders, - int max_bitrate) + ShutdownCallback shutdown_callback) : env_(environment), - path_(path), + settings_(std::move(settings)), session_(session), - max_bitrate_(max_bitrate), + shutdown_callback_(std::move(shutdown_callback)), audio_encoder_(senders.audio_sender->config().channels, StreamingOpusEncoder::kDefaultCastAudioFramesPerSecond, senders.audio_sender), - video_encoder_(StreamingVp8Encoder::Parameters{}, - env_->task_runner(), - senders.video_sender), + video_encoder_(CreateVideoEncoder( + StreamingVideoEncoder::Parameters{.codec = settings.codec}, + env_->task_runner(), + senders.video_sender)), next_task_(env_->now_function(), env_->task_runner()), console_update_task_(env_->now_function(), env_->task_runner()) { // Opus and Vp8 are the default values for the config, and if these are set // to a different value that means we offered a codec that we do not // support, which is a developer error. OSP_CHECK(senders.audio_config.codec == AudioCodec::kOpus); - OSP_CHECK(senders.video_config.codec == VideoCodec::kVp8); + OSP_CHECK(senders.video_config.codec == VideoCodec::kVp8 || + senders.video_config.codec == VideoCodec::kVp9 || + senders.video_config.codec == VideoCodec::kAv1); OSP_LOG_INFO << "Max allowed media bitrate (audio + video) will be " - << max_bitrate_; - bandwidth_being_utilized_ = max_bitrate_ / 2; + << settings_.max_bitrate; + bandwidth_being_utilized_ = settings_.max_bitrate / 2; UpdateEncoderBitrates(); next_task_.Schedule([this] { SendFileAgain(); }, Alarm::kImmediately); @@ -41,14 +51,19 @@ LoopingFileSender::LoopingFileSender(Environment* environment, LoopingFileSender::~LoopingFileSender() = default; +void LoopingFileSender::SetPlaybackRate(double rate) { + video_capturer_->SetPlaybackRate(rate); + audio_capturer_->SetPlaybackRate(rate); +} + void LoopingFileSender::UpdateEncoderBitrates() { if (bandwidth_being_utilized_ >= kHighBandwidthThreshold) { audio_encoder_.UseHighQuality(); } else { audio_encoder_.UseStandardQuality(); } - video_encoder_.SetTargetBitrate(bandwidth_being_utilized_ - - audio_encoder_.GetBitrate()); + video_encoder_->SetTargetBitrate(bandwidth_being_utilized_ - + audio_encoder_.GetBitrate()); } void LoopingFileSender::ControlForNetworkCongestion() { @@ -72,7 +87,7 @@ void LoopingFileSender::ControlForNetworkCongestion() { // Repsect the user's maximum bitrate setting. bandwidth_being_utilized_ = - std::min(bandwidth_being_utilized_, max_bitrate_); + std::min(bandwidth_being_utilized_, settings_.max_bitrate); UpdateEncoderBitrates(); } else { @@ -84,16 +99,18 @@ void LoopingFileSender::ControlForNetworkCongestion() { } void LoopingFileSender::SendFileAgain() { - OSP_LOG_INFO << "Sending " << path_ << " (starts in one second)..."; + OSP_LOG_INFO << "Sending " << settings_.path_to_file + << " (starts in one second)..."; TRACE_DEFAULT_SCOPED(TraceCategory::kStandaloneSender); OSP_DCHECK_EQ(num_capturers_running_, 0); num_capturers_running_ = 2; capture_start_time_ = latest_frame_time_ = env_->now() + seconds(1); - audio_capturer_.emplace(env_, path_, audio_encoder_.num_channels(), - audio_encoder_.sample_rate(), capture_start_time_, - this); - video_capturer_.emplace(env_, path_, capture_start_time_, this); + audio_capturer_.emplace( + env_, settings_.path_to_file.c_str(), audio_encoder_.num_channels(), + audio_encoder_.sample_rate(), capture_start_time_, this); + video_capturer_.emplace(env_, settings_.path_to_file.c_str(), + capture_start_time_, this); next_task_.ScheduleFromNow([this] { ControlForNetworkCongestion(); }, kCongestionCheckInterval); @@ -113,7 +130,7 @@ void LoopingFileSender::OnVideoFrame(const AVFrame& av_frame, Clock::time_point capture_time) { TRACE_DEFAULT_SCOPED(TraceCategory::kStandaloneSender); latest_frame_time_ = std::max(capture_time, latest_frame_time_); - StreamingVp8Encoder::VideoFrame frame{}; + StreamingVideoEncoder::VideoFrame frame{}; frame.width = av_frame.width - av_frame.crop_left - av_frame.crop_right; frame.height = av_frame.height - av_frame.crop_top - av_frame.crop_bottom; frame.yuv_planes[0] = av_frame.data[0] + av_frame.crop_left + @@ -125,9 +142,9 @@ void LoopingFileSender::OnVideoFrame(const AVFrame& av_frame, for (int i = 0; i < 3; ++i) { frame.yuv_strides[i] = av_frame.linesize[i]; } - // TODO(miu): Add performance metrics visual overlay (based on Stats + // TODO(jophba): Add performance metrics visual overlay (based on Stats // callback). - video_encoder_.EncodeAndSend(frame, capture_time, {}); + video_encoder_->EncodeAndSend(frame, capture_time, {}); } void LoopingFileSender::UpdateStatusOnConsole() { @@ -156,7 +173,14 @@ void LoopingFileSender::OnEndOfFile(SimulatedCapturer* capturer) { --num_capturers_running_; if (num_capturers_running_ == 0) { console_update_task_.Cancel(); - next_task_.Schedule([this] { SendFileAgain(); }, Alarm::kImmediately); + + if (settings_.should_loop_video) { + OSP_DLOG_INFO << "Starting the media stream over again."; + next_task_.Schedule([this] { SendFileAgain(); }, Alarm::kImmediately); + } else { + OSP_DLOG_INFO << "Video complete. Exiting..."; + shutdown_callback_(); + } } } @@ -183,5 +207,28 @@ const char* LoopingFileSender::ToTrackName(SimulatedCapturer* capturer) const { return which; } +std::unique_ptr<StreamingVideoEncoder> LoopingFileSender::CreateVideoEncoder( + const StreamingVideoEncoder::Parameters& params, + TaskRunner* task_runner, + Sender* sender) { + switch (params.codec) { + case VideoCodec::kVp8: + case VideoCodec::kVp9: + return std::make_unique<StreamingVpxEncoder>(params, task_runner, sender); + case VideoCodec::kAv1: +#if defined(CAST_STANDALONE_SENDER_HAVE_LIBAOM) + return std::make_unique<StreamingAv1Encoder>(params, task_runner, sender); +#else + OSP_LOG_FATAL << "AV1 codec selected, but could not be used because " + "LibAOM not installed."; +#endif + default: + // Since we only support VP8, VP9, and AV1, any other codec value here + // should be due only to developer error. + OSP_LOG_ERROR << "Unsupported codec " << CodecToString(params.codec); + OSP_NOTREACHED(); + } +} + } // namespace cast } // namespace openscreen |