[FFmpeg-cvslog] avcodec/mlpenc: try different filter parameters in case of out of range output from LPC

Paul B Mahol git at videolan.org
Fri Oct 27 13:39:51 EEST 2023


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed Oct 25 15:32:53 2023 +0200| [36eb774ad49bccd061b865b3400567193ed10d6c] | committer: Paul B Mahol

avcodec/mlpenc: try different filter parameters in case of out of range output from LPC

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=36eb774ad49bccd061b865b3400567193ed10d6c
---

 libavcodec/mlpenc.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/libavcodec/mlpenc.c b/libavcodec/mlpenc.c
index 2df695efe7..895362faca 100644
--- a/libavcodec/mlpenc.c
+++ b/libavcodec/mlpenc.c
@@ -86,6 +86,7 @@ typedef struct DecodingParams {
     uint16_t        blocksize;                  ///< number of PCM samples in current audio block
     uint8_t         quant_step_size[MAX_CHANNELS];  ///< left shift to apply to Huffman-decoded residuals
     int8_t          output_shift[MAX_CHANNELS]; ///< Left shift to apply to decoded PCM values to get final 24-bit output.
+    uint8_t         max_order[MAX_CHANNELS];
 
     MatrixParams    matrix_params;
 
@@ -126,6 +127,7 @@ typedef struct MLPSubstream {
     MLPBlock        b[MAX_HEADER_INTERVAL + 1];
     unsigned int    major_cur_subblock_index;
     unsigned int    major_filter_state_subblock;
+    int32_t         coefs[MAX_CHANNELS][MAX_LPC_ORDER][MAX_LPC_ORDER];
 } MLPSubstream;
 
 typedef struct MLPEncodeContext {
@@ -411,6 +413,7 @@ static void clear_decoding_params(DecodingParams *decoding_params)
     memset(dp->quant_step_size, 0, sizeof(dp->quant_step_size));
     memset(dp->sample_buffer,   0, sizeof(dp->sample_buffer  ));
     memset(dp->output_shift,    0, sizeof(dp->output_shift   ));
+    memset(dp->max_order, MAX_FIR_ORDER, sizeof(dp->max_order));
 }
 
 /** Clears a ChannelParams struct the way it should be after a restart header. */
@@ -1348,16 +1351,18 @@ static void code_filter_coeffs(MLPEncodeContext *ctx, FilterParams *fp, const in
  *  necessary information to the context.
  */
 static void set_filter(MLPEncodeContext *ctx, MLPSubstream *s,
-                       int channel, int clear_filter)
+                       int channel, int retry_filter)
 {
     ChannelParams *cp = &s->b[1].channel_params[channel];
+    DecodingParams *dp1 = &s->b[1].decoding_params;
     FilterParams *fp = &cp->filter_params[FIR];
 
-    if (clear_filter) {
+    if (retry_filter)
+        dp1->max_order[channel]--;
+
+    if (dp1->max_order[channel] == 0) {
         fp->order = 0;
     } else {
-        const int max_order = MAX_FIR_ORDER;
-        int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
         int32_t *lpc_samples = ctx->lpc_sample_buffer;
         int32_t *fcoeff = cp->coeff[FIR];
         int shift[MAX_LPC_ORDER];
@@ -1374,9 +1379,9 @@ static void set_filter(MLPEncodeContext *ctx, MLPSubstream *s,
 
         order = ff_lpc_calc_coefs(&ctx->lpc_ctx, ctx->lpc_sample_buffer,
                                   lpc_samples - ctx->lpc_sample_buffer,
-                                  MLP_MIN_LPC_ORDER, max_order,
+                                  MLP_MIN_LPC_ORDER, dp1->max_order[channel],
                                   ctx->lpc_coeff_precision,
-                                  coefs, shift, ctx->lpc_type, ctx->lpc_passes,
+                                  s->coefs[channel], shift, ctx->lpc_type, ctx->lpc_passes,
                                   ctx->prediction_order, MLP_MIN_LPC_SHIFT,
                                   MLP_MAX_LPC_SHIFT, 0);
 
@@ -1384,7 +1389,7 @@ static void set_filter(MLPEncodeContext *ctx, MLPSubstream *s,
         fp->shift = order ? shift[order-1] : 0;
 
         for (unsigned int i = 0; i < order; i++)
-            fcoeff[i] = coefs[order-1][i];
+            fcoeff[i] = s->coefs[channel][order-1][i];
 
         code_filter_coeffs(ctx, fp, fcoeff);
     }
@@ -1839,11 +1844,9 @@ static void apply_filters(MLPEncodeContext *ctx, MLPSubstream *s)
     RestartHeader *rh = s->cur_restart_header;
 
     for (int ch = rh->min_channel; ch <= rh->max_channel; ch++) {
-        if (apply_filter(ctx, s, ch) < 0) {
-            /* Filter is horribly wrong.
-             * Clear filter parameters and update state. */
+        while (apply_filter(ctx, s, ch) < 0) {
+            /* Filter is horribly wrong. Retry. */
             set_filter(ctx, s, ch, 1);
-            apply_filter(ctx, s, ch);
         }
     }
 }



More information about the ffmpeg-cvslog mailing list