diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h index cda554876b..ad531667f5 100644 --- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h +++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h @@ -25,8 +25,7 @@ class CriticalSectionWrapper; template class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder { public: - // For constructing an encoder in instantaneous mode. Allowed combinations - // are + // Allowed combinations of sample rate, frame size, and bit rate are // - 16000 Hz, 30 ms, 10000-32000 bps // - 16000 Hz, 60 ms, 10000-32000 bps // - 32000 Hz, 30 ms, 10000-56000 bps (if T has super-wideband support) @@ -34,34 +33,24 @@ class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder { struct Config { Config(); bool IsOk() const; + int payload_type; int sample_rate_hz; int frame_size_ms; - int bit_rate; // Limit on the short-term average bit rate, in bits/second. - int max_bit_rate; + int bit_rate; // Limit on the short-term average bit rate, in bits/s. int max_payload_size_bytes; - }; + int max_bit_rate; - // For constructing an encoder in channel-adaptive mode. Allowed combinations - // are - // - 16000 Hz, 30 ms, 10000-32000 bps - // - 16000 Hz, 60 ms, 10000-32000 bps - // - 32000 Hz, 30 ms, 10000-56000 bps (if T has super-wideband support) - // - 48000 Hz, 30 ms, 10000-56000 bps (if T has super-wideband support) - struct ConfigAdaptive { - ConfigAdaptive(); - bool IsOk() const; - int payload_type; - int sample_rate_hz; - int initial_frame_size_ms; - int initial_bit_rate; - int max_bit_rate; - bool enforce_frame_size; // Prevent adaptive changes to the frame size? - int max_payload_size_bytes; + // If true, the encoder will dynamically adjust frame size and bit rate; + // the configured values are then merely the starting point. + bool adaptive_mode; + + // In adaptive mode, prevent adaptive changes to the frame size. (Not used + // in nonadaptive mode.) + bool enforce_frame_size; }; explicit AudioEncoderDecoderIsacT(const Config& config); - explicit AudioEncoderDecoderIsacT(const ConfigAdaptive& config); ~AudioEncoderDecoderIsacT() override; // AudioEncoder public methods. diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h index e81686a96c..186d31811f 100644 --- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h +++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h @@ -22,16 +22,17 @@ namespace webrtc { const int kIsacPayloadType = 103; -const int kDefaultBitRate = 32000; template AudioEncoderDecoderIsacT::Config::Config() : payload_type(kIsacPayloadType), sample_rate_hz(16000), frame_size_ms(30), - bit_rate(kDefaultBitRate), + bit_rate(32000), + max_payload_size_bytes(-1), max_bit_rate(-1), - max_payload_size_bytes(-1) { + adaptive_mode(false), + enforce_frame_size(false) { } template @@ -47,7 +48,7 @@ bool AudioEncoderDecoderIsacT::Config::IsOk() const { if (max_payload_size_bytes > 400) return false; return (frame_size_ms == 30 || frame_size_ms == 60) && - ((bit_rate >= 10000 && bit_rate <= 32000) || bit_rate == 0); + (bit_rate >= 10000 && bit_rate <= 32000); case 32000: case 48000: if (max_bit_rate > 160000) @@ -55,47 +56,7 @@ bool AudioEncoderDecoderIsacT::Config::IsOk() const { if (max_payload_size_bytes > 600) return false; return T::has_swb && - (frame_size_ms == 30 && - ((bit_rate >= 10000 && bit_rate <= 56000) || bit_rate == 0)); - default: - return false; - } -} - -template -AudioEncoderDecoderIsacT::ConfigAdaptive::ConfigAdaptive() - : payload_type(kIsacPayloadType), - sample_rate_hz(16000), - initial_frame_size_ms(30), - initial_bit_rate(kDefaultBitRate), - max_bit_rate(-1), - enforce_frame_size(false), - max_payload_size_bytes(-1) { -} - -template -bool AudioEncoderDecoderIsacT::ConfigAdaptive::IsOk() const { - if (max_bit_rate < 32000 && max_bit_rate != -1) - return false; - if (max_payload_size_bytes < 120 && max_payload_size_bytes != -1) - return false; - switch (sample_rate_hz) { - case 16000: - if (max_bit_rate > 53400) - return false; - if (max_payload_size_bytes > 400) - return false; - return (initial_frame_size_ms == 30 || initial_frame_size_ms == 60) && - initial_bit_rate >= 10000 && initial_bit_rate <= 32000; - case 32000: - case 48000: - if (max_bit_rate > 160000) - return false; - if (max_payload_size_bytes > 600) - return false; - return T::has_swb && - (initial_frame_size_ms == 30 && initial_bit_rate >= 10000 && - initial_bit_rate <= 56000); + (frame_size_ms == 30 && bit_rate >= 10000 && bit_rate <= 56000); default: return false; } @@ -110,11 +71,15 @@ AudioEncoderDecoderIsacT::AudioEncoderDecoderIsacT(const Config& config) packet_in_progress_(false) { CHECK(config.IsOk()); CHECK_EQ(0, T::Create(&isac_state_)); - CHECK_EQ(0, T::EncoderInit(isac_state_, 1)); + CHECK_EQ(0, T::EncoderInit(isac_state_, config.adaptive_mode ? 0 : 1)); CHECK_EQ(0, T::SetEncSampRate(isac_state_, config.sample_rate_hz)); - CHECK_EQ(0, T::Control(isac_state_, config.bit_rate == 0 ? kDefaultBitRate - : config.bit_rate, - config.frame_size_ms)); + if (config.adaptive_mode) { + CHECK_EQ(0, T::ControlBwe(isac_state_, config.bit_rate, + config.frame_size_ms, config.enforce_frame_size)); + + } else { + CHECK_EQ(0, T::Control(isac_state_, config.bit_rate, config.frame_size_ms)); + } // When config.sample_rate_hz is set to 48000 Hz (iSAC-fb), the decoder is // still set to 32000 Hz, since there is no full-band mode in the decoder. CHECK_EQ(0, T::SetDecSampRate(isac_state_, @@ -124,29 +89,7 @@ AudioEncoderDecoderIsacT::AudioEncoderDecoderIsacT(const Config& config) T::SetMaxPayloadSize(isac_state_, config.max_payload_size_bytes)); if (config.max_bit_rate != -1) CHECK_EQ(0, T::SetMaxRate(isac_state_, config.max_bit_rate)); -} - -template -AudioEncoderDecoderIsacT::AudioEncoderDecoderIsacT( - const ConfigAdaptive& config) - : payload_type_(config.payload_type), - state_lock_(CriticalSectionWrapper::CreateCriticalSection()), - decoder_sample_rate_hz_(0), - lock_(CriticalSectionWrapper::CreateCriticalSection()), - packet_in_progress_(false) { - CHECK(config.IsOk()); - CHECK_EQ(0, T::Create(&isac_state_)); - CHECK_EQ(0, T::EncoderInit(isac_state_, 0)); - CHECK_EQ(0, T::SetEncSampRate(isac_state_, config.sample_rate_hz)); - CHECK_EQ(0, T::ControlBwe(isac_state_, config.initial_bit_rate, - config.initial_frame_size_ms, - config.enforce_frame_size)); - CHECK_EQ(0, T::SetDecSampRate(isac_state_, config.sample_rate_hz)); - if (config.max_payload_size_bytes != -1) - CHECK_EQ(0, - T::SetMaxPayloadSize(isac_state_, config.max_payload_size_bytes)); - if (config.max_bit_rate != -1) - CHECK_EQ(0, T::SetMaxRate(isac_state_, config.max_bit_rate)); + CHECK_EQ(0, T::DecoderInit(isac_state_)); } template diff --git a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc index 6b04081d3e..c852d8b3e6 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc +++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc @@ -293,51 +293,34 @@ void ACMGenericCodec::ResetAudioEncoder() { #endif #ifdef WEBRTC_CODEC_ISACFX } else if (!STR_CASE_CMP(codec_inst.plname, "ISAC")) { - DCHECK_EQ(codec_inst.plfreq, 16000); is_isac_ = true; - AudioEncoderDecoderIsacFix* enc_dec; - if (codec_inst.rate == -1) { - // Adaptive mode. - AudioEncoderDecoderIsacFix::ConfigAdaptive config; - config.payload_type = codec_inst.pltype; - enc_dec = new AudioEncoderDecoderIsacFix(config); - } else { - // Channel independent mode. - AudioEncoderDecoderIsacFix::Config config; + AudioEncoderDecoderIsacFix::Config config; + config.payload_type = codec_inst.pltype; + config.sample_rate_hz = codec_inst.plfreq; + config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 16); + if (codec_inst.rate != -1) config.bit_rate = codec_inst.rate; - config.frame_size_ms = codec_inst.pacsize / 16; - config.payload_type = codec_inst.pltype; - enc_dec = new AudioEncoderDecoderIsacFix(config); - } + config.max_payload_size_bytes = max_payload_size_bytes_; + config.max_bit_rate = max_rate_bps_; + config.adaptive_mode = (codec_inst.rate == -1); + auto* enc_dec = new AudioEncoderDecoderIsacFix(config); decoder_proxy_.SetDecoder(enc_dec); audio_encoder_.reset(enc_dec); #endif #ifdef WEBRTC_CODEC_ISAC } else if (!STR_CASE_CMP(codec_inst.plname, "ISAC")) { is_isac_ = true; - AudioEncoderDecoderIsac* enc_dec; - if (codec_inst.rate == -1) { - // Adaptive mode. - AudioEncoderDecoderIsac::ConfigAdaptive config; - config.sample_rate_hz = codec_inst.plfreq; - config.initial_frame_size_ms = rtc::CheckedDivExact( - 1000 * codec_inst.pacsize, config.sample_rate_hz); - config.max_payload_size_bytes = max_payload_size_bytes_; - config.max_bit_rate = max_rate_bps_; - config.payload_type = codec_inst.pltype; - enc_dec = new AudioEncoderDecoderIsac(config); - } else { - // Channel independent mode. - AudioEncoderDecoderIsac::Config config; - config.sample_rate_hz = codec_inst.plfreq; + AudioEncoderDecoderIsac::Config config; + config.payload_type = codec_inst.pltype; + config.sample_rate_hz = codec_inst.plfreq; + config.frame_size_ms = + rtc::CheckedDivExact(1000 * codec_inst.pacsize, config.sample_rate_hz); + if (codec_inst.rate != -1) config.bit_rate = codec_inst.rate; - config.frame_size_ms = rtc::CheckedDivExact(1000 * codec_inst.pacsize, - config.sample_rate_hz); - config.max_payload_size_bytes = max_payload_size_bytes_; - config.max_bit_rate = max_rate_bps_; - config.payload_type = codec_inst.pltype; - enc_dec = new AudioEncoderDecoderIsac(config); - } + config.max_payload_size_bytes = max_payload_size_bytes_; + config.max_bit_rate = max_rate_bps_; + config.adaptive_mode = (codec_inst.rate == -1); + auto* enc_dec = new AudioEncoderDecoderIsac(config); decoder_proxy_.SetDecoder(enc_dec); audio_encoder_.reset(enc_dec); #endif diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc index 728caefcfe..334a2fc4ba 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc @@ -361,6 +361,7 @@ class AudioDecoderIsacFloatTest : public AudioDecoderTest { AudioEncoderDecoderIsac::Config config; config.payload_type = payload_type_; config.sample_rate_hz = codec_input_rate_hz_; + config.adaptive_mode = false; config.frame_size_ms = 1000 * static_cast(frame_size_) / codec_input_rate_hz_; @@ -380,6 +381,7 @@ class AudioDecoderIsacSwbTest : public AudioDecoderTest { AudioEncoderDecoderIsac::Config config; config.payload_type = payload_type_; config.sample_rate_hz = codec_input_rate_hz_; + config.adaptive_mode = false; config.frame_size_ms = 1000 * static_cast(frame_size_) / codec_input_rate_hz_; @@ -399,6 +401,7 @@ class AudioDecoderIsacFixTest : public AudioDecoderTest { AudioEncoderDecoderIsacFix::Config config; config.payload_type = payload_type_; config.sample_rate_hz = codec_input_rate_hz_; + config.adaptive_mode = false; config.frame_size_ms = 1000 * static_cast(frame_size_) / codec_input_rate_hz_;