Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(901)

Side by Side Diff: webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc

Issue 1942193002: AudioEncoderOpus: Default to 32 kbit/s for mono, 64 kbit/s for stereo (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 11 matching lines...) Expand all
22 namespace { 22 namespace {
23 23
24 const int kSampleRateHz = 48000; 24 const int kSampleRateHz = 48000;
25 const int kMinBitrateBps = 500; 25 const int kMinBitrateBps = 500;
26 const int kMaxBitrateBps = 512000; 26 const int kMaxBitrateBps = 512000;
27 27
28 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { 28 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) {
29 AudioEncoderOpus::Config config; 29 AudioEncoderOpus::Config config;
30 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); 30 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48);
31 config.num_channels = codec_inst.channels; 31 config.num_channels = codec_inst.channels;
32 config.bitrate_bps = codec_inst.rate; 32 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate);
33 config.payload_type = codec_inst.pltype; 33 config.payload_type = codec_inst.pltype;
34 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip 34 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip
35 : AudioEncoderOpus::kAudio; 35 : AudioEncoderOpus::kAudio;
36 return config; 36 return config;
37 } 37 }
38 38
39 // Optimize the loss rate to configure Opus. Basically, optimized loss rate is 39 // Optimize the loss rate to configure Opus. Basically, optimized loss rate is
40 // the input loss rate rounded down to various levels, because a robustly good 40 // the input loss rate rounded down to various levels, because a robustly good
41 // audio quality is achieved by lowering the packet loss down. 41 // audio quality is achieved by lowering the packet loss down.
42 // Additionally, to prevent toggling, margins are used, i.e., when jumping to 42 // Additionally, to prevent toggling, margins are used, i.e., when jumping to
(...skipping 28 matching lines...) Expand all
71 return kPacketLossRate5; 71 return kPacketLossRate5;
72 } else if (new_loss_rate >= kPacketLossRate1) { 72 } else if (new_loss_rate >= kPacketLossRate1) {
73 return kPacketLossRate1; 73 return kPacketLossRate1;
74 } else { 74 } else {
75 return 0.0; 75 return 0.0;
76 } 76 }
77 } 77 }
78 78
79 } // namespace 79 } // namespace
80 80
81 AudioEncoderOpus::Config::Config() = default;
82 AudioEncoderOpus::Config::Config(const Config&) = default;
83 AudioEncoderOpus::Config::~Config() = default;
84 auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default;
hlundin-webrtc 2016/05/18 00:34:47 I don't understand this syntax. Please, educate me
kwiberg-webrtc 2016/05/18 02:54:28 It's a trailing return type (see http://en.cpprefe
85
81 bool AudioEncoderOpus::Config::IsOk() const { 86 bool AudioEncoderOpus::Config::IsOk() const {
82 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) 87 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0)
83 return false; 88 return false;
84 if (num_channels != 1 && num_channels != 2) 89 if (num_channels != 1 && num_channels != 2)
85 return false; 90 return false;
86 if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps) 91 if (bitrate_bps &&
92 (*bitrate_bps < kMinBitrateBps || *bitrate_bps > kMaxBitrateBps))
87 return false; 93 return false;
88 if (complexity < 0 || complexity > 10) 94 if (complexity < 0 || complexity > 10)
89 return false; 95 return false;
90 return true; 96 return true;
91 } 97 }
92 98
99 int AudioEncoderOpus::Config::GetBitrateBps() const {
100 RTC_DCHECK(IsOk());
101 if (bitrate_bps)
102 return *bitrate_bps; // Explicitly set value.
103 else
104 return num_channels == 1 ? 32000 : 64000; // Default value.
105 }
106
93 AudioEncoderOpus::AudioEncoderOpus(const Config& config) 107 AudioEncoderOpus::AudioEncoderOpus(const Config& config)
94 : packet_loss_rate_(0.0), inst_(nullptr) { 108 : packet_loss_rate_(0.0), inst_(nullptr) {
95 RTC_CHECK(RecreateEncoderInstance(config)); 109 RTC_CHECK(RecreateEncoderInstance(config));
96 } 110 }
97 111
98 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) 112 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst)
99 : AudioEncoderOpus(CreateConfig(codec_inst)) {} 113 : AudioEncoderOpus(CreateConfig(codec_inst)) {}
100 114
101 AudioEncoderOpus::~AudioEncoderOpus() { 115 AudioEncoderOpus::~AudioEncoderOpus() {
102 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); 116 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_));
103 } 117 }
104 118
105 int AudioEncoderOpus::SampleRateHz() const { 119 int AudioEncoderOpus::SampleRateHz() const {
106 return kSampleRateHz; 120 return kSampleRateHz;
107 } 121 }
108 122
109 size_t AudioEncoderOpus::NumChannels() const { 123 size_t AudioEncoderOpus::NumChannels() const {
110 return config_.num_channels; 124 return config_.num_channels;
111 } 125 }
112 126
113 size_t AudioEncoderOpus::Num10MsFramesInNextPacket() const { 127 size_t AudioEncoderOpus::Num10MsFramesInNextPacket() const {
114 return Num10msFramesPerPacket(); 128 return Num10msFramesPerPacket();
115 } 129 }
116 130
117 size_t AudioEncoderOpus::Max10MsFramesInAPacket() const { 131 size_t AudioEncoderOpus::Max10MsFramesInAPacket() const {
118 return Num10msFramesPerPacket(); 132 return Num10msFramesPerPacket();
119 } 133 }
120 134
121 int AudioEncoderOpus::GetTargetBitrate() const { 135 int AudioEncoderOpus::GetTargetBitrate() const {
122 return config_.bitrate_bps; 136 return config_.GetBitrateBps();
123 } 137 }
124 138
125 void AudioEncoderOpus::Reset() { 139 void AudioEncoderOpus::Reset() {
126 RTC_CHECK(RecreateEncoderInstance(config_)); 140 RTC_CHECK(RecreateEncoderInstance(config_));
127 } 141 }
128 142
129 bool AudioEncoderOpus::SetFec(bool enable) { 143 bool AudioEncoderOpus::SetFec(bool enable) {
130 auto conf = config_; 144 auto conf = config_;
131 conf.fec_enabled = enable; 145 conf.fec_enabled = enable;
132 return RecreateEncoderInstance(conf); 146 return RecreateEncoderInstance(conf);
(...skipping 28 matching lines...) Expand all
161 double opt_loss_rate = OptimizePacketLossRate(fraction, packet_loss_rate_); 175 double opt_loss_rate = OptimizePacketLossRate(fraction, packet_loss_rate_);
162 if (packet_loss_rate_ != opt_loss_rate) { 176 if (packet_loss_rate_ != opt_loss_rate) {
163 packet_loss_rate_ = opt_loss_rate; 177 packet_loss_rate_ = opt_loss_rate;
164 RTC_CHECK_EQ( 178 RTC_CHECK_EQ(
165 0, WebRtcOpus_SetPacketLossRate( 179 0, WebRtcOpus_SetPacketLossRate(
166 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); 180 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5)));
167 } 181 }
168 } 182 }
169 183
170 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { 184 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) {
171 config_.bitrate_bps = 185 config_.bitrate_bps = rtc::Optional<int>(
172 std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps); 186 std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps));
173 RTC_DCHECK(config_.IsOk()); 187 RTC_DCHECK(config_.IsOk());
174 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.bitrate_bps)); 188 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps()));
175 } 189 }
176 190
177 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( 191 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl(
178 uint32_t rtp_timestamp, 192 uint32_t rtp_timestamp,
179 rtc::ArrayView<const int16_t> audio, 193 rtc::ArrayView<const int16_t> audio,
180 rtc::Buffer* encoded) { 194 rtc::Buffer* encoded) {
181 195
182 if (input_buffer_.empty()) 196 if (input_buffer_.empty())
183 first_timestamp_in_buffer_ = rtp_timestamp; 197 first_timestamp_in_buffer_ = rtp_timestamp;
184 198
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 } 235 }
222 236
223 size_t AudioEncoderOpus::SamplesPer10msFrame() const { 237 size_t AudioEncoderOpus::SamplesPer10msFrame() const {
224 return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels; 238 return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels;
225 } 239 }
226 240
227 size_t AudioEncoderOpus::SufficientOutputBufferSize() const { 241 size_t AudioEncoderOpus::SufficientOutputBufferSize() const {
228 // Calculate the number of bytes we expect the encoder to produce, 242 // Calculate the number of bytes we expect the encoder to produce,
229 // then multiply by two to give a wide margin for error. 243 // then multiply by two to give a wide margin for error.
230 const size_t bytes_per_millisecond = 244 const size_t bytes_per_millisecond =
231 static_cast<size_t>(config_.bitrate_bps / (1000 * 8) + 1); 245 static_cast<size_t>(config_.GetBitrateBps() / (1000 * 8) + 1);
232 const size_t approx_encoded_bytes = 246 const size_t approx_encoded_bytes =
233 Num10msFramesPerPacket() * 10 * bytes_per_millisecond; 247 Num10msFramesPerPacket() * 10 * bytes_per_millisecond;
234 return 2 * approx_encoded_bytes; 248 return 2 * approx_encoded_bytes;
235 } 249 }
236 250
237 // If the given config is OK, recreate the Opus encoder instance with those 251 // If the given config is OK, recreate the Opus encoder instance with those
238 // settings, save the config, and return true. Otherwise, do nothing and return 252 // settings, save the config, and return true. Otherwise, do nothing and return
239 // false. 253 // false.
240 bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) { 254 bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) {
241 if (!config.IsOk()) 255 if (!config.IsOk())
242 return false; 256 return false;
243 if (inst_) 257 if (inst_)
244 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); 258 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_));
245 input_buffer_.clear(); 259 input_buffer_.clear();
246 input_buffer_.reserve(Num10msFramesPerPacket() * SamplesPer10msFrame()); 260 input_buffer_.reserve(Num10msFramesPerPacket() * SamplesPer10msFrame());
247 RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, config.num_channels, 261 RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, config.num_channels,
248 config.application)); 262 config.application));
249 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.bitrate_bps)); 263 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.GetBitrateBps()));
250 if (config.fec_enabled) { 264 if (config.fec_enabled) {
251 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); 265 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_));
252 } else { 266 } else {
253 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_)); 267 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_));
254 } 268 }
255 RTC_CHECK_EQ( 269 RTC_CHECK_EQ(
256 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz)); 270 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz));
257 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, config.complexity)); 271 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, config.complexity));
258 if (config.dtx_enabled) { 272 if (config.dtx_enabled) {
259 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); 273 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_));
260 } else { 274 } else {
261 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); 275 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_));
262 } 276 }
263 RTC_CHECK_EQ(0, 277 RTC_CHECK_EQ(0,
264 WebRtcOpus_SetPacketLossRate( 278 WebRtcOpus_SetPacketLossRate(
265 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); 279 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5)));
266 config_ = config; 280 config_ = config;
267 return true; 281 return true;
268 } 282 }
269 283
270 } // namespace webrtc 284 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698