From 278389defeeb9ea26100ca8f4783f44c9b446fa5 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jmvalin@jmvalin.ca> Date: Fri, 17 May 2013 02:03:33 -0400 Subject: [PATCH] Automatic bandwidth decisions get more conservative as rate increases. This should prevent errors in the bandwidth detection from affecting quality when we have enough bits to be close to transparent. --- celt/celt.h | 1 - src/analysis.c | 12 ------------ src/analysis.h | 1 - src/opus_encoder.c | 36 ++++++++++++++++++++++++++++++------ 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/celt/celt.h b/celt/celt.h index 0404d9181..c4b3ddbab 100644 --- a/celt/celt.h +++ b/celt/celt.h @@ -58,7 +58,6 @@ typedef struct { opus_val16 activity; opus_val16 music_prob; int bandwidth; - int opus_bandwidth; }AnalysisInfo; #define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) diff --git a/src/analysis.c b/src/analysis.c index b978b6e05..ee71bda65 100644 --- a/src/analysis.c +++ b/src/analysis.c @@ -575,19 +575,7 @@ void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info_out, con printf("%f ", features[i]); printf("\n");*/ - if (bandwidth<=12) - tonal->opus_bandwidth = OPUS_BANDWIDTH_NARROWBAND; - else if (bandwidth<=14) - tonal->opus_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; - else if (bandwidth<=16) - tonal->opus_bandwidth = OPUS_BANDWIDTH_WIDEBAND; - else if (bandwidth<=18) - tonal->opus_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; - else - tonal->opus_bandwidth = OPUS_BANDWIDTH_FULLBAND; - info->bandwidth = bandwidth; - info->opus_bandwidth = tonal->opus_bandwidth; /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/ info->noisiness = frame_noisiness; info->valid = 1; diff --git a/src/analysis.h b/src/analysis.h index 7b17118cf..bce94a510 100644 --- a/src/analysis.h +++ b/src/analysis.h @@ -60,7 +60,6 @@ typedef struct { int last_music; int last_transition; int count; - int opus_bandwidth; opus_val32 subframe_mem[3]; int analysis_offset; float pspeech[DETECT_SIZE]; diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 29ac96796..1f2491aec 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -941,9 +941,21 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ st->detected_bandwidth = 0; if (analysis_info->valid) { + int analysis_bandwidth; if (st->signal_type == OPUS_AUTO) st->voice_ratio = (int)floor(.5+100*(1-analysis_info->music_prob)); - st->detected_bandwidth = analysis_info->opus_bandwidth; + + analysis_bandwidth = analysis_info->bandwidth; + if (analysis_bandwidth<=12) + st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + else if (analysis_bandwidth<=14) + st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + else if (analysis_bandwidth<=16) + st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + else if (analysis_bandwidth<=18) + st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + else + st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; } #endif @@ -1217,12 +1229,24 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ /* Use detected bandwidth to reduce the encoded bandwidth. */ if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO) { - /* When operating in SILK/hybrid mode, we don't go below wideband to avoid - more complicated switches that require redundancy */ - if (st->mode == MODE_CELT_ONLY) - st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth); + int min_detected_bandwidth; + /* Makes bandwidth detection more conservative just in case the detector + gets it wrong when we could have coded a high bandwidth transparently. + When operating in SILK/hybrid mode, we don't go below wideband to avoid + more complicated switches that require redundancy. */ + if (st->bitrate_bps <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY) + min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + else if (st->bitrate_bps <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY) + min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + else if (st->bitrate_bps <= 30000*st->stream_channels) + min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + else if (st->bitrate_bps <= 44000*st->stream_channels) + min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; else - st->bandwidth = IMIN(st->bandwidth, IMAX(OPUS_BANDWIDTH_WIDEBAND, st->detected_bandwidth)); + min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; + + st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth); + st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth); } #endif celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth)); -- GitLab