From 599beb86871dacf9e7e714366c073940c591ef25 Mon Sep 17 00:00:00 2001 From: Ted Nakamura Date: Fri, 17 Apr 2015 14:14:07 -0700 Subject: [PATCH] Revert "AudioEncoderDecoderIsac: Merge the two config structs" Reason for revert - breaks Hangouts This reverts commit 7c324cac50ac38122b3f3b26455bc55ad834bfc0. BUG=chromium:478161 Review URL: https://webrtc-codereview.appspot.com/43209004 Cr-Commit-Position: refs/heads/master@{#9030} --- .../codecs/isac/audio_encoder_isac_t.h | 33 ++++--- .../codecs/isac/audio_encoder_isac_t_impl.h | 87 +++++++++++++++---- .../main/acm2/acm_generic_codec.cc | 55 ++++++++---- .../neteq/audio_decoder_unittest.cc | 3 - 4 files changed, 130 insertions(+), 48 deletions(-) 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 ad531667f5..cda554876b 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,7 +25,8 @@ class CriticalSectionWrapper; template class AudioEncoderDecoderIsacT : public AudioEncoder, public AudioDecoder { public: - // Allowed combinations of sample rate, frame size, and bit rate are + // For constructing an encoder in instantaneous 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) @@ -33,24 +34,34 @@ 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/s. - int max_payload_size_bytes; + int bit_rate; // Limit on the short-term average bit rate, in bits/second. int max_bit_rate; + 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; + // 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; }; 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 186d31811f..e81686a96c 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,17 +22,16 @@ 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(32000), - max_payload_size_bytes(-1), + bit_rate(kDefaultBitRate), max_bit_rate(-1), - adaptive_mode(false), - enforce_frame_size(false) { + max_payload_size_bytes(-1) { } template @@ -48,7 +47,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 >= 10000 && bit_rate <= 32000) || bit_rate == 0); case 32000: case 48000: if (max_bit_rate > 160000) @@ -56,7 +55,47 @@ 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); + (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); default: return false; } @@ -71,15 +110,11 @@ 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_, config.adaptive_mode ? 0 : 1)); + CHECK_EQ(0, T::EncoderInit(isac_state_, 1)); CHECK_EQ(0, T::SetEncSampRate(isac_state_, config.sample_rate_hz)); - 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)); - } + CHECK_EQ(0, T::Control(isac_state_, config.bit_rate == 0 ? kDefaultBitRate + : 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_, @@ -89,7 +124,29 @@ 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)); - CHECK_EQ(0, T::DecoderInit(isac_state_)); +} + +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)); } 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 c852d8b3e6..6b04081d3e 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc +++ b/webrtc/modules/audio_coding/main/acm2/acm_generic_codec.cc @@ -293,34 +293,51 @@ 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::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) + 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; config.bit_rate = codec_inst.rate; - 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); + config.frame_size_ms = codec_inst.pacsize / 16; + config.payload_type = codec_inst.pltype; + 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::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) + 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; config.bit_rate = codec_inst.rate; - 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); + 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); + } 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 334a2fc4ba..728caefcfe 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc @@ -361,7 +361,6 @@ 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_; @@ -381,7 +380,6 @@ 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_; @@ -401,7 +399,6 @@ 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_;