summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@amazon.com>2022-12-20 17:32:16 -0500
committerJean-Marc Valin <jmvalin@amazon.com>2022-12-20 17:32:16 -0500
commit145d0515a364e85d1f483b4606b05e0650bac793 (patch)
tree8f6258fb42b10ce40925f656eb4bf9a5b1bbc446
parent22528654234ca61cd49b281b651b385b2488240d (diff)
downloadopus-145d0515a364e85d1f483b4606b05e0650bac793.tar.gz
Fix DRED segfault
Properly re-initialize DRED (only) when needed
-rw-r--r--silk/structs.h5
-rw-r--r--src/opus_decoder.c21
2 files changed, 14 insertions, 12 deletions
diff --git a/silk/structs.h b/silk/structs.h
index 22f56ee0..d2d44c54 100644
--- a/silk/structs.h
+++ b/silk/structs.h
@@ -262,11 +262,6 @@ typedef struct {
/* FIXME: We should include the state struct directly to preserve the state shadow copy property. */
LPCNetPLCState *lpcnet;
int pre_filled;
-#ifdef ENABLE_NEURAL_FEC
- DREDDec dred_decoder;
- float fec_features[2*DRED_NUM_REDUNDANCY_FRAMES*DRED_NUM_FEATURES];
- int nb_fec_frames;
-#endif
#endif
} silk_PLC_struct;
diff --git a/src/opus_decoder.c b/src/opus_decoder.c
index 947d6fed..f8de4e49 100644
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -74,6 +74,11 @@ struct OpusDecoder {
#ifndef FIXED_POINT
opus_val16 softclip_mem[2];
#endif
+#ifdef ENABLE_NEURAL_FEC
+ DREDDec dred_decoder;
+ float fec_features[2*DRED_NUM_REDUNDANCY_FRAMES*DRED_NUM_FEATURES];
+ int nb_fec_frames;
+#endif
opus_uint32 rangeFinal;
};
@@ -151,7 +156,7 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));
#ifdef ENABLE_NEURAL_FEC
- init_dred_decoder(&((silk_decoder_state*)silk_dec)->sPLC.dred_decoder);
+ init_dred_decoder(&st->dred_decoder);
#endif
st->prev_mode = 0;
st->frame_size = Fs/400;
@@ -653,7 +658,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
/* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
return OPUS_BAD_ARG;
- if (decode_fec > 0 && silk_dec->sPLC.nb_fec_frames > 0) {
+ if (decode_fec > 0 && st->nb_fec_frames > 0) {
int features_per_frame;
int needed_feature_frames;
features_per_frame = frame_size/(st->Fs/100);
@@ -661,8 +666,8 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
if (!silk_dec->sPLC.pre_filled) needed_feature_frames+=2;
for (i=0;i<needed_feature_frames;i++) {
int feature_offset = (needed_feature_frames-i-1 + (decode_fec-1)*features_per_frame);
- if (feature_offset <= silk_dec->sPLC.nb_fec_frames-1) {
- lpcnet_plc_fec_add(silk_dec->sPLC.lpcnet, silk_dec->sPLC.fec_features+feature_offset*DRED_NUM_FEATURES);
+ if (feature_offset <= st->nb_fec_frames-1) {
+ lpcnet_plc_fec_add(silk_dec->sPLC.lpcnet, st->fec_features+feature_offset*DRED_NUM_FEATURES);
} else {
lpcnet_plc_fec_add(silk_dec->sPLC.lpcnet, NULL);
}
@@ -897,6 +902,7 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
break;
case OPUS_RESET_STATE:
{
+ dred_deinit_decoder(&st->dred_decoder);
OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START,
sizeof(OpusDecoder)-
((char*)&st->OPUS_DECODER_RESET_START - (char*)st));
@@ -905,6 +911,9 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
silk_InitDecoder( silk_dec );
st->stream_channels = st->channels;
st->frame_size = st->Fs/400;
+#ifdef ENABLE_NEURAL_FEC
+ init_dred_decoder(&st->dred_decoder);
+#endif
}
break;
case OPUS_GET_SAMPLE_RATE_REQUEST:
@@ -1109,11 +1118,9 @@ int opus_decoder_dred_input(OpusDecoder *st, const unsigned char *data,
if (payload != NULL)
{
int min_feature_frames;
- silk_decoder_state *silk_dec;
- silk_dec = (silk_decoder_state*)((char*)st+st->silk_dec_offset);
/*printf("Found: %p of size %d\n", payload, payload_len);*/
min_feature_frames = IMIN(2 + offset, 2*DRED_NUM_REDUNDANCY_FRAMES);
- silk_dec->sPLC.nb_fec_frames = dred_decode_redundancy_package(&silk_dec->sPLC.dred_decoder, silk_dec->sPLC.fec_features, payload, payload_len, min_feature_frames);
+ st->nb_fec_frames = dred_decode_redundancy_package(&st->dred_decoder, st->fec_features, payload, payload_len, min_feature_frames);
return 1;
}
return 0;