[FFmpeg-devel] [PATCH] [WIP] avcodec/lpc: quantize LPC coefficients by multidimensional search instead of independant scalar quantization

Michael Niedermayer michaelni at gmx.at
Mon May 18 13:53:24 CEST 2015


This improves compression but only by a very small bit
possibly it could be improved by exactly calculating the number of bits that would be needed

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 libavcodec/lpc.c |   49 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index deb02e7..930e526 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -135,6 +135,51 @@ static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
     *shift = sh;
 }
 
+static void quantize_lpc_coefs2(double *lpc_in, int order, int precision,
+                               int32_t *lpc_out, int *shift, int max_shift,
+                               int zero_shift, const int32_t *samples, int len)
+{
+    int allsteps = 1;
+    int i, j, step, improved;
+    int64_t best_score = INT64_MAX;
+    int32_t qmax;
+
+    qmax = (1 << (precision - 1)) - 1;
+
+    quantize_lpc_coefs(lpc_in, order, precision, lpc_out, shift, max_shift, zero_shift);
+
+    for (i=0; i<order; i++)
+        allsteps *= 3;
+
+    do {
+        improved = 0;
+        for (step = 0; step < allsteps; step++) {
+            int tmp = step;
+            int32_t lpc_try[MAX_LPC_ORDER];
+            int64_t score = 0;
+            for (i=0; i<order; i++) {
+                lpc_try[i] = av_clip(lpc_out[i] + ((tmp + 1) % 3) - 1, -qmax, qmax);
+                tmp /= 3;
+            }
+            for (j=order; j<len; j++) {
+                int64_t v = 0;
+                for (i=0; i<order; i++) {
+                    v += samples[j - 1 - i] * (int64_t)lpc_try[i];
+                }
+                v >>= *shift;
+                v -= samples[j];
+                score += FFABS(v);
+            }
+            if (score < best_score) {
+                best_score = score;
+                memcpy(lpc_out, lpc_try, sizeof(*lpc_out) * order);
+//                 improved=1;
+            }
+//             av_log(0,0, "score %Ld\n", best_score);
+        }
+    } while(improved);
+}
+
 static int estimate_best_order(double *ref, int min_order, int max_order)
 {
     int i, est;
@@ -255,10 +300,10 @@ int ff_lpc_calc_coefs(LPCContext *s,
     if(omethod == ORDER_METHOD_EST) {
         opt_order = estimate_best_order(ref, min_order, max_order);
         i = opt_order-1;
-        quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
+        quantize_lpc_coefs2(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift, samples, blocksize);
     } else {
         for(i=min_order-1; i<max_order; i++) {
-            quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
+            quantize_lpc_coefs2(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift, samples, blocksize);
         }
     }
 
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list