Including redundant frames in the final range coder state

This commit is contained in:
Jean-Marc Valin 2011-08-19 16:11:41 -04:00
parent 06677d7368
commit 06cee2b1b4
4 changed files with 29 additions and 3 deletions

View file

@ -1838,6 +1838,14 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...)
*value=st->mode; *value=st->mode;
} }
break; break;
case CELT_GET_RANGE_REQUEST:
{
opus_uint32 * value = va_arg(ap, opus_uint32 *);
if (value==0)
goto bad_arg;
*value=st->rng;
}
break;
#endif #endif
default: default:
goto bad_request; goto bad_request;
@ -2741,6 +2749,14 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...)
st->signalling = value; st->signalling = value;
} }
break; break;
case CELT_GET_RANGE_REQUEST:
{
opus_uint32 * value = va_arg(ap, opus_uint32 *);
if (value==0)
goto bad_arg;
*value=st->rng;
}
break;
#endif #endif
default: default:
goto bad_request; goto bad_request;

View file

@ -51,7 +51,8 @@ extern "C" {
#define _celt_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) #define _celt_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
#define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) #define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
#define _celt_check_int_ptr(ptr) ((ptr) + ((ptr) - (int*)(ptr))) #define _celt_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
#define _celt_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
/* Error codes */ /* Error codes */
/** No error */ /** No error */
@ -121,6 +122,9 @@ extern "C" {
#define CELT_SET_END_BAND_REQUEST 10001 #define CELT_SET_END_BAND_REQUEST 10001
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, _celt_check_int(x) #define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, _celt_check_int(x)
#define CELT_GET_RANGE_REQUEST 10002
#define CELT_GET_RANGE(x) CELT_GET_RANGE_REQUEST, _celt_check_uint_ptr(x)
/** Contains the state of an encoder. One encoder state is needed /** Contains the state of an encoder. One encoder state is needed
for each stream. It is initialised once at the beginning of the for each stream. It is initialised once at the beginning of the
stream. Do *not* re-initialise the state for every frame. stream. Do *not* re-initialise the state for every frame.

View file

@ -196,6 +196,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
int c; int c;
int F2_5, F5, F10, F20; int F2_5, F5, F10, F20;
const opus_val16 *window; const opus_val16 *window;
opus_uint32 redundant_rng = 0;
ALLOC_STACK; ALLOC_STACK;
silk_dec = (char*)st+st->silk_dec_offset; silk_dec = (char*)st+st->silk_dec_offset;
@ -373,6 +374,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
{ {
celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
celt_decode_native(celt_dec, data+len, redundancy_bytes, redundant_audio, F5); celt_decode_native(celt_dec, data+len, redundancy_bytes, redundant_audio, F5);
celt_decoder_ctl(celt_dec, CELT_GET_RANGE(&redundant_rng));
celt_decoder_ctl(celt_dec, CELT_RESET_STATE); celt_decoder_ctl(celt_dec, CELT_RESET_STATE);
} }
@ -416,6 +418,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
celt_decode_native(celt_dec, data+len, redundancy_bytes, redundant_audio, F5); celt_decode_native(celt_dec, data+len, redundancy_bytes, redundant_audio, F5);
celt_decoder_ctl(celt_dec, CELT_GET_RANGE(&redundant_rng));
smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
} }
@ -439,7 +442,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
st->channels, window, st->Fs); st->channels, window, st->Fs);
} }
st->rangeFinal = dec.rng; st->rangeFinal = dec.rng ^ redundant_rng;
st->prev_mode = mode; st->prev_mode = mode;
st->prev_redundancy = redundancy; st->prev_redundancy = redundancy;

View file

@ -258,6 +258,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
int nb_compr_bytes; int nb_compr_bytes;
int to_celt = 0; int to_celt = 0;
opus_int32 mono_rate; opus_int32 mono_rate;
opus_uint32 redundant_rng = 0;
ALLOC_STACK; ALLOC_STACK;
if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs && if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
@ -685,6 +686,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
celt_encoder_ctl(celt_enc, CELT_SET_VBR(0)); celt_encoder_ctl(celt_enc, CELT_SET_VBR(0));
celt_encode_native(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes); celt_encode_native(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes);
celt_encoder_ctl(celt_enc, CELT_GET_RANGE(&redundant_rng));
celt_encoder_ctl(celt_enc, CELT_RESET_STATE); celt_encoder_ctl(celt_enc, CELT_RESET_STATE);
} }
@ -710,6 +712,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
celt_encode_native(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes); celt_encode_native(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, data+nb_compr_bytes, redundancy_bytes);
celt_encode_native(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes); celt_encode_native(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes);
celt_encoder_ctl(celt_enc, CELT_GET_RANGE(&redundant_rng));
} }
@ -729,7 +732,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
data--; data--;
data[0] = gen_toc(st->mode, st->Fs/frame_size, st->bandwidth, st->stream_channels); data[0] = gen_toc(st->mode, st->Fs/frame_size, st->bandwidth, st->stream_channels);
st->rangeFinal = enc.rng; st->rangeFinal = enc.rng ^ redundant_rng;
if (to_celt) if (to_celt)
st->prev_mode = MODE_CELT_ONLY; st->prev_mode = MODE_CELT_ONLY;