| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" | 11 #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 | 14 |
| 15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
| 16 #include "webrtc/base/exp_filter.h" |
| 16 #include "webrtc/base/safe_conversions.h" | 17 #include "webrtc/base/safe_conversions.h" |
| 17 #include "webrtc/common_types.h" | 18 #include "webrtc/common_types.h" |
| 18 #include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adapto
r_impl.h" | 19 #include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adapto
r_impl.h" |
| 19 #include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h
" | 20 #include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h
" |
| 20 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" | 21 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" |
| 21 #include "webrtc/system_wrappers/include/clock.h" | 22 #include "webrtc/system_wrappers/include/clock.h" |
| 22 | 23 |
| 23 namespace webrtc { | 24 namespace webrtc { |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 const int kSampleRateHz = 48000; | 28 constexpr int kSampleRateHz = 48000; |
| 28 const int kMinBitrateBps = 500; | 29 constexpr int kMinBitrateBps = 500; |
| 29 const int kMaxBitrateBps = 512000; | 30 constexpr int kMaxBitrateBps = 512000; |
| 30 constexpr int kSupportedFrameLengths[] = {20, 60}; | 31 constexpr int kSupportedFrameLengths[] = {20, 60}; |
| 31 | 32 |
| 33 // PacketLossFractionSmoother uses an exponential filter with a time constant |
| 34 // of -1.0 / ln(0.9999) = 10000 ms. |
| 35 constexpr float kAlphaForPacketLossFractionSmoother = 0.9999f; |
| 36 |
| 32 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { | 37 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { |
| 33 AudioEncoderOpus::Config config; | 38 AudioEncoderOpus::Config config; |
| 34 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); | 39 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); |
| 35 config.num_channels = codec_inst.channels; | 40 config.num_channels = codec_inst.channels; |
| 36 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); | 41 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); |
| 37 config.payload_type = codec_inst.pltype; | 42 config.payload_type = codec_inst.pltype; |
| 38 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip | 43 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip |
| 39 : AudioEncoderOpus::kAudio; | 44 : AudioEncoderOpus::kAudio; |
| 40 return config; | 45 return config; |
| 41 } | 46 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 return kPacketLossRate5; | 80 return kPacketLossRate5; |
| 76 } else if (new_loss_rate >= kPacketLossRate1) { | 81 } else if (new_loss_rate >= kPacketLossRate1) { |
| 77 return kPacketLossRate1; | 82 return kPacketLossRate1; |
| 78 } else { | 83 } else { |
| 79 return 0.0; | 84 return 0.0; |
| 80 } | 85 } |
| 81 } | 86 } |
| 82 | 87 |
| 83 } // namespace | 88 } // namespace |
| 84 | 89 |
| 90 class AudioEncoderOpus::PacketLossFractionSmoother { |
| 91 public: |
| 92 explicit PacketLossFractionSmoother(const Clock* clock) |
| 93 : clock_(clock), |
| 94 last_sample_time_ms_(clock_->TimeInMilliseconds()), |
| 95 smoother_(kAlphaForPacketLossFractionSmoother) {} |
| 96 |
| 97 // Gets the smoothed packet loss fraction. |
| 98 float GetAverage() const { |
| 99 float value = smoother_.filtered(); |
| 100 return (value == rtc::ExpFilter::kValueUndefined) ? 0.0f : value; |
| 101 } |
| 102 |
| 103 // Add new observation to the packet loss fraction smoother. |
| 104 void AddSample(float packet_loss_fraction) { |
| 105 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 106 smoother_.Apply(static_cast<float>(now_ms - last_sample_time_ms_), |
| 107 packet_loss_fraction); |
| 108 last_sample_time_ms_ = now_ms; |
| 109 } |
| 110 |
| 111 private: |
| 112 const Clock* const clock_; |
| 113 int64_t last_sample_time_ms_; |
| 114 |
| 115 // An exponential filter is used to smooth the packet loss fraction. |
| 116 rtc::ExpFilter smoother_; |
| 117 }; |
| 118 |
| 85 AudioEncoderOpus::Config::Config() = default; | 119 AudioEncoderOpus::Config::Config() = default; |
| 86 AudioEncoderOpus::Config::Config(const Config&) = default; | 120 AudioEncoderOpus::Config::Config(const Config&) = default; |
| 87 AudioEncoderOpus::Config::~Config() = default; | 121 AudioEncoderOpus::Config::~Config() = default; |
| 88 auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default; | 122 auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default; |
| 89 | 123 |
| 90 bool AudioEncoderOpus::Config::IsOk() const { | 124 bool AudioEncoderOpus::Config::IsOk() const { |
| 91 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) | 125 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) |
| 92 return false; | 126 return false; |
| 93 if (num_channels != 1 && num_channels != 2) | 127 if (num_channels != 1 && num_channels != 2) |
| 94 return false; | 128 return false; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 106 return *bitrate_bps; // Explicitly set value. | 140 return *bitrate_bps; // Explicitly set value. |
| 107 else | 141 else |
| 108 return num_channels == 1 ? 32000 : 64000; // Default value. | 142 return num_channels == 1 ? 32000 : 64000; // Default value. |
| 109 } | 143 } |
| 110 | 144 |
| 111 AudioEncoderOpus::AudioEncoderOpus( | 145 AudioEncoderOpus::AudioEncoderOpus( |
| 112 const Config& config, | 146 const Config& config, |
| 113 AudioNetworkAdaptorCreator&& audio_network_adaptor_creator) | 147 AudioNetworkAdaptorCreator&& audio_network_adaptor_creator) |
| 114 : packet_loss_rate_(0.0), | 148 : packet_loss_rate_(0.0), |
| 115 inst_(nullptr), | 149 inst_(nullptr), |
| 150 packet_loss_fraction_smoother_(new PacketLossFractionSmoother( |
| 151 config.clock ? config.clock : Clock::GetRealTimeClock())), |
| 116 audio_network_adaptor_creator_( | 152 audio_network_adaptor_creator_( |
| 117 audio_network_adaptor_creator | 153 audio_network_adaptor_creator |
| 118 ? audio_network_adaptor_creator | 154 ? std::move(audio_network_adaptor_creator) |
| 119 : [this](const std::string& config_string, const Clock* clock) { | 155 : [this](const std::string& config_string, const Clock* clock) { |
| 120 return DefaultAudioNetworkAdaptorCreator(config_string, | 156 return DefaultAudioNetworkAdaptorCreator(config_string, |
| 121 clock); | 157 clock); |
| 122 }) { | 158 }) { |
| 123 RTC_CHECK(RecreateEncoderInstance(config)); | 159 RTC_CHECK(RecreateEncoderInstance(config)); |
| 124 } | 160 } |
| 125 | 161 |
| 126 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) | 162 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) |
| 127 : AudioEncoderOpus(CreateConfig(codec_inst), nullptr) {} | 163 : AudioEncoderOpus(CreateConfig(codec_inst), nullptr) {} |
| 128 | 164 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 | 263 |
| 228 void AudioEncoderOpus::OnReceivedUplinkBandwidth(int uplink_bandwidth_bps) { | 264 void AudioEncoderOpus::OnReceivedUplinkBandwidth(int uplink_bandwidth_bps) { |
| 229 if (!audio_network_adaptor_) | 265 if (!audio_network_adaptor_) |
| 230 return; | 266 return; |
| 231 audio_network_adaptor_->SetUplinkBandwidth(uplink_bandwidth_bps); | 267 audio_network_adaptor_->SetUplinkBandwidth(uplink_bandwidth_bps); |
| 232 ApplyAudioNetworkAdaptor(); | 268 ApplyAudioNetworkAdaptor(); |
| 233 } | 269 } |
| 234 | 270 |
| 235 void AudioEncoderOpus::OnReceivedUplinkPacketLossFraction( | 271 void AudioEncoderOpus::OnReceivedUplinkPacketLossFraction( |
| 236 float uplink_packet_loss_fraction) { | 272 float uplink_packet_loss_fraction) { |
| 237 if (!audio_network_adaptor_) | 273 if (!audio_network_adaptor_) { |
| 238 return; | 274 packet_loss_fraction_smoother_->AddSample(uplink_packet_loss_fraction); |
| 275 float average_fraction_loss = packet_loss_fraction_smoother_->GetAverage(); |
| 276 return SetProjectedPacketLossRate(average_fraction_loss); |
| 277 } |
| 239 audio_network_adaptor_->SetUplinkPacketLossFraction( | 278 audio_network_adaptor_->SetUplinkPacketLossFraction( |
| 240 uplink_packet_loss_fraction); | 279 uplink_packet_loss_fraction); |
| 241 ApplyAudioNetworkAdaptor(); | 280 ApplyAudioNetworkAdaptor(); |
| 242 } | 281 } |
| 243 | 282 |
| 244 void AudioEncoderOpus::OnReceivedTargetAudioBitrate( | 283 void AudioEncoderOpus::OnReceivedTargetAudioBitrate( |
| 245 int target_audio_bitrate_bps) { | 284 int target_audio_bitrate_bps) { |
| 246 if (!audio_network_adaptor_) | 285 if (!audio_network_adaptor_) |
| 247 return; | 286 return SetTargetBitrate(target_audio_bitrate_bps); |
| 248 audio_network_adaptor_->SetTargetAudioBitrate(target_audio_bitrate_bps); | 287 audio_network_adaptor_->SetTargetAudioBitrate(target_audio_bitrate_bps); |
| 249 ApplyAudioNetworkAdaptor(); | 288 ApplyAudioNetworkAdaptor(); |
| 250 } | 289 } |
| 251 | 290 |
| 252 void AudioEncoderOpus::OnReceivedRtt(int rtt_ms) { | 291 void AudioEncoderOpus::OnReceivedRtt(int rtt_ms) { |
| 253 if (!audio_network_adaptor_) | 292 if (!audio_network_adaptor_) |
| 254 return; | 293 return; |
| 255 audio_network_adaptor_->SetRtt(rtt_ms); | 294 audio_network_adaptor_->SetRtt(rtt_ms); |
| 256 ApplyAudioNetworkAdaptor(); | 295 ApplyAudioNetworkAdaptor(); |
| 257 } | 296 } |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 AudioNetworkAdaptorImpl::Config config; | 446 AudioNetworkAdaptorImpl::Config config; |
| 408 config.clock = clock; | 447 config.clock = clock; |
| 409 return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl( | 448 return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl( |
| 410 config, ControllerManagerImpl::Create( | 449 config, ControllerManagerImpl::Create( |
| 411 config_string, NumChannels(), kSupportedFrameLengths, | 450 config_string, NumChannels(), kSupportedFrameLengths, |
| 412 num_channels_to_encode_, next_frame_length_ms_, | 451 num_channels_to_encode_, next_frame_length_ms_, |
| 413 GetTargetBitrate(), config_.fec_enabled, GetDtx(), clock))); | 452 GetTargetBitrate(), config_.fec_enabled, GetDtx(), clock))); |
| 414 } | 453 } |
| 415 | 454 |
| 416 } // namespace webrtc | 455 } // namespace webrtc |
| OLD | NEW |