aboutsummaryrefslogtreecommitdiff
path: root/video/video_send_stream.cc
diff options
context:
space:
mode:
Diffstat (limited to 'video/video_send_stream.cc')
-rw-r--r--video/video_send_stream.cc175
1 files changed, 116 insertions, 59 deletions
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index 91c246c66e..591a8d58d8 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -23,7 +23,6 @@
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/field_trial.h"
#include "video/adaptation/overuse_frame_detector.h"
-#include "video/video_send_stream_impl.h"
#include "video/video_stream_encoder.h"
namespace webrtc {
@@ -65,7 +64,10 @@ VideoStreamEncoder::BitrateAllocationCallbackType
GetBitrateAllocationCallbackType(const VideoSendStream::Config& config) {
if (webrtc::RtpExtension::FindHeaderExtensionByUri(
config.rtp.extensions,
- webrtc::RtpExtension::kVideoLayersAllocationUri)) {
+ webrtc::RtpExtension::kVideoLayersAllocationUri,
+ config.crypto_options.srtp.enable_encrypted_rtp_header_extensions
+ ? RtpExtension::Filter::kPreferEncryptedExtension
+ : RtpExtension::Filter::kDiscardEncryptedExtension)) {
return VideoStreamEncoder::BitrateAllocationCallbackType::
kVideoLayersAllocation;
}
@@ -77,6 +79,32 @@ GetBitrateAllocationCallbackType(const VideoSendStream::Config& config) {
kVideoBitrateAllocationWhenScreenSharing;
}
+RtpSenderFrameEncryptionConfig CreateFrameEncryptionConfig(
+ const VideoSendStream::Config* config) {
+ RtpSenderFrameEncryptionConfig frame_encryption_config;
+ frame_encryption_config.frame_encryptor = config->frame_encryptor;
+ frame_encryption_config.crypto_options = config->crypto_options;
+ return frame_encryption_config;
+}
+
+RtpSenderObservers CreateObservers(RtcpRttStats* call_stats,
+ EncoderRtcpFeedback* encoder_feedback,
+ SendStatisticsProxy* stats_proxy,
+ SendDelayStats* send_delay_stats) {
+ RtpSenderObservers observers;
+ observers.rtcp_rtt_stats = call_stats;
+ observers.intra_frame_callback = encoder_feedback;
+ observers.rtcp_loss_notification_observer = encoder_feedback;
+ observers.report_block_data_observer = stats_proxy;
+ observers.rtp_stats = stats_proxy;
+ observers.bitrate_observer = stats_proxy;
+ observers.frame_count_observer = stats_proxy;
+ observers.rtcp_type_observer = stats_proxy;
+ observers.send_delay_observer = stats_proxy;
+ observers.send_packet_observer = send_delay_stats;
+ return observers;
+}
+
} // namespace
namespace internal {
@@ -96,46 +124,65 @@ VideoSendStream::VideoSendStream(
const std::map<uint32_t, RtpState>& suspended_ssrcs,
const std::map<uint32_t, RtpPayloadState>& suspended_payload_states,
std::unique_ptr<FecController> fec_controller)
- : worker_queue_(transport->GetWorkerQueue()),
+ : rtp_transport_queue_(transport->GetWorkerQueue()),
+ transport_(transport),
stats_proxy_(clock, config, encoder_config.content_type),
config_(std::move(config)),
- content_type_(encoder_config.content_type) {
+ content_type_(encoder_config.content_type),
+ video_stream_encoder_(std::make_unique<VideoStreamEncoder>(
+ clock,
+ num_cpu_cores,
+ &stats_proxy_,
+ config_.encoder_settings,
+ std::make_unique<OveruseFrameDetector>(&stats_proxy_),
+ task_queue_factory,
+ GetBitrateAllocationCallbackType(config_))),
+ encoder_feedback_(
+ clock,
+ config_.rtp.ssrcs,
+ video_stream_encoder_.get(),
+ [this](uint32_t ssrc, const std::vector<uint16_t>& seq_nums) {
+ return rtp_video_sender_->GetSentRtpPacketInfos(ssrc, seq_nums);
+ }),
+ rtp_video_sender_(
+ transport->CreateRtpVideoSender(suspended_ssrcs,
+ suspended_payload_states,
+ config_.rtp,
+ config_.rtcp_report_interval_ms,
+ config_.send_transport,
+ CreateObservers(call_stats,
+ &encoder_feedback_,
+ &stats_proxy_,
+ send_delay_stats),
+ event_log,
+ std::move(fec_controller),
+ CreateFrameEncryptionConfig(&config_),
+ config_.frame_transformer)),
+ send_stream_(clock,
+ &stats_proxy_,
+ rtp_transport_queue_,
+ transport,
+ bitrate_allocator,
+ video_stream_encoder_.get(),
+ &config_,
+ encoder_config.max_bitrate_bps,
+ encoder_config.bitrate_priority,
+ encoder_config.content_type,
+ rtp_video_sender_) {
RTC_DCHECK(config_.encoder_settings.encoder_factory);
RTC_DCHECK(config_.encoder_settings.bitrate_allocator_factory);
- video_stream_encoder_ = std::make_unique<VideoStreamEncoder>(
- clock, num_cpu_cores, &stats_proxy_, config_.encoder_settings,
- std::make_unique<OveruseFrameDetector>(&stats_proxy_), task_queue_factory,
- GetBitrateAllocationCallbackType(config_));
-
- // TODO(srte): Initialization should not be done posted on a task queue.
- // Note that the posted task must not outlive this scope since the closure
- // references local variables.
- worker_queue_->PostTask(ToQueuedTask(
- [this, clock, call_stats, transport, bitrate_allocator, send_delay_stats,
- event_log, &suspended_ssrcs, &encoder_config, &suspended_payload_states,
- &fec_controller]() {
- send_stream_.reset(new VideoSendStreamImpl(
- clock, &stats_proxy_, worker_queue_, call_stats, transport,
- bitrate_allocator, send_delay_stats, video_stream_encoder_.get(),
- event_log, &config_, encoder_config.max_bitrate_bps,
- encoder_config.bitrate_priority, suspended_ssrcs,
- suspended_payload_states, encoder_config.content_type,
- std::move(fec_controller)));
- },
- [this]() { thread_sync_event_.Set(); }));
-
- // Wait for ConstructionTask to complete so that |send_stream_| can be used.
- // |module_process_thread| must be registered and deregistered on the thread
- // it was created on.
- thread_sync_event_.Wait(rtc::Event::kForever);
- send_stream_->RegisterProcessThread(module_process_thread);
+ video_stream_encoder_->SetFecControllerOverride(rtp_video_sender_);
+
+ rtp_video_sender_->RegisterProcessThread(module_process_thread);
ReconfigureVideoEncoder(std::move(encoder_config));
}
VideoSendStream::~VideoSendStream() {
RTC_DCHECK_RUN_ON(&thread_checker_);
- RTC_DCHECK(!send_stream_);
+ RTC_DCHECK(!running_);
+ rtp_video_sender_->DeRegisterProcessThread();
+ transport_->DestroyRtpVideoSender(rtp_video_sender_);
}
void VideoSendStream::UpdateActiveSimulcastLayers(
@@ -158,35 +205,43 @@ void VideoSendStream::UpdateActiveSimulcastLayers(
RTC_LOG(LS_INFO) << "UpdateActiveSimulcastLayers: "
<< active_layers_string.str();
- VideoSendStreamImpl* send_stream = send_stream_.get();
- worker_queue_->PostTask([this, send_stream, active_layers] {
- send_stream->UpdateActiveSimulcastLayers(active_layers);
- thread_sync_event_.Set();
- });
-
- thread_sync_event_.Wait(rtc::Event::kForever);
+ rtp_transport_queue_->PostTask(
+ ToQueuedTask(transport_queue_safety_, [this, active_layers] {
+ send_stream_.UpdateActiveSimulcastLayers(active_layers);
+ }));
}
void VideoSendStream::Start() {
RTC_DCHECK_RUN_ON(&thread_checker_);
- RTC_LOG(LS_INFO) << "VideoSendStream::Start";
- VideoSendStreamImpl* send_stream = send_stream_.get();
- worker_queue_->PostTask([this, send_stream] {
- send_stream->Start();
+ RTC_DLOG(LS_INFO) << "VideoSendStream::Start";
+ if (running_)
+ return;
+
+ running_ = true;
+
+ rtp_transport_queue_->PostTask(ToQueuedTask([this] {
+ transport_queue_safety_->SetAlive();
+ send_stream_.Start();
thread_sync_event_.Set();
- });
+ }));
// It is expected that after VideoSendStream::Start has been called, incoming
// frames are not dropped in VideoStreamEncoder. To ensure this, Start has to
// be synchronized.
+ // TODO(tommi): ^^^ Validate if this still holds.
thread_sync_event_.Wait(rtc::Event::kForever);
}
void VideoSendStream::Stop() {
RTC_DCHECK_RUN_ON(&thread_checker_);
- RTC_LOG(LS_INFO) << "VideoSendStream::Stop";
- VideoSendStreamImpl* send_stream = send_stream_.get();
- worker_queue_->PostTask([send_stream] { send_stream->Stop(); });
+ if (!running_)
+ return;
+ RTC_DLOG(LS_INFO) << "VideoSendStream::Stop";
+ running_ = false;
+ rtp_transport_queue_->PostTask(ToQueuedTask(transport_queue_safety_, [this] {
+ transport_queue_safety_->SetNotAlive();
+ send_stream_.Stop();
+ }));
}
void VideoSendStream::AddAdaptationResource(
@@ -209,10 +264,8 @@ void VideoSendStream::SetSource(
}
void VideoSendStream::ReconfigureVideoEncoder(VideoEncoderConfig config) {
- // TODO(perkj): Some test cases in VideoSendStreamTest call
- // ReconfigureVideoEncoder from the network thread.
- // RTC_DCHECK_RUN_ON(&thread_checker_);
- RTC_DCHECK(content_type_ == config.content_type);
+ RTC_DCHECK_RUN_ON(&thread_checker_);
+ RTC_DCHECK_EQ(content_type_, config.content_type);
video_stream_encoder_->ConfigureEncoder(
std::move(config),
config_.rtp.max_packet_size - CalculateMaxHeaderSize(config_.rtp));
@@ -226,7 +279,7 @@ VideoSendStream::Stats VideoSendStream::GetStats() {
}
absl::optional<float> VideoSendStream::GetPacingFactorOverride() const {
- return send_stream_->configured_pacing_factor_;
+ return send_stream_.configured_pacing_factor();
}
void VideoSendStream::StopPermanentlyAndGetRtpStates(
@@ -234,12 +287,16 @@ void VideoSendStream::StopPermanentlyAndGetRtpStates(
VideoSendStream::RtpPayloadStateMap* payload_state_map) {
RTC_DCHECK_RUN_ON(&thread_checker_);
video_stream_encoder_->Stop();
- send_stream_->DeRegisterProcessThread();
- worker_queue_->PostTask([this, rtp_state_map, payload_state_map]() {
- send_stream_->Stop();
- *rtp_state_map = send_stream_->GetRtpStates();
- *payload_state_map = send_stream_->GetRtpPayloadStates();
- send_stream_.reset();
+
+ running_ = false;
+ // Always run these cleanup steps regardless of whether running_ was set
+ // or not. This will unregister callbacks before destruction.
+ // See `VideoSendStreamImpl::StopVideoSendStream` for more.
+ rtp_transport_queue_->PostTask([this, rtp_state_map, payload_state_map]() {
+ transport_queue_safety_->SetNotAlive();
+ send_stream_.Stop();
+ *rtp_state_map = send_stream_.GetRtpStates();
+ *payload_state_map = send_stream_.GetRtpPayloadStates();
thread_sync_event_.Set();
});
thread_sync_event_.Wait(rtc::Event::kForever);
@@ -247,7 +304,7 @@ void VideoSendStream::StopPermanentlyAndGetRtpStates(
void VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
// Called on a network thread.
- send_stream_->DeliverRtcp(packet, length);
+ send_stream_.DeliverRtcp(packet, length);
}
} // namespace internal