aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-15 13:50:38 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-15 13:50:38 -0500
commitcbe93e23be564195d8bcc9842aeb764c32e3fe48 (patch)
tree802f6dc9b49960a2bb82da4d7fa2430d60234b6b /src
parentaad4117d780cee87e1be03e4a108b9e601367dc8 (diff)
downloadlibopus-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.c24
-rw-r--r--src/opus_multistream_encoder.c2
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 */