Commit b4948943 authored by Mickaël Raulet's avatar Mickaël Raulet Committed by Michael Niedermayer

hevc: optimize residual coding(cherry picked from commit 70692a44708157b4dfa50e402e446bfa2b27f55e)

Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 3ed65d98
This diff is collapsed.
......@@ -653,10 +653,6 @@ typedef struct TransformUnit {
int cur_intra_pred_mode;
} TransformUnit;
typedef struct ResidualCoding {
uint8_t significant_coeff_group_flag[8][8];
} ResidualCoding;
typedef struct SAOParams {
uint8_t type_idx[3]; ///< sao_type_idx
......@@ -726,16 +722,10 @@ typedef struct HEVCNAL {
typedef struct HEVCLocalContext {
uint8_t cabac_state[HEVC_CONTEXTS];
int ctx_set;
int greater1_ctx;
int last_coeff_abs_level_greater1_flag;
int c_rice_param;
int last_coeff_abs_level_remaining;
GetBitContext gb;
CABACContext cc;
TransformTree tt;
TransformUnit tu;
ResidualCoding rc;
uint8_t first_qp_group;
int8_t qp_y;
int8_t curr_qp_y;
......@@ -935,17 +925,12 @@ int ff_hevc_last_significant_coeff_y_prefix_decode(HEVCContext *s, int c_idx,
int log2_size);
int ff_hevc_last_significant_coeff_suffix_decode(HEVCContext *s,
int last_significant_coeff_prefix);
int ff_hevc_significant_coeff_group_flag_decode(HEVCContext *s, int c_idx, int x_cg,
int y_cg, int log2_trafo_size);
int ff_hevc_significant_coeff_group_flag_decode(HEVCContext *s, int c_idx, int ctx_cg);
int ff_hevc_significant_coeff_flag_decode(HEVCContext *s, int c_idx, int x_c, int y_c,
int log2_trafo_size, int scan_idx);
int ff_hevc_coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx,
int i, int n,
int first_greater1_coeff_idx,
int first_subset);
int ff_hevc_coeff_abs_level_greater2_flag_decode(HEVCContext *s, int c_idx,
int i, int n);
int ff_hevc_coeff_abs_level_remaining(HEVCContext *s, int n, int base_level);
int log2_trafo_size, int scan_idx, int prev_sig);
int ff_hevc_coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx, int ctx_set);
int ff_hevc_coeff_abs_level_greater2_flag_decode(HEVCContext *s, int c_idx, int inc);
int ff_hevc_coeff_abs_level_remaining(HEVCContext *s, int base_level, int rc_rice_param);
int ff_hevc_coeff_sign_flag(HEVCContext *s, uint8_t nb);
/**
......
......@@ -764,24 +764,17 @@ int ff_hevc_last_significant_coeff_suffix_decode(HEVCContext *s,
return value;
}
int ff_hevc_significant_coeff_group_flag_decode(HEVCContext *s, int c_idx, int x_cg,
int y_cg, int log2_trafo_size)
int ff_hevc_significant_coeff_group_flag_decode(HEVCContext *s, int c_idx, int ctx_cg)
{
int ctx_cg = 0;
int inc;
if (x_cg < (1 << (log2_trafo_size - 2)) - 1)
ctx_cg += s->HEVClc.rc.significant_coeff_group_flag[x_cg + 1][y_cg];
if (y_cg < (1 << (log2_trafo_size - 2)) - 1)
ctx_cg += s->HEVClc.rc.significant_coeff_group_flag[x_cg][y_cg + 1];
inc = FFMIN(ctx_cg, 1) + (c_idx>0 ? 2 : 0);
return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_GROUP_FLAG] + inc);
}
int ff_hevc_significant_coeff_flag_decode(HEVCContext *s, int c_idx, int x_c, int y_c,
int log2_trafo_size, int scan_idx)
int log2_trafo_size, int scan_idx, int prev_sig)
{
static const uint8_t ctx_idx_map[] = {
0, 1, 4, 5, 2, 3, 4, 5, 6, 6, 8, 8, 7, 7, 8, 8
......@@ -796,13 +789,6 @@ int ff_hevc_significant_coeff_flag_decode(HEVCContext *s, int c_idx, int x_c, in
} else if (log2_trafo_size == 2) {
sig_ctx = ctx_idx_map[(y_c << 2) + x_c];
} else {
int prev_sig = 0;
if (x_cg < ((1 << log2_trafo_size) - 1) >> 2)
prev_sig += s->HEVClc.rc.significant_coeff_group_flag[x_cg + 1][y_cg];
if (y_cg < ((1 << log2_trafo_size) - 1) >> 2)
prev_sig += (s->HEVClc.rc.significant_coeff_group_flag[x_cg][y_cg + 1] << 1);
switch (prev_sig) {
case 0: {
int x_off = x_c & 3;
......@@ -839,82 +825,46 @@ int ff_hevc_significant_coeff_flag_decode(HEVCContext *s, int c_idx, int x_c, in
return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_FLAG] + inc);
}
int ff_hevc_coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx,
int i, int n,
int first_elem,
int first_subset)
int ff_hevc_coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx, int inc)
{
int inc;
if (first_elem) {
s->HEVClc.ctx_set = (i > 0 && c_idx == 0) ? 2 : 0;
if (!first_subset && s->HEVClc.greater1_ctx == 0)
s->HEVClc.ctx_set++;
s->HEVClc.greater1_ctx = 1;
}
inc = (s->HEVClc.ctx_set << 2) + s->HEVClc.greater1_ctx;
if (c_idx > 0)
inc += 16;
s->HEVClc.last_coeff_abs_level_greater1_flag =
GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER1_FLAG] + inc);
if (s->HEVClc.last_coeff_abs_level_greater1_flag) {
s->HEVClc.greater1_ctx = 0;
} else if (s->HEVClc.greater1_ctx > 0 && s->HEVClc.greater1_ctx < 3) {
s->HEVClc.greater1_ctx++;
}
return s->HEVClc.last_coeff_abs_level_greater1_flag;
return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER1_FLAG] + inc);
}
int ff_hevc_coeff_abs_level_greater2_flag_decode(HEVCContext *s, int c_idx,
int i, int n)
int ff_hevc_coeff_abs_level_greater2_flag_decode(HEVCContext *s, int c_idx, int inc)
{
int inc;
inc = s->HEVClc.ctx_set;
if (c_idx > 0)
inc += 4;
return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER2_FLAG] + inc);
}
int ff_hevc_coeff_abs_level_remaining(HEVCContext *s, int first_elem, int base_level)
int ff_hevc_coeff_abs_level_remaining(HEVCContext *s, int base_level, int rc_rice_param)
{
int i;
HEVCLocalContext *lc = &s->HEVClc;
int prefix = 0;
int suffix = 0;
if (first_elem) {
lc->c_rice_param = 0;
lc->last_coeff_abs_level_remaining = 0;
}
int last_coeff_abs_level_remaining;
int i;
while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc))
prefix++;
if (prefix == CABAC_MAX_BIN)
av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix);
if (prefix < 3) {
for (i = 0; i < lc->c_rice_param; i++)
for (i = 0; i < rc_rice_param; i++)
suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc.cc);
lc->last_coeff_abs_level_remaining = (prefix << lc->c_rice_param) + suffix;
last_coeff_abs_level_remaining = (prefix << rc_rice_param) + suffix;
} else {
for (i = 0; i < prefix - 3 + lc->c_rice_param; i++)
int prefix_minus3 = prefix - 3;
for (i = 0; i < prefix_minus3 + rc_rice_param; i++)
suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc.cc);
lc->last_coeff_abs_level_remaining = (((1 << (prefix - 3)) + 3 - 1)
<< lc->c_rice_param) + suffix;
last_coeff_abs_level_remaining = (((1 << prefix_minus3) + 3 - 1)
<< rc_rice_param) + suffix;
}
lc->c_rice_param = FFMIN(lc->c_rice_param +
((base_level + lc->last_coeff_abs_level_remaining) >
(3 * (1 << lc->c_rice_param))), 4);
return lc->last_coeff_abs_level_remaining;
return last_coeff_abs_level_remaining;
}
int ff_hevc_coeff_sign_flag(HEVCContext *s, uint8_t nb)
......
......@@ -182,7 +182,7 @@ static void copy_CTB(uint8_t *dst, uint8_t *src, int width, int height, int stri
#define CTB(tab, x, y) ((tab)[(y) * s->sps->ctb_width + (x)])
static void sao_filter_CTB(HEVCContext *s, int x, int y, int c_idx_min, int c_idx_max)
static void sao_filter_CTB(HEVCContext *s, int x, int y)
{
// TODO: This should be easily parallelizable
// TODO: skip CBs when (cu_transquant_bypass_flag || (pcm_loop_filter_disable_flag && pcm_flag))
......@@ -283,8 +283,8 @@ static void sao_filter_CTB(HEVCContext *s, int x, int y, int c_idx_min, int c_id
(edges[2] ? width + (x_shift >> chroma) : width) << s->sps->pixel_shift,
(edges[3] ? height + (y_shift >> chroma) : height), stride);
for (class_index = 0; class_index < class && c_idx >= c_idx_min &&
c_idx < c_idx_max; class_index++) {
for (class_index = 0; class_index < class; class_index++) {
switch (sao[class_index]->type_idx[c_idx]) {
case SAO_BAND:
s->hevcdsp.sao_band_filter[classes[class_index]](dst, src, stride, sao[class_index], edges, width, height, c_idx);
......@@ -334,11 +334,8 @@ static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)
int pcmf = (s->sps->pcm_enabled_flag && s->sps->pcm.loop_filter_disable_flag) ||
s->pps->transquant_bypass_enable_flag;
if (s->deblock[ctb].disable)
return;
if (x0) {
left_tc_offset = s->deblock[ctb-1].tc_offset;
if(x0) {
left_tc_offset = s->deblock[ctb-1].tc_offset;
left_beta_offset = s->deblock[ctb-1].beta_offset;
}
......@@ -649,7 +646,7 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0, int l
}
// bs for TU internal vertical PU boundaries
if (log2_trafo_size > s->sps->log2_min_pu_size && !is_intra)
if (log2_trafo_size > log2_min_pu_size && !is_intra)
for (j = 0; j < (1 << log2_trafo_size); j += 4) {
int y_pu = (y0 + j) >> log2_min_pu_size;
int y_tu = (y0 + j) >> log2_min_tu_size;
......@@ -665,7 +662,6 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0, int l
uint8_t curr_cbf_luma = s->cbf_luma[y_tu * pic_width_in_min_tu + xq_tu];
RefPicList* left_refPicList = ff_hevc_get_ref_list(s, s->ref, x0 + i - 1, y0 + j);
bs = boundary_strength(s, curr, curr_cbf_luma, left, left_cbf_luma, left_refPicList, 0);
if (s->sh.disable_deblocking_filter_flag == 1)
bs = 0;
......@@ -680,11 +676,9 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0, int l
void ff_hevc_hls_filter(HEVCContext *s, int x, int y)
{
int c_idx_min = s->sh.slice_sample_adaptive_offset_flag[0] != 0 ? 0 : 1;
int c_idx_max = s->sh.slice_sample_adaptive_offset_flag[1] != 0 ? 3 : 1;
deblocking_filter_CTB(s, x, y);
if (s->sps->sao_enabled)
sao_filter_CTB(s, x, y, c_idx_min, c_idx_max);
sao_filter_CTB(s, x, y);
}
void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size)
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment