ref: 3acaa70965c5570ef1711fee9b3a15eac3e74ffe
parent: 60c48ade0a9d192b8535023bf7c7db40341ece1e
author: Jean-Marc Valin <jmvalin@amazon.com>
date: Thu Jun 30 16:11:26 EDT 2022
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.
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -482,7 +482,8 @@
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>0</dt><dd>Disable inband FEC (default).</dd>
- * <dt>1</dt><dd>Enable inband FEC.</dd>
+ * <dt>1</dt><dd>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.</dd>
+ * <dt>2</dt><dd>Inband FEC enabled, but does not necessarily switch to SILK if we have music.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x)
@@ -491,7 +492,8 @@
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
* <dl>
* <dt>0</dt><dd>Inband FEC disabled (default).</dd>
- * <dt>1</dt><dd>Inband FEC enabled.</dd>
+ * <dt>1</dt><dd>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.</dd>
+ * <dt>2</dt><dd>Inband FEC enabled, but does not necessarily switch to SILK if we have music.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x)
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -87,6 +87,7 @@
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 @@
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 @@
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 @@
{
goto bad_arg;
}
- *value = st->silk_mode.useInBandFEC;
+ *value = st->fec_config;
}
break;
case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
--- a/tests/test_opus_api.c
+++ b/tests/test_opus_api.c
@@ -1298,7 +1298,7 @@
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")