diff options
Diffstat (limited to 'media/engine/webrtc_voice_engine.cc')
-rw-r--r-- | media/engine/webrtc_voice_engine.cc | 113 |
1 files changed, 107 insertions, 6 deletions
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index 85c72804c1..38dc3462ac 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -36,7 +36,9 @@ #include "rtc_base/constructor_magic.h" #include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/field_trial_units.h" +#include "rtc_base/experiments/struct_parameters_parser.h" #include "rtc_base/helpers.h" +#include "rtc_base/ignore_wundef.h" #include "rtc_base/logging.h" #include "rtc_base/race_checker.h" #include "rtc_base/strings/audio_format_to_string.h" @@ -46,6 +48,16 @@ #include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/metrics.h" +#if WEBRTC_ENABLE_PROTOBUF +RTC_PUSH_IGNORING_WUNDEF() +#ifdef WEBRTC_ANDROID_PLATFORM_BUILD +#include "external/webrtc/webrtc/modules/audio_coding/audio_network_adaptor/config.pb.h" +#else +#include "modules/audio_coding/audio_network_adaptor/config.pb.h" +#endif +RTC_POP_IGNORING_WUNDEF() +#endif + namespace cricket { namespace { @@ -99,6 +111,12 @@ std::string ToString(const AudioCodec& codec) { return ss.Release(); } +// If this field trial is enabled, we will negotiate and use RFC 2198 +// redundancy for opus audio. +bool IsAudioRedForOpusFieldTrialEnabled() { + return webrtc::field_trial::IsEnabled("WebRTC-Audio-Red-For-Opus"); +} + bool IsCodec(const AudioCodec& codec, const char* ref_name) { return absl::EqualsIgnoreCase(codec.name, ref_name); } @@ -185,6 +203,38 @@ absl::optional<int> ComputeSendBitrate(int max_send_bitrate_bps, } } +struct AdaptivePtimeConfig { + bool enabled = false; + webrtc::DataRate min_payload_bitrate = webrtc::DataRate::KilobitsPerSec(16); + webrtc::DataRate min_encoder_bitrate = webrtc::DataRate::KilobitsPerSec(12); + bool use_slow_adaptation = true; + + absl::optional<std::string> audio_network_adaptor_config; + + std::unique_ptr<webrtc::StructParametersParser> Parser() { + return webrtc::StructParametersParser::Create( // + "enabled", &enabled, // + "min_payload_bitrate", &min_payload_bitrate, // + "min_encoder_bitrate", &min_encoder_bitrate, // + "use_slow_adaptation", &use_slow_adaptation); + } + + AdaptivePtimeConfig() { + Parser()->Parse( + webrtc::field_trial::FindFullName("WebRTC-Audio-AdaptivePtime")); +#if WEBRTC_ENABLE_PROTOBUF + webrtc::audio_network_adaptor::config::ControllerManager config; + auto* frame_length_controller = + config.add_controllers()->mutable_frame_length_controller_v2(); + frame_length_controller->set_min_payload_bitrate_bps( + min_payload_bitrate.bps()); + frame_length_controller->set_use_slow_adaptation(use_slow_adaptation); + config.add_controllers()->mutable_bitrate_controller(); + audio_network_adaptor_config = config.SerializeAsString(); +#endif + } +}; + } // namespace WebRtcVoiceEngine::WebRtcVoiceEngine( @@ -682,6 +732,11 @@ std::vector<AudioCodec> WebRtcVoiceEngine::CollectCodecs( } } + // Add red codec. + if (IsAudioRedForOpusFieldTrialEnabled()) { + map_format({kRedCodecName, 48000, 2}, &out); + } + // Add telephone-event codecs last. for (const auto& dtmf : generate_dtmf) { if (dtmf.second) { @@ -726,7 +781,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream config_.rtp.extensions = extensions; config_.has_dscp = rtp_parameters_.encodings[0].network_priority != webrtc::Priority::kLow; - config_.audio_network_adaptor_config = audio_network_adaptor_config; config_.encoder_factory = encoder_factory; config_.codec_pair_id = codec_pair_id; config_.track_id = track_id; @@ -737,6 +791,9 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream rtp_parameters_.rtcp.cname = c_name; rtp_parameters_.header_extensions = extensions; + audio_network_adaptor_config_from_options_ = audio_network_adaptor_config; + UpdateAudioNetworkAdaptorConfig(); + if (send_codec_spec) { UpdateSendCodecSpec(*send_codec_spec); } @@ -787,10 +844,12 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream void SetAudioNetworkAdaptorConfig( const absl::optional<std::string>& audio_network_adaptor_config) { RTC_DCHECK(worker_thread_checker_.IsCurrent()); - if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { + if (audio_network_adaptor_config_from_options_ == + audio_network_adaptor_config) { return; } - config_.audio_network_adaptor_config = audio_network_adaptor_config; + audio_network_adaptor_config_from_options_ = audio_network_adaptor_config; + UpdateAudioNetworkAdaptorConfig(); UpdateAllowedBitrateRange(); ReconfigureAudioSendStream(); } @@ -937,6 +996,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream rtp_parameters_.encodings[0].max_bitrate_bps; double old_priority = rtp_parameters_.encodings[0].bitrate_priority; webrtc::Priority old_dscp = rtp_parameters_.encodings[0].network_priority; + bool old_adaptive_ptime = rtp_parameters_.encodings[0].adaptive_ptime; rtp_parameters_ = parameters; config_.bitrate_priority = rtp_parameters_.encodings[0].bitrate_priority; config_.has_dscp = (rtp_parameters_.encodings[0].network_priority != @@ -945,15 +1005,19 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream bool reconfigure_send_stream = (rtp_parameters_.encodings[0].max_bitrate_bps != old_rtp_max_bitrate) || (rtp_parameters_.encodings[0].bitrate_priority != old_priority) || - (rtp_parameters_.encodings[0].network_priority != old_dscp); + (rtp_parameters_.encodings[0].network_priority != old_dscp) || + (rtp_parameters_.encodings[0].adaptive_ptime != old_adaptive_ptime); if (rtp_parameters_.encodings[0].max_bitrate_bps != old_rtp_max_bitrate) { // Update the bitrate range. if (send_rate) { config_.send_codec_spec->target_bitrate_bps = send_rate; } - UpdateAllowedBitrateRange(); } if (reconfigure_send_stream) { + // Changing adaptive_ptime may update the audio network adaptor config + // used. + UpdateAudioNetworkAdaptorConfig(); + UpdateAllowedBitrateRange(); ReconfigureAudioSendStream(); } @@ -989,6 +1053,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream // The order of precedence, from lowest to highest is: // - a reasonable default of 32kbps min/max // - fixed target bitrate from codec spec + // - lower min bitrate if adaptive ptime is enabled // - bitrate configured in the rtp_parameter encodings settings const int kDefaultBitrateBps = 32000; config_.min_bitrate_bps = kDefaultBitrateBps; @@ -1000,6 +1065,12 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream config_.max_bitrate_bps = *config_.send_codec_spec->target_bitrate_bps; } + if (rtp_parameters_.encodings[0].adaptive_ptime) { + config_.min_bitrate_bps = std::min( + config_.min_bitrate_bps, + static_cast<int>(adaptive_ptime_config_.min_encoder_bitrate.bps())); + } + if (rtp_parameters_.encodings[0].min_bitrate_bps) { config_.min_bitrate_bps = *rtp_parameters_.encodings[0].min_bitrate_bps; } @@ -1033,12 +1104,24 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream UpdateAllowedBitrateRange(); } + void UpdateAudioNetworkAdaptorConfig() { + if (adaptive_ptime_config_.enabled || + rtp_parameters_.encodings[0].adaptive_ptime) { + config_.audio_network_adaptor_config = + adaptive_ptime_config_.audio_network_adaptor_config; + return; + } + config_.audio_network_adaptor_config = + audio_network_adaptor_config_from_options_; + } + void ReconfigureAudioSendStream() { RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_DCHECK(stream_); stream_->Reconfigure(config_); } + const AdaptivePtimeConfig adaptive_ptime_config_; rtc::ThreadChecker worker_thread_checker_; rtc::RaceChecker audio_capture_race_checker_; webrtc::Call* call_ = nullptr; @@ -1056,6 +1139,9 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream int max_send_bitrate_bps_; webrtc::RtpParameters rtp_parameters_; absl::optional<webrtc::AudioCodecSpec> audio_codec_spec_; + // TODO(webrtc:11717): Remove this once audio_network_adaptor in AudioOptions + // has been removed. + absl::optional<std::string> audio_network_adaptor_config_from_options_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); }; @@ -1541,7 +1627,9 @@ bool WebRtcVoiceMediaChannel::SetRecvCodecs( << old_codec.id << ")"; } auto format = AudioCodecToSdpAudioFormat(codec); - if (!IsCodec(codec, "cn") && !IsCodec(codec, "telephone-event") && + if (!IsCodec(codec, kCnCodecName) && !IsCodec(codec, kDtmfCodecName) && + (!IsAudioRedForOpusFieldTrialEnabled() || + !IsCodec(codec, kRedCodecName)) && !engine()->decoder_factory_->IsSupportedDecoder(format)) { RTC_LOG(LS_ERROR) << "Unsupported codec: " << rtc::ToString(format); return false; @@ -1692,6 +1780,19 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs( } } + if (IsAudioRedForOpusFieldTrialEnabled()) { + // Loop through the codecs to find the RED codec that matches opus + // with respect to clockrate and number of channels. + for (const AudioCodec& red_codec : codecs) { + if (IsCodec(red_codec, kRedCodecName) && + red_codec.clockrate == send_codec_spec->format.clockrate_hz && + red_codec.channels == send_codec_spec->format.num_channels) { + send_codec_spec->red_payload_type = red_codec.id; + break; + } + } + } + if (send_codec_spec_ != send_codec_spec) { send_codec_spec_ = std::move(send_codec_spec); // Apply new settings to all streams. |