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 <stdlib.h> |
| 14 |
13 #include <algorithm> | 15 #include <algorithm> |
14 #include <iterator> | 16 #include <iterator> |
15 | 17 |
16 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
18 #include "webrtc/base/numerics/exp_filter.h" | 20 #include "webrtc/base/numerics/exp_filter.h" |
19 #include "webrtc/base/safe_conversions.h" | 21 #include "webrtc/base/safe_conversions.h" |
| 22 #include "webrtc/base/string_to_number.h" |
20 #include "webrtc/base/timeutils.h" | 23 #include "webrtc/base/timeutils.h" |
21 #include "webrtc/common_types.h" | 24 #include "webrtc/common_types.h" |
22 #include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adapto
r_impl.h" | 25 #include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adapto
r_impl.h" |
23 #include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h
" | 26 #include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h
" |
24 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" | 27 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" |
25 #include "webrtc/system_wrappers/include/field_trial.h" | 28 #include "webrtc/system_wrappers/include/field_trial.h" |
26 | 29 |
27 namespace webrtc { | 30 namespace webrtc { |
28 | 31 |
29 namespace { | 32 namespace { |
30 | 33 |
| 34 // Codec parameters for Opus. |
| 35 // draft-spittka-payload-rtp-opus-03 |
| 36 |
| 37 // Recommended bitrates: |
| 38 // 8-12 kb/s for NB speech, |
| 39 // 16-20 kb/s for WB speech, |
| 40 // 28-40 kb/s for FB speech, |
| 41 // 48-64 kb/s for FB mono music, and |
| 42 // 64-128 kb/s for FB stereo music. |
| 43 // The current implementation applies the following values to mono signals, |
| 44 // and multiplies them by 2 for stereo. |
| 45 const int kOpusBitrateNbBps = 12000; |
| 46 const int kOpusBitrateWbBps = 20000; |
| 47 const int kOpusBitrateFbBps = 32000; |
| 48 |
| 49 // Opus bitrate should be in the range between 6000 and 510000. |
| 50 const int kOpusMinBitrateBps = 6000; |
| 51 const int kOpusMaxBitrateBps = 510000; |
| 52 |
| 53 // TODO(ossu): These are from kCodecPrefs in webrtcvoiceengine.cc |
| 54 const int kOpusSupportedFrameLengths[] = {10, 20, 40, 60}; |
| 55 |
31 constexpr int kSampleRateHz = 48000; | 56 constexpr int kSampleRateHz = 48000; |
32 | 57 |
33 // Opus API allows a min bitrate of 500bps, but Opus documentation suggests | 58 // Opus API allows a min bitrate of 500bps, but Opus documentation suggests |
34 // a minimum bitrate of 6kbps. | 59 // a minimum bitrate of 6kbps. |
35 constexpr int kMinBitrateBps = 6000; | 60 constexpr int kMinBitrateBps = 6000; |
36 | 61 |
37 constexpr int kMaxBitrateBps = 512000; | 62 constexpr int kMaxBitrateBps = 512000; |
38 | 63 |
39 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME | 64 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME |
40 constexpr int kSupportedFrameLengths[] = {20, 60, 120}; | 65 constexpr int kANASupportedFrameLengths[] = {20, 60, 120}; |
41 #else | 66 #else |
42 constexpr int kSupportedFrameLengths[] = {20, 60}; | 67 constexpr int kANASupportedFrameLengths[] = {20, 60}; |
43 #endif | 68 #endif |
44 | 69 |
45 // PacketLossFractionSmoother uses an exponential filter with a time constant | 70 // PacketLossFractionSmoother uses an exponential filter with a time constant |
46 // of -1.0 / ln(0.9999) = 10000 ms. | 71 // of -1.0 / ln(0.9999) = 10000 ms. |
47 constexpr float kAlphaForPacketLossFractionSmoother = 0.9999f; | 72 constexpr float kAlphaForPacketLossFractionSmoother = 0.9999f; |
48 | 73 |
49 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { | 74 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { |
50 AudioEncoderOpus::Config config; | 75 AudioEncoderOpus::Config config; |
51 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); | 76 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); |
52 config.num_channels = codec_inst.channels; | 77 config.num_channels = codec_inst.channels; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 return kPacketLossRate5; | 121 return kPacketLossRate5; |
97 } else if (new_loss_rate >= kPacketLossRate1) { | 122 } else if (new_loss_rate >= kPacketLossRate1) { |
98 return kPacketLossRate1; | 123 return kPacketLossRate1; |
99 } else { | 124 } else { |
100 return 0.0f; | 125 return 0.0f; |
101 } | 126 } |
102 } | 127 } |
103 | 128 |
104 } // namespace | 129 } // namespace |
105 | 130 |
| 131 rtc::Optional<AudioFormatInfo> AudioEncoderOpus::QueryAudioFormat( |
| 132 const SdpAudioFormat& format) { |
| 133 if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0 && |
| 134 format.clockrate_hz == 48000 && format.num_channels == 2) { |
| 135 int num_channels = 1; |
| 136 const auto stereo_param = format.parameters.find("stereo"); |
| 137 if (stereo_param != format.parameters.end()) { |
| 138 if (stereo_param->second == "1") { |
| 139 num_channels = 2; |
| 140 } else if (stereo_param->second != "0") { |
| 141 return rtc::Optional<AudioFormatInfo>(); |
| 142 } |
| 143 } |
| 144 |
| 145 int max_playback_rate = 48000; |
| 146 const auto maxplaybackrate_param = |
| 147 format.parameters.find("maxplaybackrate"); |
| 148 if (maxplaybackrate_param != format.parameters.end()) { |
| 149 const auto opt_max_playback_rate = |
| 150 rtc::StringToNumber<int>(maxplaybackrate_param->second); |
| 151 if (opt_max_playback_rate) { |
| 152 max_playback_rate = *opt_max_playback_rate; |
| 153 if (max_playback_rate <= 0) { |
| 154 return rtc::Optional<AudioFormatInfo>(); |
| 155 } |
| 156 } |
| 157 } |
| 158 |
| 159 int bitrate; |
| 160 if (max_playback_rate && max_playback_rate <= 8000) { |
| 161 bitrate = kOpusBitrateNbBps * num_channels; |
| 162 } else if (max_playback_rate && max_playback_rate <= 16000) { |
| 163 bitrate = kOpusBitrateWbBps * num_channels; |
| 164 } else { |
| 165 bitrate = kOpusBitrateFbBps * num_channels; |
| 166 } |
| 167 |
| 168 AudioFormatInfo info(48000, num_channels, bitrate, kOpusMinBitrateBps, |
| 169 kOpusMaxBitrateBps); |
| 170 info.allow_comfort_noise = false; |
| 171 info.supports_network_adaption = true; |
| 172 |
| 173 return rtc::Optional<AudioFormatInfo>(info); |
| 174 } |
| 175 return rtc::Optional<AudioFormatInfo>(); |
| 176 } |
| 177 |
| 178 AudioEncoderOpus::Config AudioEncoderOpus::CreateConfig( |
| 179 int payload_type, |
| 180 const SdpAudioFormat& format) { |
| 181 auto get_param_int = |
| 182 [&format] (const std::string& param) { |
| 183 auto it = format.parameters.find(param); |
| 184 if (it != format.parameters.end()) { |
| 185 return rtc::StringToNumber<int>(it->second.c_str()); |
| 186 } |
| 187 return rtc::Optional<int>(); |
| 188 }; |
| 189 |
| 190 auto get_param = |
| 191 [&format] (const std::string& param) { |
| 192 auto it = format.parameters.find(param); |
| 193 return (it == format.parameters.end()) |
| 194 ? std::string() |
| 195 : it->second; |
| 196 }; |
| 197 |
| 198 AudioEncoderOpus::Config config; |
| 199 config.num_channels = (get_param("stereo") == "1") ? 2 : 1; |
| 200 config.fec_enabled = (get_param("useinbandfec") == "1"); |
| 201 config.dtx_enabled = (get_param("usedtx") == "1"); |
| 202 const auto max_playback_rate = get_param_int("maxplaybackrate"); |
| 203 if (max_playback_rate && *max_playback_rate > 0) { |
| 204 config.max_playback_rate_hz = *max_playback_rate; |
| 205 } |
| 206 const auto max_average_bitrate = get_param_int("maxaveragebitrate"); |
| 207 bool use_param = true; |
| 208 int bitrate = 0; |
| 209 if (max_average_bitrate && *max_average_bitrate > 0) { |
| 210 bitrate = *max_average_bitrate; |
| 211 } else { |
| 212 if (max_playback_rate && *max_playback_rate <= 8000) { |
| 213 bitrate = kOpusBitrateNbBps * config.num_channels; |
| 214 } else if (max_playback_rate && *max_playback_rate <= 16000) { |
| 215 bitrate = kOpusBitrateWbBps * config.num_channels; |
| 216 } else { |
| 217 bitrate = kOpusBitrateFbBps * config.num_channels; |
| 218 } |
| 219 use_param = false; |
| 220 } |
| 221 |
| 222 if (bitrate < kOpusMinBitrateBps || bitrate > kOpusMaxBitrateBps) { |
| 223 bitrate = (bitrate < kOpusMinBitrateBps) ? kOpusMinBitrateBps |
| 224 : kOpusMaxBitrateBps; |
| 225 std::string rate_source = |
| 226 use_param ? "Codec parameter \"maxaveragebitrate\"" |
| 227 : "Default Opus bitrate"; |
| 228 LOG(LS_WARNING) << rate_source |
| 229 << " is invalid and is replaced by: " << bitrate; |
| 230 } |
| 231 config.bitrate_bps = rtc::Optional<int>(bitrate); |
| 232 config.payload_type = payload_type; |
| 233 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip |
| 234 : AudioEncoderOpus::kAudio; |
| 235 #if WEBRTC_OPUS_VARIABLE_COMPLEXITY |
| 236 config.low_rate_complexity = 9; |
| 237 #endif |
| 238 |
| 239 // TODO(ossu): What to do if ptime is not between minptime and maxptime? |
| 240 const auto ptime = get_param_int("ptime"); |
| 241 if (ptime) { |
| 242 // Expects kOpusSupportedFrameLengths to be sorted. |
| 243 for (const int supported_frame_length : kOpusSupportedFrameLengths) { |
| 244 if (supported_frame_length >= *ptime) { |
| 245 config.frame_size_ms = *ptime; |
| 246 } |
| 247 } |
| 248 } |
| 249 |
| 250 const int min_frame_length_ms = |
| 251 std::min(std::max(get_param_int("minptime").value_or(10), 10), 60); |
| 252 const int max_frame_length_ms = |
| 253 std::min(std::max(get_param_int("maxptime").value_or(60), 10), 60); |
| 254 if (min_frame_length_ms <= max_frame_length_ms) { |
| 255 for (const int frame_length_ms : kANASupportedFrameLengths) { |
| 256 if (frame_length_ms >= min_frame_length_ms && |
| 257 frame_length_ms <= max_frame_length_ms) { |
| 258 config.supported_frame_lengths_ms.push_back(frame_length_ms); |
| 259 } |
| 260 } |
| 261 } |
| 262 |
| 263 // As a fallback, just pick the whole set of supported frame lengths. |
| 264 if (config.supported_frame_lengths_ms.empty()) { |
| 265 for (const int frame_length_ms : kANASupportedFrameLengths) { |
| 266 config.supported_frame_lengths_ms.push_back(frame_length_ms); |
| 267 } |
| 268 } |
| 269 |
| 270 RTC_DCHECK(std::is_sorted(config.supported_frame_lengths_ms.begin(), |
| 271 config.supported_frame_lengths_ms.end())); |
| 272 |
| 273 return config; |
| 274 } |
| 275 |
106 class AudioEncoderOpus::PacketLossFractionSmoother { | 276 class AudioEncoderOpus::PacketLossFractionSmoother { |
107 public: | 277 public: |
108 explicit PacketLossFractionSmoother(const Clock* clock) | 278 explicit PacketLossFractionSmoother(const Clock* clock) |
109 : clock_(clock), | 279 : clock_(clock), |
110 last_sample_time_ms_(clock_->TimeInMilliseconds()), | 280 last_sample_time_ms_(clock_->TimeInMilliseconds()), |
111 smoother_(kAlphaForPacketLossFractionSmoother) {} | 281 smoother_(kAlphaForPacketLossFractionSmoother) {} |
112 | 282 |
113 // Gets the smoothed packet loss fraction. | 283 // Gets the smoothed packet loss fraction. |
114 float GetAverage() const { | 284 float GetAverage() const { |
115 float value = smoother_.filtered(); | 285 float value = smoother_.filtered(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 event_log, clock); | 369 event_log, clock); |
200 }), | 370 }), |
201 bitrate_smoother_(bitrate_smoother | 371 bitrate_smoother_(bitrate_smoother |
202 ? std::move(bitrate_smoother) : std::unique_ptr<SmoothingFilter>( | 372 ? std::move(bitrate_smoother) : std::unique_ptr<SmoothingFilter>( |
203 // We choose 5sec as initial time constant due to empirical data. | 373 // We choose 5sec as initial time constant due to empirical data. |
204 new SmoothingFilterImpl(5000, config.clock))) { | 374 new SmoothingFilterImpl(5000, config.clock))) { |
205 RTC_CHECK(RecreateEncoderInstance(config)); | 375 RTC_CHECK(RecreateEncoderInstance(config)); |
206 } | 376 } |
207 | 377 |
208 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) | 378 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) |
209 : AudioEncoderOpus(CreateConfig(codec_inst), nullptr) {} | 379 : AudioEncoderOpus(webrtc::CreateConfig(codec_inst), nullptr) {} |
| 380 |
| 381 AudioEncoderOpus::AudioEncoderOpus(int payload_type, |
| 382 const SdpAudioFormat& format) |
| 383 : AudioEncoderOpus(CreateConfig(payload_type, format), nullptr) {} |
210 | 384 |
211 AudioEncoderOpus::~AudioEncoderOpus() { | 385 AudioEncoderOpus::~AudioEncoderOpus() { |
212 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); | 386 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); |
213 } | 387 } |
214 | 388 |
215 int AudioEncoderOpus::SampleRateHz() const { | 389 int AudioEncoderOpus::SampleRateHz() const { |
216 return kSampleRateHz; | 390 return kSampleRateHz; |
217 } | 391 } |
218 | 392 |
219 size_t AudioEncoderOpus::NumChannels() const { | 393 size_t AudioEncoderOpus::NumChannels() const { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 } | 534 } |
361 | 535 |
362 void AudioEncoderOpus::SetReceiverFrameLengthRange(int min_frame_length_ms, | 536 void AudioEncoderOpus::SetReceiverFrameLengthRange(int min_frame_length_ms, |
363 int max_frame_length_ms) { | 537 int max_frame_length_ms) { |
364 // Ensure that |SetReceiverFrameLengthRange| is called before | 538 // Ensure that |SetReceiverFrameLengthRange| is called before |
365 // |EnableAudioNetworkAdaptor|, otherwise we need to recreate | 539 // |EnableAudioNetworkAdaptor|, otherwise we need to recreate |
366 // |audio_network_adaptor_|, which is not a needed use case. | 540 // |audio_network_adaptor_|, which is not a needed use case. |
367 RTC_DCHECK(!audio_network_adaptor_); | 541 RTC_DCHECK(!audio_network_adaptor_); |
368 | 542 |
369 config_.supported_frame_lengths_ms.clear(); | 543 config_.supported_frame_lengths_ms.clear(); |
370 std::copy_if(std::begin(kSupportedFrameLengths), | 544 std::copy_if(std::begin(kANASupportedFrameLengths), |
371 std::end(kSupportedFrameLengths), | 545 std::end(kANASupportedFrameLengths), |
372 std::back_inserter(config_.supported_frame_lengths_ms), | 546 std::back_inserter(config_.supported_frame_lengths_ms), |
373 [&](int frame_length_ms) { | 547 [&](int frame_length_ms) { |
374 return frame_length_ms >= min_frame_length_ms && | 548 return frame_length_ms >= min_frame_length_ms && |
375 frame_length_ms <= max_frame_length_ms; | 549 frame_length_ms <= max_frame_length_ms; |
376 }); | 550 }); |
377 RTC_DCHECK(std::is_sorted(config_.supported_frame_lengths_ms.begin(), | 551 RTC_DCHECK(std::is_sorted(config_.supported_frame_lengths_ms.begin(), |
378 config_.supported_frame_lengths_ms.end())); | 552 config_.supported_frame_lengths_ms.end())); |
379 } | 553 } |
380 | 554 |
381 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( | 555 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 config_.uplink_bandwidth_update_interval_ms) { | 734 config_.uplink_bandwidth_update_interval_ms) { |
561 rtc::Optional<float> smoothed_bitrate = bitrate_smoother_->GetAverage(); | 735 rtc::Optional<float> smoothed_bitrate = bitrate_smoother_->GetAverage(); |
562 if (smoothed_bitrate) | 736 if (smoothed_bitrate) |
563 audio_network_adaptor_->SetUplinkBandwidth(*smoothed_bitrate); | 737 audio_network_adaptor_->SetUplinkBandwidth(*smoothed_bitrate); |
564 bitrate_smoother_last_update_time_ = rtc::Optional<int64_t>(now_ms); | 738 bitrate_smoother_last_update_time_ = rtc::Optional<int64_t>(now_ms); |
565 } | 739 } |
566 } | 740 } |
567 } | 741 } |
568 | 742 |
569 } // namespace webrtc | 743 } // namespace webrtc |
OLD | NEW |