ref: 4350819785bd16c6fd30100366001f19d5807d03
parent: f4ee2925f65c0cf73f0f5bb80b915181675f474c
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Wed Jan 31 07:59:08 EST 2024
Handle the offset from the DRED frame id
--- a/silk/dred_decoder.c
+++ b/silk/dred_decoder.c
@@ -55,7 +55,7 @@
}
}
-int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int min_feature_frames)
+int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int min_feature_frames, int dred_frame_offset)
{
ec_dec ec;
int q_level;
@@ -71,7 +71,8 @@
/* decode initial state and initialize RDOVAE decoder */
ec_dec_init(&ec, (unsigned char*)bytes, num_bytes);
- dec->dred_offset = sign_extend(ec_dec_uint(&ec, 32), 5);
+ /* Compute total offset, including DRED position in a multiframe packet. */
+ dec->dred_offset = sign_extend(ec_dec_uint(&ec, 32), 5) + dred_frame_offset;
q0 = ec_dec_uint(&ec, 16);
dQ = ec_dec_uint(&ec, 8);
/*printf("%d %d %d\n", dred_offset, q0, dQ);*/
--- a/silk/dred_decoder.h
+++ b/silk/dred_decoder.h
@@ -44,6 +44,6 @@
};
-int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int min_feature_frames);
+int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int min_feature_frames, int dred_frame_offset);
#endif
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -1294,7 +1294,7 @@
}
#ifdef ENABLE_DRED
-static int dred_find_payload(const unsigned char *data, opus_int32 len, const unsigned char **payload)
+static int dred_find_payload(const unsigned char *data, opus_int32 len, const unsigned char **payload, int *dred_frame_offset)
{
const unsigned char *data0;
int len0;
@@ -1302,6 +1302,7 @@
int ret;
const unsigned char *frames[48];
opus_int16 size[48];
+ int frame_size;
*payload = NULL;
/* Get the padding section of the packet. */
@@ -1308,6 +1309,7 @@
ret = opus_packet_parse_impl(data, len, 0, NULL, frames, size, NULL, NULL, &data0, &len0);
if (ret < 0)
return ret;
+ frame_size = opus_packet_get_samples_per_frame(data, 48000);
data = data0;
len = len0;
/* Scan extensions in order until we find the earliest frame with DRED data. */
@@ -1336,6 +1338,8 @@
opus_int32 curr_payload_len;
curr_payload = data0+header_size;
curr_payload_len = (data-data0)-header_size;
+ /* DRED position in the packet, in units of 2.5 ms like for the signaled DRED offset. */
+ *dred_frame_offset = frame*frame_size/120;
#ifdef DRED_EXPERIMENTAL_VERSION
/* Check that temporary extension type and version match.
This check will be removed once extension is finalized. */
@@ -1397,10 +1401,11 @@
#ifdef ENABLE_DRED
const unsigned char *payload;
opus_int32 payload_len;
+ int dred_frame_offset=0;
VALIDATE_DRED_DECODER(dred_dec);
if (!dred_dec->loaded) return OPUS_UNIMPLEMENTED;
dred->process_stage = -1;
- payload_len = dred_find_payload(data, len, &payload);
+ payload_len = dred_find_payload(data, len, &payload, &dred_frame_offset);
if (payload_len < 0)
return payload_len;
if (payload != NULL)
@@ -1409,7 +1414,7 @@
int min_feature_frames;
offset = 100*max_dred_samples/sampling_rate;
min_feature_frames = IMIN(2 + offset, 2*DRED_NUM_REDUNDANCY_FRAMES);
- dred_ec_decode(dred, payload, payload_len, min_feature_frames);
+ dred_ec_decode(dred, payload, payload_len, min_feature_frames, dred_frame_offset);
if (!defer_processing)
opus_dred_process(dred_dec, dred, dred);
return dred->nb_latents*sampling_rate/25 - sampling_rate/50;
--
⑨