diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2012-10-27 00:46:43 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2012-11-05 15:32:30 -0500 |
commit | 2e76f34387762405b79d2f7f26659826089c7275 (patch) | |
tree | 5e4b4a7b4a94c551874fd7f2127a04357c22932a /libavcodec/flacenc.c | |
parent | 13e1ee6c84f095b052026b18611ce68c76666474 (diff) | |
download | ffmpeg-2e76f34387762405b79d2f7f26659826089c7275.tar.gz |
flacenc: use RICE2 entropy coding mode for 24-bit
Diffstat (limited to 'libavcodec/flacenc.c')
-rw-r--r-- | libavcodec/flacenc.c | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index b00df9580b..93d4646604 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -43,7 +43,11 @@ #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER) #define MAX_LPC_PRECISION 15 #define MAX_LPC_SHIFT 15 -#define MAX_RICE_PARAM 14 + +enum CodingMode { + CODING_MODE_RICE = 4, + CODING_MODE_RICE2 = 5, +}; typedef struct CompressionOptions { int compression_level; @@ -60,6 +64,7 @@ typedef struct CompressionOptions { } CompressionOptions; typedef struct RiceContext { + enum CodingMode coding_mode; int porder; int params[MAX_PARTITIONS]; } RiceContext; @@ -435,8 +440,15 @@ static void init_frame(FlacEncodeContext *s, int nb_samples) } for (ch = 0; ch < s->channels; ch++) { - frame->subframes[ch].wasted = 0; - frame->subframes[ch].obits = s->avctx->bits_per_raw_sample; + FlacSubframe *sub = &frame->subframes[ch]; + + sub->wasted = 0; + sub->obits = s->avctx->bits_per_raw_sample; + + if (sub->obits > 16) + sub->rc.coding_mode = CODING_MODE_RICE2; + else + sub->rc.coding_mode = CODING_MODE_RICE; } frame->verbatim_only = 0; @@ -518,7 +530,7 @@ static uint64_t subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub, part_end = psize; for (p = 0; p < 1 << porder; p++) { int k = sub->rc.params[p]; - count += 4; + count += sub->rc.coding_mode; count += rice_count_exact(&sub->residual[i], part_end - i, k); i = part_end; part_end = FFMIN(s->frame.blocksize, part_end + psize); @@ -534,7 +546,7 @@ static uint64_t subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub, /** * Solve for d/dk(rice_encode_count) = n-((sum-(n>>1))>>(k+1)) = 0. */ -static int find_optimal_param(uint64_t sum, int n) +static int find_optimal_param(uint64_t sum, int n, int max_param) { int k; uint64_t sum2; @@ -543,7 +555,7 @@ static int find_optimal_param(uint64_t sum, int n) return 0; sum2 = sum - (n >> 1); k = av_log2(av_clipl_int32(sum2 / n)); - return FFMIN(k, MAX_RICE_PARAM); + return FFMIN(k, max_param); } @@ -551,15 +563,17 @@ static uint64_t calc_optimal_rice_params(RiceContext *rc, int porder, uint64_t *sums, int n, int pred_order) { int i; - int k, cnt, part; + int k, cnt, part, max_param; uint64_t all_bits; + max_param = (1 << rc->coding_mode) - 2; + part = (1 << porder); all_bits = 4 * part; cnt = (n >> porder) - pred_order; for (i = 0; i < part; i++) { - k = find_optimal_param(sums[i], cnt); + k = find_optimal_param(sums[i], cnt, max_param); rc->params[i] = k; all_bits += rice_encode_count(sums[i], cnt, k); cnt = n >> porder; @@ -612,6 +626,8 @@ static uint64_t calc_rice_params(RiceContext *rc, int pmin, int pmax, assert(pmax >= 0 && pmax <= MAX_PARTITION_ORDER); assert(pmin <= pmax); + tmp_rc.coding_mode = rc->coding_mode; + udata = av_malloc(n * sizeof(uint32_t)); for (i = 0; i < n; i++) udata[i] = (2*data[i]) ^ (data[i]>>31); @@ -650,7 +666,7 @@ static uint64_t find_subframe_rice_params(FlacEncodeContext *s, int pmax = get_max_p_order(s->options.max_partition_order, s->frame.blocksize, pred_order); - uint64_t bits = 8 + pred_order * sub->obits + 2 + 4; + uint64_t bits = 8 + pred_order * sub->obits + 2 + sub->rc.coding_mode; if (sub->type == FLAC_SUBFRAME_LPC) bits += 4 + 5 + pred_order * s->options.lpc_coeff_precision; bits += calc_rice_params(&sub->rc, pmin, pmax, sub->residual, @@ -925,12 +941,18 @@ static void remove_wasted_bits(FlacEncodeContext *s) sub->wasted = v; sub->obits -= v; + + /* for 24-bit, check if removing wasted bits makes the range better + suited for using RICE instead of RICE2 for entropy coding */ + if (sub->obits <= 17) + sub->rc.coding_mode = CODING_MODE_RICE; } } } -static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) +static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n, + int max_rice_param) { int i, best; int32_t lt, rt; @@ -950,7 +972,7 @@ static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) } /* estimate bit counts */ for (i = 0; i < 4; i++) { - k = find_optimal_param(2 * sum[i], n); + k = find_optimal_param(2 * sum[i], n, max_rice_param); sum[i] = rice_encode_count( 2 * sum[i], n, k); } @@ -989,9 +1011,10 @@ static void channel_decorrelation(FlacEncodeContext *s) return; } - if (s->options.ch_mode < 0) - frame->ch_mode = estimate_stereo_mode(left, right, n); - else + if (s->options.ch_mode < 0) { + int max_rice_param = (1 << frame->subframes[0].rc.coding_mode) - 2; + frame->ch_mode = estimate_stereo_mode(left, right, n, max_rice_param); + } else frame->ch_mode = s->options.ch_mode; /* perform decorrelation and adjust bits-per-sample */ @@ -1100,7 +1123,7 @@ static void write_subframes(FlacEncodeContext *s) } /* rice-encoded block */ - put_bits(&s->pb, 2, 0); + put_bits(&s->pb, 2, sub->rc.coding_mode - 4); /* partition order */ porder = sub->rc.porder; @@ -1111,7 +1134,7 @@ static void write_subframes(FlacEncodeContext *s) part_end = &sub->residual[psize]; for (p = 0; p < 1 << porder; p++) { int k = sub->rc.params[p]; - put_bits(&s->pb, 4, k); + put_bits(&s->pb, sub->rc.coding_mode, k); while (res < part_end) set_sr_golomb_flac(&s->pb, *res++, k, INT32_MAX, 0); part_end = FFMIN(frame_end, part_end + psize); |