summaryrefslogtreecommitdiff
path: root/libavcodec/flacenc.c
diff options
context:
space:
mode:
authorLoren Merritt <lorenm@u.washington.edu>2007-09-29 05:41:27 +0000
committerLoren Merritt <lorenm@u.washington.edu>2007-09-29 05:41:27 +0000
commit14bd2a9f25fc0de4fb1a2d4afaef09162c51bb35 (patch)
tree83c7e0dc6971c767b00d046fd43a733d39c98ef9 /libavcodec/flacenc.c
parentf6215b1b069680a782ca28058b3ec6d9bb4a45e1 (diff)
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
Diffstat (limited to 'libavcodec/flacenc.c')
-rw-r--r--libavcodec/flacenc.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index e997bca129..3b01a3ba1a 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,