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

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: adding a missing deps 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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698