From 14bd2a9f25fc0de4fb1a2d4afaef09162c51bb35 Mon Sep 17 00:00:00 2001
From: Loren Merritt <lorenm@u.washington.edu>
Date: Sat, 29 Sep 2007 05:41:27 +0000
Subject: [PATCH] replace brute force find_optimal_param() with a closed-form
 solution. overall flac encoding: 4-15% faster. output is not identical to the
 previous algorithm due to occasional rounding errors, but the differece is
 less than .0005% bitrate.

Originally committed as revision 10612 to svn://svn.ffmpeg.org/ffmpeg/trunk
---
 libavcodec/flacenc.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index e997bca129e..3b01a3ba1a3 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -447,20 +447,19 @@ static void copy_samples(FlacEncodeContext *s, int16_t *samples)
 
 #define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k)))
 
+/**
+ * Solve for d/dk(rice_encode_count) = n-((sum-(n>>1))>>(k+1)) = 0
+ */
 static int find_optimal_param(uint32_t sum, int n)
 {
-    int k, k_opt;
-    uint32_t nbits[MAX_RICE_PARAM+1];
-
-    k_opt = 0;
-    nbits[0] = UINT32_MAX;
-    for(k=0; k<=MAX_RICE_PARAM; k++) {
-        nbits[k] = rice_encode_count(sum, n, k);
-        if(nbits[k] < nbits[k_opt]) {
-            k_opt = k;
-        }
-    }
-    return k_opt;
+    int k;
+    uint32_t sum2;
+
+    if(sum <= n>>1)
+        return 0;
+    sum2 = sum-(n>>1);
+    k = av_log2(n<256 ? FASTDIV(sum2,n) : sum2/n);
+    return FFMIN(k, MAX_RICE_PARAM);
 }
 
 static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder,
-- 
GitLab