1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2015 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
11*d9f75844SAndroid Build Coastguard Worker #include "audio/audio_send_stream.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker #include <string>
15*d9f75844SAndroid Build Coastguard Worker #include <utility>
16*d9f75844SAndroid Build Coastguard Worker #include <vector>
17*d9f75844SAndroid Build Coastguard Worker
18*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/audio_encoder.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/audio_encoder_factory.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/audio_format.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/call/transport.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/crypto/frame_encryptor_interface.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/function_view.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_event_log/rtc_event_log.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h"
26*d9f75844SAndroid Build Coastguard Worker #include "audio/audio_state.h"
27*d9f75844SAndroid Build Coastguard Worker #include "audio/channel_send.h"
28*d9f75844SAndroid Build Coastguard Worker #include "audio/conversion.h"
29*d9f75844SAndroid Build Coastguard Worker #include "call/rtp_config.h"
30*d9f75844SAndroid Build Coastguard Worker #include "call/rtp_transport_controller_send_interface.h"
31*d9f75844SAndroid Build Coastguard Worker #include "common_audio/vad/include/vad.h"
32*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
33*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/rtc_stream_config.h"
34*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_channel.h"
35*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
36*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_coding/codecs/red/audio_encoder_copy_red.h"
37*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_processing/include/audio_processing.h"
38*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
39*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
40*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
41*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/audio_format_to_string.h"
42*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/trace_event.h"
43*d9f75844SAndroid Build Coastguard Worker
44*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
45*d9f75844SAndroid Build Coastguard Worker namespace {
46*d9f75844SAndroid Build Coastguard Worker
UpdateEventLogStreamConfig(RtcEventLog * event_log,const AudioSendStream::Config & config,const AudioSendStream::Config * old_config)47*d9f75844SAndroid Build Coastguard Worker void UpdateEventLogStreamConfig(RtcEventLog* event_log,
48*d9f75844SAndroid Build Coastguard Worker const AudioSendStream::Config& config,
49*d9f75844SAndroid Build Coastguard Worker const AudioSendStream::Config* old_config) {
50*d9f75844SAndroid Build Coastguard Worker using SendCodecSpec = AudioSendStream::Config::SendCodecSpec;
51*d9f75844SAndroid Build Coastguard Worker // Only update if any of the things we log have changed.
52*d9f75844SAndroid Build Coastguard Worker auto payload_types_equal = [](const absl::optional<SendCodecSpec>& a,
53*d9f75844SAndroid Build Coastguard Worker const absl::optional<SendCodecSpec>& b) {
54*d9f75844SAndroid Build Coastguard Worker if (a.has_value() && b.has_value()) {
55*d9f75844SAndroid Build Coastguard Worker return a->format.name == b->format.name &&
56*d9f75844SAndroid Build Coastguard Worker a->payload_type == b->payload_type;
57*d9f75844SAndroid Build Coastguard Worker }
58*d9f75844SAndroid Build Coastguard Worker return !a.has_value() && !b.has_value();
59*d9f75844SAndroid Build Coastguard Worker };
60*d9f75844SAndroid Build Coastguard Worker
61*d9f75844SAndroid Build Coastguard Worker if (old_config && config.rtp.ssrc == old_config->rtp.ssrc &&
62*d9f75844SAndroid Build Coastguard Worker config.rtp.extensions == old_config->rtp.extensions &&
63*d9f75844SAndroid Build Coastguard Worker payload_types_equal(config.send_codec_spec,
64*d9f75844SAndroid Build Coastguard Worker old_config->send_codec_spec)) {
65*d9f75844SAndroid Build Coastguard Worker return;
66*d9f75844SAndroid Build Coastguard Worker }
67*d9f75844SAndroid Build Coastguard Worker
68*d9f75844SAndroid Build Coastguard Worker auto rtclog_config = std::make_unique<rtclog::StreamConfig>();
69*d9f75844SAndroid Build Coastguard Worker rtclog_config->local_ssrc = config.rtp.ssrc;
70*d9f75844SAndroid Build Coastguard Worker rtclog_config->rtp_extensions = config.rtp.extensions;
71*d9f75844SAndroid Build Coastguard Worker if (config.send_codec_spec) {
72*d9f75844SAndroid Build Coastguard Worker rtclog_config->codecs.emplace_back(config.send_codec_spec->format.name,
73*d9f75844SAndroid Build Coastguard Worker config.send_codec_spec->payload_type, 0);
74*d9f75844SAndroid Build Coastguard Worker }
75*d9f75844SAndroid Build Coastguard Worker event_log->Log(std::make_unique<RtcEventAudioSendStreamConfig>(
76*d9f75844SAndroid Build Coastguard Worker std::move(rtclog_config)));
77*d9f75844SAndroid Build Coastguard Worker }
78*d9f75844SAndroid Build Coastguard Worker
79*d9f75844SAndroid Build Coastguard Worker } // namespace
80*d9f75844SAndroid Build Coastguard Worker
81*d9f75844SAndroid Build Coastguard Worker constexpr char AudioAllocationConfig::kKey[];
82*d9f75844SAndroid Build Coastguard Worker
Parser()83*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<StructParametersParser> AudioAllocationConfig::Parser() {
84*d9f75844SAndroid Build Coastguard Worker return StructParametersParser::Create( //
85*d9f75844SAndroid Build Coastguard Worker "min", &min_bitrate, //
86*d9f75844SAndroid Build Coastguard Worker "max", &max_bitrate, //
87*d9f75844SAndroid Build Coastguard Worker "prio_rate", &priority_bitrate, //
88*d9f75844SAndroid Build Coastguard Worker "prio_rate_raw", &priority_bitrate_raw, //
89*d9f75844SAndroid Build Coastguard Worker "rate_prio", &bitrate_priority);
90*d9f75844SAndroid Build Coastguard Worker }
91*d9f75844SAndroid Build Coastguard Worker
AudioAllocationConfig(const FieldTrialsView & field_trials)92*d9f75844SAndroid Build Coastguard Worker AudioAllocationConfig::AudioAllocationConfig(
93*d9f75844SAndroid Build Coastguard Worker const FieldTrialsView& field_trials) {
94*d9f75844SAndroid Build Coastguard Worker Parser()->Parse(field_trials.Lookup(kKey));
95*d9f75844SAndroid Build Coastguard Worker if (priority_bitrate_raw && !priority_bitrate.IsZero()) {
96*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_WARNING) << "'priority_bitrate' and '_raw' are mutually "
97*d9f75844SAndroid Build Coastguard Worker "exclusive but both were configured.";
98*d9f75844SAndroid Build Coastguard Worker }
99*d9f75844SAndroid Build Coastguard Worker }
100*d9f75844SAndroid Build Coastguard Worker
101*d9f75844SAndroid Build Coastguard Worker namespace internal {
AudioSendStream(Clock * clock,const webrtc::AudioSendStream::Config & config,const rtc::scoped_refptr<webrtc::AudioState> & audio_state,TaskQueueFactory * task_queue_factory,RtpTransportControllerSendInterface * rtp_transport,BitrateAllocatorInterface * bitrate_allocator,RtcEventLog * event_log,RtcpRttStats * rtcp_rtt_stats,const absl::optional<RtpState> & suspended_rtp_state,const FieldTrialsView & field_trials)102*d9f75844SAndroid Build Coastguard Worker AudioSendStream::AudioSendStream(
103*d9f75844SAndroid Build Coastguard Worker Clock* clock,
104*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioSendStream::Config& config,
105*d9f75844SAndroid Build Coastguard Worker const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
106*d9f75844SAndroid Build Coastguard Worker TaskQueueFactory* task_queue_factory,
107*d9f75844SAndroid Build Coastguard Worker RtpTransportControllerSendInterface* rtp_transport,
108*d9f75844SAndroid Build Coastguard Worker BitrateAllocatorInterface* bitrate_allocator,
109*d9f75844SAndroid Build Coastguard Worker RtcEventLog* event_log,
110*d9f75844SAndroid Build Coastguard Worker RtcpRttStats* rtcp_rtt_stats,
111*d9f75844SAndroid Build Coastguard Worker const absl::optional<RtpState>& suspended_rtp_state,
112*d9f75844SAndroid Build Coastguard Worker const FieldTrialsView& field_trials)
113*d9f75844SAndroid Build Coastguard Worker : AudioSendStream(
114*d9f75844SAndroid Build Coastguard Worker clock,
115*d9f75844SAndroid Build Coastguard Worker config,
116*d9f75844SAndroid Build Coastguard Worker audio_state,
117*d9f75844SAndroid Build Coastguard Worker task_queue_factory,
118*d9f75844SAndroid Build Coastguard Worker rtp_transport,
119*d9f75844SAndroid Build Coastguard Worker bitrate_allocator,
120*d9f75844SAndroid Build Coastguard Worker event_log,
121*d9f75844SAndroid Build Coastguard Worker suspended_rtp_state,
122*d9f75844SAndroid Build Coastguard Worker voe::CreateChannelSend(clock,
123*d9f75844SAndroid Build Coastguard Worker task_queue_factory,
124*d9f75844SAndroid Build Coastguard Worker config.send_transport,
125*d9f75844SAndroid Build Coastguard Worker rtcp_rtt_stats,
126*d9f75844SAndroid Build Coastguard Worker event_log,
127*d9f75844SAndroid Build Coastguard Worker config.frame_encryptor.get(),
128*d9f75844SAndroid Build Coastguard Worker config.crypto_options,
129*d9f75844SAndroid Build Coastguard Worker config.rtp.extmap_allow_mixed,
130*d9f75844SAndroid Build Coastguard Worker config.rtcp_report_interval_ms,
131*d9f75844SAndroid Build Coastguard Worker config.rtp.ssrc,
132*d9f75844SAndroid Build Coastguard Worker config.frame_transformer,
133*d9f75844SAndroid Build Coastguard Worker rtp_transport->transport_feedback_observer(),
134*d9f75844SAndroid Build Coastguard Worker field_trials),
135*d9f75844SAndroid Build Coastguard Worker field_trials) {}
136*d9f75844SAndroid Build Coastguard Worker
AudioSendStream(Clock * clock,const webrtc::AudioSendStream::Config & config,const rtc::scoped_refptr<webrtc::AudioState> & audio_state,TaskQueueFactory * task_queue_factory,RtpTransportControllerSendInterface * rtp_transport,BitrateAllocatorInterface * bitrate_allocator,RtcEventLog * event_log,const absl::optional<RtpState> & suspended_rtp_state,std::unique_ptr<voe::ChannelSendInterface> channel_send,const FieldTrialsView & field_trials)137*d9f75844SAndroid Build Coastguard Worker AudioSendStream::AudioSendStream(
138*d9f75844SAndroid Build Coastguard Worker Clock* clock,
139*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioSendStream::Config& config,
140*d9f75844SAndroid Build Coastguard Worker const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
141*d9f75844SAndroid Build Coastguard Worker TaskQueueFactory* task_queue_factory,
142*d9f75844SAndroid Build Coastguard Worker RtpTransportControllerSendInterface* rtp_transport,
143*d9f75844SAndroid Build Coastguard Worker BitrateAllocatorInterface* bitrate_allocator,
144*d9f75844SAndroid Build Coastguard Worker RtcEventLog* event_log,
145*d9f75844SAndroid Build Coastguard Worker const absl::optional<RtpState>& suspended_rtp_state,
146*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<voe::ChannelSendInterface> channel_send,
147*d9f75844SAndroid Build Coastguard Worker const FieldTrialsView& field_trials)
148*d9f75844SAndroid Build Coastguard Worker : clock_(clock),
149*d9f75844SAndroid Build Coastguard Worker field_trials_(field_trials),
150*d9f75844SAndroid Build Coastguard Worker rtp_transport_queue_(rtp_transport->GetWorkerQueue()),
151*d9f75844SAndroid Build Coastguard Worker allocate_audio_without_feedback_(
152*d9f75844SAndroid Build Coastguard Worker field_trials_.IsEnabled("WebRTC-Audio-ABWENoTWCC")),
153*d9f75844SAndroid Build Coastguard Worker enable_audio_alr_probing_(
154*d9f75844SAndroid Build Coastguard Worker !field_trials_.IsDisabled("WebRTC-Audio-AlrProbing")),
155*d9f75844SAndroid Build Coastguard Worker allocation_settings_(field_trials_),
156*d9f75844SAndroid Build Coastguard Worker config_(Config(/*send_transport=*/nullptr)),
157*d9f75844SAndroid Build Coastguard Worker audio_state_(audio_state),
158*d9f75844SAndroid Build Coastguard Worker channel_send_(std::move(channel_send)),
159*d9f75844SAndroid Build Coastguard Worker event_log_(event_log),
160*d9f75844SAndroid Build Coastguard Worker use_legacy_overhead_calculation_(
161*d9f75844SAndroid Build Coastguard Worker field_trials_.IsEnabled("WebRTC-Audio-LegacyOverhead")),
162*d9f75844SAndroid Build Coastguard Worker bitrate_allocator_(bitrate_allocator),
163*d9f75844SAndroid Build Coastguard Worker rtp_transport_(rtp_transport),
164*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_(channel_send_->GetRtpRtcp()),
165*d9f75844SAndroid Build Coastguard Worker suspended_rtp_state_(suspended_rtp_state) {
166*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "AudioSendStream: " << config.rtp.ssrc;
167*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(rtp_transport_queue_);
168*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(audio_state_);
169*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(channel_send_);
170*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(bitrate_allocator_);
171*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(rtp_transport);
172*d9f75844SAndroid Build Coastguard Worker
173*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(rtp_rtcp_module_);
174*d9f75844SAndroid Build Coastguard Worker
175*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
176*d9f75844SAndroid Build Coastguard Worker ConfigureStream(config, true, nullptr);
177*d9f75844SAndroid Build Coastguard Worker UpdateCachedTargetAudioBitrateConstraints();
178*d9f75844SAndroid Build Coastguard Worker }
179*d9f75844SAndroid Build Coastguard Worker
~AudioSendStream()180*d9f75844SAndroid Build Coastguard Worker AudioSendStream::~AudioSendStream() {
181*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
182*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "~AudioSendStream: " << config_.rtp.ssrc;
183*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!sending_);
184*d9f75844SAndroid Build Coastguard Worker channel_send_->ResetSenderCongestionControlObjects();
185*d9f75844SAndroid Build Coastguard Worker
186*d9f75844SAndroid Build Coastguard Worker // Blocking call to synchronize state with worker queue to ensure that there
187*d9f75844SAndroid Build Coastguard Worker // are no pending tasks left that keeps references to audio.
188*d9f75844SAndroid Build Coastguard Worker rtp_transport_queue_->RunSynchronous([] {});
189*d9f75844SAndroid Build Coastguard Worker }
190*d9f75844SAndroid Build Coastguard Worker
GetConfig() const191*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioSendStream::Config& AudioSendStream::GetConfig() const {
192*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
193*d9f75844SAndroid Build Coastguard Worker return config_;
194*d9f75844SAndroid Build Coastguard Worker }
195*d9f75844SAndroid Build Coastguard Worker
Reconfigure(const webrtc::AudioSendStream::Config & new_config,SetParametersCallback callback)196*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::Reconfigure(
197*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioSendStream::Config& new_config,
198*d9f75844SAndroid Build Coastguard Worker SetParametersCallback callback) {
199*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
200*d9f75844SAndroid Build Coastguard Worker ConfigureStream(new_config, false, std::move(callback));
201*d9f75844SAndroid Build Coastguard Worker }
202*d9f75844SAndroid Build Coastguard Worker
FindExtensionIds(const std::vector<RtpExtension> & extensions)203*d9f75844SAndroid Build Coastguard Worker AudioSendStream::ExtensionIds AudioSendStream::FindExtensionIds(
204*d9f75844SAndroid Build Coastguard Worker const std::vector<RtpExtension>& extensions) {
205*d9f75844SAndroid Build Coastguard Worker ExtensionIds ids;
206*d9f75844SAndroid Build Coastguard Worker for (const auto& extension : extensions) {
207*d9f75844SAndroid Build Coastguard Worker if (extension.uri == RtpExtension::kAudioLevelUri) {
208*d9f75844SAndroid Build Coastguard Worker ids.audio_level = extension.id;
209*d9f75844SAndroid Build Coastguard Worker } else if (extension.uri == RtpExtension::kAbsSendTimeUri) {
210*d9f75844SAndroid Build Coastguard Worker ids.abs_send_time = extension.id;
211*d9f75844SAndroid Build Coastguard Worker } else if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
212*d9f75844SAndroid Build Coastguard Worker ids.transport_sequence_number = extension.id;
213*d9f75844SAndroid Build Coastguard Worker } else if (extension.uri == RtpExtension::kMidUri) {
214*d9f75844SAndroid Build Coastguard Worker ids.mid = extension.id;
215*d9f75844SAndroid Build Coastguard Worker } else if (extension.uri == RtpExtension::kRidUri) {
216*d9f75844SAndroid Build Coastguard Worker ids.rid = extension.id;
217*d9f75844SAndroid Build Coastguard Worker } else if (extension.uri == RtpExtension::kRepairedRidUri) {
218*d9f75844SAndroid Build Coastguard Worker ids.repaired_rid = extension.id;
219*d9f75844SAndroid Build Coastguard Worker } else if (extension.uri == RtpExtension::kAbsoluteCaptureTimeUri) {
220*d9f75844SAndroid Build Coastguard Worker ids.abs_capture_time = extension.id;
221*d9f75844SAndroid Build Coastguard Worker }
222*d9f75844SAndroid Build Coastguard Worker }
223*d9f75844SAndroid Build Coastguard Worker return ids;
224*d9f75844SAndroid Build Coastguard Worker }
225*d9f75844SAndroid Build Coastguard Worker
TransportSeqNumId(const AudioSendStream::Config & config)226*d9f75844SAndroid Build Coastguard Worker int AudioSendStream::TransportSeqNumId(const AudioSendStream::Config& config) {
227*d9f75844SAndroid Build Coastguard Worker return FindExtensionIds(config.rtp.extensions).transport_sequence_number;
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker
ConfigureStream(const webrtc::AudioSendStream::Config & new_config,bool first_time,SetParametersCallback callback)230*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::ConfigureStream(
231*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioSendStream::Config& new_config,
232*d9f75844SAndroid Build Coastguard Worker bool first_time,
233*d9f75844SAndroid Build Coastguard Worker SetParametersCallback callback) {
234*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "AudioSendStream::ConfigureStream: "
235*d9f75844SAndroid Build Coastguard Worker << new_config.ToString();
236*d9f75844SAndroid Build Coastguard Worker UpdateEventLogStreamConfig(event_log_, new_config,
237*d9f75844SAndroid Build Coastguard Worker first_time ? nullptr : &config_);
238*d9f75844SAndroid Build Coastguard Worker
239*d9f75844SAndroid Build Coastguard Worker const auto& old_config = config_;
240*d9f75844SAndroid Build Coastguard Worker
241*d9f75844SAndroid Build Coastguard Worker // Configuration parameters which cannot be changed.
242*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(first_time ||
243*d9f75844SAndroid Build Coastguard Worker old_config.send_transport == new_config.send_transport);
244*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(first_time || old_config.rtp.ssrc == new_config.rtp.ssrc);
245*d9f75844SAndroid Build Coastguard Worker if (suspended_rtp_state_ && first_time) {
246*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->SetRtpState(*suspended_rtp_state_);
247*d9f75844SAndroid Build Coastguard Worker }
248*d9f75844SAndroid Build Coastguard Worker if (first_time || old_config.rtp.c_name != new_config.rtp.c_name) {
249*d9f75844SAndroid Build Coastguard Worker channel_send_->SetRTCP_CNAME(new_config.rtp.c_name);
250*d9f75844SAndroid Build Coastguard Worker }
251*d9f75844SAndroid Build Coastguard Worker
252*d9f75844SAndroid Build Coastguard Worker // Enable the frame encryptor if a new frame encryptor has been provided.
253*d9f75844SAndroid Build Coastguard Worker if (first_time || new_config.frame_encryptor != old_config.frame_encryptor) {
254*d9f75844SAndroid Build Coastguard Worker channel_send_->SetFrameEncryptor(new_config.frame_encryptor);
255*d9f75844SAndroid Build Coastguard Worker }
256*d9f75844SAndroid Build Coastguard Worker
257*d9f75844SAndroid Build Coastguard Worker if (first_time ||
258*d9f75844SAndroid Build Coastguard Worker new_config.frame_transformer != old_config.frame_transformer) {
259*d9f75844SAndroid Build Coastguard Worker channel_send_->SetEncoderToPacketizerFrameTransformer(
260*d9f75844SAndroid Build Coastguard Worker new_config.frame_transformer);
261*d9f75844SAndroid Build Coastguard Worker }
262*d9f75844SAndroid Build Coastguard Worker
263*d9f75844SAndroid Build Coastguard Worker if (first_time ||
264*d9f75844SAndroid Build Coastguard Worker new_config.rtp.extmap_allow_mixed != old_config.rtp.extmap_allow_mixed) {
265*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->SetExtmapAllowMixed(new_config.rtp.extmap_allow_mixed);
266*d9f75844SAndroid Build Coastguard Worker }
267*d9f75844SAndroid Build Coastguard Worker
268*d9f75844SAndroid Build Coastguard Worker const ExtensionIds old_ids = FindExtensionIds(old_config.rtp.extensions);
269*d9f75844SAndroid Build Coastguard Worker const ExtensionIds new_ids = FindExtensionIds(new_config.rtp.extensions);
270*d9f75844SAndroid Build Coastguard Worker
271*d9f75844SAndroid Build Coastguard Worker // Audio level indication
272*d9f75844SAndroid Build Coastguard Worker if (first_time || new_ids.audio_level != old_ids.audio_level) {
273*d9f75844SAndroid Build Coastguard Worker channel_send_->SetSendAudioLevelIndicationStatus(new_ids.audio_level != 0,
274*d9f75844SAndroid Build Coastguard Worker new_ids.audio_level);
275*d9f75844SAndroid Build Coastguard Worker }
276*d9f75844SAndroid Build Coastguard Worker
277*d9f75844SAndroid Build Coastguard Worker if (first_time || new_ids.abs_send_time != old_ids.abs_send_time) {
278*d9f75844SAndroid Build Coastguard Worker absl::string_view uri = AbsoluteSendTime::Uri();
279*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->DeregisterSendRtpHeaderExtension(uri);
280*d9f75844SAndroid Build Coastguard Worker if (new_ids.abs_send_time) {
281*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->RegisterRtpHeaderExtension(uri, new_ids.abs_send_time);
282*d9f75844SAndroid Build Coastguard Worker }
283*d9f75844SAndroid Build Coastguard Worker }
284*d9f75844SAndroid Build Coastguard Worker
285*d9f75844SAndroid Build Coastguard Worker bool transport_seq_num_id_changed =
286*d9f75844SAndroid Build Coastguard Worker new_ids.transport_sequence_number != old_ids.transport_sequence_number;
287*d9f75844SAndroid Build Coastguard Worker if (first_time ||
288*d9f75844SAndroid Build Coastguard Worker (transport_seq_num_id_changed && !allocate_audio_without_feedback_)) {
289*d9f75844SAndroid Build Coastguard Worker if (!first_time) {
290*d9f75844SAndroid Build Coastguard Worker channel_send_->ResetSenderCongestionControlObjects();
291*d9f75844SAndroid Build Coastguard Worker }
292*d9f75844SAndroid Build Coastguard Worker
293*d9f75844SAndroid Build Coastguard Worker RtcpBandwidthObserver* bandwidth_observer = nullptr;
294*d9f75844SAndroid Build Coastguard Worker
295*d9f75844SAndroid Build Coastguard Worker if (!allocate_audio_without_feedback_ &&
296*d9f75844SAndroid Build Coastguard Worker new_ids.transport_sequence_number != 0) {
297*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->RegisterRtpHeaderExtension(
298*d9f75844SAndroid Build Coastguard Worker TransportSequenceNumber::Uri(), new_ids.transport_sequence_number);
299*d9f75844SAndroid Build Coastguard Worker // Probing in application limited region is only used in combination with
300*d9f75844SAndroid Build Coastguard Worker // send side congestion control, wich depends on feedback packets which
301*d9f75844SAndroid Build Coastguard Worker // requires transport sequence numbers to be enabled.
302*d9f75844SAndroid Build Coastguard Worker // Optionally request ALR probing but do not override any existing
303*d9f75844SAndroid Build Coastguard Worker // request from other streams.
304*d9f75844SAndroid Build Coastguard Worker if (enable_audio_alr_probing_) {
305*d9f75844SAndroid Build Coastguard Worker rtp_transport_->EnablePeriodicAlrProbing(true);
306*d9f75844SAndroid Build Coastguard Worker }
307*d9f75844SAndroid Build Coastguard Worker bandwidth_observer = rtp_transport_->GetBandwidthObserver();
308*d9f75844SAndroid Build Coastguard Worker }
309*d9f75844SAndroid Build Coastguard Worker channel_send_->RegisterSenderCongestionControlObjects(rtp_transport_,
310*d9f75844SAndroid Build Coastguard Worker bandwidth_observer);
311*d9f75844SAndroid Build Coastguard Worker }
312*d9f75844SAndroid Build Coastguard Worker // MID RTP header extension.
313*d9f75844SAndroid Build Coastguard Worker if ((first_time || new_ids.mid != old_ids.mid ||
314*d9f75844SAndroid Build Coastguard Worker new_config.rtp.mid != old_config.rtp.mid) &&
315*d9f75844SAndroid Build Coastguard Worker new_ids.mid != 0 && !new_config.rtp.mid.empty()) {
316*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->RegisterRtpHeaderExtension(RtpMid::Uri(), new_ids.mid);
317*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->SetMid(new_config.rtp.mid);
318*d9f75844SAndroid Build Coastguard Worker }
319*d9f75844SAndroid Build Coastguard Worker
320*d9f75844SAndroid Build Coastguard Worker if (first_time || new_ids.abs_capture_time != old_ids.abs_capture_time) {
321*d9f75844SAndroid Build Coastguard Worker absl::string_view uri = AbsoluteCaptureTimeExtension::Uri();
322*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->DeregisterSendRtpHeaderExtension(uri);
323*d9f75844SAndroid Build Coastguard Worker if (new_ids.abs_capture_time) {
324*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->RegisterRtpHeaderExtension(uri,
325*d9f75844SAndroid Build Coastguard Worker new_ids.abs_capture_time);
326*d9f75844SAndroid Build Coastguard Worker }
327*d9f75844SAndroid Build Coastguard Worker }
328*d9f75844SAndroid Build Coastguard Worker
329*d9f75844SAndroid Build Coastguard Worker if (!ReconfigureSendCodec(new_config)) {
330*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_ERROR) << "Failed to set up send codec state.";
331*d9f75844SAndroid Build Coastguard Worker
332*d9f75844SAndroid Build Coastguard Worker webrtc::InvokeSetParametersCallback(
333*d9f75844SAndroid Build Coastguard Worker callback, webrtc::RTCError(webrtc::RTCErrorType::INTERNAL_ERROR,
334*d9f75844SAndroid Build Coastguard Worker "Failed to set up send codec state."));
335*d9f75844SAndroid Build Coastguard Worker }
336*d9f75844SAndroid Build Coastguard Worker
337*d9f75844SAndroid Build Coastguard Worker // Set currently known overhead (used in ANA, opus only).
338*d9f75844SAndroid Build Coastguard Worker {
339*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&overhead_per_packet_lock_);
340*d9f75844SAndroid Build Coastguard Worker UpdateOverheadForEncoder();
341*d9f75844SAndroid Build Coastguard Worker }
342*d9f75844SAndroid Build Coastguard Worker
343*d9f75844SAndroid Build Coastguard Worker channel_send_->CallEncoder([this](AudioEncoder* encoder) {
344*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
345*d9f75844SAndroid Build Coastguard Worker if (!encoder) {
346*d9f75844SAndroid Build Coastguard Worker return;
347*d9f75844SAndroid Build Coastguard Worker }
348*d9f75844SAndroid Build Coastguard Worker frame_length_range_ = encoder->GetFrameLengthRange();
349*d9f75844SAndroid Build Coastguard Worker UpdateCachedTargetAudioBitrateConstraints();
350*d9f75844SAndroid Build Coastguard Worker });
351*d9f75844SAndroid Build Coastguard Worker
352*d9f75844SAndroid Build Coastguard Worker if (sending_) {
353*d9f75844SAndroid Build Coastguard Worker ReconfigureBitrateObserver(new_config);
354*d9f75844SAndroid Build Coastguard Worker }
355*d9f75844SAndroid Build Coastguard Worker
356*d9f75844SAndroid Build Coastguard Worker config_ = new_config;
357*d9f75844SAndroid Build Coastguard Worker if (!first_time) {
358*d9f75844SAndroid Build Coastguard Worker UpdateCachedTargetAudioBitrateConstraints();
359*d9f75844SAndroid Build Coastguard Worker }
360*d9f75844SAndroid Build Coastguard Worker
361*d9f75844SAndroid Build Coastguard Worker webrtc::InvokeSetParametersCallback(callback, webrtc::RTCError::OK());
362*d9f75844SAndroid Build Coastguard Worker }
363*d9f75844SAndroid Build Coastguard Worker
Start()364*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::Start() {
365*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
366*d9f75844SAndroid Build Coastguard Worker if (sending_) {
367*d9f75844SAndroid Build Coastguard Worker return;
368*d9f75844SAndroid Build Coastguard Worker }
369*d9f75844SAndroid Build Coastguard Worker if (!config_.has_dscp && config_.min_bitrate_bps != -1 &&
370*d9f75844SAndroid Build Coastguard Worker config_.max_bitrate_bps != -1 &&
371*d9f75844SAndroid Build Coastguard Worker (allocate_audio_without_feedback_ || TransportSeqNumId(config_) != 0)) {
372*d9f75844SAndroid Build Coastguard Worker rtp_transport_->AccountForAudioPacketsInPacedSender(true);
373*d9f75844SAndroid Build Coastguard Worker rtp_transport_->IncludeOverheadInPacedSender();
374*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->SetAsPartOfAllocation(true);
375*d9f75844SAndroid Build Coastguard Worker ConfigureBitrateObserver();
376*d9f75844SAndroid Build Coastguard Worker } else {
377*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->SetAsPartOfAllocation(false);
378*d9f75844SAndroid Build Coastguard Worker }
379*d9f75844SAndroid Build Coastguard Worker channel_send_->StartSend();
380*d9f75844SAndroid Build Coastguard Worker sending_ = true;
381*d9f75844SAndroid Build Coastguard Worker audio_state()->AddSendingStream(this, encoder_sample_rate_hz_,
382*d9f75844SAndroid Build Coastguard Worker encoder_num_channels_);
383*d9f75844SAndroid Build Coastguard Worker }
384*d9f75844SAndroid Build Coastguard Worker
Stop()385*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::Stop() {
386*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
387*d9f75844SAndroid Build Coastguard Worker if (!sending_) {
388*d9f75844SAndroid Build Coastguard Worker return;
389*d9f75844SAndroid Build Coastguard Worker }
390*d9f75844SAndroid Build Coastguard Worker
391*d9f75844SAndroid Build Coastguard Worker RemoveBitrateObserver();
392*d9f75844SAndroid Build Coastguard Worker channel_send_->StopSend();
393*d9f75844SAndroid Build Coastguard Worker sending_ = false;
394*d9f75844SAndroid Build Coastguard Worker audio_state()->RemoveSendingStream(this);
395*d9f75844SAndroid Build Coastguard Worker }
396*d9f75844SAndroid Build Coastguard Worker
SendAudioData(std::unique_ptr<AudioFrame> audio_frame)397*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::SendAudioData(std::unique_ptr<AudioFrame> audio_frame) {
398*d9f75844SAndroid Build Coastguard Worker RTC_CHECK_RUNS_SERIALIZED(&audio_capture_race_checker_);
399*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_GT(audio_frame->sample_rate_hz_, 0);
400*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "AudioSendStream::SendAudioData");
401*d9f75844SAndroid Build Coastguard Worker double duration = static_cast<double>(audio_frame->samples_per_channel_) /
402*d9f75844SAndroid Build Coastguard Worker audio_frame->sample_rate_hz_;
403*d9f75844SAndroid Build Coastguard Worker {
404*d9f75844SAndroid Build Coastguard Worker // Note: SendAudioData() passes the frame further down the pipeline and it
405*d9f75844SAndroid Build Coastguard Worker // may eventually get sent. But this method is invoked even if we are not
406*d9f75844SAndroid Build Coastguard Worker // connected, as long as we have an AudioSendStream (created as a result of
407*d9f75844SAndroid Build Coastguard Worker // an O/A exchange). This means that we are calculating audio levels whether
408*d9f75844SAndroid Build Coastguard Worker // or not we are sending samples.
409*d9f75844SAndroid Build Coastguard Worker // TODO(https://crbug.com/webrtc/10771): All "media-source" related stats
410*d9f75844SAndroid Build Coastguard Worker // should move from send-streams to the local audio sources or tracks; a
411*d9f75844SAndroid Build Coastguard Worker // send-stream should not be required to read the microphone audio levels.
412*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&audio_level_lock_);
413*d9f75844SAndroid Build Coastguard Worker audio_level_.ComputeLevel(*audio_frame, duration);
414*d9f75844SAndroid Build Coastguard Worker }
415*d9f75844SAndroid Build Coastguard Worker channel_send_->ProcessAndEncodeAudio(std::move(audio_frame));
416*d9f75844SAndroid Build Coastguard Worker }
417*d9f75844SAndroid Build Coastguard Worker
SendTelephoneEvent(int payload_type,int payload_frequency,int event,int duration_ms)418*d9f75844SAndroid Build Coastguard Worker bool AudioSendStream::SendTelephoneEvent(int payload_type,
419*d9f75844SAndroid Build Coastguard Worker int payload_frequency,
420*d9f75844SAndroid Build Coastguard Worker int event,
421*d9f75844SAndroid Build Coastguard Worker int duration_ms) {
422*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
423*d9f75844SAndroid Build Coastguard Worker channel_send_->SetSendTelephoneEventPayloadType(payload_type,
424*d9f75844SAndroid Build Coastguard Worker payload_frequency);
425*d9f75844SAndroid Build Coastguard Worker return channel_send_->SendTelephoneEventOutband(event, duration_ms);
426*d9f75844SAndroid Build Coastguard Worker }
427*d9f75844SAndroid Build Coastguard Worker
SetMuted(bool muted)428*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::SetMuted(bool muted) {
429*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
430*d9f75844SAndroid Build Coastguard Worker channel_send_->SetInputMute(muted);
431*d9f75844SAndroid Build Coastguard Worker }
432*d9f75844SAndroid Build Coastguard Worker
GetStats() const433*d9f75844SAndroid Build Coastguard Worker webrtc::AudioSendStream::Stats AudioSendStream::GetStats() const {
434*d9f75844SAndroid Build Coastguard Worker return GetStats(true);
435*d9f75844SAndroid Build Coastguard Worker }
436*d9f75844SAndroid Build Coastguard Worker
GetStats(bool has_remote_tracks) const437*d9f75844SAndroid Build Coastguard Worker webrtc::AudioSendStream::Stats AudioSendStream::GetStats(
438*d9f75844SAndroid Build Coastguard Worker bool has_remote_tracks) const {
439*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
440*d9f75844SAndroid Build Coastguard Worker webrtc::AudioSendStream::Stats stats;
441*d9f75844SAndroid Build Coastguard Worker stats.local_ssrc = config_.rtp.ssrc;
442*d9f75844SAndroid Build Coastguard Worker stats.target_bitrate_bps = channel_send_->GetTargetBitrate();
443*d9f75844SAndroid Build Coastguard Worker
444*d9f75844SAndroid Build Coastguard Worker webrtc::CallSendStatistics call_stats = channel_send_->GetRTCPStatistics();
445*d9f75844SAndroid Build Coastguard Worker stats.payload_bytes_sent = call_stats.payload_bytes_sent;
446*d9f75844SAndroid Build Coastguard Worker stats.header_and_padding_bytes_sent =
447*d9f75844SAndroid Build Coastguard Worker call_stats.header_and_padding_bytes_sent;
448*d9f75844SAndroid Build Coastguard Worker stats.retransmitted_bytes_sent = call_stats.retransmitted_bytes_sent;
449*d9f75844SAndroid Build Coastguard Worker stats.packets_sent = call_stats.packetsSent;
450*d9f75844SAndroid Build Coastguard Worker stats.total_packet_send_delay = call_stats.total_packet_send_delay;
451*d9f75844SAndroid Build Coastguard Worker stats.retransmitted_packets_sent = call_stats.retransmitted_packets_sent;
452*d9f75844SAndroid Build Coastguard Worker // RTT isn't known until a RTCP report is received. Until then, VoiceEngine
453*d9f75844SAndroid Build Coastguard Worker // returns 0 to indicate an error value.
454*d9f75844SAndroid Build Coastguard Worker if (call_stats.rttMs > 0) {
455*d9f75844SAndroid Build Coastguard Worker stats.rtt_ms = call_stats.rttMs;
456*d9f75844SAndroid Build Coastguard Worker }
457*d9f75844SAndroid Build Coastguard Worker if (config_.send_codec_spec) {
458*d9f75844SAndroid Build Coastguard Worker const auto& spec = *config_.send_codec_spec;
459*d9f75844SAndroid Build Coastguard Worker stats.codec_name = spec.format.name;
460*d9f75844SAndroid Build Coastguard Worker stats.codec_payload_type = spec.payload_type;
461*d9f75844SAndroid Build Coastguard Worker
462*d9f75844SAndroid Build Coastguard Worker // Get data from the last remote RTCP report.
463*d9f75844SAndroid Build Coastguard Worker for (const auto& block : channel_send_->GetRemoteRTCPReportBlocks()) {
464*d9f75844SAndroid Build Coastguard Worker // Lookup report for send ssrc only.
465*d9f75844SAndroid Build Coastguard Worker if (block.source_SSRC == stats.local_ssrc) {
466*d9f75844SAndroid Build Coastguard Worker stats.packets_lost = block.cumulative_num_packets_lost;
467*d9f75844SAndroid Build Coastguard Worker stats.fraction_lost = Q8ToFloat(block.fraction_lost);
468*d9f75844SAndroid Build Coastguard Worker // Convert timestamps to milliseconds.
469*d9f75844SAndroid Build Coastguard Worker if (spec.format.clockrate_hz / 1000 > 0) {
470*d9f75844SAndroid Build Coastguard Worker stats.jitter_ms =
471*d9f75844SAndroid Build Coastguard Worker block.interarrival_jitter / (spec.format.clockrate_hz / 1000);
472*d9f75844SAndroid Build Coastguard Worker }
473*d9f75844SAndroid Build Coastguard Worker break;
474*d9f75844SAndroid Build Coastguard Worker }
475*d9f75844SAndroid Build Coastguard Worker }
476*d9f75844SAndroid Build Coastguard Worker }
477*d9f75844SAndroid Build Coastguard Worker
478*d9f75844SAndroid Build Coastguard Worker {
479*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&audio_level_lock_);
480*d9f75844SAndroid Build Coastguard Worker stats.audio_level = audio_level_.LevelFullRange();
481*d9f75844SAndroid Build Coastguard Worker stats.total_input_energy = audio_level_.TotalEnergy();
482*d9f75844SAndroid Build Coastguard Worker stats.total_input_duration = audio_level_.TotalDuration();
483*d9f75844SAndroid Build Coastguard Worker }
484*d9f75844SAndroid Build Coastguard Worker
485*d9f75844SAndroid Build Coastguard Worker stats.ana_statistics = channel_send_->GetANAStatistics();
486*d9f75844SAndroid Build Coastguard Worker
487*d9f75844SAndroid Build Coastguard Worker AudioProcessing* ap = audio_state_->audio_processing();
488*d9f75844SAndroid Build Coastguard Worker if (ap) {
489*d9f75844SAndroid Build Coastguard Worker stats.apm_statistics = ap->GetStatistics(has_remote_tracks);
490*d9f75844SAndroid Build Coastguard Worker }
491*d9f75844SAndroid Build Coastguard Worker
492*d9f75844SAndroid Build Coastguard Worker stats.report_block_datas = std::move(call_stats.report_block_datas);
493*d9f75844SAndroid Build Coastguard Worker
494*d9f75844SAndroid Build Coastguard Worker stats.nacks_rcvd = call_stats.nacks_rcvd;
495*d9f75844SAndroid Build Coastguard Worker
496*d9f75844SAndroid Build Coastguard Worker return stats;
497*d9f75844SAndroid Build Coastguard Worker }
498*d9f75844SAndroid Build Coastguard Worker
DeliverRtcp(const uint8_t * packet,size_t length)499*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
500*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
501*d9f75844SAndroid Build Coastguard Worker channel_send_->ReceivedRTCPPacket(packet, length);
502*d9f75844SAndroid Build Coastguard Worker
503*d9f75844SAndroid Build Coastguard Worker {
504*d9f75844SAndroid Build Coastguard Worker // Poll if overhead has changed, which it can do if ack triggers us to stop
505*d9f75844SAndroid Build Coastguard Worker // sending mid/rid.
506*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&overhead_per_packet_lock_);
507*d9f75844SAndroid Build Coastguard Worker UpdateOverheadForEncoder();
508*d9f75844SAndroid Build Coastguard Worker }
509*d9f75844SAndroid Build Coastguard Worker UpdateCachedTargetAudioBitrateConstraints();
510*d9f75844SAndroid Build Coastguard Worker }
511*d9f75844SAndroid Build Coastguard Worker
OnBitrateUpdated(BitrateAllocationUpdate update)512*d9f75844SAndroid Build Coastguard Worker uint32_t AudioSendStream::OnBitrateUpdated(BitrateAllocationUpdate update) {
513*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(rtp_transport_queue_);
514*d9f75844SAndroid Build Coastguard Worker
515*d9f75844SAndroid Build Coastguard Worker // Pick a target bitrate between the constraints. Overrules the allocator if
516*d9f75844SAndroid Build Coastguard Worker // it 1) allocated a bitrate of zero to disable the stream or 2) allocated a
517*d9f75844SAndroid Build Coastguard Worker // higher than max to allow for e.g. extra FEC.
518*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(cached_constraints_.has_value());
519*d9f75844SAndroid Build Coastguard Worker update.target_bitrate.Clamp(cached_constraints_->min,
520*d9f75844SAndroid Build Coastguard Worker cached_constraints_->max);
521*d9f75844SAndroid Build Coastguard Worker update.stable_target_bitrate.Clamp(cached_constraints_->min,
522*d9f75844SAndroid Build Coastguard Worker cached_constraints_->max);
523*d9f75844SAndroid Build Coastguard Worker
524*d9f75844SAndroid Build Coastguard Worker channel_send_->OnBitrateAllocation(update);
525*d9f75844SAndroid Build Coastguard Worker
526*d9f75844SAndroid Build Coastguard Worker // The amount of audio protection is not exposed by the encoder, hence
527*d9f75844SAndroid Build Coastguard Worker // always returning 0.
528*d9f75844SAndroid Build Coastguard Worker return 0;
529*d9f75844SAndroid Build Coastguard Worker }
530*d9f75844SAndroid Build Coastguard Worker
SetTransportOverhead(int transport_overhead_per_packet_bytes)531*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::SetTransportOverhead(
532*d9f75844SAndroid Build Coastguard Worker int transport_overhead_per_packet_bytes) {
533*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
534*d9f75844SAndroid Build Coastguard Worker {
535*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&overhead_per_packet_lock_);
536*d9f75844SAndroid Build Coastguard Worker transport_overhead_per_packet_bytes_ = transport_overhead_per_packet_bytes;
537*d9f75844SAndroid Build Coastguard Worker UpdateOverheadForEncoder();
538*d9f75844SAndroid Build Coastguard Worker }
539*d9f75844SAndroid Build Coastguard Worker UpdateCachedTargetAudioBitrateConstraints();
540*d9f75844SAndroid Build Coastguard Worker }
541*d9f75844SAndroid Build Coastguard Worker
UpdateOverheadForEncoder()542*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::UpdateOverheadForEncoder() {
543*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&worker_thread_checker_);
544*d9f75844SAndroid Build Coastguard Worker size_t overhead_per_packet_bytes = GetPerPacketOverheadBytes();
545*d9f75844SAndroid Build Coastguard Worker if (overhead_per_packet_ == overhead_per_packet_bytes) {
546*d9f75844SAndroid Build Coastguard Worker return;
547*d9f75844SAndroid Build Coastguard Worker }
548*d9f75844SAndroid Build Coastguard Worker overhead_per_packet_ = overhead_per_packet_bytes;
549*d9f75844SAndroid Build Coastguard Worker
550*d9f75844SAndroid Build Coastguard Worker channel_send_->CallEncoder([&](AudioEncoder* encoder) {
551*d9f75844SAndroid Build Coastguard Worker encoder->OnReceivedOverhead(overhead_per_packet_bytes);
552*d9f75844SAndroid Build Coastguard Worker });
553*d9f75844SAndroid Build Coastguard Worker if (total_packet_overhead_bytes_ != overhead_per_packet_bytes) {
554*d9f75844SAndroid Build Coastguard Worker total_packet_overhead_bytes_ = overhead_per_packet_bytes;
555*d9f75844SAndroid Build Coastguard Worker if (registered_with_allocator_) {
556*d9f75844SAndroid Build Coastguard Worker ConfigureBitrateObserver();
557*d9f75844SAndroid Build Coastguard Worker }
558*d9f75844SAndroid Build Coastguard Worker }
559*d9f75844SAndroid Build Coastguard Worker }
560*d9f75844SAndroid Build Coastguard Worker
TestOnlyGetPerPacketOverheadBytes() const561*d9f75844SAndroid Build Coastguard Worker size_t AudioSendStream::TestOnlyGetPerPacketOverheadBytes() const {
562*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&overhead_per_packet_lock_);
563*d9f75844SAndroid Build Coastguard Worker return GetPerPacketOverheadBytes();
564*d9f75844SAndroid Build Coastguard Worker }
565*d9f75844SAndroid Build Coastguard Worker
GetPerPacketOverheadBytes() const566*d9f75844SAndroid Build Coastguard Worker size_t AudioSendStream::GetPerPacketOverheadBytes() const {
567*d9f75844SAndroid Build Coastguard Worker return transport_overhead_per_packet_bytes_ +
568*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->ExpectedPerPacketOverhead();
569*d9f75844SAndroid Build Coastguard Worker }
570*d9f75844SAndroid Build Coastguard Worker
GetRtpState() const571*d9f75844SAndroid Build Coastguard Worker RtpState AudioSendStream::GetRtpState() const {
572*d9f75844SAndroid Build Coastguard Worker return rtp_rtcp_module_->GetRtpState();
573*d9f75844SAndroid Build Coastguard Worker }
574*d9f75844SAndroid Build Coastguard Worker
GetChannel() const575*d9f75844SAndroid Build Coastguard Worker const voe::ChannelSendInterface* AudioSendStream::GetChannel() const {
576*d9f75844SAndroid Build Coastguard Worker return channel_send_.get();
577*d9f75844SAndroid Build Coastguard Worker }
578*d9f75844SAndroid Build Coastguard Worker
audio_state()579*d9f75844SAndroid Build Coastguard Worker internal::AudioState* AudioSendStream::audio_state() {
580*d9f75844SAndroid Build Coastguard Worker internal::AudioState* audio_state =
581*d9f75844SAndroid Build Coastguard Worker static_cast<internal::AudioState*>(audio_state_.get());
582*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(audio_state);
583*d9f75844SAndroid Build Coastguard Worker return audio_state;
584*d9f75844SAndroid Build Coastguard Worker }
585*d9f75844SAndroid Build Coastguard Worker
audio_state() const586*d9f75844SAndroid Build Coastguard Worker const internal::AudioState* AudioSendStream::audio_state() const {
587*d9f75844SAndroid Build Coastguard Worker internal::AudioState* audio_state =
588*d9f75844SAndroid Build Coastguard Worker static_cast<internal::AudioState*>(audio_state_.get());
589*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(audio_state);
590*d9f75844SAndroid Build Coastguard Worker return audio_state;
591*d9f75844SAndroid Build Coastguard Worker }
592*d9f75844SAndroid Build Coastguard Worker
StoreEncoderProperties(int sample_rate_hz,size_t num_channels)593*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::StoreEncoderProperties(int sample_rate_hz,
594*d9f75844SAndroid Build Coastguard Worker size_t num_channels) {
595*d9f75844SAndroid Build Coastguard Worker encoder_sample_rate_hz_ = sample_rate_hz;
596*d9f75844SAndroid Build Coastguard Worker encoder_num_channels_ = num_channels;
597*d9f75844SAndroid Build Coastguard Worker if (sending_) {
598*d9f75844SAndroid Build Coastguard Worker // Update AudioState's information about the stream.
599*d9f75844SAndroid Build Coastguard Worker audio_state()->AddSendingStream(this, sample_rate_hz, num_channels);
600*d9f75844SAndroid Build Coastguard Worker }
601*d9f75844SAndroid Build Coastguard Worker }
602*d9f75844SAndroid Build Coastguard Worker
603*d9f75844SAndroid Build Coastguard Worker // Apply current codec settings to a single voe::Channel used for sending.
SetupSendCodec(const Config & new_config)604*d9f75844SAndroid Build Coastguard Worker bool AudioSendStream::SetupSendCodec(const Config& new_config) {
605*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(new_config.send_codec_spec);
606*d9f75844SAndroid Build Coastguard Worker const auto& spec = *new_config.send_codec_spec;
607*d9f75844SAndroid Build Coastguard Worker
608*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(new_config.encoder_factory);
609*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<AudioEncoder> encoder =
610*d9f75844SAndroid Build Coastguard Worker new_config.encoder_factory->MakeAudioEncoder(
611*d9f75844SAndroid Build Coastguard Worker spec.payload_type, spec.format, new_config.codec_pair_id);
612*d9f75844SAndroid Build Coastguard Worker
613*d9f75844SAndroid Build Coastguard Worker if (!encoder) {
614*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_ERROR) << "Unable to create encoder for "
615*d9f75844SAndroid Build Coastguard Worker << rtc::ToString(spec.format);
616*d9f75844SAndroid Build Coastguard Worker return false;
617*d9f75844SAndroid Build Coastguard Worker }
618*d9f75844SAndroid Build Coastguard Worker
619*d9f75844SAndroid Build Coastguard Worker // If a bitrate has been specified for the codec, use it over the
620*d9f75844SAndroid Build Coastguard Worker // codec's default.
621*d9f75844SAndroid Build Coastguard Worker if (spec.target_bitrate_bps) {
622*d9f75844SAndroid Build Coastguard Worker encoder->OnReceivedTargetAudioBitrate(*spec.target_bitrate_bps);
623*d9f75844SAndroid Build Coastguard Worker }
624*d9f75844SAndroid Build Coastguard Worker
625*d9f75844SAndroid Build Coastguard Worker // Enable ANA if configured (currently only used by Opus).
626*d9f75844SAndroid Build Coastguard Worker if (new_config.audio_network_adaptor_config) {
627*d9f75844SAndroid Build Coastguard Worker if (encoder->EnableAudioNetworkAdaptor(
628*d9f75844SAndroid Build Coastguard Worker *new_config.audio_network_adaptor_config, event_log_)) {
629*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "Audio network adaptor enabled on SSRC "
630*d9f75844SAndroid Build Coastguard Worker << new_config.rtp.ssrc;
631*d9f75844SAndroid Build Coastguard Worker } else {
632*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "Failed to enable Audio network adaptor on SSRC "
633*d9f75844SAndroid Build Coastguard Worker << new_config.rtp.ssrc;
634*d9f75844SAndroid Build Coastguard Worker }
635*d9f75844SAndroid Build Coastguard Worker }
636*d9f75844SAndroid Build Coastguard Worker
637*d9f75844SAndroid Build Coastguard Worker // Wrap the encoder in an AudioEncoderCNG, if VAD is enabled.
638*d9f75844SAndroid Build Coastguard Worker if (spec.cng_payload_type) {
639*d9f75844SAndroid Build Coastguard Worker AudioEncoderCngConfig cng_config;
640*d9f75844SAndroid Build Coastguard Worker cng_config.num_channels = encoder->NumChannels();
641*d9f75844SAndroid Build Coastguard Worker cng_config.payload_type = *spec.cng_payload_type;
642*d9f75844SAndroid Build Coastguard Worker cng_config.speech_encoder = std::move(encoder);
643*d9f75844SAndroid Build Coastguard Worker cng_config.vad_mode = Vad::kVadNormal;
644*d9f75844SAndroid Build Coastguard Worker encoder = CreateComfortNoiseEncoder(std::move(cng_config));
645*d9f75844SAndroid Build Coastguard Worker
646*d9f75844SAndroid Build Coastguard Worker RegisterCngPayloadType(*spec.cng_payload_type,
647*d9f75844SAndroid Build Coastguard Worker new_config.send_codec_spec->format.clockrate_hz);
648*d9f75844SAndroid Build Coastguard Worker }
649*d9f75844SAndroid Build Coastguard Worker
650*d9f75844SAndroid Build Coastguard Worker // Wrap the encoder in a RED encoder, if RED is enabled.
651*d9f75844SAndroid Build Coastguard Worker if (spec.red_payload_type) {
652*d9f75844SAndroid Build Coastguard Worker AudioEncoderCopyRed::Config red_config;
653*d9f75844SAndroid Build Coastguard Worker red_config.payload_type = *spec.red_payload_type;
654*d9f75844SAndroid Build Coastguard Worker red_config.speech_encoder = std::move(encoder);
655*d9f75844SAndroid Build Coastguard Worker encoder = std::make_unique<AudioEncoderCopyRed>(std::move(red_config),
656*d9f75844SAndroid Build Coastguard Worker field_trials_);
657*d9f75844SAndroid Build Coastguard Worker }
658*d9f75844SAndroid Build Coastguard Worker
659*d9f75844SAndroid Build Coastguard Worker // Set currently known overhead (used in ANA, opus only).
660*d9f75844SAndroid Build Coastguard Worker // If overhead changes later, it will be updated in UpdateOverheadForEncoder.
661*d9f75844SAndroid Build Coastguard Worker {
662*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&overhead_per_packet_lock_);
663*d9f75844SAndroid Build Coastguard Worker size_t overhead = GetPerPacketOverheadBytes();
664*d9f75844SAndroid Build Coastguard Worker if (overhead > 0) {
665*d9f75844SAndroid Build Coastguard Worker encoder->OnReceivedOverhead(overhead);
666*d9f75844SAndroid Build Coastguard Worker }
667*d9f75844SAndroid Build Coastguard Worker }
668*d9f75844SAndroid Build Coastguard Worker
669*d9f75844SAndroid Build Coastguard Worker StoreEncoderProperties(encoder->SampleRateHz(), encoder->NumChannels());
670*d9f75844SAndroid Build Coastguard Worker channel_send_->SetEncoder(new_config.send_codec_spec->payload_type,
671*d9f75844SAndroid Build Coastguard Worker std::move(encoder));
672*d9f75844SAndroid Build Coastguard Worker
673*d9f75844SAndroid Build Coastguard Worker return true;
674*d9f75844SAndroid Build Coastguard Worker }
675*d9f75844SAndroid Build Coastguard Worker
ReconfigureSendCodec(const Config & new_config)676*d9f75844SAndroid Build Coastguard Worker bool AudioSendStream::ReconfigureSendCodec(const Config& new_config) {
677*d9f75844SAndroid Build Coastguard Worker const auto& old_config = config_;
678*d9f75844SAndroid Build Coastguard Worker
679*d9f75844SAndroid Build Coastguard Worker if (!new_config.send_codec_spec) {
680*d9f75844SAndroid Build Coastguard Worker // We cannot de-configure a send codec. So we will do nothing.
681*d9f75844SAndroid Build Coastguard Worker // By design, the send codec should have not been configured.
682*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!old_config.send_codec_spec);
683*d9f75844SAndroid Build Coastguard Worker return true;
684*d9f75844SAndroid Build Coastguard Worker }
685*d9f75844SAndroid Build Coastguard Worker
686*d9f75844SAndroid Build Coastguard Worker if (new_config.send_codec_spec == old_config.send_codec_spec &&
687*d9f75844SAndroid Build Coastguard Worker new_config.audio_network_adaptor_config ==
688*d9f75844SAndroid Build Coastguard Worker old_config.audio_network_adaptor_config) {
689*d9f75844SAndroid Build Coastguard Worker return true;
690*d9f75844SAndroid Build Coastguard Worker }
691*d9f75844SAndroid Build Coastguard Worker
692*d9f75844SAndroid Build Coastguard Worker // If we have no encoder, or the format or payload type's changed, create a
693*d9f75844SAndroid Build Coastguard Worker // new encoder.
694*d9f75844SAndroid Build Coastguard Worker if (!old_config.send_codec_spec ||
695*d9f75844SAndroid Build Coastguard Worker new_config.send_codec_spec->format !=
696*d9f75844SAndroid Build Coastguard Worker old_config.send_codec_spec->format ||
697*d9f75844SAndroid Build Coastguard Worker new_config.send_codec_spec->payload_type !=
698*d9f75844SAndroid Build Coastguard Worker old_config.send_codec_spec->payload_type ||
699*d9f75844SAndroid Build Coastguard Worker new_config.send_codec_spec->red_payload_type !=
700*d9f75844SAndroid Build Coastguard Worker old_config.send_codec_spec->red_payload_type) {
701*d9f75844SAndroid Build Coastguard Worker return SetupSendCodec(new_config);
702*d9f75844SAndroid Build Coastguard Worker }
703*d9f75844SAndroid Build Coastguard Worker
704*d9f75844SAndroid Build Coastguard Worker const absl::optional<int>& new_target_bitrate_bps =
705*d9f75844SAndroid Build Coastguard Worker new_config.send_codec_spec->target_bitrate_bps;
706*d9f75844SAndroid Build Coastguard Worker // If a bitrate has been specified for the codec, use it over the
707*d9f75844SAndroid Build Coastguard Worker // codec's default.
708*d9f75844SAndroid Build Coastguard Worker if (new_target_bitrate_bps &&
709*d9f75844SAndroid Build Coastguard Worker new_target_bitrate_bps !=
710*d9f75844SAndroid Build Coastguard Worker old_config.send_codec_spec->target_bitrate_bps) {
711*d9f75844SAndroid Build Coastguard Worker channel_send_->CallEncoder([&](AudioEncoder* encoder) {
712*d9f75844SAndroid Build Coastguard Worker encoder->OnReceivedTargetAudioBitrate(*new_target_bitrate_bps);
713*d9f75844SAndroid Build Coastguard Worker });
714*d9f75844SAndroid Build Coastguard Worker }
715*d9f75844SAndroid Build Coastguard Worker
716*d9f75844SAndroid Build Coastguard Worker ReconfigureANA(new_config);
717*d9f75844SAndroid Build Coastguard Worker ReconfigureCNG(new_config);
718*d9f75844SAndroid Build Coastguard Worker
719*d9f75844SAndroid Build Coastguard Worker return true;
720*d9f75844SAndroid Build Coastguard Worker }
721*d9f75844SAndroid Build Coastguard Worker
ReconfigureANA(const Config & new_config)722*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::ReconfigureANA(const Config& new_config) {
723*d9f75844SAndroid Build Coastguard Worker if (new_config.audio_network_adaptor_config ==
724*d9f75844SAndroid Build Coastguard Worker config_.audio_network_adaptor_config) {
725*d9f75844SAndroid Build Coastguard Worker return;
726*d9f75844SAndroid Build Coastguard Worker }
727*d9f75844SAndroid Build Coastguard Worker if (new_config.audio_network_adaptor_config) {
728*d9f75844SAndroid Build Coastguard Worker // This lock needs to be acquired before CallEncoder, since it aquires
729*d9f75844SAndroid Build Coastguard Worker // another lock and we need to maintain the same order at all call sites to
730*d9f75844SAndroid Build Coastguard Worker // avoid deadlock.
731*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&overhead_per_packet_lock_);
732*d9f75844SAndroid Build Coastguard Worker size_t overhead = GetPerPacketOverheadBytes();
733*d9f75844SAndroid Build Coastguard Worker channel_send_->CallEncoder([&](AudioEncoder* encoder) {
734*d9f75844SAndroid Build Coastguard Worker if (encoder->EnableAudioNetworkAdaptor(
735*d9f75844SAndroid Build Coastguard Worker *new_config.audio_network_adaptor_config, event_log_)) {
736*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "Audio network adaptor enabled on SSRC "
737*d9f75844SAndroid Build Coastguard Worker << new_config.rtp.ssrc;
738*d9f75844SAndroid Build Coastguard Worker if (overhead > 0) {
739*d9f75844SAndroid Build Coastguard Worker encoder->OnReceivedOverhead(overhead);
740*d9f75844SAndroid Build Coastguard Worker }
741*d9f75844SAndroid Build Coastguard Worker } else {
742*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "Failed to enable Audio network adaptor on SSRC "
743*d9f75844SAndroid Build Coastguard Worker << new_config.rtp.ssrc;
744*d9f75844SAndroid Build Coastguard Worker }
745*d9f75844SAndroid Build Coastguard Worker });
746*d9f75844SAndroid Build Coastguard Worker } else {
747*d9f75844SAndroid Build Coastguard Worker channel_send_->CallEncoder(
748*d9f75844SAndroid Build Coastguard Worker [&](AudioEncoder* encoder) { encoder->DisableAudioNetworkAdaptor(); });
749*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "Audio network adaptor disabled on SSRC "
750*d9f75844SAndroid Build Coastguard Worker << new_config.rtp.ssrc;
751*d9f75844SAndroid Build Coastguard Worker }
752*d9f75844SAndroid Build Coastguard Worker }
753*d9f75844SAndroid Build Coastguard Worker
ReconfigureCNG(const Config & new_config)754*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::ReconfigureCNG(const Config& new_config) {
755*d9f75844SAndroid Build Coastguard Worker if (new_config.send_codec_spec->cng_payload_type ==
756*d9f75844SAndroid Build Coastguard Worker config_.send_codec_spec->cng_payload_type) {
757*d9f75844SAndroid Build Coastguard Worker return;
758*d9f75844SAndroid Build Coastguard Worker }
759*d9f75844SAndroid Build Coastguard Worker
760*d9f75844SAndroid Build Coastguard Worker // Register the CNG payload type if it's been added, don't do anything if CNG
761*d9f75844SAndroid Build Coastguard Worker // is removed. Payload types must not be redefined.
762*d9f75844SAndroid Build Coastguard Worker if (new_config.send_codec_spec->cng_payload_type) {
763*d9f75844SAndroid Build Coastguard Worker RegisterCngPayloadType(*new_config.send_codec_spec->cng_payload_type,
764*d9f75844SAndroid Build Coastguard Worker new_config.send_codec_spec->format.clockrate_hz);
765*d9f75844SAndroid Build Coastguard Worker }
766*d9f75844SAndroid Build Coastguard Worker
767*d9f75844SAndroid Build Coastguard Worker // Wrap or unwrap the encoder in an AudioEncoderCNG.
768*d9f75844SAndroid Build Coastguard Worker channel_send_->ModifyEncoder([&](std::unique_ptr<AudioEncoder>* encoder_ptr) {
769*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<AudioEncoder> old_encoder(std::move(*encoder_ptr));
770*d9f75844SAndroid Build Coastguard Worker auto sub_encoders = old_encoder->ReclaimContainedEncoders();
771*d9f75844SAndroid Build Coastguard Worker if (!sub_encoders.empty()) {
772*d9f75844SAndroid Build Coastguard Worker // Replace enc with its sub encoder. We need to put the sub
773*d9f75844SAndroid Build Coastguard Worker // encoder in a temporary first, since otherwise the old value
774*d9f75844SAndroid Build Coastguard Worker // of enc would be destroyed before the new value got assigned,
775*d9f75844SAndroid Build Coastguard Worker // which would be bad since the new value is a part of the old
776*d9f75844SAndroid Build Coastguard Worker // value.
777*d9f75844SAndroid Build Coastguard Worker auto tmp = std::move(sub_encoders[0]);
778*d9f75844SAndroid Build Coastguard Worker old_encoder = std::move(tmp);
779*d9f75844SAndroid Build Coastguard Worker }
780*d9f75844SAndroid Build Coastguard Worker if (new_config.send_codec_spec->cng_payload_type) {
781*d9f75844SAndroid Build Coastguard Worker AudioEncoderCngConfig config;
782*d9f75844SAndroid Build Coastguard Worker config.speech_encoder = std::move(old_encoder);
783*d9f75844SAndroid Build Coastguard Worker config.num_channels = config.speech_encoder->NumChannels();
784*d9f75844SAndroid Build Coastguard Worker config.payload_type = *new_config.send_codec_spec->cng_payload_type;
785*d9f75844SAndroid Build Coastguard Worker config.vad_mode = Vad::kVadNormal;
786*d9f75844SAndroid Build Coastguard Worker *encoder_ptr = CreateComfortNoiseEncoder(std::move(config));
787*d9f75844SAndroid Build Coastguard Worker } else {
788*d9f75844SAndroid Build Coastguard Worker *encoder_ptr = std::move(old_encoder);
789*d9f75844SAndroid Build Coastguard Worker }
790*d9f75844SAndroid Build Coastguard Worker });
791*d9f75844SAndroid Build Coastguard Worker }
792*d9f75844SAndroid Build Coastguard Worker
ReconfigureBitrateObserver(const webrtc::AudioSendStream::Config & new_config)793*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::ReconfigureBitrateObserver(
794*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioSendStream::Config& new_config) {
795*d9f75844SAndroid Build Coastguard Worker // Since the Config's default is for both of these to be -1, this test will
796*d9f75844SAndroid Build Coastguard Worker // allow us to configure the bitrate observer if the new config has bitrate
797*d9f75844SAndroid Build Coastguard Worker // limits set, but would only have us call RemoveBitrateObserver if we were
798*d9f75844SAndroid Build Coastguard Worker // previously configured with bitrate limits.
799*d9f75844SAndroid Build Coastguard Worker if (config_.min_bitrate_bps == new_config.min_bitrate_bps &&
800*d9f75844SAndroid Build Coastguard Worker config_.max_bitrate_bps == new_config.max_bitrate_bps &&
801*d9f75844SAndroid Build Coastguard Worker config_.bitrate_priority == new_config.bitrate_priority &&
802*d9f75844SAndroid Build Coastguard Worker TransportSeqNumId(config_) == TransportSeqNumId(new_config) &&
803*d9f75844SAndroid Build Coastguard Worker config_.audio_network_adaptor_config ==
804*d9f75844SAndroid Build Coastguard Worker new_config.audio_network_adaptor_config) {
805*d9f75844SAndroid Build Coastguard Worker return;
806*d9f75844SAndroid Build Coastguard Worker }
807*d9f75844SAndroid Build Coastguard Worker
808*d9f75844SAndroid Build Coastguard Worker if (!new_config.has_dscp && new_config.min_bitrate_bps != -1 &&
809*d9f75844SAndroid Build Coastguard Worker new_config.max_bitrate_bps != -1 && TransportSeqNumId(new_config) != 0) {
810*d9f75844SAndroid Build Coastguard Worker rtp_transport_->AccountForAudioPacketsInPacedSender(true);
811*d9f75844SAndroid Build Coastguard Worker rtp_transport_->IncludeOverheadInPacedSender();
812*d9f75844SAndroid Build Coastguard Worker // We may get a callback immediately as the observer is registered, so
813*d9f75844SAndroid Build Coastguard Worker // make sure the bitrate limits in config_ are up-to-date.
814*d9f75844SAndroid Build Coastguard Worker config_.min_bitrate_bps = new_config.min_bitrate_bps;
815*d9f75844SAndroid Build Coastguard Worker config_.max_bitrate_bps = new_config.max_bitrate_bps;
816*d9f75844SAndroid Build Coastguard Worker
817*d9f75844SAndroid Build Coastguard Worker config_.bitrate_priority = new_config.bitrate_priority;
818*d9f75844SAndroid Build Coastguard Worker ConfigureBitrateObserver();
819*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->SetAsPartOfAllocation(true);
820*d9f75844SAndroid Build Coastguard Worker } else {
821*d9f75844SAndroid Build Coastguard Worker rtp_transport_->AccountForAudioPacketsInPacedSender(false);
822*d9f75844SAndroid Build Coastguard Worker RemoveBitrateObserver();
823*d9f75844SAndroid Build Coastguard Worker rtp_rtcp_module_->SetAsPartOfAllocation(false);
824*d9f75844SAndroid Build Coastguard Worker }
825*d9f75844SAndroid Build Coastguard Worker }
826*d9f75844SAndroid Build Coastguard Worker
ConfigureBitrateObserver()827*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::ConfigureBitrateObserver() {
828*d9f75844SAndroid Build Coastguard Worker // This either updates the current observer or adds a new observer.
829*d9f75844SAndroid Build Coastguard Worker // TODO(srte): Add overhead compensation here.
830*d9f75844SAndroid Build Coastguard Worker auto constraints = GetMinMaxBitrateConstraints();
831*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(constraints.has_value());
832*d9f75844SAndroid Build Coastguard Worker
833*d9f75844SAndroid Build Coastguard Worker DataRate priority_bitrate = allocation_settings_.priority_bitrate;
834*d9f75844SAndroid Build Coastguard Worker if (use_legacy_overhead_calculation_) {
835*d9f75844SAndroid Build Coastguard Worker // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
836*d9f75844SAndroid Build Coastguard Worker constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
837*d9f75844SAndroid Build Coastguard Worker const TimeDelta kMinPacketDuration = TimeDelta::Millis(20);
838*d9f75844SAndroid Build Coastguard Worker DataRate max_overhead =
839*d9f75844SAndroid Build Coastguard Worker DataSize::Bytes(kOverheadPerPacket) / kMinPacketDuration;
840*d9f75844SAndroid Build Coastguard Worker priority_bitrate += max_overhead;
841*d9f75844SAndroid Build Coastguard Worker } else {
842*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(frame_length_range_);
843*d9f75844SAndroid Build Coastguard Worker const DataSize overhead_per_packet =
844*d9f75844SAndroid Build Coastguard Worker DataSize::Bytes(total_packet_overhead_bytes_);
845*d9f75844SAndroid Build Coastguard Worker DataRate min_overhead = overhead_per_packet / frame_length_range_->second;
846*d9f75844SAndroid Build Coastguard Worker priority_bitrate += min_overhead;
847*d9f75844SAndroid Build Coastguard Worker }
848*d9f75844SAndroid Build Coastguard Worker
849*d9f75844SAndroid Build Coastguard Worker if (allocation_settings_.priority_bitrate_raw)
850*d9f75844SAndroid Build Coastguard Worker priority_bitrate = *allocation_settings_.priority_bitrate_raw;
851*d9f75844SAndroid Build Coastguard Worker
852*d9f75844SAndroid Build Coastguard Worker rtp_transport_queue_->RunOrPost([this, constraints, priority_bitrate,
853*d9f75844SAndroid Build Coastguard Worker config_bitrate_priority =
854*d9f75844SAndroid Build Coastguard Worker config_.bitrate_priority] {
855*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(rtp_transport_queue_);
856*d9f75844SAndroid Build Coastguard Worker bitrate_allocator_->AddObserver(
857*d9f75844SAndroid Build Coastguard Worker this,
858*d9f75844SAndroid Build Coastguard Worker MediaStreamAllocationConfig{
859*d9f75844SAndroid Build Coastguard Worker constraints->min.bps<uint32_t>(), constraints->max.bps<uint32_t>(),
860*d9f75844SAndroid Build Coastguard Worker 0, priority_bitrate.bps(), true,
861*d9f75844SAndroid Build Coastguard Worker allocation_settings_.bitrate_priority.value_or(
862*d9f75844SAndroid Build Coastguard Worker config_bitrate_priority)});
863*d9f75844SAndroid Build Coastguard Worker });
864*d9f75844SAndroid Build Coastguard Worker registered_with_allocator_ = true;
865*d9f75844SAndroid Build Coastguard Worker }
866*d9f75844SAndroid Build Coastguard Worker
RemoveBitrateObserver()867*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::RemoveBitrateObserver() {
868*d9f75844SAndroid Build Coastguard Worker registered_with_allocator_ = false;
869*d9f75844SAndroid Build Coastguard Worker rtp_transport_queue_->RunSynchronous([this] {
870*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(rtp_transport_queue_);
871*d9f75844SAndroid Build Coastguard Worker bitrate_allocator_->RemoveObserver(this);
872*d9f75844SAndroid Build Coastguard Worker });
873*d9f75844SAndroid Build Coastguard Worker }
874*d9f75844SAndroid Build Coastguard Worker
875*d9f75844SAndroid Build Coastguard Worker absl::optional<AudioSendStream::TargetAudioBitrateConstraints>
GetMinMaxBitrateConstraints() const876*d9f75844SAndroid Build Coastguard Worker AudioSendStream::GetMinMaxBitrateConstraints() const {
877*d9f75844SAndroid Build Coastguard Worker if (config_.min_bitrate_bps < 0 || config_.max_bitrate_bps < 0) {
878*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_WARNING) << "Config is invalid: min_bitrate_bps="
879*d9f75844SAndroid Build Coastguard Worker << config_.min_bitrate_bps
880*d9f75844SAndroid Build Coastguard Worker << "; max_bitrate_bps=" << config_.max_bitrate_bps
881*d9f75844SAndroid Build Coastguard Worker << "; both expected greater or equal to 0";
882*d9f75844SAndroid Build Coastguard Worker return absl::nullopt;
883*d9f75844SAndroid Build Coastguard Worker }
884*d9f75844SAndroid Build Coastguard Worker TargetAudioBitrateConstraints constraints{
885*d9f75844SAndroid Build Coastguard Worker DataRate::BitsPerSec(config_.min_bitrate_bps),
886*d9f75844SAndroid Build Coastguard Worker DataRate::BitsPerSec(config_.max_bitrate_bps)};
887*d9f75844SAndroid Build Coastguard Worker
888*d9f75844SAndroid Build Coastguard Worker // If bitrates were explicitly overriden via field trial, use those values.
889*d9f75844SAndroid Build Coastguard Worker if (allocation_settings_.min_bitrate)
890*d9f75844SAndroid Build Coastguard Worker constraints.min = *allocation_settings_.min_bitrate;
891*d9f75844SAndroid Build Coastguard Worker if (allocation_settings_.max_bitrate)
892*d9f75844SAndroid Build Coastguard Worker constraints.max = *allocation_settings_.max_bitrate;
893*d9f75844SAndroid Build Coastguard Worker
894*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_GE(constraints.min, DataRate::Zero());
895*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_GE(constraints.max, DataRate::Zero());
896*d9f75844SAndroid Build Coastguard Worker if (constraints.max < constraints.min) {
897*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_WARNING) << "TargetAudioBitrateConstraints::max is less than "
898*d9f75844SAndroid Build Coastguard Worker << "TargetAudioBitrateConstraints::min";
899*d9f75844SAndroid Build Coastguard Worker return absl::nullopt;
900*d9f75844SAndroid Build Coastguard Worker }
901*d9f75844SAndroid Build Coastguard Worker if (use_legacy_overhead_calculation_) {
902*d9f75844SAndroid Build Coastguard Worker // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
903*d9f75844SAndroid Build Coastguard Worker const DataSize kOverheadPerPacket = DataSize::Bytes(20 + 8 + 10 + 12);
904*d9f75844SAndroid Build Coastguard Worker const TimeDelta kMaxFrameLength =
905*d9f75844SAndroid Build Coastguard Worker TimeDelta::Millis(60); // Based on Opus spec
906*d9f75844SAndroid Build Coastguard Worker const DataRate kMinOverhead = kOverheadPerPacket / kMaxFrameLength;
907*d9f75844SAndroid Build Coastguard Worker constraints.min += kMinOverhead;
908*d9f75844SAndroid Build Coastguard Worker constraints.max += kMinOverhead;
909*d9f75844SAndroid Build Coastguard Worker } else {
910*d9f75844SAndroid Build Coastguard Worker if (!frame_length_range_.has_value()) {
911*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_WARNING) << "frame_length_range_ is not set";
912*d9f75844SAndroid Build Coastguard Worker return absl::nullopt;
913*d9f75844SAndroid Build Coastguard Worker }
914*d9f75844SAndroid Build Coastguard Worker const DataSize kOverheadPerPacket =
915*d9f75844SAndroid Build Coastguard Worker DataSize::Bytes(total_packet_overhead_bytes_);
916*d9f75844SAndroid Build Coastguard Worker constraints.min += kOverheadPerPacket / frame_length_range_->second;
917*d9f75844SAndroid Build Coastguard Worker constraints.max += kOverheadPerPacket / frame_length_range_->first;
918*d9f75844SAndroid Build Coastguard Worker }
919*d9f75844SAndroid Build Coastguard Worker return constraints;
920*d9f75844SAndroid Build Coastguard Worker }
921*d9f75844SAndroid Build Coastguard Worker
RegisterCngPayloadType(int payload_type,int clockrate_hz)922*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::RegisterCngPayloadType(int payload_type,
923*d9f75844SAndroid Build Coastguard Worker int clockrate_hz) {
924*d9f75844SAndroid Build Coastguard Worker channel_send_->RegisterCngPayloadType(payload_type, clockrate_hz);
925*d9f75844SAndroid Build Coastguard Worker }
926*d9f75844SAndroid Build Coastguard Worker
UpdateCachedTargetAudioBitrateConstraints()927*d9f75844SAndroid Build Coastguard Worker void AudioSendStream::UpdateCachedTargetAudioBitrateConstraints() {
928*d9f75844SAndroid Build Coastguard Worker absl::optional<AudioSendStream::TargetAudioBitrateConstraints>
929*d9f75844SAndroid Build Coastguard Worker new_constraints = GetMinMaxBitrateConstraints();
930*d9f75844SAndroid Build Coastguard Worker if (!new_constraints.has_value()) {
931*d9f75844SAndroid Build Coastguard Worker return;
932*d9f75844SAndroid Build Coastguard Worker }
933*d9f75844SAndroid Build Coastguard Worker rtp_transport_queue_->RunOrPost([this, new_constraints]() {
934*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(rtp_transport_queue_);
935*d9f75844SAndroid Build Coastguard Worker cached_constraints_ = new_constraints;
936*d9f75844SAndroid Build Coastguard Worker });
937*d9f75844SAndroid Build Coastguard Worker }
938*d9f75844SAndroid Build Coastguard Worker
939*d9f75844SAndroid Build Coastguard Worker } // namespace internal
940*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
941