From 3acaa70965c5570ef1711fee9b3a15eac3e74ffe Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Thu, 30 Jun 2022 20:11:26 -0400 Subject: Adds OPUS_SET_INBAND_FEC(2) option Unlike OPUS_SET_INBAND_FEC(1), the encoder does not necessarily switch to SILK if we have music. --- include/opus_defines.h | 6 ++++-- src/opus_encoder.c | 13 ++++++++----- tests/test_opus_api.c | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/opus_defines.h b/include/opus_defines.h index ceee5b84..94b9e0d9 100644 --- a/include/opus_defines.h +++ b/include/opus_defines.h @@ -482,7 +482,8 @@ extern "C" { * @param[in] x opus_int32: Allowed values: *
*
0
Disable inband FEC (default).
- *
1
Enable inband FEC.
+ *
1
Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.
+ *
2
Inband FEC enabled, but does not necessarily switch to SILK if we have music.
*
* @hideinitializer */ #define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) @@ -491,7 +492,8 @@ extern "C" { * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Inband FEC disabled (default).
- *
1
Inband FEC enabled.
+ *
1
Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.
+ *
2
Inband FEC enabled, but does not necessarily switch to SILK if we have music.
*
* @hideinitializer */ #define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 253fe9e8..64b6726c 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -87,6 +87,7 @@ struct OpusEncoder { int lfe; int arch; int use_dtx; /* general DTX for both SILK and CELT */ + int fec_config; #ifndef DISABLE_FLOAT_API TonalityAnalysisState analysis; #endif @@ -1389,8 +1390,9 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY; - /* When FEC is enabled and there's enough packet loss, use SILK */ - if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4) + /* When FEC is enabled and there's enough packet loss, use SILK. + Unless the FEC is set to 2, in which case we don't switch to SILK if we're confident we have music. */ + if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4 && (st->fec_config != 2 || voice_est > 25)) st->mode = MODE_SILK_ONLY; /* When encoding voice and DTX is enabled but the generalized DTX cannot be used, use SILK in order to make use of its DTX. */ @@ -2439,11 +2441,12 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_SET_INBAND_FEC_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) + if(value<0 || value>2) { goto bad_arg; } - st->silk_mode.useInBandFEC = value; + st->fec_config = value; + st->silk_mode.useInBandFEC = (value != 0); } break; case OPUS_GET_INBAND_FEC_REQUEST: @@ -2453,7 +2456,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { goto bad_arg; } - *value = st->silk_mode.useInBandFEC; + *value = st->fec_config; } break; case OPUS_SET_PACKET_LOSS_PERC_REQUEST: diff --git a/tests/test_opus_api.c b/tests/test_opus_api.c index fb385c63..0e7ed2cc 100644 --- a/tests/test_opus_api.c +++ b/tests/test_opus_api.c @@ -1298,7 +1298,7 @@ opus_int32 test_enc_api(void) err=opus_encoder_ctl(enc,OPUS_GET_INBAND_FEC(null_int_ptr)); if(err!=OPUS_BAD_ARG)test_failed(); cfgs++; - CHECK_SETGET(OPUS_SET_INBAND_FEC(i),OPUS_GET_INBAND_FEC(&i),-1,2, + CHECK_SETGET(OPUS_SET_INBAND_FEC(i),OPUS_GET_INBAND_FEC(&i),-1,3, 1,0, " OPUS_SET_INBAND_FEC .......................... OK.\n", " OPUS_GET_INBAND_FEC .......................... OK.\n") -- cgit v1.2.3