| 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/safe_conversions.h" | 16 #include "webrtc/base/safe_conversions.h" | 
| 17 #include "webrtc/common_types.h" | 17 #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/controller_manager.h
     " | 
| 18 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" | 20 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" | 
|  | 21 #include "webrtc/system_wrappers/include/clock.h" | 
| 19 | 22 | 
| 20 namespace webrtc { | 23 namespace webrtc { | 
| 21 | 24 | 
| 22 namespace { | 25 namespace { | 
| 23 | 26 | 
| 24 const int kSampleRateHz = 48000; | 27 const int kSampleRateHz = 48000; | 
| 25 const int kMinBitrateBps = 500; | 28 const int kMinBitrateBps = 500; | 
| 26 const int kMaxBitrateBps = 512000; | 29 const int kMaxBitrateBps = 512000; | 
|  | 30 constexpr int kSupportedFrameLengths[] = {20, 60}; | 
| 27 | 31 | 
| 28 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { | 32 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { | 
| 29   AudioEncoderOpus::Config config; | 33   AudioEncoderOpus::Config config; | 
| 30   config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); | 34   config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); | 
| 31   config.num_channels = codec_inst.channels; | 35   config.num_channels = codec_inst.channels; | 
| 32   config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); | 36   config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); | 
| 33   config.payload_type = codec_inst.pltype; | 37   config.payload_type = codec_inst.pltype; | 
| 34   config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip | 38   config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip | 
| 35                                                 : AudioEncoderOpus::kAudio; | 39                                                 : AudioEncoderOpus::kAudio; | 
| 36   return config; | 40   return config; | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 97 } | 101 } | 
| 98 | 102 | 
| 99 int AudioEncoderOpus::Config::GetBitrateBps() const { | 103 int AudioEncoderOpus::Config::GetBitrateBps() const { | 
| 100   RTC_DCHECK(IsOk()); | 104   RTC_DCHECK(IsOk()); | 
| 101   if (bitrate_bps) | 105   if (bitrate_bps) | 
| 102     return *bitrate_bps;  // Explicitly set value. | 106     return *bitrate_bps;  // Explicitly set value. | 
| 103   else | 107   else | 
| 104     return num_channels == 1 ? 32000 : 64000;  // Default value. | 108     return num_channels == 1 ? 32000 : 64000;  // Default value. | 
| 105 } | 109 } | 
| 106 | 110 | 
| 107 AudioEncoderOpus::AudioEncoderOpus(const Config& config) | 111 AudioEncoderOpus::AudioEncoderOpus( | 
| 108     : packet_loss_rate_(0.0), inst_(nullptr) { | 112     const Config& config, | 
|  | 113     AudioNetworkAdaptorCreator&& audio_network_adaptor_creator) | 
|  | 114     : packet_loss_rate_(0.0), | 
|  | 115       inst_(nullptr), | 
|  | 116       audio_network_adaptor_creator_( | 
|  | 117           audio_network_adaptor_creator | 
|  | 118               ? audio_network_adaptor_creator | 
|  | 119               : [this](const std::string& config_string, const Clock* clock) { | 
|  | 120                   return DefaultAudioNetworkAdaptorCreator(config_string, | 
|  | 121                                                            clock); | 
|  | 122                 }) { | 
| 109   RTC_CHECK(RecreateEncoderInstance(config)); | 123   RTC_CHECK(RecreateEncoderInstance(config)); | 
| 110 } | 124 } | 
| 111 | 125 | 
| 112 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) | 126 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) | 
| 113     : AudioEncoderOpus(CreateConfig(codec_inst)) {} | 127     : AudioEncoderOpus(CreateConfig(codec_inst), nullptr) {} | 
| 114 | 128 | 
| 115 AudioEncoderOpus::~AudioEncoderOpus() { | 129 AudioEncoderOpus::~AudioEncoderOpus() { | 
| 116   RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); | 130   RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); | 
| 117 } | 131 } | 
| 118 | 132 | 
| 119 int AudioEncoderOpus::SampleRateHz() const { | 133 int AudioEncoderOpus::SampleRateHz() const { | 
| 120   return kSampleRateHz; | 134   return kSampleRateHz; | 
| 121 } | 135 } | 
| 122 | 136 | 
| 123 size_t AudioEncoderOpus::NumChannels() const { | 137 size_t AudioEncoderOpus::NumChannels() const { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 134 | 148 | 
| 135 int AudioEncoderOpus::GetTargetBitrate() const { | 149 int AudioEncoderOpus::GetTargetBitrate() const { | 
| 136   return config_.GetBitrateBps(); | 150   return config_.GetBitrateBps(); | 
| 137 } | 151 } | 
| 138 | 152 | 
| 139 void AudioEncoderOpus::Reset() { | 153 void AudioEncoderOpus::Reset() { | 
| 140   RTC_CHECK(RecreateEncoderInstance(config_)); | 154   RTC_CHECK(RecreateEncoderInstance(config_)); | 
| 141 } | 155 } | 
| 142 | 156 | 
| 143 bool AudioEncoderOpus::SetFec(bool enable) { | 157 bool AudioEncoderOpus::SetFec(bool enable) { | 
| 144   auto conf = config_; | 158   if (enable) { | 
| 145   conf.fec_enabled = enable; | 159     RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); | 
| 146   return RecreateEncoderInstance(conf); | 160   } else { | 
|  | 161     RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_)); | 
|  | 162   } | 
|  | 163   config_.fec_enabled = enable; | 
|  | 164   return true; | 
| 147 } | 165 } | 
| 148 | 166 | 
| 149 bool AudioEncoderOpus::SetDtx(bool enable) { | 167 bool AudioEncoderOpus::SetDtx(bool enable) { | 
| 150   auto conf = config_; | 168   if (enable) { | 
| 151   conf.dtx_enabled = enable; | 169     RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); | 
| 152   return RecreateEncoderInstance(conf); | 170   } else { | 
|  | 171     RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); | 
|  | 172   } | 
|  | 173   config_.dtx_enabled = enable; | 
|  | 174   return true; | 
| 153 } | 175 } | 
| 154 | 176 | 
| 155 bool AudioEncoderOpus::GetDtx() const { | 177 bool AudioEncoderOpus::GetDtx() const { | 
| 156   return config_.dtx_enabled; | 178   return config_.dtx_enabled; | 
| 157 } | 179 } | 
| 158 | 180 | 
| 159 bool AudioEncoderOpus::SetApplication(Application application) { | 181 bool AudioEncoderOpus::SetApplication(Application application) { | 
| 160   auto conf = config_; | 182   auto conf = config_; | 
| 161   switch (application) { | 183   switch (application) { | 
| 162     case Application::kSpeech: | 184     case Application::kSpeech: | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 185   } | 207   } | 
| 186 } | 208 } | 
| 187 | 209 | 
| 188 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { | 210 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { | 
| 189   config_.bitrate_bps = rtc::Optional<int>( | 211   config_.bitrate_bps = rtc::Optional<int>( | 
| 190       std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps)); | 212       std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps)); | 
| 191   RTC_DCHECK(config_.IsOk()); | 213   RTC_DCHECK(config_.IsOk()); | 
| 192   RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps())); | 214   RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps())); | 
| 193 } | 215 } | 
| 194 | 216 | 
|  | 217 bool AudioEncoderOpus::EnableAudioNetworkAdaptor( | 
|  | 218     const std::string& config_string, | 
|  | 219     const Clock* clock) { | 
|  | 220   audio_network_adaptor_ = audio_network_adaptor_creator_(config_string, clock); | 
|  | 221   return audio_network_adaptor_.get() != nullptr; | 
|  | 222 } | 
|  | 223 | 
|  | 224 void AudioEncoderOpus::DisableAudioNetworkAdaptor() { | 
|  | 225   audio_network_adaptor_.reset(nullptr); | 
|  | 226 } | 
|  | 227 | 
|  | 228 void AudioEncoderOpus::OnReceivedUplinkBandwidth(int uplink_bandwidth_bps) { | 
|  | 229   if (!audio_network_adaptor_) | 
|  | 230     return; | 
|  | 231   audio_network_adaptor_->SetUplinkBandwidth(uplink_bandwidth_bps); | 
|  | 232   ApplyAudioNetworkAdaptor(); | 
|  | 233 } | 
|  | 234 | 
|  | 235 void AudioEncoderOpus::OnReceivedUplinkPacketLossFraction( | 
|  | 236     float uplink_packet_loss_fraction) { | 
|  | 237   if (!audio_network_adaptor_) | 
|  | 238     return; | 
|  | 239   audio_network_adaptor_->SetUplinkPacketLossFraction( | 
|  | 240       uplink_packet_loss_fraction); | 
|  | 241   ApplyAudioNetworkAdaptor(); | 
|  | 242 } | 
|  | 243 | 
|  | 244 void AudioEncoderOpus::OnReceivedTargetAudioBitrate( | 
|  | 245     int target_audio_bitrate_bps) { | 
|  | 246   if (!audio_network_adaptor_) | 
|  | 247     return; | 
|  | 248   audio_network_adaptor_->SetTargetAudioBitrate(target_audio_bitrate_bps); | 
|  | 249   ApplyAudioNetworkAdaptor(); | 
|  | 250 } | 
|  | 251 | 
|  | 252 void AudioEncoderOpus::OnReceivedRtt(int rtt_ms) { | 
|  | 253   if (!audio_network_adaptor_) | 
|  | 254     return; | 
|  | 255   audio_network_adaptor_->SetRtt(rtt_ms); | 
|  | 256   ApplyAudioNetworkAdaptor(); | 
|  | 257 } | 
|  | 258 | 
|  | 259 void AudioEncoderOpus::SetReceiverFrameLengthRange(int min_frame_length_ms, | 
|  | 260                                                    int max_frame_length_ms) { | 
|  | 261   if (!audio_network_adaptor_) | 
|  | 262     return; | 
|  | 263   audio_network_adaptor_->SetReceiverFrameLengthRange(min_frame_length_ms, | 
|  | 264                                                       max_frame_length_ms); | 
|  | 265   ApplyAudioNetworkAdaptor(); | 
|  | 266 } | 
|  | 267 | 
| 195 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( | 268 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( | 
| 196     uint32_t rtp_timestamp, | 269     uint32_t rtp_timestamp, | 
| 197     rtc::ArrayView<const int16_t> audio, | 270     rtc::ArrayView<const int16_t> audio, | 
| 198     rtc::Buffer* encoded) { | 271     rtc::Buffer* encoded) { | 
| 199 | 272 | 
| 200   if (input_buffer_.empty()) | 273   if (input_buffer_.empty()) | 
| 201     first_timestamp_in_buffer_ = rtp_timestamp; | 274     first_timestamp_in_buffer_ = rtp_timestamp; | 
| 202 | 275 | 
| 203   input_buffer_.insert(input_buffer_.end(), audio.cbegin(), audio.cend()); | 276   input_buffer_.insert(input_buffer_.end(), audio.cbegin(), audio.cend()); | 
| 204   if (input_buffer_.size() < | 277   if (input_buffer_.size() < | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 219                                      config_.num_channels), | 292                                      config_.num_channels), | 
| 220                 rtc::saturated_cast<int16_t>(max_encoded_bytes), | 293                 rtc::saturated_cast<int16_t>(max_encoded_bytes), | 
| 221                 encoded.data()); | 294                 encoded.data()); | 
| 222 | 295 | 
| 223             RTC_CHECK_GE(status, 0);  // Fails only if fed invalid data. | 296             RTC_CHECK_GE(status, 0);  // Fails only if fed invalid data. | 
| 224 | 297 | 
| 225             return static_cast<size_t>(status); | 298             return static_cast<size_t>(status); | 
| 226           }); | 299           }); | 
| 227   input_buffer_.clear(); | 300   input_buffer_.clear(); | 
| 228 | 301 | 
|  | 302   // Will use new packet size for next encoding. | 
|  | 303   config_.frame_size_ms = next_frame_length_ms_; | 
|  | 304 | 
| 229   info.encoded_timestamp = first_timestamp_in_buffer_; | 305   info.encoded_timestamp = first_timestamp_in_buffer_; | 
| 230   info.payload_type = config_.payload_type; | 306   info.payload_type = config_.payload_type; | 
| 231   info.send_even_if_empty = true;  // Allows Opus to send empty packets. | 307   info.send_even_if_empty = true;  // Allows Opus to send empty packets. | 
| 232   info.speech = (info.encoded_bytes > 0); | 308   info.speech = (info.encoded_bytes > 0); | 
| 233   info.encoder_type = CodecType::kOpus; | 309   info.encoder_type = CodecType::kOpus; | 
| 234   return info; | 310   return info; | 
| 235 } | 311 } | 
| 236 | 312 | 
| 237 size_t AudioEncoderOpus::Num10msFramesPerPacket() const { | 313 size_t AudioEncoderOpus::Num10msFramesPerPacket() const { | 
| 238   return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10)); | 314   return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10)); | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 275   RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, config.complexity)); | 351   RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, config.complexity)); | 
| 276   if (config.dtx_enabled) { | 352   if (config.dtx_enabled) { | 
| 277     RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); | 353     RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); | 
| 278   } else { | 354   } else { | 
| 279     RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); | 355     RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); | 
| 280   } | 356   } | 
| 281   RTC_CHECK_EQ(0, | 357   RTC_CHECK_EQ(0, | 
| 282                WebRtcOpus_SetPacketLossRate( | 358                WebRtcOpus_SetPacketLossRate( | 
| 283                    inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); | 359                    inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); | 
| 284   config_ = config; | 360   config_ = config; | 
|  | 361 | 
|  | 362   num_channels_to_encode_ = NumChannels(); | 
|  | 363   next_frame_length_ms_ = config_.frame_size_ms; | 
| 285   return true; | 364   return true; | 
| 286 } | 365 } | 
| 287 | 366 | 
|  | 367 void AudioEncoderOpus::SetFrameLength(int frame_length_ms) { | 
|  | 368   next_frame_length_ms_ = frame_length_ms; | 
|  | 369 } | 
|  | 370 | 
|  | 371 void AudioEncoderOpus::SetNumChannelsToEncode(size_t num_channels_to_encode) { | 
|  | 372   RTC_DCHECK_GT(num_channels_to_encode, 0u); | 
|  | 373   RTC_DCHECK_LE(num_channels_to_encode, config_.num_channels); | 
|  | 374 | 
|  | 375   if (num_channels_to_encode_ == num_channels_to_encode) | 
|  | 376     return; | 
|  | 377 | 
|  | 378   RTC_CHECK_EQ(0, WebRtcOpus_SetForceChannels(inst_, num_channels_to_encode)); | 
|  | 379   num_channels_to_encode_ = num_channels_to_encode; | 
|  | 380 } | 
|  | 381 | 
|  | 382 void AudioEncoderOpus::ApplyAudioNetworkAdaptor() { | 
|  | 383   auto config = audio_network_adaptor_->GetEncoderRuntimeConfig(); | 
|  | 384   // |audio_network_adaptor_| is supposed to be configured to output all | 
|  | 385   // following parameters. | 
|  | 386   RTC_DCHECK(config.bitrate_bps); | 
|  | 387   RTC_DCHECK(config.frame_length_ms); | 
|  | 388   RTC_DCHECK(config.uplink_packet_loss_fraction); | 
|  | 389   RTC_DCHECK(config.enable_fec); | 
|  | 390   RTC_DCHECK(config.enable_dtx); | 
|  | 391   RTC_DCHECK(config.num_channels); | 
|  | 392 | 
|  | 393   RTC_DCHECK(*config.frame_length_ms == 20 || *config.frame_length_ms == 60); | 
|  | 394 | 
|  | 395   SetTargetBitrate(*config.bitrate_bps); | 
|  | 396   SetFrameLength(*config.frame_length_ms); | 
|  | 397   SetFec(*config.enable_fec); | 
|  | 398   SetProjectedPacketLossRate(*config.uplink_packet_loss_fraction); | 
|  | 399   SetDtx(*config.enable_dtx); | 
|  | 400   SetNumChannelsToEncode(*config.num_channels); | 
|  | 401 } | 
|  | 402 | 
|  | 403 std::unique_ptr<AudioNetworkAdaptor> | 
|  | 404 AudioEncoderOpus::DefaultAudioNetworkAdaptorCreator( | 
|  | 405     const std::string& config_string, | 
|  | 406     const Clock* clock) const { | 
|  | 407   AudioNetworkAdaptorImpl::Config config; | 
|  | 408   config.clock = clock; | 
|  | 409   return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl( | 
|  | 410       config, ControllerManagerImpl::Create( | 
|  | 411                   config_string, NumChannels(), kSupportedFrameLengths, | 
|  | 412                   num_channels_to_encode_, next_frame_length_ms_, | 
|  | 413                   GetTargetBitrate(), config_.fec_enabled, GetDtx(), clock))); | 
|  | 414 } | 
|  | 415 | 
| 288 }  // namespace webrtc | 416 }  // namespace webrtc | 
| OLD | NEW | 
|---|