mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
flacenc: use RICE2 entropy coding mode for 24-bit
This commit is contained in:
parent
13e1ee6c84
commit
2e76f34387
@ -43,7 +43,11 @@
|
|||||||
#define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
|
#define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER)
|
||||||
#define MAX_LPC_PRECISION 15
|
#define MAX_LPC_PRECISION 15
|
||||||
#define MAX_LPC_SHIFT 15
|
#define MAX_LPC_SHIFT 15
|
||||||
#define MAX_RICE_PARAM 14
|
|
||||||
|
enum CodingMode {
|
||||||
|
CODING_MODE_RICE = 4,
|
||||||
|
CODING_MODE_RICE2 = 5,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct CompressionOptions {
|
typedef struct CompressionOptions {
|
||||||
int compression_level;
|
int compression_level;
|
||||||
@ -60,6 +64,7 @@ typedef struct CompressionOptions {
|
|||||||
} CompressionOptions;
|
} CompressionOptions;
|
||||||
|
|
||||||
typedef struct RiceContext {
|
typedef struct RiceContext {
|
||||||
|
enum CodingMode coding_mode;
|
||||||
int porder;
|
int porder;
|
||||||
int params[MAX_PARTITIONS];
|
int params[MAX_PARTITIONS];
|
||||||
} RiceContext;
|
} RiceContext;
|
||||||
@ -435,8 +440,15 @@ static void init_frame(FlacEncodeContext *s, int nb_samples)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (ch = 0; ch < s->channels; ch++) {
|
for (ch = 0; ch < s->channels; ch++) {
|
||||||
frame->subframes[ch].wasted = 0;
|
FlacSubframe *sub = &frame->subframes[ch];
|
||||||
frame->subframes[ch].obits = s->avctx->bits_per_raw_sample;
|
|
||||||
|
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;
|
frame->verbatim_only = 0;
|
||||||
@ -518,7 +530,7 @@ static uint64_t subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub,
|
|||||||
part_end = psize;
|
part_end = psize;
|
||||||
for (p = 0; p < 1 << porder; p++) {
|
for (p = 0; p < 1 << porder; p++) {
|
||||||
int k = sub->rc.params[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);
|
count += rice_count_exact(&sub->residual[i], part_end - i, k);
|
||||||
i = part_end;
|
i = part_end;
|
||||||
part_end = FFMIN(s->frame.blocksize, part_end + psize);
|
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.
|
* 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;
|
int k;
|
||||||
uint64_t sum2;
|
uint64_t sum2;
|
||||||
@ -543,7 +555,7 @@ static int find_optimal_param(uint64_t sum, int n)
|
|||||||
return 0;
|
return 0;
|
||||||
sum2 = sum - (n >> 1);
|
sum2 = sum - (n >> 1);
|
||||||
k = av_log2(av_clipl_int32(sum2 / n));
|
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)
|
uint64_t *sums, int n, int pred_order)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int k, cnt, part;
|
int k, cnt, part, max_param;
|
||||||
uint64_t all_bits;
|
uint64_t all_bits;
|
||||||
|
|
||||||
|
max_param = (1 << rc->coding_mode) - 2;
|
||||||
|
|
||||||
part = (1 << porder);
|
part = (1 << porder);
|
||||||
all_bits = 4 * part;
|
all_bits = 4 * part;
|
||||||
|
|
||||||
cnt = (n >> porder) - pred_order;
|
cnt = (n >> porder) - pred_order;
|
||||||
for (i = 0; i < part; i++) {
|
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;
|
rc->params[i] = k;
|
||||||
all_bits += rice_encode_count(sums[i], cnt, k);
|
all_bits += rice_encode_count(sums[i], cnt, k);
|
||||||
cnt = n >> porder;
|
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(pmax >= 0 && pmax <= MAX_PARTITION_ORDER);
|
||||||
assert(pmin <= pmax);
|
assert(pmin <= pmax);
|
||||||
|
|
||||||
|
tmp_rc.coding_mode = rc->coding_mode;
|
||||||
|
|
||||||
udata = av_malloc(n * sizeof(uint32_t));
|
udata = av_malloc(n * sizeof(uint32_t));
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
udata[i] = (2*data[i]) ^ (data[i]>>31);
|
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,
|
int pmax = get_max_p_order(s->options.max_partition_order,
|
||||||
s->frame.blocksize, pred_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)
|
if (sub->type == FLAC_SUBFRAME_LPC)
|
||||||
bits += 4 + 5 + pred_order * s->options.lpc_coeff_precision;
|
bits += 4 + 5 + pred_order * s->options.lpc_coeff_precision;
|
||||||
bits += calc_rice_params(&sub->rc, pmin, pmax, sub->residual,
|
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->wasted = v;
|
||||||
sub->obits -= 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;
|
int i, best;
|
||||||
int32_t lt, rt;
|
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 */
|
/* estimate bit counts */
|
||||||
for (i = 0; i < 4; i++) {
|
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);
|
sum[i] = rice_encode_count( 2 * sum[i], n, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,9 +1011,10 @@ static void channel_decorrelation(FlacEncodeContext *s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->options.ch_mode < 0)
|
if (s->options.ch_mode < 0) {
|
||||||
frame->ch_mode = estimate_stereo_mode(left, right, n);
|
int max_rice_param = (1 << frame->subframes[0].rc.coding_mode) - 2;
|
||||||
else
|
frame->ch_mode = estimate_stereo_mode(left, right, n, max_rice_param);
|
||||||
|
} else
|
||||||
frame->ch_mode = s->options.ch_mode;
|
frame->ch_mode = s->options.ch_mode;
|
||||||
|
|
||||||
/* perform decorrelation and adjust bits-per-sample */
|
/* perform decorrelation and adjust bits-per-sample */
|
||||||
@ -1100,7 +1123,7 @@ static void write_subframes(FlacEncodeContext *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* rice-encoded block */
|
/* rice-encoded block */
|
||||||
put_bits(&s->pb, 2, 0);
|
put_bits(&s->pb, 2, sub->rc.coding_mode - 4);
|
||||||
|
|
||||||
/* partition order */
|
/* partition order */
|
||||||
porder = sub->rc.porder;
|
porder = sub->rc.porder;
|
||||||
@ -1111,7 +1134,7 @@ static void write_subframes(FlacEncodeContext *s)
|
|||||||
part_end = &sub->residual[psize];
|
part_end = &sub->residual[psize];
|
||||||
for (p = 0; p < 1 << porder; p++) {
|
for (p = 0; p < 1 << porder; p++) {
|
||||||
int k = sub->rc.params[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)
|
while (res < part_end)
|
||||||
set_sr_golomb_flac(&s->pb, *res++, k, INT32_MAX, 0);
|
set_sr_golomb_flac(&s->pb, *res++, k, INT32_MAX, 0);
|
||||||
part_end = FFMIN(frame_end, part_end + psize);
|
part_end = FFMIN(frame_end, part_end + psize);
|
||||||
|
Loading…
Reference in New Issue
Block a user