Chromium Code Reviews| Index: webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc |
| diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc |
| index be32aef152e80e05feed810d415f5718ca04a869..a4ae2ca6d5983e6ae939cbe9113e2c609578dde9 100644 |
| --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc |
| +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc |
| @@ -48,11 +48,6 @@ constexpr int kOpusBitrateNbBps = 12000; |
| constexpr int kOpusBitrateWbBps = 20000; |
| constexpr int kOpusBitrateFbBps = 32000; |
| -// Opus API allows a min bitrate of 500bps, but Opus documentation suggests |
| -// bitrate should be in the range of 6000 to 510000, inclusive. |
| -constexpr int kOpusMinBitrateBps = 6000; |
| -constexpr int kOpusMaxBitrateBps = 510000; |
| - |
| constexpr int kSampleRateHz = 48000; |
| constexpr int kDefaultMaxPlaybackRate = 48000; |
| @@ -133,8 +128,8 @@ int CalculateDefaultBitrate(int max_playback_rate, size_t num_channels) { |
| return kOpusBitrateFbBps * rtc::dchecked_cast<int>(num_channels); |
| } |
| }(); |
| - RTC_DCHECK_GE(bitrate, kOpusMinBitrateBps); |
| - RTC_DCHECK_LE(bitrate, kOpusMaxBitrateBps); |
| + RTC_DCHECK_GE(bitrate, AudioEncoderOpusConfig::kMinBitrateBps); |
| + RTC_DCHECK_LE(bitrate, AudioEncoderOpusConfig::kMaxBitrateBps); |
| return bitrate; |
| } |
| @@ -150,7 +145,8 @@ int CalculateBitrate(int max_playback_rate_hz, |
| const auto bitrate = rtc::StringToNumber<int>(*bitrate_param); |
| if (bitrate) { |
| const int chosen_bitrate = |
| - std::max(kOpusMinBitrateBps, std::min(*bitrate, kOpusMaxBitrateBps)); |
| + std::max(AudioEncoderOpusConfig::kMinBitrateBps, |
| + std::min(*bitrate, AudioEncoderOpusConfig::kMaxBitrateBps)); |
| if (bitrate != chosen_bitrate) { |
| LOG(LS_WARNING) << "Invalid maxaveragebitrate " << *bitrate |
| << " clamped to " << chosen_bitrate; |
| @@ -195,7 +191,7 @@ int GetFrameSizeMs(const SdpAudioFormat& format) { |
| return *(std::end(kOpusSupportedFrameLengths) - 1); |
| } |
| - return AudioEncoderOpus::Config::kDefaultFrameSizeMs; |
| + return AudioEncoderOpusConfig::kDefaultFrameSizeMs; |
| } |
| void FindSupportedFrameLengths(int min_frame_length_ms, |
| @@ -211,9 +207,14 @@ void FindSupportedFrameLengths(int min_frame_length_ms, |
| RTC_DCHECK(std::is_sorted(out->begin(), out->end())); |
| } |
| +int GetBitrateBps(const AudioEncoderOpusConfig& config) { |
| + RTC_DCHECK(config.IsOk()); |
| + return config.bitrate_bps; |
| +} |
| + |
| } // namespace |
| -rtc::Optional<AudioCodecInfo> AudioEncoderOpus::QueryAudioEncoder( |
| +rtc::Optional<AudioCodecInfo> AudioEncoderOpusImpl::QueryAudioEncoder( |
| const SdpAudioFormat& format) { |
| if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0 && |
| format.clockrate_hz == 48000 && format.num_channels == 2) { |
| @@ -221,8 +222,9 @@ rtc::Optional<AudioCodecInfo> AudioEncoderOpus::QueryAudioEncoder( |
| const int bitrate = |
| CalculateBitrate(GetMaxPlaybackRate(format), num_channels, |
| GetFormatParameter(format, "maxaveragebitrate")); |
| - AudioCodecInfo info(48000, num_channels, bitrate, kOpusMinBitrateBps, |
| - kOpusMaxBitrateBps); |
| + AudioCodecInfo info(48000, num_channels, bitrate, |
| + AudioEncoderOpusConfig::kMinBitrateBps, |
| + AudioEncoderOpusConfig::kMaxBitrateBps); |
| info.allow_comfort_noise = false; |
| info.supports_network_adaption = true; |
| @@ -231,46 +233,44 @@ rtc::Optional<AudioCodecInfo> AudioEncoderOpus::QueryAudioEncoder( |
| return rtc::Optional<AudioCodecInfo>(); |
| } |
| -AudioEncoderOpus::Config AudioEncoderOpus::CreateConfig( |
| +AudioEncoderOpusConfig AudioEncoderOpusImpl::CreateConfig( |
| const CodecInst& codec_inst) { |
| - AudioEncoderOpus::Config config; |
| + AudioEncoderOpusConfig config; |
| config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); |
| config.num_channels = codec_inst.channels; |
| - config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); |
| - config.payload_type = codec_inst.pltype; |
| - config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip |
| - : AudioEncoderOpus::kAudio; |
| + config.bitrate_bps = codec_inst.rate; |
| + config.application = config.num_channels == 1 |
| + ? AudioEncoderOpusConfig::ApplicationMode::kVoip |
| + : AudioEncoderOpusConfig::ApplicationMode::kAudio; |
| config.supported_frame_lengths_ms.push_back(config.frame_size_ms); |
| -#if WEBRTC_OPUS_VARIABLE_COMPLEXITY |
| - config.low_rate_complexity = 9; |
| -#endif |
| return config; |
| } |
| -AudioEncoderOpus::Config AudioEncoderOpus::CreateConfig( |
| - int payload_type, |
| +rtc::Optional<AudioEncoderOpusConfig> AudioEncoderOpusImpl::SdpToConfig( |
| const SdpAudioFormat& format) { |
| - AudioEncoderOpus::Config config; |
| + if (STR_CASE_CMP(format.name.c_str(), "opus") != 0 || |
| + format.clockrate_hz != 48000 || format.num_channels != 2) { |
| + return rtc::Optional<AudioEncoderOpusConfig>(); |
| + } |
| + AudioEncoderOpusConfig config; |
| config.num_channels = GetChannelCount(format); |
| config.frame_size_ms = GetFrameSizeMs(format); |
| config.max_playback_rate_hz = GetMaxPlaybackRate(format); |
| config.fec_enabled = (GetFormatParameter(format, "useinbandfec") == "1"); |
| config.dtx_enabled = (GetFormatParameter(format, "usedtx") == "1"); |
| config.cbr_enabled = (GetFormatParameter(format, "cbr") == "1"); |
| - config.bitrate_bps = rtc::Optional<int>( |
| + config.bitrate_bps = |
| CalculateBitrate(config.max_playback_rate_hz, config.num_channels, |
| - GetFormatParameter(format, "maxaveragebitrate"))); |
| - config.payload_type = payload_type; |
| - config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip |
| - : AudioEncoderOpus::kAudio; |
| -#if WEBRTC_OPUS_VARIABLE_COMPLEXITY |
| - config.low_rate_complexity = 9; |
| -#endif |
| + GetFormatParameter(format, "maxaveragebitrate")); |
| + config.application = config.num_channels == 1 |
| + ? AudioEncoderOpusConfig::ApplicationMode::kVoip |
| + : AudioEncoderOpusConfig::ApplicationMode::kAudio; |
| constexpr int kMinANAFrameLength = kANASupportedFrameLengths[0]; |
| constexpr int kMaxANAFrameLength = |
| kANASupportedFrameLengths[arraysize(kANASupportedFrameLengths) - 1]; |
| + |
| // For now, minptime and maxptime are only used with ANA. If ptime is outside |
| // of this range, it will get adjusted once ANA takes hold. Ideally, we'd know |
| // if ANA was to be used when setting up the config, and adjust accordingly. |
| @@ -281,10 +281,28 @@ AudioEncoderOpus::Config AudioEncoderOpus::CreateConfig( |
| FindSupportedFrameLengths(min_frame_length_ms, max_frame_length_ms, |
| &config.supported_frame_lengths_ms); |
| - return config; |
| + RTC_DCHECK(config.IsOk()); |
| + return rtc::Optional<AudioEncoderOpusConfig>(config); |
| +} |
| + |
| +rtc::Optional<int> AudioEncoderOpusImpl::GetNewComplexity( |
| + const AudioEncoderOpusConfig& config) { |
| + RTC_DCHECK(config.IsOk()); |
| + const int bitrate_bps = GetBitrateBps(config); |
| + if (bitrate_bps >= config.complexity_threshold_bps - |
| + config.complexity_threshold_window_bps && |
| + bitrate_bps <= config.complexity_threshold_bps + |
| + config.complexity_threshold_window_bps) { |
| + // Within the hysteresis window; make no change. |
| + return rtc::Optional<int>(); |
| + } else { |
| + return rtc::Optional<int>(bitrate_bps <= config.complexity_threshold_bps |
| + ? config.low_rate_complexity |
| + : config.complexity); |
| + } |
| } |
| -class AudioEncoderOpus::PacketLossFractionSmoother { |
| +class AudioEncoderOpusImpl::PacketLossFractionSmoother { |
| public: |
| explicit PacketLossFractionSmoother() |
| : last_sample_time_ms_(rtc::TimeMillis()), |
| @@ -311,58 +329,13 @@ class AudioEncoderOpus::PacketLossFractionSmoother { |
| rtc::ExpFilter smoother_; |
| }; |
| -AudioEncoderOpus::Config::Config() { |
| -#if WEBRTC_OPUS_VARIABLE_COMPLEXITY |
| - low_rate_complexity = 9; |
| -#endif |
| -} |
| -AudioEncoderOpus::Config::Config(const Config&) = default; |
| -AudioEncoderOpus::Config::~Config() = default; |
| -auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default; |
| - |
| -bool AudioEncoderOpus::Config::IsOk() const { |
| - if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) |
| - return false; |
| - if (num_channels != 1 && num_channels != 2) |
| - return false; |
| - if (bitrate_bps && |
| - (*bitrate_bps < kOpusMinBitrateBps || *bitrate_bps > kOpusMaxBitrateBps)) |
| - return false; |
| - if (complexity < 0 || complexity > 10) |
| - return false; |
| - if (low_rate_complexity < 0 || low_rate_complexity > 10) |
| - return false; |
| - return true; |
| -} |
| - |
| -int AudioEncoderOpus::Config::GetBitrateBps() const { |
| - RTC_DCHECK(IsOk()); |
| - if (bitrate_bps) |
| - return *bitrate_bps; // Explicitly set value. |
| - else |
| - return num_channels == 1 ? 32000 : 64000; // Default value. |
| -} |
| - |
| -rtc::Optional<int> AudioEncoderOpus::Config::GetNewComplexity() const { |
| - RTC_DCHECK(IsOk()); |
| - const int bitrate_bps = GetBitrateBps(); |
| - if (bitrate_bps >= |
| - complexity_threshold_bps - complexity_threshold_window_bps && |
| - bitrate_bps <= |
| - complexity_threshold_bps + complexity_threshold_window_bps) { |
| - // Within the hysteresis window; make no change. |
| - return rtc::Optional<int>(); |
| - } |
| - return bitrate_bps <= complexity_threshold_bps |
| - ? rtc::Optional<int>(low_rate_complexity) |
| - : rtc::Optional<int>(complexity); |
| -} |
| - |
| -AudioEncoderOpus::AudioEncoderOpus( |
| - const Config& config, |
| +AudioEncoderOpusImpl::AudioEncoderOpusImpl( |
| + const AudioEncoderOpusConfig& config, |
| + int payload_type, |
| AudioNetworkAdaptorCreator&& audio_network_adaptor_creator, |
| std::unique_ptr<SmoothingFilter> bitrate_smoother) |
| - : send_side_bwe_with_overhead_(webrtc::field_trial::IsEnabled( |
| + : payload_type_(payload_type), |
| + send_side_bwe_with_overhead_(webrtc::field_trial::IsEnabled( |
| "WebRTC-SendSideBwe-WithOverhead")), |
| packet_loss_rate_(0.0), |
| inst_(nullptr), |
| @@ -382,42 +355,42 @@ AudioEncoderOpus::AudioEncoderOpus( |
| RTC_CHECK(RecreateEncoderInstance(config)); |
| } |
| -AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) |
| - : AudioEncoderOpus(CreateConfig(codec_inst), nullptr) {} |
| +AudioEncoderOpusImpl::AudioEncoderOpusImpl(const CodecInst& codec_inst) |
| + : AudioEncoderOpusImpl(CreateConfig(codec_inst), codec_inst.pltype) {} |
| -AudioEncoderOpus::AudioEncoderOpus(int payload_type, |
| - const SdpAudioFormat& format) |
| - : AudioEncoderOpus(CreateConfig(payload_type, format), nullptr) {} |
| +AudioEncoderOpusImpl::AudioEncoderOpusImpl(int payload_type, |
| + const SdpAudioFormat& format) |
| + : AudioEncoderOpusImpl(*SdpToConfig(format), payload_type) {} |
| -AudioEncoderOpus::~AudioEncoderOpus() { |
| +AudioEncoderOpusImpl::~AudioEncoderOpusImpl() { |
| RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); |
| } |
| -int AudioEncoderOpus::SampleRateHz() const { |
| +int AudioEncoderOpusImpl::SampleRateHz() const { |
| return kSampleRateHz; |
| } |
| -size_t AudioEncoderOpus::NumChannels() const { |
| +size_t AudioEncoderOpusImpl::NumChannels() const { |
| return config_.num_channels; |
| } |
| -size_t AudioEncoderOpus::Num10MsFramesInNextPacket() const { |
| +size_t AudioEncoderOpusImpl::Num10MsFramesInNextPacket() const { |
| return Num10msFramesPerPacket(); |
| } |
| -size_t AudioEncoderOpus::Max10MsFramesInAPacket() const { |
| +size_t AudioEncoderOpusImpl::Max10MsFramesInAPacket() const { |
| return Num10msFramesPerPacket(); |
| } |
| -int AudioEncoderOpus::GetTargetBitrate() const { |
| - return config_.GetBitrateBps(); |
| +int AudioEncoderOpusImpl::GetTargetBitrate() const { |
| + return GetBitrateBps(config_); |
| } |
| -void AudioEncoderOpus::Reset() { |
| +void AudioEncoderOpusImpl::Reset() { |
| RTC_CHECK(RecreateEncoderInstance(config_)); |
| } |
| -bool AudioEncoderOpus::SetFec(bool enable) { |
| +bool AudioEncoderOpusImpl::SetFec(bool enable) { |
| if (enable) { |
| RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); |
| } else { |
| @@ -427,7 +400,7 @@ bool AudioEncoderOpus::SetFec(bool enable) { |
| return true; |
| } |
| -bool AudioEncoderOpus::SetDtx(bool enable) { |
| +bool AudioEncoderOpusImpl::SetDtx(bool enable) { |
| if (enable) { |
| RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); |
| } else { |
| @@ -437,30 +410,30 @@ bool AudioEncoderOpus::SetDtx(bool enable) { |
| return true; |
| } |
| -bool AudioEncoderOpus::GetDtx() const { |
| +bool AudioEncoderOpusImpl::GetDtx() const { |
| return config_.dtx_enabled; |
| } |
| -bool AudioEncoderOpus::SetApplication(Application application) { |
| +bool AudioEncoderOpusImpl::SetApplication(Application application) { |
| auto conf = config_; |
| switch (application) { |
| case Application::kSpeech: |
| - conf.application = AudioEncoderOpus::kVoip; |
| + conf.application = AudioEncoderOpusConfig::ApplicationMode::kVoip; |
| break; |
| case Application::kAudio: |
| - conf.application = AudioEncoderOpus::kAudio; |
| + conf.application = AudioEncoderOpusConfig::ApplicationMode::kAudio; |
| break; |
| } |
| return RecreateEncoderInstance(conf); |
| } |
| -void AudioEncoderOpus::SetMaxPlaybackRate(int frequency_hz) { |
| +void AudioEncoderOpusImpl::SetMaxPlaybackRate(int frequency_hz) { |
| auto conf = config_; |
| conf.max_playback_rate_hz = frequency_hz; |
| RTC_CHECK(RecreateEncoderInstance(conf)); |
| } |
| -bool AudioEncoderOpus::EnableAudioNetworkAdaptor( |
| +bool AudioEncoderOpusImpl::EnableAudioNetworkAdaptor( |
| const std::string& config_string, |
| RtcEventLog* event_log) { |
| audio_network_adaptor_ = |
| @@ -468,11 +441,11 @@ bool AudioEncoderOpus::EnableAudioNetworkAdaptor( |
| return audio_network_adaptor_.get() != nullptr; |
| } |
| -void AudioEncoderOpus::DisableAudioNetworkAdaptor() { |
| +void AudioEncoderOpusImpl::DisableAudioNetworkAdaptor() { |
| audio_network_adaptor_.reset(nullptr); |
| } |
| -void AudioEncoderOpus::OnReceivedUplinkPacketLossFraction( |
| +void AudioEncoderOpusImpl::OnReceivedUplinkPacketLossFraction( |
| float uplink_packet_loss_fraction) { |
| if (!audio_network_adaptor_) { |
| packet_loss_fraction_smoother_->AddSample(uplink_packet_loss_fraction); |
| @@ -484,7 +457,7 @@ void AudioEncoderOpus::OnReceivedUplinkPacketLossFraction( |
| ApplyAudioNetworkAdaptor(); |
| } |
| -void AudioEncoderOpus::OnReceivedUplinkRecoverablePacketLossFraction( |
| +void AudioEncoderOpusImpl::OnReceivedUplinkRecoverablePacketLossFraction( |
| float uplink_recoverable_packet_loss_fraction) { |
| if (!audio_network_adaptor_) |
| return; |
| @@ -493,7 +466,7 @@ void AudioEncoderOpus::OnReceivedUplinkRecoverablePacketLossFraction( |
| ApplyAudioNetworkAdaptor(); |
| } |
| -void AudioEncoderOpus::OnReceivedUplinkBandwidth( |
| +void AudioEncoderOpusImpl::OnReceivedUplinkBandwidth( |
| int target_audio_bitrate_bps, |
| rtc::Optional<int64_t> probing_interval_ms) { |
| if (audio_network_adaptor_) { |
| @@ -517,28 +490,30 @@ void AudioEncoderOpus::OnReceivedUplinkBandwidth( |
| } else if (send_side_bwe_with_overhead_) { |
| if (!overhead_bytes_per_packet_) { |
| LOG(LS_INFO) |
| - << "AudioEncoderOpus: Overhead unknown, target audio bitrate " |
| + << "AudioEncoderOpusImpl: Overhead unknown, target audio bitrate " |
| << target_audio_bitrate_bps << " bps is ignored."; |
| return; |
| } |
| const int overhead_bps = static_cast<int>( |
| *overhead_bytes_per_packet_ * 8 * 100 / Num10MsFramesInNextPacket()); |
| - SetTargetBitrate(std::min( |
| - kOpusMaxBitrateBps, |
| - std::max(kOpusMinBitrateBps, target_audio_bitrate_bps - overhead_bps))); |
| + SetTargetBitrate( |
| + std::min(AudioEncoderOpusConfig::kMaxBitrateBps, |
|
ossu
2017/06/16 09:53:53
A candidate for SafeClamp here. Perhaps not in thi
kwiberg-webrtc
2017/06/16 12:44:14
Yes, this part of the CL is just search+replace fo
|
| + std::max(AudioEncoderOpusConfig::kMinBitrateBps, |
| + target_audio_bitrate_bps - overhead_bps))); |
| } else { |
| SetTargetBitrate(target_audio_bitrate_bps); |
| } |
| } |
| -void AudioEncoderOpus::OnReceivedRtt(int rtt_ms) { |
| +void AudioEncoderOpusImpl::OnReceivedRtt(int rtt_ms) { |
| if (!audio_network_adaptor_) |
| return; |
| audio_network_adaptor_->SetRtt(rtt_ms); |
| ApplyAudioNetworkAdaptor(); |
| } |
| -void AudioEncoderOpus::OnReceivedOverhead(size_t overhead_bytes_per_packet) { |
| +void AudioEncoderOpusImpl::OnReceivedOverhead( |
| + size_t overhead_bytes_per_packet) { |
| if (audio_network_adaptor_) { |
| audio_network_adaptor_->SetOverhead(overhead_bytes_per_packet); |
| ApplyAudioNetworkAdaptor(); |
| @@ -548,8 +523,9 @@ void AudioEncoderOpus::OnReceivedOverhead(size_t overhead_bytes_per_packet) { |
| } |
| } |
| -void AudioEncoderOpus::SetReceiverFrameLengthRange(int min_frame_length_ms, |
| - int max_frame_length_ms) { |
| +void AudioEncoderOpusImpl::SetReceiverFrameLengthRange( |
| + int min_frame_length_ms, |
| + int max_frame_length_ms) { |
| // Ensure that |SetReceiverFrameLengthRange| is called before |
| // |EnableAudioNetworkAdaptor|, otherwise we need to recreate |
| // |audio_network_adaptor_|, which is not a needed use case. |
| @@ -558,7 +534,7 @@ void AudioEncoderOpus::SetReceiverFrameLengthRange(int min_frame_length_ms, |
| &config_.supported_frame_lengths_ms); |
| } |
| -AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( |
| +AudioEncoder::EncodedInfo AudioEncoderOpusImpl::EncodeImpl( |
| uint32_t rtp_timestamp, |
| rtc::ArrayView<const int16_t> audio, |
| rtc::Buffer* encoded) { |
| @@ -597,26 +573,26 @@ AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( |
| config_.frame_size_ms = next_frame_length_ms_; |
| info.encoded_timestamp = first_timestamp_in_buffer_; |
| - info.payload_type = config_.payload_type; |
| + info.payload_type = payload_type_; |
| info.send_even_if_empty = true; // Allows Opus to send empty packets. |
| info.speech = (info.encoded_bytes > 0); |
| info.encoder_type = CodecType::kOpus; |
| return info; |
| } |
| -size_t AudioEncoderOpus::Num10msFramesPerPacket() const { |
| +size_t AudioEncoderOpusImpl::Num10msFramesPerPacket() const { |
| return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10)); |
| } |
| -size_t AudioEncoderOpus::SamplesPer10msFrame() const { |
| +size_t AudioEncoderOpusImpl::SamplesPer10msFrame() const { |
| return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels; |
| } |
| -size_t AudioEncoderOpus::SufficientOutputBufferSize() const { |
| +size_t AudioEncoderOpusImpl::SufficientOutputBufferSize() const { |
| // Calculate the number of bytes we expect the encoder to produce, |
| // then multiply by two to give a wide margin for error. |
| const size_t bytes_per_millisecond = |
| - static_cast<size_t>(config_.GetBitrateBps() / (1000 * 8) + 1); |
| + static_cast<size_t>(GetBitrateBps(config_) / (1000 * 8) + 1); |
| const size_t approx_encoded_bytes = |
| Num10msFramesPerPacket() * 10 * bytes_per_millisecond; |
| return 2 * approx_encoded_bytes; |
| @@ -625,7 +601,8 @@ size_t AudioEncoderOpus::SufficientOutputBufferSize() const { |
| // If the given config is OK, recreate the Opus encoder instance with those |
| // settings, save the config, and return true. Otherwise, do nothing and return |
| // false. |
| -bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) { |
| +bool AudioEncoderOpusImpl::RecreateEncoderInstance( |
| + const AudioEncoderOpusConfig& config) { |
| if (!config.IsOk()) |
| return false; |
| config_ = config; |
| @@ -633,9 +610,13 @@ bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) { |
| RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); |
| input_buffer_.clear(); |
| input_buffer_.reserve(Num10msFramesPerPacket() * SamplesPer10msFrame()); |
| - RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, config.num_channels, |
| - config.application)); |
| - RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.GetBitrateBps())); |
| + RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate( |
| + &inst_, config.num_channels, |
| + config.application == |
| + AudioEncoderOpusConfig::ApplicationMode::kVoip |
| + ? 0 |
| + : 1)); |
| + RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, GetBitrateBps(config))); |
| if (config.fec_enabled) { |
| RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); |
| } else { |
| @@ -645,7 +626,7 @@ bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) { |
| 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz)); |
| // Use the default complexity if the start bitrate is within the hysteresis |
| // window. |
| - complexity_ = config.GetNewComplexity().value_or(config.complexity); |
| + complexity_ = GetNewComplexity(config).value_or(config.complexity); |
| RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); |
| if (config.dtx_enabled) { |
| RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); |
| @@ -665,11 +646,12 @@ bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) { |
| return true; |
| } |
| -void AudioEncoderOpus::SetFrameLength(int frame_length_ms) { |
| +void AudioEncoderOpusImpl::SetFrameLength(int frame_length_ms) { |
| next_frame_length_ms_ = frame_length_ms; |
| } |
| -void AudioEncoderOpus::SetNumChannelsToEncode(size_t num_channels_to_encode) { |
| +void AudioEncoderOpusImpl::SetNumChannelsToEncode( |
| + size_t num_channels_to_encode) { |
| RTC_DCHECK_GT(num_channels_to_encode, 0); |
| RTC_DCHECK_LE(num_channels_to_encode, config_.num_channels); |
| @@ -680,7 +662,7 @@ void AudioEncoderOpus::SetNumChannelsToEncode(size_t num_channels_to_encode) { |
| num_channels_to_encode_ = num_channels_to_encode; |
| } |
| -void AudioEncoderOpus::SetProjectedPacketLossRate(float fraction) { |
| +void AudioEncoderOpusImpl::SetProjectedPacketLossRate(float fraction) { |
| float opt_loss_rate = OptimizePacketLossRate(fraction, packet_loss_rate_); |
| if (packet_loss_rate_ != opt_loss_rate) { |
| packet_loss_rate_ = opt_loss_rate; |
| @@ -690,19 +672,20 @@ void AudioEncoderOpus::SetProjectedPacketLossRate(float fraction) { |
| } |
| } |
| -void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { |
| - config_.bitrate_bps = rtc::Optional<int>(rtc::SafeClamp<int>( |
| - bits_per_second, kOpusMinBitrateBps, kOpusMaxBitrateBps)); |
| +void AudioEncoderOpusImpl::SetTargetBitrate(int bits_per_second) { |
| + config_.bitrate_bps = rtc::SafeClamp<int>( |
| + bits_per_second, AudioEncoderOpusConfig::kMinBitrateBps, |
| + AudioEncoderOpusConfig::kMaxBitrateBps); |
| RTC_DCHECK(config_.IsOk()); |
| - RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps())); |
| - const auto new_complexity = config_.GetNewComplexity(); |
| + RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, GetBitrateBps(config_))); |
| + const auto new_complexity = GetNewComplexity(config_); |
| if (new_complexity && complexity_ != *new_complexity) { |
| complexity_ = *new_complexity; |
| RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); |
| } |
| } |
| -void AudioEncoderOpus::ApplyAudioNetworkAdaptor() { |
| +void AudioEncoderOpusImpl::ApplyAudioNetworkAdaptor() { |
| auto config = audio_network_adaptor_->GetEncoderRuntimeConfig(); |
| RTC_DCHECK(!config.frame_length_ms || *config.frame_length_ms == 20 || |
| *config.frame_length_ms == 60); |
| @@ -722,20 +705,20 @@ void AudioEncoderOpus::ApplyAudioNetworkAdaptor() { |
| } |
| std::unique_ptr<AudioNetworkAdaptor> |
| -AudioEncoderOpus::DefaultAudioNetworkAdaptorCreator( |
| +AudioEncoderOpusImpl::DefaultAudioNetworkAdaptorCreator( |
| const ProtoString& config_string, |
| RtcEventLog* event_log) const { |
| AudioNetworkAdaptorImpl::Config config; |
| config.event_log = event_log; |
| return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl( |
| - config, |
| - ControllerManagerImpl::Create( |
| - config_string, NumChannels(), supported_frame_lengths_ms(), |
| - kOpusMinBitrateBps, num_channels_to_encode_, next_frame_length_ms_, |
| - GetTargetBitrate(), config_.fec_enabled, GetDtx()))); |
| + config, ControllerManagerImpl::Create( |
| + config_string, NumChannels(), supported_frame_lengths_ms(), |
| + AudioEncoderOpusConfig::kMinBitrateBps, |
| + num_channels_to_encode_, next_frame_length_ms_, |
| + GetTargetBitrate(), config_.fec_enabled, GetDtx()))); |
| } |
| -void AudioEncoderOpus::MaybeUpdateUplinkBandwidth() { |
| +void AudioEncoderOpusImpl::MaybeUpdateUplinkBandwidth() { |
| if (audio_network_adaptor_) { |
| int64_t now_ms = rtc::TimeMillis(); |
| if (!bitrate_smoother_last_update_time_ || |