diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-11-15 13:50:38 -0500 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-11-15 13:50:38 -0500 |
commit | cbe93e23be564195d8bcc9842aeb764c32e3fe48 (patch) | |
tree | 802f6dc9b49960a2bb82da4d7fa2430d60234b6b /src | |
parent | aad4117d780cee87e1be03e4a108b9e601367dc8 (diff) | |
download | libopus-cbe93e23be564195d8bcc9842aeb764c32e3fe48.tar.gz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/opus_encoder.c | 24 | ||||
-rw-r--r-- | src/opus_multistream_encoder.c | 2 |
2 files changed, 24 insertions, 2 deletions
diff --git a/src/opus_encoder.c b/src/opus_encoder.c index d2066f04..a365e56d 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 7cb1af7d..cec62667 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 */ |