diff options
author | Mickaƫl Raulet <mraulet@insa-rennes.fr> | 2014-07-15 00:20:22 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-07-15 14:08:20 +0200 |
commit | 453f8eaee213a1940c5d5dda7cb1bcd148e2c183 (patch) | |
tree | 81a50e2209a60e5d5e5cad9016a5fd20e5079fb6 /libavcodec/hevc_cabac.c | |
parent | 5a41999d81459297183c4e27618e38f8ba719853 (diff) | |
download | ffmpeg-453f8eaee213a1940c5d5dda7cb1bcd148e2c183.tar.gz |
hevc/rext: add support for Range extension tools
SPS features/flags:
- transform_skip_rotation_enabled_flag
- transform_skip_context_enabled_flag
- implicit_rdpcm_enabled_flag
- explicit_rdpcm_enabled_flag
- intra_smoothing_disabled_flag
- persistent_rice_adaptation_enabled_flag
PPS features/flags:
- log2_max_transform_skip_block_size
- cross_component_prediction_enabled_flag
- chroma_qp_offset_list_enabled_flag
- diff_cu_chroma_qp_offset_depth
- chroma_qp_offset_list_len_minus1
- cb_qp_offset_list
- cr_qp_offset_list
- log2_sao_offset_scale_luma
- log2_sao_offset_scale_chroma
(cherry picked from commit 005294c5b939a23099871c6130c8a7cc331f73ee)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/hevc_cabac.c')
-rw-r--r-- | libavcodec/hevc_cabac.c | 406 |
1 files changed, 279 insertions, 127 deletions
diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index d2b4f29b83..92b2d7af80 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); } |