shithub: opus

Download patch

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;
--