ref: cbe93e23be564195d8bcc9842aeb764c32e3fe48
parent: aad4117d780cee87e1be03e4a108b9e601367dc8
author: Jean-Marc Valin <[email protected]>
date: Fri Nov 15 08:50:38 EST 2013
Adds OPUS_SET_PREDICTION_DISABLED() ctl to force "independent" frames Works by turning off pitch and energy prediction in CELT, while setting first_frame_after_reset in SILK to disable pitch and LSF interpolation and reduce LPC gain.
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -163,6 +163,8 @@
#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040
#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
+#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
+#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
@@ -585,6 +587,14 @@
* </dl>
* @hideinitializer */
#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
+
+/** If set to 1, disables almost all use of prediction, making frames almost
+ completely independent. This reduces quality. (default : 0)
+ * @hideinitializer */
+#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x)
+/** Gets the encoder's configured prediction status.
+ * @hideinitializer */
+#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x)
/**@}*/
--- a/silk/control.h
+++ b/silk/control.h
@@ -92,6 +92,9 @@
/* I: Opus encoder is allowing us to switch bandwidth */
opus_int opusCanSwitch;
+ /* I: Make frames as independent as possible (but still use LPC) */
+ opus_int reducedDependency;
+
/* O: Internal sampling rate used, in Hertz; 8000/12000/16000 */
opus_int32 internalSampleRate;
--- a/silk/enc_API.c
+++ b/silk/enc_API.c
@@ -156,6 +156,11 @@
opus_int transition, curr_block, tot_blocks;
SAVE_STACK;
+ if (encControl->reducedDependency)
+ {
+ psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1;
+ psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1;
+ }
psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
/* Check values in encoder control structure */
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -205,6 +205,7 @@
st->silk_mode.useInBandFEC = 0;
st->silk_mode.useDTX = 0;
st->silk_mode.useCBR = 0;
+ st->silk_mode.reducedDependency = 0;
/* Create CELT encoder */
/* Initialize CELT encoder */
@@ -1671,9 +1672,12 @@
celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
if (st->mode != MODE_SILK_ONLY)
{
+ opus_val32 celt_pred=2;
celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
- /* Allow prediction unless we decide to disable it later */
- celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2));
+ /* We may still decide to disable prediction later */
+ if (st->silk_mode.reducedDependency)
+ celt_pred = 0;
+ celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(celt_pred));
if (st->mode == MODE_HYBRID)
{
@@ -2385,6 +2389,22 @@
goto bad_arg;
}
*value = st->variable_duration;
+ }
+ break;
+ case OPUS_SET_PREDICTION_DISABLED_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value > 1 || value < 0)
+ goto bad_arg;
+ st->silk_mode.reducedDependency = value;
+ }
+ break;
+ case OPUS_GET_PREDICTION_DISABLED_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (!value)
+ goto bad_arg;
+ *value = st->silk_mode.reducedDependency;
}
break;
case OPUS_RESET_STATE:
--- a/src/opus_multistream_encoder.c
+++ b/src/opus_multistream_encoder.c
@@ -1028,6 +1028,7 @@
case OPUS_GET_SAMPLE_RATE_REQUEST:
case OPUS_GET_INBAND_FEC_REQUEST:
case OPUS_GET_FORCE_CHANNELS_REQUEST:
+ case OPUS_GET_PREDICTION_DISABLED_REQUEST:
{
OpusEncoder *enc;
/* For int32* GET params, just query the first stream */
@@ -1073,6 +1074,7 @@
case OPUS_SET_DTX_REQUEST:
case OPUS_SET_FORCE_MODE_REQUEST:
case OPUS_SET_FORCE_CHANNELS_REQUEST:
+ case OPUS_SET_PREDICTION_DISABLED_REQUEST:
{
int s;
/* This works for int32 params */