xref: /aosp_15_r20/external/webrtc/video/video_send_stream.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker #include "video/video_send_stream.h"
11*d9f75844SAndroid Build Coastguard Worker 
12*d9f75844SAndroid Build Coastguard Worker #include <utility>
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include "api/array_view.h"
15*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h"
16*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_stream_encoder_settings.h"
17*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
18*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_header_extension_size.h"
19*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_sender.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
23*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
24*d9f75844SAndroid Build Coastguard Worker #include "video/adaptation/overuse_frame_detector.h"
25*d9f75844SAndroid Build Coastguard Worker #include "video/frame_cadence_adapter.h"
26*d9f75844SAndroid Build Coastguard Worker #include "video/video_stream_encoder.h"
27*d9f75844SAndroid Build Coastguard Worker 
28*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
29*d9f75844SAndroid Build Coastguard Worker 
30*d9f75844SAndroid Build Coastguard Worker namespace {
31*d9f75844SAndroid Build Coastguard Worker 
CalculateMaxHeaderSize(const RtpConfig & config)32*d9f75844SAndroid Build Coastguard Worker size_t CalculateMaxHeaderSize(const RtpConfig& config) {
33*d9f75844SAndroid Build Coastguard Worker   size_t header_size = kRtpHeaderSize;
34*d9f75844SAndroid Build Coastguard Worker   size_t extensions_size = 0;
35*d9f75844SAndroid Build Coastguard Worker   size_t fec_extensions_size = 0;
36*d9f75844SAndroid Build Coastguard Worker   if (!config.extensions.empty()) {
37*d9f75844SAndroid Build Coastguard Worker     RtpHeaderExtensionMap extensions_map(config.extensions);
38*d9f75844SAndroid Build Coastguard Worker     extensions_size = RtpHeaderExtensionSize(RTPSender::VideoExtensionSizes(),
39*d9f75844SAndroid Build Coastguard Worker                                              extensions_map);
40*d9f75844SAndroid Build Coastguard Worker     fec_extensions_size =
41*d9f75844SAndroid Build Coastguard Worker         RtpHeaderExtensionSize(RTPSender::FecExtensionSizes(), extensions_map);
42*d9f75844SAndroid Build Coastguard Worker   }
43*d9f75844SAndroid Build Coastguard Worker   header_size += extensions_size;
44*d9f75844SAndroid Build Coastguard Worker   if (config.flexfec.payload_type >= 0) {
45*d9f75844SAndroid Build Coastguard Worker     // All FEC extensions again plus maximum FlexFec overhead.
46*d9f75844SAndroid Build Coastguard Worker     header_size += fec_extensions_size + 32;
47*d9f75844SAndroid Build Coastguard Worker   } else {
48*d9f75844SAndroid Build Coastguard Worker     if (config.ulpfec.ulpfec_payload_type >= 0) {
49*d9f75844SAndroid Build Coastguard Worker       // Header with all the FEC extensions will be repeated plus maximum
50*d9f75844SAndroid Build Coastguard Worker       // UlpFec overhead.
51*d9f75844SAndroid Build Coastguard Worker       header_size += fec_extensions_size + 18;
52*d9f75844SAndroid Build Coastguard Worker     }
53*d9f75844SAndroid Build Coastguard Worker     if (config.ulpfec.red_payload_type >= 0) {
54*d9f75844SAndroid Build Coastguard Worker       header_size += 1;  // RED header.
55*d9f75844SAndroid Build Coastguard Worker     }
56*d9f75844SAndroid Build Coastguard Worker   }
57*d9f75844SAndroid Build Coastguard Worker   // Additional room for Rtx.
58*d9f75844SAndroid Build Coastguard Worker   if (config.rtx.payload_type >= 0)
59*d9f75844SAndroid Build Coastguard Worker     header_size += kRtxHeaderSize;
60*d9f75844SAndroid Build Coastguard Worker   return header_size;
61*d9f75844SAndroid Build Coastguard Worker }
62*d9f75844SAndroid Build Coastguard Worker 
63*d9f75844SAndroid Build Coastguard Worker VideoStreamEncoder::BitrateAllocationCallbackType
GetBitrateAllocationCallbackType(const VideoSendStream::Config & config,const FieldTrialsView & field_trials)64*d9f75844SAndroid Build Coastguard Worker GetBitrateAllocationCallbackType(const VideoSendStream::Config& config,
65*d9f75844SAndroid Build Coastguard Worker                                  const FieldTrialsView& field_trials) {
66*d9f75844SAndroid Build Coastguard Worker   if (webrtc::RtpExtension::FindHeaderExtensionByUri(
67*d9f75844SAndroid Build Coastguard Worker           config.rtp.extensions,
68*d9f75844SAndroid Build Coastguard Worker           webrtc::RtpExtension::kVideoLayersAllocationUri,
69*d9f75844SAndroid Build Coastguard Worker           config.crypto_options.srtp.enable_encrypted_rtp_header_extensions
70*d9f75844SAndroid Build Coastguard Worker               ? RtpExtension::Filter::kPreferEncryptedExtension
71*d9f75844SAndroid Build Coastguard Worker               : RtpExtension::Filter::kDiscardEncryptedExtension)) {
72*d9f75844SAndroid Build Coastguard Worker     return VideoStreamEncoder::BitrateAllocationCallbackType::
73*d9f75844SAndroid Build Coastguard Worker         kVideoLayersAllocation;
74*d9f75844SAndroid Build Coastguard Worker   }
75*d9f75844SAndroid Build Coastguard Worker   if (field_trials.IsEnabled("WebRTC-Target-Bitrate-Rtcp")) {
76*d9f75844SAndroid Build Coastguard Worker     return VideoStreamEncoder::BitrateAllocationCallbackType::
77*d9f75844SAndroid Build Coastguard Worker         kVideoBitrateAllocation;
78*d9f75844SAndroid Build Coastguard Worker   }
79*d9f75844SAndroid Build Coastguard Worker   return VideoStreamEncoder::BitrateAllocationCallbackType::
80*d9f75844SAndroid Build Coastguard Worker       kVideoBitrateAllocationWhenScreenSharing;
81*d9f75844SAndroid Build Coastguard Worker }
82*d9f75844SAndroid Build Coastguard Worker 
CreateFrameEncryptionConfig(const VideoSendStream::Config * config)83*d9f75844SAndroid Build Coastguard Worker RtpSenderFrameEncryptionConfig CreateFrameEncryptionConfig(
84*d9f75844SAndroid Build Coastguard Worker     const VideoSendStream::Config* config) {
85*d9f75844SAndroid Build Coastguard Worker   RtpSenderFrameEncryptionConfig frame_encryption_config;
86*d9f75844SAndroid Build Coastguard Worker   frame_encryption_config.frame_encryptor = config->frame_encryptor.get();
87*d9f75844SAndroid Build Coastguard Worker   frame_encryption_config.crypto_options = config->crypto_options;
88*d9f75844SAndroid Build Coastguard Worker   return frame_encryption_config;
89*d9f75844SAndroid Build Coastguard Worker }
90*d9f75844SAndroid Build Coastguard Worker 
CreateObservers(RtcpRttStats * call_stats,EncoderRtcpFeedback * encoder_feedback,SendStatisticsProxy * stats_proxy,SendDelayStats * send_delay_stats)91*d9f75844SAndroid Build Coastguard Worker RtpSenderObservers CreateObservers(RtcpRttStats* call_stats,
92*d9f75844SAndroid Build Coastguard Worker                                    EncoderRtcpFeedback* encoder_feedback,
93*d9f75844SAndroid Build Coastguard Worker                                    SendStatisticsProxy* stats_proxy,
94*d9f75844SAndroid Build Coastguard Worker                                    SendDelayStats* send_delay_stats) {
95*d9f75844SAndroid Build Coastguard Worker   RtpSenderObservers observers;
96*d9f75844SAndroid Build Coastguard Worker   observers.rtcp_rtt_stats = call_stats;
97*d9f75844SAndroid Build Coastguard Worker   observers.intra_frame_callback = encoder_feedback;
98*d9f75844SAndroid Build Coastguard Worker   observers.rtcp_loss_notification_observer = encoder_feedback;
99*d9f75844SAndroid Build Coastguard Worker   observers.report_block_data_observer = stats_proxy;
100*d9f75844SAndroid Build Coastguard Worker   observers.rtp_stats = stats_proxy;
101*d9f75844SAndroid Build Coastguard Worker   observers.bitrate_observer = stats_proxy;
102*d9f75844SAndroid Build Coastguard Worker   observers.frame_count_observer = stats_proxy;
103*d9f75844SAndroid Build Coastguard Worker   observers.rtcp_type_observer = stats_proxy;
104*d9f75844SAndroid Build Coastguard Worker   observers.send_delay_observer = stats_proxy;
105*d9f75844SAndroid Build Coastguard Worker   observers.send_packet_observer = send_delay_stats;
106*d9f75844SAndroid Build Coastguard Worker   return observers;
107*d9f75844SAndroid Build Coastguard Worker }
108*d9f75844SAndroid Build Coastguard Worker 
CreateVideoStreamEncoder(Clock * clock,int num_cpu_cores,TaskQueueFactory * task_queue_factory,SendStatisticsProxy * stats_proxy,const VideoStreamEncoderSettings & encoder_settings,VideoStreamEncoder::BitrateAllocationCallbackType bitrate_allocation_callback_type,const FieldTrialsView & field_trials,webrtc::VideoEncoderFactory::EncoderSelectorInterface * encoder_selector)109*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<VideoStreamEncoder> CreateVideoStreamEncoder(
110*d9f75844SAndroid Build Coastguard Worker     Clock* clock,
111*d9f75844SAndroid Build Coastguard Worker     int num_cpu_cores,
112*d9f75844SAndroid Build Coastguard Worker     TaskQueueFactory* task_queue_factory,
113*d9f75844SAndroid Build Coastguard Worker     SendStatisticsProxy* stats_proxy,
114*d9f75844SAndroid Build Coastguard Worker     const VideoStreamEncoderSettings& encoder_settings,
115*d9f75844SAndroid Build Coastguard Worker     VideoStreamEncoder::BitrateAllocationCallbackType
116*d9f75844SAndroid Build Coastguard Worker         bitrate_allocation_callback_type,
117*d9f75844SAndroid Build Coastguard Worker     const FieldTrialsView& field_trials,
118*d9f75844SAndroid Build Coastguard Worker     webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector) {
119*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<TaskQueueBase, TaskQueueDeleter> encoder_queue =
120*d9f75844SAndroid Build Coastguard Worker       task_queue_factory->CreateTaskQueue("EncoderQueue",
121*d9f75844SAndroid Build Coastguard Worker                                           TaskQueueFactory::Priority::NORMAL);
122*d9f75844SAndroid Build Coastguard Worker   TaskQueueBase* encoder_queue_ptr = encoder_queue.get();
123*d9f75844SAndroid Build Coastguard Worker   return std::make_unique<VideoStreamEncoder>(
124*d9f75844SAndroid Build Coastguard Worker       clock, num_cpu_cores, stats_proxy, encoder_settings,
125*d9f75844SAndroid Build Coastguard Worker       std::make_unique<OveruseFrameDetector>(stats_proxy, field_trials),
126*d9f75844SAndroid Build Coastguard Worker       FrameCadenceAdapterInterface::Create(clock, encoder_queue_ptr,
127*d9f75844SAndroid Build Coastguard Worker                                            field_trials),
128*d9f75844SAndroid Build Coastguard Worker       std::move(encoder_queue), bitrate_allocation_callback_type, field_trials,
129*d9f75844SAndroid Build Coastguard Worker       encoder_selector);
130*d9f75844SAndroid Build Coastguard Worker }
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker }  // namespace
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker namespace internal {
135*d9f75844SAndroid Build Coastguard Worker 
VideoSendStream(Clock * clock,int num_cpu_cores,TaskQueueFactory * task_queue_factory,TaskQueueBase * network_queue,RtcpRttStats * call_stats,RtpTransportControllerSendInterface * transport,BitrateAllocatorInterface * bitrate_allocator,SendDelayStats * send_delay_stats,RtcEventLog * event_log,VideoSendStream::Config config,VideoEncoderConfig encoder_config,const std::map<uint32_t,RtpState> & suspended_ssrcs,const std::map<uint32_t,RtpPayloadState> & suspended_payload_states,std::unique_ptr<FecController> fec_controller,const FieldTrialsView & field_trials)136*d9f75844SAndroid Build Coastguard Worker VideoSendStream::VideoSendStream(
137*d9f75844SAndroid Build Coastguard Worker     Clock* clock,
138*d9f75844SAndroid Build Coastguard Worker     int num_cpu_cores,
139*d9f75844SAndroid Build Coastguard Worker     TaskQueueFactory* task_queue_factory,
140*d9f75844SAndroid Build Coastguard Worker     TaskQueueBase* network_queue,
141*d9f75844SAndroid Build Coastguard Worker     RtcpRttStats* call_stats,
142*d9f75844SAndroid Build Coastguard Worker     RtpTransportControllerSendInterface* transport,
143*d9f75844SAndroid Build Coastguard Worker     BitrateAllocatorInterface* bitrate_allocator,
144*d9f75844SAndroid Build Coastguard Worker     SendDelayStats* send_delay_stats,
145*d9f75844SAndroid Build Coastguard Worker     RtcEventLog* event_log,
146*d9f75844SAndroid Build Coastguard Worker     VideoSendStream::Config config,
147*d9f75844SAndroid Build Coastguard Worker     VideoEncoderConfig encoder_config,
148*d9f75844SAndroid Build Coastguard Worker     const std::map<uint32_t, RtpState>& suspended_ssrcs,
149*d9f75844SAndroid Build Coastguard Worker     const std::map<uint32_t, RtpPayloadState>& suspended_payload_states,
150*d9f75844SAndroid Build Coastguard Worker     std::unique_ptr<FecController> fec_controller,
151*d9f75844SAndroid Build Coastguard Worker     const FieldTrialsView& field_trials)
152*d9f75844SAndroid Build Coastguard Worker     : rtp_transport_queue_(transport->GetWorkerQueue()),
153*d9f75844SAndroid Build Coastguard Worker       transport_(transport),
154*d9f75844SAndroid Build Coastguard Worker       stats_proxy_(clock, config, encoder_config.content_type, field_trials),
155*d9f75844SAndroid Build Coastguard Worker       config_(std::move(config)),
156*d9f75844SAndroid Build Coastguard Worker       content_type_(encoder_config.content_type),
157*d9f75844SAndroid Build Coastguard Worker       video_stream_encoder_(CreateVideoStreamEncoder(
158*d9f75844SAndroid Build Coastguard Worker           clock,
159*d9f75844SAndroid Build Coastguard Worker           num_cpu_cores,
160*d9f75844SAndroid Build Coastguard Worker           task_queue_factory,
161*d9f75844SAndroid Build Coastguard Worker           &stats_proxy_,
162*d9f75844SAndroid Build Coastguard Worker           config_.encoder_settings,
163*d9f75844SAndroid Build Coastguard Worker           GetBitrateAllocationCallbackType(config_, field_trials),
164*d9f75844SAndroid Build Coastguard Worker           field_trials,
165*d9f75844SAndroid Build Coastguard Worker           config_.encoder_selector)),
166*d9f75844SAndroid Build Coastguard Worker       encoder_feedback_(
167*d9f75844SAndroid Build Coastguard Worker           clock,
168*d9f75844SAndroid Build Coastguard Worker           config_.rtp.ssrcs,
169*d9f75844SAndroid Build Coastguard Worker           video_stream_encoder_.get(),
170*d9f75844SAndroid Build Coastguard Worker           [this](uint32_t ssrc, const std::vector<uint16_t>& seq_nums) {
171*d9f75844SAndroid Build Coastguard Worker             return rtp_video_sender_->GetSentRtpPacketInfos(ssrc, seq_nums);
172*d9f75844SAndroid Build Coastguard Worker           }),
173*d9f75844SAndroid Build Coastguard Worker       rtp_video_sender_(
174*d9f75844SAndroid Build Coastguard Worker           transport->CreateRtpVideoSender(suspended_ssrcs,
175*d9f75844SAndroid Build Coastguard Worker                                           suspended_payload_states,
176*d9f75844SAndroid Build Coastguard Worker                                           config_.rtp,
177*d9f75844SAndroid Build Coastguard Worker                                           config_.rtcp_report_interval_ms,
178*d9f75844SAndroid Build Coastguard Worker                                           config_.send_transport,
179*d9f75844SAndroid Build Coastguard Worker                                           CreateObservers(call_stats,
180*d9f75844SAndroid Build Coastguard Worker                                                           &encoder_feedback_,
181*d9f75844SAndroid Build Coastguard Worker                                                           &stats_proxy_,
182*d9f75844SAndroid Build Coastguard Worker                                                           send_delay_stats),
183*d9f75844SAndroid Build Coastguard Worker                                           event_log,
184*d9f75844SAndroid Build Coastguard Worker                                           std::move(fec_controller),
185*d9f75844SAndroid Build Coastguard Worker                                           CreateFrameEncryptionConfig(&config_),
186*d9f75844SAndroid Build Coastguard Worker                                           config_.frame_transformer)),
187*d9f75844SAndroid Build Coastguard Worker       send_stream_(clock,
188*d9f75844SAndroid Build Coastguard Worker                    &stats_proxy_,
189*d9f75844SAndroid Build Coastguard Worker                    transport,
190*d9f75844SAndroid Build Coastguard Worker                    bitrate_allocator,
191*d9f75844SAndroid Build Coastguard Worker                    video_stream_encoder_.get(),
192*d9f75844SAndroid Build Coastguard Worker                    &config_,
193*d9f75844SAndroid Build Coastguard Worker                    encoder_config.max_bitrate_bps,
194*d9f75844SAndroid Build Coastguard Worker                    encoder_config.bitrate_priority,
195*d9f75844SAndroid Build Coastguard Worker                    encoder_config.content_type,
196*d9f75844SAndroid Build Coastguard Worker                    rtp_video_sender_,
197*d9f75844SAndroid Build Coastguard Worker                    field_trials) {
198*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(config_.encoder_settings.encoder_factory);
199*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(config_.encoder_settings.bitrate_allocator_factory);
200*d9f75844SAndroid Build Coastguard Worker 
201*d9f75844SAndroid Build Coastguard Worker   video_stream_encoder_->SetFecControllerOverride(rtp_video_sender_);
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker   ReconfigureVideoEncoder(std::move(encoder_config));
204*d9f75844SAndroid Build Coastguard Worker }
205*d9f75844SAndroid Build Coastguard Worker 
~VideoSendStream()206*d9f75844SAndroid Build Coastguard Worker VideoSendStream::~VideoSendStream() {
207*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
208*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(!running_);
209*d9f75844SAndroid Build Coastguard Worker   transport_->DestroyRtpVideoSender(rtp_video_sender_);
210*d9f75844SAndroid Build Coastguard Worker }
211*d9f75844SAndroid Build Coastguard Worker 
Start()212*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::Start() {
213*d9f75844SAndroid Build Coastguard Worker   const std::vector<bool> active_layers(config_.rtp.ssrcs.size(), true);
214*d9f75844SAndroid Build Coastguard Worker   StartPerRtpStream(active_layers);
215*d9f75844SAndroid Build Coastguard Worker }
216*d9f75844SAndroid Build Coastguard Worker 
StartPerRtpStream(const std::vector<bool> active_layers)217*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::StartPerRtpStream(const std::vector<bool> active_layers) {
218*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
219*d9f75844SAndroid Build Coastguard Worker 
220*d9f75844SAndroid Build Coastguard Worker   // Keep our `running_` flag expected state in sync with active layers since
221*d9f75844SAndroid Build Coastguard Worker   // the `send_stream_` will be implicitly stopped/started depending on the
222*d9f75844SAndroid Build Coastguard Worker   // state of the layers.
223*d9f75844SAndroid Build Coastguard Worker   bool running = false;
224*d9f75844SAndroid Build Coastguard Worker 
225*d9f75844SAndroid Build Coastguard Worker   rtc::StringBuilder active_layers_string;
226*d9f75844SAndroid Build Coastguard Worker   active_layers_string << "{";
227*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < active_layers.size(); ++i) {
228*d9f75844SAndroid Build Coastguard Worker     if (active_layers[i]) {
229*d9f75844SAndroid Build Coastguard Worker       running = true;
230*d9f75844SAndroid Build Coastguard Worker       active_layers_string << "1";
231*d9f75844SAndroid Build Coastguard Worker     } else {
232*d9f75844SAndroid Build Coastguard Worker       active_layers_string << "0";
233*d9f75844SAndroid Build Coastguard Worker     }
234*d9f75844SAndroid Build Coastguard Worker     if (i < active_layers.size() - 1) {
235*d9f75844SAndroid Build Coastguard Worker       active_layers_string << ", ";
236*d9f75844SAndroid Build Coastguard Worker     }
237*d9f75844SAndroid Build Coastguard Worker   }
238*d9f75844SAndroid Build Coastguard Worker   active_layers_string << "}";
239*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "StartPerRtpStream: " << active_layers_string.str();
240*d9f75844SAndroid Build Coastguard Worker 
241*d9f75844SAndroid Build Coastguard Worker   rtp_transport_queue_->RunOrPost(
242*d9f75844SAndroid Build Coastguard Worker       SafeTask(transport_queue_safety_, [this, active_layers] {
243*d9f75844SAndroid Build Coastguard Worker         send_stream_.StartPerRtpStream(active_layers);
244*d9f75844SAndroid Build Coastguard Worker       }));
245*d9f75844SAndroid Build Coastguard Worker 
246*d9f75844SAndroid Build Coastguard Worker   running_ = running;
247*d9f75844SAndroid Build Coastguard Worker }
248*d9f75844SAndroid Build Coastguard Worker 
Stop()249*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::Stop() {
250*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
251*d9f75844SAndroid Build Coastguard Worker   if (!running_)
252*d9f75844SAndroid Build Coastguard Worker     return;
253*d9f75844SAndroid Build Coastguard Worker   RTC_DLOG(LS_INFO) << "VideoSendStream::Stop";
254*d9f75844SAndroid Build Coastguard Worker   running_ = false;
255*d9f75844SAndroid Build Coastguard Worker   rtp_transport_queue_->RunOrPost(SafeTask(transport_queue_safety_, [this] {
256*d9f75844SAndroid Build Coastguard Worker     // As the stream can get re-used and implicitly restarted via changing
257*d9f75844SAndroid Build Coastguard Worker     // the state of the active layers, we do not mark the
258*d9f75844SAndroid Build Coastguard Worker     // `transport_queue_safety_` flag with `SetNotAlive()` here. That's only
259*d9f75844SAndroid Build Coastguard Worker     // done when we stop permanently via `StopPermanentlyAndGetRtpStates()`.
260*d9f75844SAndroid Build Coastguard Worker     send_stream_.Stop();
261*d9f75844SAndroid Build Coastguard Worker   }));
262*d9f75844SAndroid Build Coastguard Worker }
263*d9f75844SAndroid Build Coastguard Worker 
started()264*d9f75844SAndroid Build Coastguard Worker bool VideoSendStream::started() {
265*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
266*d9f75844SAndroid Build Coastguard Worker   return running_;
267*d9f75844SAndroid Build Coastguard Worker }
268*d9f75844SAndroid Build Coastguard Worker 
AddAdaptationResource(rtc::scoped_refptr<Resource> resource)269*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::AddAdaptationResource(
270*d9f75844SAndroid Build Coastguard Worker     rtc::scoped_refptr<Resource> resource) {
271*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
272*d9f75844SAndroid Build Coastguard Worker   video_stream_encoder_->AddAdaptationResource(resource);
273*d9f75844SAndroid Build Coastguard Worker }
274*d9f75844SAndroid Build Coastguard Worker 
275*d9f75844SAndroid Build Coastguard Worker std::vector<rtc::scoped_refptr<Resource>>
GetAdaptationResources()276*d9f75844SAndroid Build Coastguard Worker VideoSendStream::GetAdaptationResources() {
277*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
278*d9f75844SAndroid Build Coastguard Worker   return video_stream_encoder_->GetAdaptationResources();
279*d9f75844SAndroid Build Coastguard Worker }
280*d9f75844SAndroid Build Coastguard Worker 
SetSource(rtc::VideoSourceInterface<webrtc::VideoFrame> * source,const DegradationPreference & degradation_preference)281*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::SetSource(
282*d9f75844SAndroid Build Coastguard Worker     rtc::VideoSourceInterface<webrtc::VideoFrame>* source,
283*d9f75844SAndroid Build Coastguard Worker     const DegradationPreference& degradation_preference) {
284*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
285*d9f75844SAndroid Build Coastguard Worker   video_stream_encoder_->SetSource(source, degradation_preference);
286*d9f75844SAndroid Build Coastguard Worker }
287*d9f75844SAndroid Build Coastguard Worker 
ReconfigureVideoEncoder(VideoEncoderConfig config)288*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::ReconfigureVideoEncoder(VideoEncoderConfig config) {
289*d9f75844SAndroid Build Coastguard Worker   ReconfigureVideoEncoder(std::move(config), nullptr);
290*d9f75844SAndroid Build Coastguard Worker }
291*d9f75844SAndroid Build Coastguard Worker 
ReconfigureVideoEncoder(VideoEncoderConfig config,SetParametersCallback callback)292*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::ReconfigureVideoEncoder(VideoEncoderConfig config,
293*d9f75844SAndroid Build Coastguard Worker                                               SetParametersCallback callback) {
294*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
295*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_EQ(content_type_, config.content_type);
296*d9f75844SAndroid Build Coastguard Worker   video_stream_encoder_->ConfigureEncoder(
297*d9f75844SAndroid Build Coastguard Worker       std::move(config),
298*d9f75844SAndroid Build Coastguard Worker       config_.rtp.max_packet_size - CalculateMaxHeaderSize(config_.rtp),
299*d9f75844SAndroid Build Coastguard Worker       std::move(callback));
300*d9f75844SAndroid Build Coastguard Worker }
301*d9f75844SAndroid Build Coastguard Worker 
GetStats()302*d9f75844SAndroid Build Coastguard Worker VideoSendStream::Stats VideoSendStream::GetStats() {
303*d9f75844SAndroid Build Coastguard Worker   // TODO(perkj, solenberg): Some test cases in EndToEndTest call GetStats from
304*d9f75844SAndroid Build Coastguard Worker   // a network thread. See comment in Call::GetStats().
305*d9f75844SAndroid Build Coastguard Worker   // RTC_DCHECK_RUN_ON(&thread_checker_);
306*d9f75844SAndroid Build Coastguard Worker   return stats_proxy_.GetStats();
307*d9f75844SAndroid Build Coastguard Worker }
308*d9f75844SAndroid Build Coastguard Worker 
GetPacingFactorOverride() const309*d9f75844SAndroid Build Coastguard Worker absl::optional<float> VideoSendStream::GetPacingFactorOverride() const {
310*d9f75844SAndroid Build Coastguard Worker   return send_stream_.configured_pacing_factor();
311*d9f75844SAndroid Build Coastguard Worker }
312*d9f75844SAndroid Build Coastguard Worker 
StopPermanentlyAndGetRtpStates(VideoSendStream::RtpStateMap * rtp_state_map,VideoSendStream::RtpPayloadStateMap * payload_state_map)313*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::StopPermanentlyAndGetRtpStates(
314*d9f75844SAndroid Build Coastguard Worker     VideoSendStream::RtpStateMap* rtp_state_map,
315*d9f75844SAndroid Build Coastguard Worker     VideoSendStream::RtpPayloadStateMap* payload_state_map) {
316*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
317*d9f75844SAndroid Build Coastguard Worker   video_stream_encoder_->Stop();
318*d9f75844SAndroid Build Coastguard Worker 
319*d9f75844SAndroid Build Coastguard Worker   running_ = false;
320*d9f75844SAndroid Build Coastguard Worker   // Always run these cleanup steps regardless of whether running_ was set
321*d9f75844SAndroid Build Coastguard Worker   // or not. This will unregister callbacks before destruction.
322*d9f75844SAndroid Build Coastguard Worker   // See `VideoSendStreamImpl::StopVideoSendStream` for more.
323*d9f75844SAndroid Build Coastguard Worker   rtp_transport_queue_->RunSynchronous(
324*d9f75844SAndroid Build Coastguard Worker       [this, rtp_state_map, payload_state_map]() {
325*d9f75844SAndroid Build Coastguard Worker         transport_queue_safety_->SetNotAlive();
326*d9f75844SAndroid Build Coastguard Worker         send_stream_.Stop();
327*d9f75844SAndroid Build Coastguard Worker         *rtp_state_map = send_stream_.GetRtpStates();
328*d9f75844SAndroid Build Coastguard Worker         *payload_state_map = send_stream_.GetRtpPayloadStates();
329*d9f75844SAndroid Build Coastguard Worker       });
330*d9f75844SAndroid Build Coastguard Worker }
331*d9f75844SAndroid Build Coastguard Worker 
DeliverRtcp(const uint8_t * packet,size_t length)332*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
333*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK_RUN_ON(&thread_checker_);
334*d9f75844SAndroid Build Coastguard Worker   send_stream_.DeliverRtcp(packet, length);
335*d9f75844SAndroid Build Coastguard Worker }
336*d9f75844SAndroid Build Coastguard Worker 
GenerateKeyFrame(const std::vector<std::string> & rids)337*d9f75844SAndroid Build Coastguard Worker void VideoSendStream::GenerateKeyFrame(const std::vector<std::string>& rids) {
338*d9f75844SAndroid Build Coastguard Worker   // Map rids to layers. If rids is empty, generate a keyframe for all layers.
339*d9f75844SAndroid Build Coastguard Worker   std::vector<VideoFrameType> next_frames(config_.rtp.ssrcs.size(),
340*d9f75844SAndroid Build Coastguard Worker                                           VideoFrameType::kVideoFrameKey);
341*d9f75844SAndroid Build Coastguard Worker   if (!config_.rtp.rids.empty() && !rids.empty()) {
342*d9f75844SAndroid Build Coastguard Worker     std::fill(next_frames.begin(), next_frames.end(),
343*d9f75844SAndroid Build Coastguard Worker               VideoFrameType::kVideoFrameDelta);
344*d9f75844SAndroid Build Coastguard Worker     for (const auto& rid : rids) {
345*d9f75844SAndroid Build Coastguard Worker       for (size_t i = 0; i < config_.rtp.rids.size(); i++) {
346*d9f75844SAndroid Build Coastguard Worker         if (config_.rtp.rids[i] == rid) {
347*d9f75844SAndroid Build Coastguard Worker           next_frames[i] = VideoFrameType::kVideoFrameKey;
348*d9f75844SAndroid Build Coastguard Worker           break;
349*d9f75844SAndroid Build Coastguard Worker         }
350*d9f75844SAndroid Build Coastguard Worker       }
351*d9f75844SAndroid Build Coastguard Worker     }
352*d9f75844SAndroid Build Coastguard Worker   }
353*d9f75844SAndroid Build Coastguard Worker   if (video_stream_encoder_) {
354*d9f75844SAndroid Build Coastguard Worker     video_stream_encoder_->SendKeyFrame(next_frames);
355*d9f75844SAndroid Build Coastguard Worker   }
356*d9f75844SAndroid Build Coastguard Worker }
357*d9f75844SAndroid Build Coastguard Worker 
358*d9f75844SAndroid Build Coastguard Worker }  // namespace internal
359*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
360