[FFmpeg-devel] [PATCH] avcodec/flacdec: Add lpc16m instead of using lpc32 + post analysis and correction

Michael Niedermayer michaelni at gmx.at
Sun May 17 17:03:14 CEST 2015


This is slower on x86 as the lpc16* functions are not optimized while lpc32 is
If someone wants to optimize lpc16m and it would actually be faster then this
could be applied and used until then the current solution in git is better as
its faster

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavcodec/flacdec.c |   31 ++-----------------------------
 libavcodec/flacdsp.c |   29 +++++++++++++++++++++++++++++
 libavcodec/flacdsp.h |    2 ++
 3 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 30fe416..05a7ec8 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -315,33 +315,6 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
     return 0;
 }
 
-static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32],
-                                   int order, int qlevel, int len, int bps)
-{
-    int i, j;
-    int ebps = 1 << (bps-1);
-    unsigned sigma = 0;
-
-    for (i = order; i < len; i++)
-        sigma |= decoded[i] + ebps;
-
-    if (sigma < 2*ebps)
-        return;
-
-    for (i = len - 1; i >= order; i--) {
-        int64_t p = 0;
-        for (j = 0; j < order; j++)
-            p += coeffs[j] * (int64_t)decoded[i-order+j];
-        decoded[i] -= p >> qlevel;
-    }
-    for (i = order; i < len; i++, decoded++) {
-        int32_t p = 0;
-        for (j = 0; j < order; j++)
-            p += coeffs[j] * (uint32_t)decoded[j];
-        decoded[j] += p >> qlevel;
-    }
-}
-
 static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
                                int bps)
 {
@@ -377,10 +350,10 @@ static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
         || (   !s->buggy_lpc && bps <= 16
             && bps + coeff_prec + av_log2(pred_order) <= 32)) {
         s->dsp.lpc16(decoded, coeffs, pred_order, qlevel, s->blocksize);
+    } else if (bps + coeff_prec <= 32) {
+        s->dsp.lpc16m(decoded, coeffs, pred_order, qlevel, s->blocksize, bps);
     } else {
         s->dsp.lpc32(decoded, coeffs, pred_order, qlevel, s->blocksize);
-        if (s->flac_stream_info.bps <= 16)
-            lpc_analyze_remodulate(decoded, coeffs, pred_order, qlevel, s->blocksize, bps);
     }
 
     return 0;
diff --git a/libavcodec/flacdsp.c b/libavcodec/flacdsp.c
index 30b6648..a171948 100644
--- a/libavcodec/flacdsp.c
+++ b/libavcodec/flacdsp.c
@@ -43,6 +43,34 @@
 #define PLANAR 1
 #include "flacdsp_template.c"
 
+static void flac_lpc_16m_c(int32_t *decoded, const int coeffs[32],
+                           int pred_order, int qlevel, int len, int bps)
+{
+    int i, j;
+
+    for (i = pred_order; i < len - 1; i += 2, decoded += 2) {
+        int c = coeffs[0];
+        int d = decoded[0];
+        int s0 = 0, s1 = 0;
+        for (j = 1; j < pred_order; j++) {
+            s0 += c*d;
+            d = decoded[j];
+            s1 += c*d;
+            c = coeffs[j];
+        }
+        s0 += c*d;
+        d = decoded[j] = sign_extend(decoded[j    ] + (s0 >> qlevel), bps);
+        s1 += c*d;
+        decoded[j + 1] = sign_extend(decoded[j + 1] + (s1 >> qlevel), bps);
+    }
+    if (i < len) {
+        int sum = 0;
+        for (j = 0; j < pred_order; j++)
+            sum += coeffs[j] * decoded[j];
+        decoded[j] = sign_extend(decoded[j] + (sum >> qlevel), bps);
+    }
+}
+
 static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32],
                           int pred_order, int qlevel, int len)
 {
@@ -89,6 +117,7 @@ av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int cha
                              int bps)
 {
     c->lpc16        = flac_lpc_16_c;
+    c->lpc16m       = flac_lpc_16m_c;
     c->lpc32        = flac_lpc_32_c;
     c->lpc16_encode = flac_lpc_encode_c_16;
     c->lpc32_encode = flac_lpc_encode_c_32;
diff --git a/libavcodec/flacdsp.h b/libavcodec/flacdsp.h
index f5cbd94..52c79c9 100644
--- a/libavcodec/flacdsp.h
+++ b/libavcodec/flacdsp.h
@@ -27,6 +27,8 @@ typedef struct FLACDSPContext {
                            int len, int shift);
     void (*lpc16)(int32_t *samples, const int coeffs[32], int order,
                   int qlevel, int len);
+    void (*lpc16m)(int32_t *samples, const int coeffs[32], int order,
+                   int qlevel, int len, int bps);
     void (*lpc32)(int32_t *samples, const int coeffs[32], int order,
                   int qlevel, int len);
     void (*lpc16_encode)(int32_t *res, const int32_t *smp, int len, int order,
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list