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

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

Issue 2362703002: Adding audio network adaptor to AudioEncoderOpus. (Closed)
Patch Set: some updates Created 4 years, 2 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
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 15 matching lines...) Expand all
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 = rtc::Optional<int>(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 config.audio_network_adaptor_enabled = false;
36 return config; 37 return config;
37 } 38 }
38 39
39 // Optimize the loss rate to configure Opus. Basically, optimized loss rate is 40 // 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 41 // the input loss rate rounded down to various levels, because a robustly good
41 // audio quality is achieved by lowering the packet loss down. 42 // audio quality is achieved by lowering the packet loss down.
42 // Additionally, to prevent toggling, margins are used, i.e., when jumping to 43 // Additionally, to prevent toggling, margins are used, i.e., when jumping to
43 // a loss rate from below, a higher threshold is used than jumping to the same 44 // a loss rate from below, a higher threshold is used than jumping to the same
44 // level from above. 45 // level from above.
45 double OptimizePacketLossRate(double new_loss_rate, double old_loss_rate) { 46 double OptimizePacketLossRate(double new_loss_rate, double old_loss_rate) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 } 98 }
98 99
99 int AudioEncoderOpus::Config::GetBitrateBps() const { 100 int AudioEncoderOpus::Config::GetBitrateBps() const {
100 RTC_DCHECK(IsOk()); 101 RTC_DCHECK(IsOk());
101 if (bitrate_bps) 102 if (bitrate_bps)
102 return *bitrate_bps; // Explicitly set value. 103 return *bitrate_bps; // Explicitly set value.
103 else 104 else
104 return num_channels == 1 ? 32000 : 64000; // Default value. 105 return num_channels == 1 ? 32000 : 64000; // Default value.
105 } 106 }
106 107
107 AudioEncoderOpus::AudioEncoderOpus(const Config& config) 108 AudioEncoderOpus::AudioEncoderOpus(
108 : packet_loss_rate_(0.0), inst_(nullptr) { 109 const Config& config,
110 std::unique_ptr<AudioNetworkAdaptor> audio_network_adaptor)
111 : packet_loss_rate_(0.0),
112 inst_(nullptr),
113 audio_network_adaptor_(std::move(audio_network_adaptor)) {
109 RTC_CHECK(RecreateEncoderInstance(config)); 114 RTC_CHECK(RecreateEncoderInstance(config));
110 } 115 }
111 116
112 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) 117 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst)
113 : AudioEncoderOpus(CreateConfig(codec_inst)) {} 118 : AudioEncoderOpus(CreateConfig(codec_inst), nullptr) {}
114 119
115 AudioEncoderOpus::~AudioEncoderOpus() { 120 AudioEncoderOpus::~AudioEncoderOpus() {
116 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); 121 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_));
117 } 122 }
118 123
119 int AudioEncoderOpus::SampleRateHz() const { 124 int AudioEncoderOpus::SampleRateHz() const {
120 return kSampleRateHz; 125 return kSampleRateHz;
121 } 126 }
122 127
123 size_t AudioEncoderOpus::NumChannels() const { 128 size_t AudioEncoderOpus::NumChannels() const {
(...skipping 10 matching lines...) Expand all
134 139
135 int AudioEncoderOpus::GetTargetBitrate() const { 140 int AudioEncoderOpus::GetTargetBitrate() const {
136 return config_.GetBitrateBps(); 141 return config_.GetBitrateBps();
137 } 142 }
138 143
139 void AudioEncoderOpus::Reset() { 144 void AudioEncoderOpus::Reset() {
140 RTC_CHECK(RecreateEncoderInstance(config_)); 145 RTC_CHECK(RecreateEncoderInstance(config_));
141 } 146 }
142 147
143 bool AudioEncoderOpus::SetFec(bool enable) { 148 bool AudioEncoderOpus::SetFec(bool enable) {
144 auto conf = config_; 149 if (enable) {
145 conf.fec_enabled = enable; 150 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_));
146 return RecreateEncoderInstance(conf); 151 } else {
152 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_));
153 }
154 config_.fec_enabled = enable;
155 return true;
147 } 156 }
148 157
149 bool AudioEncoderOpus::SetDtx(bool enable) { 158 bool AudioEncoderOpus::SetDtx(bool enable) {
150 auto conf = config_; 159 if (enable) {
151 conf.dtx_enabled = enable; 160 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_));
152 return RecreateEncoderInstance(conf); 161 } else {
162 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_));
163 }
164 config_.dtx_enabled = enable;
165 return true;
153 } 166 }
154 167
155 bool AudioEncoderOpus::GetDtx() const { 168 bool AudioEncoderOpus::GetDtx() const {
156 return config_.dtx_enabled; 169 return config_.dtx_enabled;
157 } 170 }
158 171
159 bool AudioEncoderOpus::SetApplication(Application application) { 172 bool AudioEncoderOpus::SetApplication(Application application) {
160 auto conf = config_; 173 auto conf = config_;
161 switch (application) { 174 switch (application) {
162 case Application::kSpeech: 175 case Application::kSpeech:
(...skipping 22 matching lines...) Expand all
185 } 198 }
186 } 199 }
187 200
188 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { 201 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) {
189 config_.bitrate_bps = rtc::Optional<int>( 202 config_.bitrate_bps = rtc::Optional<int>(
190 std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps)); 203 std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps));
191 RTC_DCHECK(config_.IsOk()); 204 RTC_DCHECK(config_.IsOk());
192 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps())); 205 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps()));
193 } 206 }
194 207
208 bool AudioEncoderOpus::SetAudioNetworkAdaptor(bool enable) {
209 if (config_.audio_network_adaptor_enabled == enable)
210 return true;
211 config_.audio_network_adaptor_enabled = enable;
212 if (config_.audio_network_adaptor_enabled) {
213 // TODO(minyue): Create AudioNetworkAdaptorImpl.
214 } else {
215 audio_network_adaptor_.reset(nullptr);
216 }
217 return true;
218 }
kwiberg-webrtc 2016/09/27 09:35:54 Hmm. I don't quite understand in what circumstance
minyue-webrtc 2016/09/27 16:02:33 My intention is to make it hook up in similar mann
219
220 void AudioEncoderOpus::OnReceivedUplinkBandwidth(int uplink_bandwidth_bps) {
221 if (!config_.audio_network_adaptor_enabled)
222 return;
223 RTC_DCHECK(audio_network_adaptor_);
224 audio_network_adaptor_->SetUplinkBandwidth(uplink_bandwidth_bps);
225 ApplyAudioNetworkAdaptor();
226 }
227
228 void AudioEncoderOpus::OnReceivedUplinkPacketLossFraction(
229 float uplink_packet_loss_fraction) {
230 if (!config_.audio_network_adaptor_enabled)
231 return;
232 RTC_DCHECK(audio_network_adaptor_);
233 audio_network_adaptor_->SetUplinkPacketLossFraction(
234 uplink_packet_loss_fraction);
235 ApplyAudioNetworkAdaptor();
236 }
237
238 void AudioEncoderOpus::OnReceivedTargetAudioBitrate(
239 int target_audio_bitrate_bps) {
240 if (!config_.audio_network_adaptor_enabled)
241 return;
242 RTC_DCHECK(audio_network_adaptor_);
243 audio_network_adaptor_->SetTargetAudioBitrate(target_audio_bitrate_bps);
244 ApplyAudioNetworkAdaptor();
245 }
246
247 void AudioEncoderOpus::OnReceivedRtt(int rtt_ms) {
248 if (!config_.audio_network_adaptor_enabled)
249 return;
250 RTC_DCHECK(audio_network_adaptor_);
251 audio_network_adaptor_->SetRtt(rtt_ms);
252 ApplyAudioNetworkAdaptor();
253 }
254
255 void AudioEncoderOpus::SetReceiverFrameLengthRange(int min_frame_length_ms,
256 int max_frame_length_ms) {
257 if (!config_.audio_network_adaptor_enabled)
258 return;
259 RTC_DCHECK(audio_network_adaptor_);
260 audio_network_adaptor_->SetReceiverFrameLengthRange(min_frame_length_ms,
261 max_frame_length_ms);
262 ApplyAudioNetworkAdaptor();
263 }
264
195 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl( 265 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl(
196 uint32_t rtp_timestamp, 266 uint32_t rtp_timestamp,
197 rtc::ArrayView<const int16_t> audio, 267 rtc::ArrayView<const int16_t> audio,
198 rtc::Buffer* encoded) { 268 rtc::Buffer* encoded) {
199 269
200 if (input_buffer_.empty()) 270 if (input_buffer_.empty())
201 first_timestamp_in_buffer_ = rtp_timestamp; 271 first_timestamp_in_buffer_ = rtp_timestamp;
202 272
203 input_buffer_.insert(input_buffer_.end(), audio.cbegin(), audio.cend()); 273 input_buffer_.insert(input_buffer_.end(), audio.cbegin(), audio.cend());
204 if (input_buffer_.size() < 274 if (input_buffer_.size() <
(...skipping 14 matching lines...) Expand all
219 config_.num_channels), 289 config_.num_channels),
220 rtc::saturated_cast<int16_t>(max_encoded_bytes), 290 rtc::saturated_cast<int16_t>(max_encoded_bytes),
221 encoded.data()); 291 encoded.data());
222 292
223 RTC_CHECK_GE(status, 0); // Fails only if fed invalid data. 293 RTC_CHECK_GE(status, 0); // Fails only if fed invalid data.
224 294
225 return static_cast<size_t>(status); 295 return static_cast<size_t>(status);
226 }); 296 });
227 input_buffer_.clear(); 297 input_buffer_.clear();
228 298
299 // Will use new packet size for next encoding.
300 config_.frame_size_ms = next_frame_size_ms_;
301
229 info.encoded_timestamp = first_timestamp_in_buffer_; 302 info.encoded_timestamp = first_timestamp_in_buffer_;
230 info.payload_type = config_.payload_type; 303 info.payload_type = config_.payload_type;
231 info.send_even_if_empty = true; // Allows Opus to send empty packets. 304 info.send_even_if_empty = true; // Allows Opus to send empty packets.
232 info.speech = (info.encoded_bytes > 0); 305 info.speech = (info.encoded_bytes > 0);
233 info.encoder_type = CodecType::kOpus; 306 info.encoder_type = CodecType::kOpus;
234 return info; 307 return info;
235 } 308 }
236 309
237 size_t AudioEncoderOpus::Num10msFramesPerPacket() const { 310 size_t AudioEncoderOpus::Num10msFramesPerPacket() const {
238 return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10)); 311 return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, config.complexity)); 348 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, config.complexity));
276 if (config.dtx_enabled) { 349 if (config.dtx_enabled) {
277 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); 350 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_));
278 } else { 351 } else {
279 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); 352 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_));
280 } 353 }
281 RTC_CHECK_EQ(0, 354 RTC_CHECK_EQ(0,
282 WebRtcOpus_SetPacketLossRate( 355 WebRtcOpus_SetPacketLossRate(
283 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); 356 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5)));
284 config_ = config; 357 config_ = config;
358
359 num_channels_to_encode_ = 0; // Opus automatic mode.
360 next_frame_size_ms_ = config_.frame_size_ms;
285 return true; 361 return true;
286 } 362 }
287 363
364 void AudioEncoderOpus::SetFrameLength(int frame_length_ms) {
365 next_frame_size_ms_ = frame_length_ms;
366 }
367
368 void AudioEncoderOpus::SetNumChannelsToEncode(size_t num_channels_to_encode) {
369 RTC_DCHECK_GT(num_channels_to_encode, 0u);
370 RTC_DCHECK_LE(num_channels_to_encode, config_.num_channels);
371
372 if (num_channels_to_encode_ == num_channels_to_encode)
373 return;
374
375 // RTC_CHECK_EQ(0, WebRtcOpus_SetForceChannels(inst_,
376 // num_channels_to_encode));
kwiberg-webrtc 2016/09/27 09:35:54 Remove commented-out code.
minyue-webrtc 2016/09/27 16:02:33 Yes, we can do it now. Since WebRtcOpus_SetForceCh
377 num_channels_to_encode_ = num_channels_to_encode;
378 }
379
380 void AudioEncoderOpus::ApplyAudioNetworkAdaptor() {
kwiberg-webrtc 2016/09/27 09:35:55 "ApplyAudioNetworkAdaptorConfig"?
minyue-webrtc 2016/09/27 16:02:33 I think ApplyAudioNetworkAdaptor may be better sin
381 auto config = audio_network_adaptor_->GetEncoderRuntimeConfig();
382
383 RTC_DCHECK(config.bitrate_bps && config.frame_length_ms &&
384 config.uplink_packet_loss_fraction && config.enable_fec &&
385 config.enable_dtx && config.num_channels);
kwiberg-webrtc 2016/09/27 09:35:54 It's often better to split things like this up int
minyue-webrtc 2016/09/27 16:02:33 ok. will change in next patch set.
386 RTC_DCHECK(*config.frame_length_ms == 20 || *config.frame_length_ms == 60);
387
388 SetTargetBitrate(*config.bitrate_bps);
389 SetFrameLength(*config.frame_length_ms);
390 SetFec(*config.enable_fec);
391 SetProjectedPacketLossRate(*config.uplink_packet_loss_fraction);
392 SetDtx(*config.enable_dtx);
393 SetNumChannelsToEncode(*config.num_channels);
394 }
395
288 } // namespace webrtc 396 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698