diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 75bdb806505de96d063a0ba12a6e7d42aefcc3e5..17f72524e279e2207c84964c924a61bd9255fc22 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -628,6 +628,11 @@ static int hls_slice_header(HEVCContext *s) sh->slice_cr_qp_offset = 0; } + if (s->pps->chroma_qp_offset_list_enabled_flag) + sh->cu_chroma_qp_offset_enabled_flag = get_bits1(gb); + else + sh->cu_chroma_qp_offset_enabled_flag = 0; + if (s->pps->deblocking_filter_control_present_flag) { int deblocking_filter_override_flag = 0; @@ -738,6 +743,8 @@ static int hls_slice_header(HEVCContext *s) s->HEVClc->qp_y = s->sh.slice_qp; s->slice_initialized = 1; + s->HEVClc->tu.cu_qp_offset_cb = 0; + s->HEVClc->tu.cu_qp_offset_cr = 0; return 0; } @@ -830,6 +837,22 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry) #undef SET_SAO #undef CTB +static int hls_cross_component_pred(HEVCContext *s, int idx) { + HEVCLocalContext *lc = s->HEVClc; + int log2_res_scale_abs_plus1 = ff_hevc_log2_res_scale_abs(s, idx); + + if (log2_res_scale_abs_plus1 != 0) { + int res_scale_sign_flag = ff_hevc_res_scale_sign_flag(s, idx); + lc->tu.res_scale_val = (1 << (log2_res_scale_abs_plus1 - 1)) * + (1 - 2 * res_scale_sign_flag); + } else { + lc->tu.res_scale_val = 0; + } + + + return 0; +} + static int hls_transform_unit(HEVCContext *s, int x0, int y0, int xBase, int yBase, int cb_xBase, int cb_yBase, int log2_cb_size, int log2_trafo_size, @@ -882,6 +905,25 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, ff_hevc_set_qPy(s, x0, y0, cb_xBase, cb_yBase, log2_cb_size); } + if (s->sh.cu_chroma_qp_offset_enabled_flag && cbf_chroma && + !lc->cu.cu_transquant_bypass_flag && !lc->tu.is_cu_chroma_qp_offset_coded) { + int cu_chroma_qp_offset_flag = ff_hevc_cu_chroma_qp_offset_flag(s); + if (cu_chroma_qp_offset_flag) { + int cu_chroma_qp_offset_idx = 0; + if (s->pps->chroma_qp_offset_list_len_minus1 > 0) { + cu_chroma_qp_offset_idx = ff_hevc_cu_chroma_qp_offset_idx(s); + av_log(s->avctx, AV_LOG_ERROR, + "cu_chroma_qp_offset_idx not yet tested.\n"); + } + lc->tu.cu_qp_offset_cb = s->pps->cb_qp_offset_list[cu_chroma_qp_offset_idx]; + lc->tu.cu_qp_offset_cr = s->pps->cr_qp_offset_list[cu_chroma_qp_offset_idx]; + } else { + lc->tu.cu_qp_offset_cb = 0; + lc->tu.cu_qp_offset_cr = 0; + } + lc->tu.is_cu_chroma_qp_offset_coded = 1; + } + if (lc->cu.pred_mode == MODE_INTRA && log2_trafo_size < 4) { if (lc->tu.intra_pred_mode >= 6 && lc->tu.intra_pred_mode <= 14) { @@ -900,13 +942,20 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, } } + lc->tu.cross_pf = 0; if (cbf_luma) ff_hevc_hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0); if (log2_trafo_size > 2 || s->sps->chroma_format_idc == 3) { int trafo_size_h = 1 << (log2_trafo_size_c + s->sps->hshift[1]); int trafo_size_v = 1 << (log2_trafo_size_c + s->sps->vshift[1]); + lc->tu.cross_pf = (s->pps->cross_component_prediction_enabled_flag && cbf_luma && + (lc->cu.pred_mode == MODE_INTER || + (lc->tu.chroma_mode_c == 4))); + if (lc->tu.cross_pf) { + hls_cross_component_pred(s, 0); + } for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) { if (lc->cu.pred_mode == MODE_INTRA) { ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v); @@ -915,8 +964,27 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0 + (i << log2_trafo_size_c))) ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c), log2_trafo_size_c, scan_idx_c, 1); + else + if (lc->tu.cross_pf) { + ptrdiff_t stride = s->frame->linesize[1]; + int hshift = s->sps->hshift[1]; + int vshift = s->sps->vshift[1]; + int16_t *coeffs_y = lc->tu.coeffs[0]; + int16_t *coeffs = lc->tu.coeffs[1]; + int size = 1 << log2_trafo_size_c; + + uint8_t *dst = &s->frame->data[1][(y0 >> vshift) * stride + + ((x0 >> hshift) << s->sps->pixel_shift)]; + for (i = 0; i < (size * size); i++) { + coeffs[i] = ((lc->tu.res_scale_val * coeffs_y[i]) >> 3); + } + s->hevcdsp.transform_add[log2_trafo_size-2](dst, coeffs, stride); + } } + if (lc->tu.cross_pf) { + hls_cross_component_pred(s, 1); + } for (i = 0; i < (s->sps->chroma_format_idc == 2 ? 2 : 1); i++) { if (lc->cu.pred_mode == MODE_INTRA) { ff_hevc_set_neighbour_available(s, x0, y0 + (i << log2_trafo_size_c), trafo_size_h, trafo_size_v); @@ -925,6 +993,22 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0 + (i << log2_trafo_size_c))) ff_hevc_hls_residual_coding(s, x0, y0 + (i << log2_trafo_size_c), log2_trafo_size_c, scan_idx_c, 2); + else + if (lc->tu.cross_pf) { + ptrdiff_t stride = s->frame->linesize[2]; + int hshift = s->sps->hshift[2]; + int vshift = s->sps->vshift[2]; + int16_t *coeffs_y = lc->tu.coeffs[0]; + int16_t *coeffs = lc->tu.coeffs[1]; + int size = 1 << log2_trafo_size_c; + + uint8_t *dst = &s->frame->data[2][(y0 >> vshift) * stride + + ((x0 >> hshift) << s->sps->pixel_shift)]; + for (i = 0; i < (size * size); i++) { + coeffs[i] = ((lc->tu.res_scale_val * coeffs_y[i]) >> 3); + } + s->hevcdsp.transform_add[log2_trafo_size-2](dst, coeffs, stride); + } } } else if (blk_idx == 3) { int trafo_size_h = 1 << (log2_trafo_size + 1); @@ -2070,6 +2154,11 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0, lc->tu.cu_qp_delta = 0; } + if (s->sh.cu_chroma_qp_offset_enabled_flag && + log2_cb_size >= s->sps->log2_ctb_size - s->pps->diff_cu_chroma_qp_offset_depth) { + lc->tu.is_cu_chroma_qp_offset_coded = 0; + } + if (split_cu_flag) { const int cb_size_split = cb_size >> 1; const int x1 = x0 + cb_size_split; diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 8272502bffe95f6a94b39c2f2626977335af3983..2a5ce2523c18bc7d3830384eec252c07995c2d9c 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -602,6 +602,8 @@ typedef struct SliceHeader { int slice_cb_qp_offset; int slice_cr_qp_offset; + uint8_t cu_chroma_qp_offset_enabled_flag; + int beta_offset; ///< beta_offset_div2 * 2 int tc_offset; ///< tc_offset_div2 * 2 @@ -692,13 +694,20 @@ typedef struct TransformTree { } TransformTree; typedef struct TransformUnit { + DECLARE_ALIGNED(32, int16_t, coeffs[2][MAX_TB_SIZE * MAX_TB_SIZE]); int cu_qp_delta; + int res_scale_val; + // Inferred parameters; int intra_pred_mode; int intra_pred_mode_c; int chroma_mode_c; uint8_t is_cu_qp_delta_coded; + uint8_t is_cu_chroma_qp_offset_coded; + int8_t cu_qp_offset_cb; + int8_t cu_qp_offset_cr; + uint8_t cross_pf; } TransformUnit; typedef struct DBParams { @@ -750,6 +759,8 @@ typedef struct HEVCLocalContext { DECLARE_ALIGNED(16, int16_t, mc_buffer[(MAX_PB_SIZE + 7) * MAX_PB_SIZE]); uint8_t cabac_state[HEVC_CONTEXTS]; + uint8_t stat_coeff[4]; + uint8_t first_qp_group; GetBitContext gb; @@ -988,6 +999,8 @@ int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s); int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size); int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth); int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth); +int ff_hevc_log2_res_scale_abs(HEVCContext *s, int idx); +int ff_hevc_res_scale_sign_flag(HEVCContext *s, int idx); /** * Get the number of candidate references for the current frame. @@ -1019,6 +1032,8 @@ void ff_hevc_deblocking_boundary_strengths(HEVCContext *s, int x0, int y0, int log2_trafo_size); int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s); int ff_hevc_cu_qp_delta_abs(HEVCContext *s); +int ff_hevc_cu_chroma_qp_offset_flag(HEVCContext *s); +int ff_hevc_cu_chroma_qp_offset_idx(HEVCContext *s); void ff_hevc_hls_filter(HEVCContext *s, int x, int y, int ctb_size); void ff_hevc_hls_filters(HEVCContext *s, int x_ctb, int y_ctb, int ctb_size); void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index d2b4f29b837326440e5d8471e5c7775572c58775..92b2d7af80c6b3deab72741ab5925db321e76650 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -546,6 +546,9 @@ static void cabac_init_state(HEVCContext *s) pre = 124 + (pre & 1); s->HEVClc->cabac_state[i] = pre; } + + for (i = 0; i < 4; i++) + s->HEVClc->stat_coeff[i] = 0; } void ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts) @@ -696,6 +699,22 @@ int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s) return get_cabac_bypass(&s->HEVClc->cc); } +int ff_hevc_cu_chroma_qp_offset_flag(HEVCContext *s) +{ + return GET_CABAC(elem_offset[CU_CHROMA_QP_OFFSET_FLAG]); +} + +int ff_hevc_cu_chroma_qp_offset_idx(HEVCContext *s) +{ + int c_max= FFMAX(5, s->pps->chroma_qp_offset_list_len_minus1); + int i = 0; + + while (i < c_max && GET_CABAC(elem_offset[CU_CHROMA_QP_OFFSET_IDX])) + i++; + + return i; +} + int ff_hevc_pred_mode_decode(HEVCContext *s) { return GET_CABAC(elem_offset[PRED_MODE_FLAG]); @@ -899,33 +918,53 @@ static int ff_hevc_transform_skip_flag_decode(HEVCContext *s, int c_idx) return GET_CABAC(elem_offset[TRANSFORM_SKIP_FLAG] + !!c_idx); } -#define LAST_SIG_COEFF(elem) \ - int i = 0; \ - int max = (log2_size << 1) - 1; \ - int ctx_offset, ctx_shift; \ - \ - if (c_idx == 0) { \ - ctx_offset = 3 * (log2_size - 2) + ((log2_size - 1) >> 2); \ - ctx_shift = (log2_size + 1) >> 2; \ - } else { \ - ctx_offset = 15; \ - ctx_shift = log2_size - 2; \ - } \ - while (i < max && \ - GET_CABAC(elem_offset[elem] + (i >> ctx_shift) + ctx_offset)) \ - i++; \ - return i; +static int explicit_rdpcm_flag_decode(HEVCContext *s, int c_idx) +{ + return GET_CABAC(elem_offset[EXPLICIT_RDPCM_FLAG] + !!c_idx); +} -static av_always_inline int last_significant_coeff_x_prefix_decode(HEVCContext *s, int c_idx, - int log2_size) +static int explicit_rdpcm_dir_flag_decode(HEVCContext *s, int c_idx) { - LAST_SIG_COEFF(LAST_SIGNIFICANT_COEFF_X_PREFIX) + return GET_CABAC(elem_offset[EXPLICIT_RDPCM_DIR_FLAG] + !!c_idx); +} + +int ff_hevc_log2_res_scale_abs(HEVCContext *s, int idx) { + int i =0; + + while (i < 4 && GET_CABAC(elem_offset[LOG2_RES_SCALE_ABS] + 4 * idx + i)) + i++; + + return i; } -static av_always_inline int last_significant_coeff_y_prefix_decode(HEVCContext *s, int c_idx, - int log2_size) +int ff_hevc_res_scale_sign_flag(HEVCContext *s, int idx) { + return GET_CABAC(elem_offset[RES_SCALE_SIGN_FLAG] + idx); +} + +static av_always_inline void last_significant_coeff_xy_prefix_decode(HEVCContext *s, int c_idx, + int log2_size, int *last_scx_prefix, int *last_scy_prefix) { - LAST_SIG_COEFF(LAST_SIGNIFICANT_COEFF_Y_PREFIX) + int i = 0; + int max = (log2_size << 1) - 1; + int ctx_offset, ctx_shift; + + if (!c_idx) { + ctx_offset = 3 * (log2_size - 2) + ((log2_size - 1) >> 2); + ctx_shift = (log2_size + 1) >> 2; + } else { + ctx_offset = 15; + ctx_shift = log2_size - 2; + } + while (i < max && + GET_CABAC(elem_offset[LAST_SIGNIFICANT_COEFF_X_PREFIX] + (i >> ctx_shift) + ctx_offset)) + i++; + *last_scx_prefix = i; + + i = 0; + while (i < max && + GET_CABAC(elem_offset[LAST_SIGNIFICANT_COEFF_Y_PREFIX] + (i >> ctx_shift) + ctx_offset)) + i++; + *last_scy_prefix = i; } static av_always_inline int last_significant_coeff_suffix_decode(HEVCContext *s, @@ -948,58 +987,18 @@ static av_always_inline int significant_coeff_group_flag_decode(HEVCContext *s, return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_GROUP_FLAG] + inc); } - -static av_always_inline int significant_coeff_flag_decode(HEVCContext *s, int c_idx, int x_c, int y_c, - int log2_trafo_size, int scan_idx, int prev_sig) +static av_always_inline int significant_coeff_flag_decode(HEVCContext *s, int x_c, int y_c, + int offset, const uint8_t *ctx_idx_map) { - static const uint8_t ctx_idx_map[] = { - 0, 1, 4, 5, 2, 3, 4, 5, 6, 6, 8, 8, 7, 7, 8, 8 - }; - int x_cg = x_c >> 2; - int y_cg = y_c >> 2; - int sig_ctx; - int inc; - - if (x_c + y_c == 0) { - sig_ctx = 0; - } else if (log2_trafo_size == 2) { - sig_ctx = ctx_idx_map[(y_c << 2) + x_c]; - } else { - switch (prev_sig) { - case 0: { - int x_off = x_c & 3; - int y_off = y_c & 3; - sig_ctx = ((x_off + y_off) == 0) ? 2 : ((x_off + y_off) <= 2) ? 1 : 0; - } - break; - case 1: - sig_ctx = 2 - FFMIN(y_c & 3, 2); - break; - case 2: - sig_ctx = 2 - FFMIN(x_c & 3, 2); - break; - default: - sig_ctx = 2; - } - - if (c_idx == 0 && (x_cg > 0 || y_cg > 0)) - sig_ctx += 3; - - if (log2_trafo_size == 3) { - sig_ctx += (scan_idx == SCAN_DIAG) ? 9 : 15; - } else { - sig_ctx += c_idx ? 12 : 21; - } - } - - if (c_idx == 0) - inc = sig_ctx; - else - inc = sig_ctx + 27; - + int inc = ctx_idx_map[(y_c << 2) + x_c] + offset; return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_FLAG] + inc); } +static av_always_inline int significant_coeff_flag_decode_0(HEVCContext *s, int c_idx, int offset) +{ + return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_FLAG] + offset); +} + static av_always_inline int coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx, int inc) { @@ -1017,7 +1016,7 @@ static av_always_inline int coeff_abs_level_greater2_flag_decode(HEVCContext *s, return GET_CABAC(elem_offset[COEFF_ABS_LEVEL_GREATER2_FLAG] + inc); } -static av_always_inline int coeff_abs_level_remaining_decode(HEVCContext *s, int base_level, int rc_rice_param) +static av_always_inline int coeff_abs_level_remaining_decode(HEVCContext *s, int rc_rice_param) { int prefix = 0; int suffix = 0; @@ -1058,8 +1057,8 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, { #define GET_COORD(offset, n) \ do { \ - x_c = (scan_x_cg[offset >> 4] << 2) + scan_x_off[n]; \ - y_c = (scan_y_cg[offset >> 4] << 2) + scan_y_off[n]; \ + x_c = (x_cg << 2) + scan_x_off[n]; \ + y_c = (y_cg << 2) + scan_y_off[n]; \ } while (0) HEVCLocalContext *lc = s->HEVClc; int transform_skip_flag = 0; @@ -1080,15 +1079,21 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, int vshift = s->sps->vshift[c_idx]; uint8_t *dst = &s->frame->data[c_idx][(y0 >> vshift) * stride + ((x0 >> hshift) << s->sps->pixel_shift)]; - DECLARE_ALIGNED(16, int16_t, coeffs[MAX_TB_SIZE * MAX_TB_SIZE]) = {0}; - DECLARE_ALIGNED(8, uint8_t, significant_coeff_group_flag[8][8]) = {{0}}; + int16_t *coeffs = lc->tu.coeffs[c_idx > 0]; + uint8_t significant_coeff_group_flag[8][8] = {{0}}; + int explicit_rdpcm_flag = 0; + int explicit_rdpcm_dir_flag; int trafo_size = 1 << log2_trafo_size; int i; int qp,shift,add,scale,scale_m; const uint8_t level_scale[] = { 40, 45, 51, 57, 64, 72 }; - const uint8_t *scale_matrix; + const uint8_t *scale_matrix = NULL; uint8_t dc_scale; + int pred_mode_intra = (c_idx == 0) ? lc->tu.intra_pred_mode : + lc->tu.intra_pred_mode_c; + + memset(coeffs, 0, trafo_size * trafo_size * sizeof(int16_t)); // Derive QP for dequant if (!lc->cu.cu_transquant_bypass_flag) { @@ -1114,17 +1119,26 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, int qp_i, offset; if (c_idx == 1) - offset = s->pps->cb_qp_offset + s->sh.slice_cb_qp_offset; + offset = s->pps->cb_qp_offset + s->sh.slice_cb_qp_offset + + lc->tu.cu_qp_offset_cb; else - offset = s->pps->cr_qp_offset + s->sh.slice_cr_qp_offset; + offset = s->pps->cr_qp_offset + s->sh.slice_cr_qp_offset + + lc->tu.cu_qp_offset_cr; qp_i = av_clip(qp_y + offset, - s->sps->qp_bd_offset, 57); - if (qp_i < 30) - qp = qp_i; - else if (qp_i > 43) - qp = qp_i - 6; - else - qp = qp_c[qp_i - 30]; + if (s->sps->chroma_format_idc == 1) { + if (qp_i < 30) + qp = qp_i; + else if (qp_i > 43) + qp = qp_i - 6; + else + qp = qp_c[qp_i - 30]; + } else { + if (qp_i > 51) + qp = 51; + else + qp = qp_i; + } qp += s->sps->qp_bd_offset; } @@ -1147,17 +1161,28 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, if (log2_trafo_size >= 4) dc_scale = sl->sl_dc[log2_trafo_size - 4][matrix_id]; } + } else { + shift = 0; + add = 0; + scale = 0; + dc_scale = 0; } if (s->pps->transform_skip_enabled_flag && !lc->cu.cu_transquant_bypass_flag && - log2_trafo_size == 2) { + log2_trafo_size <= s->pps->log2_max_transform_skip_block_size) { transform_skip_flag = ff_hevc_transform_skip_flag_decode(s, c_idx); } - last_significant_coeff_x = - last_significant_coeff_x_prefix_decode(s, c_idx, log2_trafo_size); - last_significant_coeff_y = - last_significant_coeff_y_prefix_decode(s, c_idx, log2_trafo_size); + if (lc->cu.pred_mode == MODE_INTER && s->sps->explicit_rdpcm_enabled_flag && + (transform_skip_flag || lc->cu.cu_transquant_bypass_flag)) { + explicit_rdpcm_flag = explicit_rdpcm_flag_decode(s, c_idx); + if (explicit_rdpcm_flag) { + explicit_rdpcm_dir_flag = explicit_rdpcm_dir_flag_decode(s, c_idx); + } + } + + last_significant_coeff_xy_prefix_decode(s, c_idx, log2_trafo_size, + &last_significant_coeff_x, &last_significant_coeff_y); if (last_significant_coeff_x > 3) { int suffix = last_significant_coeff_suffix_decode(s, last_significant_coeff_x); @@ -1230,6 +1255,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, int64_t trans_coeff_level; int prev_sig = 0; int offset = i << 4; + int rice_init = 0; uint8_t significant_coeff_flag_idx[16]; uint8_t nb_significant_coeff_flag = 0; @@ -1264,26 +1290,85 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, } if (x_cg < ((1 << log2_trafo_size) - 1) >> 2) - prev_sig = significant_coeff_group_flag[x_cg + 1][y_cg]; + prev_sig = !!significant_coeff_group_flag[x_cg + 1][y_cg]; if (y_cg < ((1 << log2_trafo_size) - 1) >> 2) - prev_sig += (significant_coeff_group_flag[x_cg][y_cg + 1] << 1); - - for (n = n_end; n >= 0; n--) { - GET_COORD(offset, n); - - if (significant_coeff_group_flag[x_cg][y_cg] && - (n > 0 || implicit_non_zero_coeff == 0)) { - if (significant_coeff_flag_decode(s, c_idx, x_c, y_c, log2_trafo_size, scan_idx, prev_sig) == 1) { + prev_sig += (!!significant_coeff_group_flag[x_cg][y_cg + 1] << 1); + + if (significant_coeff_group_flag[x_cg][y_cg] && n_end >= 0) { + static const uint8_t ctx_idx_map[] = { + 0, 1, 4, 5, 2, 3, 4, 5, 6, 6, 8, 8, 7, 7, 8, 8, // log2_trafo_size == 2 + 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, // prev_sig == 0 + 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, // prev_sig == 1 + 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, 2, 1, 0, 0, // prev_sig == 2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 // default + }; + const uint8_t *ctx_idx_map_p; + int scf_offset = 0; + if (s->sps->transform_skip_context_enabled_flag && + (transform_skip_flag || lc->cu.cu_transquant_bypass_flag)) { + ctx_idx_map_p = (uint8_t*) &ctx_idx_map[4 * 16]; + if (c_idx == 0) { + scf_offset = 40; + } else { + scf_offset = 14 + 27; + } + } else { + if (c_idx != 0) + scf_offset = 27; + if (log2_trafo_size == 2) { + ctx_idx_map_p = (uint8_t*) &ctx_idx_map[0]; + } else { + ctx_idx_map_p = (uint8_t*) &ctx_idx_map[(prev_sig + 1) << 4]; + if (c_idx == 0) { + if ((x_cg > 0 || y_cg > 0)) + scf_offset += 3; + if (log2_trafo_size == 3) { + scf_offset += (scan_idx == SCAN_DIAG) ? 9 : 15; + } else { + scf_offset += 21; + } + } else { + if (log2_trafo_size == 3) + scf_offset += 9; + else + scf_offset += 12; + } + } + } + for (n = n_end; n > 0; n--) { + x_c = scan_x_off[n]; + y_c = scan_y_off[n]; + if (significant_coeff_flag_decode(s, x_c, y_c, scf_offset, ctx_idx_map_p)) { significant_coeff_flag_idx[nb_significant_coeff_flag] = n; nb_significant_coeff_flag++; implicit_non_zero_coeff = 0; } - } else { - int last_cg = (x_c == (x_cg << 2) && y_c == (y_cg << 2)); - if (last_cg && implicit_non_zero_coeff && significant_coeff_group_flag[x_cg][y_cg]) { - significant_coeff_flag_idx[nb_significant_coeff_flag] = n; + } + if (implicit_non_zero_coeff == 0) { + if (s->sps->transform_skip_context_enabled_flag && + (transform_skip_flag || lc->cu.cu_transquant_bypass_flag)) { + if (c_idx == 0) { + scf_offset = 42; + } else { + scf_offset = 16 + 27; + } + } else { + if (i == 0) { + if (c_idx == 0) + scf_offset = 0; + else + scf_offset = 27; + } else { + scf_offset = 2 + scf_offset; + } + } + if (significant_coeff_flag_decode_0(s, c_idx, scf_offset) == 1) { + significant_coeff_flag_idx[nb_significant_coeff_flag] = 0; nb_significant_coeff_flag++; } + } else { + significant_coeff_flag_idx[nb_significant_coeff_flag] = 0; + nb_significant_coeff_flag++; } } @@ -1291,41 +1376,55 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, if (n_end) { - int first_nz_pos_in_cg = 16; - int last_nz_pos_in_cg = -1; + int first_nz_pos_in_cg; + int last_nz_pos_in_cg; int c_rice_param = 0; int first_greater1_coeff_idx = -1; - uint8_t coeff_abs_level_greater1_flag[16] = {0}; + uint8_t coeff_abs_level_greater1_flag[8]; uint16_t coeff_sign_flag; int sum_abs = 0; - int sign_hidden = 0; + int sign_hidden; + int sb_type; + // initialize first elem of coeff_bas_level_greater1_flag int ctx_set = (i > 0 && c_idx == 0) ? 2 : 0; + if (s->sps->persistent_rice_adaptation_enabled_flag) { + if (!transform_skip_flag && !lc->cu.cu_transquant_bypass_flag) + sb_type = 2 * (c_idx == 0 ? 1 : 0); + else + sb_type = 2 * (c_idx == 0 ? 1 : 0) + 1; + c_rice_param = lc->stat_coeff[sb_type] / 4; + } + if (!(i == num_last_subset) && greater1_ctx == 0) ctx_set++; greater1_ctx = 1; last_nz_pos_in_cg = significant_coeff_flag_idx[0]; for (m = 0; m < (n_end > 8 ? 8 : n_end); m++) { - int n_idx = significant_coeff_flag_idx[m]; int inc = (ctx_set << 2) + greater1_ctx; - coeff_abs_level_greater1_flag[n_idx] = + coeff_abs_level_greater1_flag[m] = coeff_abs_level_greater1_flag_decode(s, c_idx, inc); - if (coeff_abs_level_greater1_flag[n_idx]) { + if (coeff_abs_level_greater1_flag[m]) { greater1_ctx = 0; + if (first_greater1_coeff_idx == -1) + first_greater1_coeff_idx = m; } else if (greater1_ctx > 0 && greater1_ctx < 3) { greater1_ctx++; } - - if (coeff_abs_level_greater1_flag[n_idx] && - first_greater1_coeff_idx == -1) - first_greater1_coeff_idx = n_idx; } first_nz_pos_in_cg = significant_coeff_flag_idx[n_end - 1]; - sign_hidden = (last_nz_pos_in_cg - first_nz_pos_in_cg >= 4 && - !lc->cu.cu_transquant_bypass_flag); + + if (lc->cu.cu_transquant_bypass_flag || + (lc->cu.pred_mode == MODE_INTRA && + s->sps->implicit_rdpcm_enabled_flag && transform_skip_flag && + (pred_mode_intra == 10 || pred_mode_intra == 26 )) || + explicit_rdpcm_flag) + sign_hidden = 0; + else + sign_hidden = (last_nz_pos_in_cg - first_nz_pos_in_cg >= 4); if (first_greater1_coeff_idx != -1) { coeff_abs_level_greater1_flag[first_greater1_coeff_idx] += coeff_abs_level_greater2_flag_decode(s, c_idx, ctx_set); @@ -1339,15 +1438,39 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, for (m = 0; m < n_end; m++) { n = significant_coeff_flag_idx[m]; GET_COORD(offset, n); - trans_coeff_level = 1 + coeff_abs_level_greater1_flag[n]; - if (trans_coeff_level == ((m < 8) ? - ((n == first_greater1_coeff_idx) ? 3 : 2) : 1)) { - int last_coeff_abs_level_remaining = coeff_abs_level_remaining_decode(s, trans_coeff_level, c_rice_param); + if (m < 8) { + trans_coeff_level = 1 + coeff_abs_level_greater1_flag[m]; + if (trans_coeff_level == ((m == first_greater1_coeff_idx) ? 3 : 2)) { + int last_coeff_abs_level_remaining = coeff_abs_level_remaining_decode(s, c_rice_param); + + trans_coeff_level += last_coeff_abs_level_remaining; + if (trans_coeff_level > (3 << c_rice_param)) + c_rice_param = s->sps->persistent_rice_adaptation_enabled_flag ? c_rice_param + 1 : FFMIN(c_rice_param + 1, 4); + if (s->sps->persistent_rice_adaptation_enabled_flag && !rice_init) { + int c_rice_p_init = lc->stat_coeff[sb_type] / 4; + if (last_coeff_abs_level_remaining >= (3 << c_rice_p_init)) + lc->stat_coeff[sb_type]++; + else if (2 * last_coeff_abs_level_remaining < (1 << c_rice_p_init)) + if (lc->stat_coeff[sb_type] > 0) + lc->stat_coeff[sb_type]--; + rice_init = 1; + } + } + } else { + int last_coeff_abs_level_remaining = coeff_abs_level_remaining_decode(s, c_rice_param); - trans_coeff_level += last_coeff_abs_level_remaining; + trans_coeff_level = 1 + last_coeff_abs_level_remaining; if (trans_coeff_level > (3 << c_rice_param)) - c_rice_param = FFMIN(c_rice_param + 1, 4); - + c_rice_param = s->sps->persistent_rice_adaptation_enabled_flag ? c_rice_param + 1 : FFMIN(c_rice_param + 1, 4); + if (s->sps->persistent_rice_adaptation_enabled_flag && !rice_init) { + int c_rice_p_init = lc->stat_coeff[sb_type] / 4; + if (last_coeff_abs_level_remaining >= (3 << c_rice_p_init)) + lc->stat_coeff[sb_type]++; + else if (2 * last_coeff_abs_level_remaining < (1 << c_rice_p_init)) + if (lc->stat_coeff[sb_type] > 0) + lc->stat_coeff[sb_type]--; + rice_init = 1; + } } if (s->pps->sign_data_hiding_flag && sign_hidden) { sum_abs += trans_coeff_level; @@ -1364,7 +1487,7 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, case 3: pos = (y_c << 3) + x_c; break; case 4: pos = ((y_c >> 1) << 3) + (x_c >> 1); break; case 5: pos = ((y_c >> 2) << 3) + (x_c >> 2); break; - default: pos = (y_c << 2) + x_c; + default: pos = (y_c << 2) + x_c; break; } scale_m = scale_matrix[pos]; } else { @@ -1385,12 +1508,34 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, } } - if (!lc->cu.cu_transquant_bypass_flag) { - if (transform_skip_flag) + if (lc->cu.cu_transquant_bypass_flag) { + if (explicit_rdpcm_flag || (s->sps->implicit_rdpcm_enabled_flag && + (pred_mode_intra == 10 || pred_mode_intra == 26))) { + int mode = s->sps->implicit_rdpcm_enabled_flag ? (pred_mode_intra == 26) : explicit_rdpcm_dir_flag; + + s->hevcdsp.transform_rdpcm(coeffs, log2_trafo_size, mode); + } + } else { + if (transform_skip_flag) { + int rot = s->sps->transform_skip_rotation_enabled_flag && + lc->cu.pred_mode == MODE_INTRA; + if (rot) { + for (i = 0; i < (trafo_size * trafo_size >> 1); i++) + FFSWAP(int16_t, coeffs[i], coeffs[trafo_size * trafo_size - i - 1]); + } + s->hevcdsp.transform_skip(coeffs, log2_trafo_size); - else if (lc->cu.pred_mode == MODE_INTRA && c_idx == 0 && log2_trafo_size == 2) + + if (explicit_rdpcm_flag || (s->sps->implicit_rdpcm_enabled_flag && + lc->cu.pred_mode == MODE_INTRA && + (pred_mode_intra == 10 || pred_mode_intra == 26))) { + int mode = s->sps->implicit_rdpcm_enabled_flag ? (pred_mode_intra == 26) : explicit_rdpcm_dir_flag; + + s->hevcdsp.transform_rdpcm(coeffs, log2_trafo_size, mode); + } + } else if (lc->cu.pred_mode == MODE_INTRA && c_idx == 0 && log2_trafo_size == 2) { s->hevcdsp.idct_4x4_luma(coeffs); - else { + } else { int max_xy = FFMAX(last_significant_coeff_x, last_significant_coeff_y); if (max_xy == 0) s->hevcdsp.idct_dc[log2_trafo_size-2](coeffs); @@ -1406,6 +1551,13 @@ void ff_hevc_hls_residual_coding(HEVCContext *s, int x0, int y0, } } } + if (lc->tu.cross_pf) { + int16_t *coeffs_y = lc->tu.coeffs[0]; + + for (i = 0; i < (trafo_size * trafo_size); i++) { + coeffs[i] = coeffs[i] + ((lc->tu.res_scale_val * coeffs_y[i]) >> 3); + } + } s->hevcdsp.transform_add[log2_trafo_size-2](dst, coeffs, stride); } diff --git a/libavcodec/hevcdsp.c b/libavcodec/hevcdsp.c index a22a3a5cfa72a58069663ab4dced379467974e3c..218c48f84c46418dc07d8c70542ab31a03fe9c18 100644 --- a/libavcodec/hevcdsp.c +++ b/libavcodec/hevcdsp.c @@ -200,6 +200,7 @@ void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth) hevcdsp->transform_add[2] = FUNC(transform_add16x16, depth); \ hevcdsp->transform_add[3] = FUNC(transform_add32x32, depth); \ hevcdsp->transform_skip = FUNC(transform_skip, depth); \ + hevcdsp->transform_rdpcm = FUNC(transform_rdpcm, depth); \ hevcdsp->idct_4x4_luma = FUNC(transform_4x4_luma, depth); \ hevcdsp->idct[0] = FUNC(idct_4x4, depth); \ hevcdsp->idct[1] = FUNC(idct_8x8, depth); \ diff --git a/libavcodec/hevcdsp.h b/libavcodec/hevcdsp.h index 25480646ad5cbaf01712abb82ff8c980d8e4c0d0..3b82fabff1b922f2f46df41149a062e557571d21 100644 --- a/libavcodec/hevcdsp.h +++ b/libavcodec/hevcdsp.h @@ -48,6 +48,8 @@ typedef struct HEVCDSPContext { void (*transform_skip)(int16_t *coeffs, int16_t log2_size); + void (*transform_rdpcm)(int16_t *coeffs, int16_t log2_size, int mode); + void (*idct_4x4_luma)(int16_t *coeffs); void (*idct[4])(int16_t *coeffs, int col_limit); diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c index cceba2453d25cd4ea700294e3cc97ab64eb1421c..f0bb256b4bf86e16064bc251fb3ce3c7ee495eb1 100644 --- a/libavcodec/hevcdsp_template.c +++ b/libavcodec/hevcdsp_template.c @@ -110,6 +110,29 @@ static void FUNC(transform_add32x32)(uint8_t *_dst, int16_t *coeffs, } } + +static void FUNC(transform_rdpcm)(int16_t *_coeffs, int16_t log2_size, int mode) +{ + int16_t *coeffs = (int16_t *) _coeffs; + int x, y; + int size = 1 << log2_size; + + if (mode) { + coeffs += size; + for (y = 0; y < size - 1; y++) { + for (x = 0; x < size; x++) + coeffs[x] += coeffs[x - size]; + coeffs += size; + } + } else { + for (y = 0; y < size; y++) { + for (x = 1; x < size; x++) + coeffs[x] += coeffs[x - 1]; + coeffs += size; + } + } +} + static void FUNC(transform_skip)(int16_t *_coeffs, int16_t log2_size) { int shift = 15 - BIT_DEPTH - log2_size;