ref: 54ea26241c54988ab90359badd67d4a033e0f015
parent: 885d7038d6eb16a938a5f731d8c8397980c8611e
author: Jean-Marc Valin <jmvalin@amazon.com>
date: Thu Dec 8 22:01:57 EST 2022
DRED: First version that (kinda) works Probably still has many bugs
--- a/silk/structs.h
+++ b/silk/structs.h
@@ -265,6 +265,7 @@
DREDDec dred_decoder;
float fec_features[2*DRED_NUM_REDUNDANCY_FRAMES*DRED_NUM_FEATURES];
int nb_fec_frames;
+ int pre_filled;
#endif
#endif
} silk_PLC_struct;
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -398,7 +398,7 @@
}
}
- lost_flag = data == NULL ? 1 : 2 * decode_fec;
+ lost_flag = data == NULL ? 1 : 2 * !!decode_fec;
decoded_samples = 0;
do {
/* Call SILK decoder */
@@ -643,14 +643,32 @@
int count, offset;
unsigned char toc;
int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
+ silk_decoder_state *silk_dec;
/* 48 x 2.5 ms = 120 ms */
opus_int16 size[48];
VALIDATE_OPUS_DECODER(st);
- if (decode_fec<0 || decode_fec>1)
+ silk_dec = (silk_decoder_state*)((char*)st+st->silk_dec_offset);
+ if (decode_fec<0 || (decode_fec>1 && data!=NULL))
return OPUS_BAD_ARG;
/* 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) {
+ int features_per_frame;
+ int needed_feature_frames;
+ features_per_frame = frame_size/(st->Fs/100);
+ needed_feature_frames = features_per_frame;
+ if (!silk_dec->sPLC.pre_filled) needed_feature_frames+=2;
+ silk_dec->sPLC.pre_filled = 1;
+ for (i=0;i<needed_feature_frames;i++) {
+ int feature_offset = (needed_feature_frames-i-1 + (decode_fec-1)*features_per_frame);
+ /* FIXME: Find something better than that (involving actual PLC) */
+ feature_offset = IMIN(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);
+ }
+ } else {
+ silk_dec->sPLC.pre_filled = 0;
+ }
if (len==0 || data==NULL)
{
int pcm_count=0;
--- a/src/opus_demo.c
+++ b/src/opus_demo.c
@@ -770,12 +770,15 @@
}
if (run_decoder)
run_decoder += lost_count;
+ if (!lost && lost_count > 0) {
+ opus_decoder_dred_input(dec, data, len, 100);
+ }
/* FIXME: Figure out how to trigger the decoder when the last packet of the file is lost. */
for (fr=0;fr<run_decoder;fr++) {
opus_int32 output_samples=0;
if (fr < lost_count-1) {
opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
- output_samples = opus_decode(dec, NULL, 0, out, output_samples, 1);
+ output_samples = opus_decode(dec, NULL, 0, out, output_samples, lost_count-fr);
} else if (fr == lost_count-1) {
opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
output_samples = opus_decode(dec, data, len, out, output_samples, 1);
--
⑨