diff --git a/include/opus_defines.h b/include/opus_defines.h index c39a60e317b887d2183c83a1e1e5d2be3419d64b..265089f65e351acf8e7028eee906cdadaaefd854 100644 --- a/include/opus_defines.h +++ b/include/opus_defines.h @@ -163,6 +163,8 @@ extern "C" { #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 */ @@ -586,6 +588,14 @@ extern "C" { * @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) + /**@}*/ /** @defgroup opus_genericctls Generic CTLs diff --git a/silk/control.h b/silk/control.h index 896cbe8c1241d7e8f5ac19ea24ca8aafeb1aa508..747e5426a0c3fc7cb9b5bdb7834ddd98a23e9791 100644 --- a/silk/control.h +++ b/silk/control.h @@ -92,6 +92,9 @@ typedef struct { /* 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; diff --git a/silk/enc_API.c b/silk/enc_API.c index 44b9ab3591ab4193f925fc4ec42578d7ec50eba9..b3424872de418464ac05f9c5a6f0e62ce7a6a803 100644 --- a/silk/enc_API.c +++ b/silk/enc_API.c @@ -156,6 +156,11 @@ opus_int silk_Encode( /* O Returns error co 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 */ diff --git a/src/opus_encoder.c b/src/opus_encoder.c index d2066f04c6b1faba2c4359e36f5083e4d5f10789..a365e56dbe60b47397afefd8c971c0ec93b80180 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -205,6 +205,7 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat 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 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ 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) { @@ -2387,6 +2391,22 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) *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: { void *silk_enc; diff --git a/src/opus_multistream_encoder.c b/src/opus_multistream_encoder.c index 7cb1af7dcbde63d1bfaee19c53d4b580435a7982..cec62667d97bb519c097edadebaa24ef80383194 100644 --- a/src/opus_multistream_encoder.c +++ b/src/opus_multistream_encoder.c @@ -1028,6 +1028,7 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) 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 @@ int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) 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 */