summaryrefslogtreecommitdiff
path: root/libavcodec/flacenc.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2015-05-20 01:23:39 +0200
committerMichael Niedermayer <michaelni@gmx.at>2015-05-20 01:35:29 +0200
commitb8e7f2b277b8c2ae2705ff10d6bafb696655e745 (patch)
tree0adc840565efc34f3b3dc97822df3cc2c274785c /libavcodec/flacenc.c
parent215410860f332d335fdf962762175a485777c1a7 (diff)
downloadffmpeg-b8e7f2b277b8c2ae2705ff10d6bafb696655e745.tar.gz
avcodec/flacenc: Support Multi dimensional quantization
Now with exact bit computations if exact_rice_parameters is enabled Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/flacenc.c')
-rw-r--r--libavcodec/flacenc.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index 79f821d7a0..935d55f32d 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -63,6 +63,7 @@ typedef struct CompressionOptions {
int max_partition_order;
int ch_mode;
int exact_rice_parameters;
+ int multi_dim_quant;
} CompressionOptions;
typedef struct RiceContext {
@@ -932,6 +933,49 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch)
opt_order++;
}
+ if (s->options.multi_dim_quant) {
+ int allsteps = 1;
+ int i, step, improved;
+ int64_t best_score = INT64_MAX;
+ int32_t qmax;
+
+ qmax = (1 << (s->options.lpc_coeff_precision - 1)) - 1;
+
+ for (i=0; i<opt_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;
+ int diffsum = 0;
+
+ for (i=0; i<opt_order; i++) {
+ int diff = ((tmp + 1) % 3) - 1;
+ lpc_try[i] = av_clip(coefs[opt_order - 1][i] + diff, -qmax, qmax);
+ tmp /= 3;
+ diffsum += !!diff;
+ }
+ if (diffsum >8)
+ continue;
+
+ if (s->bps_code * 4 + s->options.lpc_coeff_precision + av_log2(opt_order - 1) <= 32) {
+ s->flac_dsp.lpc16_encode(res, smp, n, opt_order, lpc_try, shift[opt_order-1]);
+ } else {
+ s->flac_dsp.lpc32_encode(res, smp, n, opt_order, lpc_try, shift[opt_order-1]);
+ }
+ score = find_subframe_rice_params(s, sub, opt_order);
+ if (score < best_score) {
+ best_score = score;
+ memcpy(coefs[opt_order-1], lpc_try, sizeof(coefs[opt_order-1]));
+ improved=1;
+ }
+ }
+ } while(improved);
+ }
+
sub->order = opt_order;
sub->type_code = sub->type | (sub->order-1);
sub->shift = shift[sub->order-1];
@@ -1411,6 +1455,7 @@ static const AVOption options[] = {
{ "right_side", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_RIGHT_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
{ "mid_side", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_MID_SIDE }, INT_MIN, INT_MAX, FLAGS, "ch_mode" },
{ "exact_rice_parameters", "Calculate rice parameters exactly", offsetof(FlacEncodeContext, options.exact_rice_parameters), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
+{ "multi_dim_quant", "Multi-dimensional quantization", offsetof(FlacEncodeContext, options.multi_dim_quant), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
{ NULL },
};