summaryrefslogtreecommitdiff
path: root/libavcodec/hevc_cabac.c
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2013-08-11 09:02:07 +0200
committerAnton Khirnov <anton@khirnov.net>2013-10-31 20:19:59 +0100
commit064698d381e1e7790f21b0199a8930ea04e2e942 (patch)
tree2ed95cea3a92d26a1c757a6c5f7e881eba3d9cf2 /libavcodec/hevc_cabac.c
parent0a9e94bba8f8a40156438a43e4fe0e9ae36236cb (diff)
downloadffmpeg-064698d381e1e7790f21b0199a8930ea04e2e942.tar.gz
Add HEVC decoder
Initially written by Guillaume Martres <smarter@ubuntu.com> as a GSoC project. Further contributions by the OpenHEVC project and other developers, namely: Mickaël Raulet <mraulet@insa-rennes.fr> Seppo Tomperi <seppo.tomperi@vtt.fi> Gildas Cocherel <gildas.cocherel@laposte.net> Khaled Jerbi <khaled_jerbi@yahoo.fr> Wassim Hamidouche <wassim.hamidouche@insa-rennes.fr> Vittorio Giovara <vittorio.giovara@gmail.com> Jan Ekström <jeebjp@gmail.com> Anton Khirnov <anton@khirnov.net> Martin Storsjö <martin@martin.st> Luca Barbato <lu_zero@gentoo.org> Yusuke Nakamura <muken.the.vfrmaniac@gmail.com> Reimar Döffinger <Reimar.Doeffinger@gmx.de> Diego Biurrun <diego@biurrun.de> Signed-off-by: Anton Khirnov <anton@khirnov.net>
Diffstat (limited to 'libavcodec/hevc_cabac.c')
-rw-r--r--libavcodec/hevc_cabac.c872
1 files changed, 872 insertions, 0 deletions
diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c
new file mode 100644
index 0000000000..f2531d41bd
--- /dev/null
+++ b/libavcodec/hevc_cabac.c
@@ -0,0 +1,872 @@
+/*
+ * HEVC CABAC decoding
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ *
+ * This file is part of Libav.
+ *
+ * Libav is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Libav is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+
+#include "cabac_functions.h"
+#include "hevc.h"
+
+#define CABAC_MAX_BIN 100
+
+/**
+ * number of bin by SyntaxElement.
+ */
+static const int8_t num_bins_in_se[] = {
+ 1, // sao_merge_flag
+ 1, // sao_type_idx
+ 0, // sao_eo_class
+ 0, // sao_band_position
+ 0, // sao_offset_abs
+ 0, // sao_offset_sign
+ 0, // end_of_slice_flag
+ 3, // split_coding_unit_flag
+ 1, // cu_transquant_bypass_flag
+ 3, // skip_flag
+ 3, // cu_qp_delta
+ 1, // pred_mode
+ 4, // part_mode
+ 0, // pcm_flag
+ 1, // prev_intra_luma_pred_mode
+ 0, // mpm_idx
+ 0, // rem_intra_luma_pred_mode
+ 2, // intra_chroma_pred_mode
+ 1, // merge_flag
+ 1, // merge_idx
+ 5, // inter_pred_idc
+ 2, // ref_idx_l0
+ 2, // ref_idx_l1
+ 2, // abs_mvd_greater0_flag
+ 2, // abs_mvd_greater1_flag
+ 0, // abs_mvd_minus2
+ 0, // mvd_sign_flag
+ 1, // mvp_lx_flag
+ 1, // no_residual_data_flag
+ 3, // split_transform_flag
+ 2, // cbf_luma
+ 4, // cbf_cb, cbf_cr
+ 2, // transform_skip_flag[][]
+ 18, // last_significant_coeff_x_prefix
+ 18, // last_significant_coeff_y_prefix
+ 0, // last_significant_coeff_x_suffix
+ 0, // last_significant_coeff_y_suffix
+ 4, // significant_coeff_group_flag
+ 42, // significant_coeff_flag
+ 24, // coeff_abs_level_greater1_flag
+ 6, // coeff_abs_level_greater2_flag
+ 0, // coeff_abs_level_remaining
+ 0, // coeff_sign_flag
+};
+
+/**
+ * Offset to ctxIdx 0 in init_values and states, indexed by SyntaxElement.
+ */
+static const int elem_offset[sizeof(num_bins_in_se)] = {
+ 0,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 2,
+ 5,
+ 6,
+ 9,
+ 12,
+ 13,
+ 17,
+ 17,
+ 18,
+ 18,
+ 18,
+ 20,
+ 21,
+ 22,
+ 27,
+ 29,
+ 31,
+ 33,
+ 35,
+ 35,
+ 35,
+ 36,
+ 37,
+ 40,
+ 42,
+ 46,
+ 48,
+ 66,
+ 84,
+ 84,
+ 84,
+ 88,
+ 130,
+ 154,
+ 160,
+ 160,
+};
+
+#define CNU 154
+/**
+ * Indexed by init_type
+ */
+static const uint8_t init_values[3][HEVC_CONTEXTS] = {
+ { // sao_merge_flag
+ 153,
+ // sao_type_idx
+ 200,
+ // split_coding_unit_flag
+ 139, 141, 157,
+ // cu_transquant_bypass_flag
+ 154,
+ // skip_flag
+ CNU, CNU, CNU,
+ // cu_qp_delta
+ 154, 154, 154,
+ // pred_mode
+ CNU,
+ // part_mode
+ 184, CNU, CNU, CNU,
+ // prev_intra_luma_pred_mode
+ 184,
+ // intra_chroma_pred_mode
+ 63, 139,
+ // merge_flag
+ CNU,
+ // merge_idx
+ CNU,
+ // inter_pred_idc
+ CNU, CNU, CNU, CNU, CNU,
+ // ref_idx_l0
+ CNU, CNU,
+ // ref_idx_l1
+ CNU, CNU,
+ // abs_mvd_greater1_flag
+ CNU, CNU,
+ // abs_mvd_greater1_flag
+ CNU, CNU,
+ // mvp_lx_flag
+ CNU,
+ // no_residual_data_flag
+ CNU,
+ // split_transform_flag
+ 153, 138, 138,
+ // cbf_luma
+ 111, 141,
+ // cbf_cb, cbf_cr
+ 94, 138, 182, 154,
+ // transform_skip_flag
+ 139, 139,
+ // last_significant_coeff_x_prefix
+ 110, 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111,
+ 79, 108, 123, 63,
+ // last_significant_coeff_y_prefix
+ 110, 110, 124, 125, 140, 153, 125, 127, 140, 109, 111, 143, 127, 111,
+ 79, 108, 123, 63,
+ // significant_coeff_group_flag
+ 91, 171, 134, 141,
+ // significant_coeff_flag
+ 111, 111, 125, 110, 110, 94, 124, 108, 124, 107, 125, 141, 179, 153,
+ 125, 107, 125, 141, 179, 153, 125, 107, 125, 141, 179, 153, 125, 140,
+ 139, 182, 182, 152, 136, 152, 136, 153, 136, 139, 111, 136, 139, 111,
+ // coeff_abs_level_greater1_flag
+ 140, 92, 137, 138, 140, 152, 138, 139, 153, 74, 149, 92, 139, 107,
+ 122, 152, 140, 179, 166, 182, 140, 227, 122, 197,
+ // coeff_abs_level_greater2_flag
+ 138, 153, 136, 167, 152, 152, },
+ { // sao_merge_flag
+ 153,
+ // sao_type_idx
+ 185,
+ // split_coding_unit_flag
+ 107, 139, 126,
+ // cu_transquant_bypass_flag
+ 154,
+ // skip_flag
+ 197, 185, 201,
+ // cu_qp_delta
+ 154, 154, 154,
+ // pred_mode
+ 149,
+ // part_mode
+ 154, 139, 154, 154,
+ // prev_intra_luma_pred_mode
+ 154,
+ // intra_chroma_pred_mode
+ 152, 139,
+ // merge_flag
+ 110,
+ // merge_idx
+ 122,
+ // inter_pred_idc
+ 95, 79, 63, 31, 31,
+ // ref_idx_l0
+ 153, 153,
+ // ref_idx_l1
+ 153, 153,
+ // abs_mvd_greater1_flag
+ 140, 198,
+ // abs_mvd_greater1_flag
+ 140, 198,
+ // mvp_lx_flag
+ 168,
+ // no_residual_data_flag
+ 79,
+ // split_transform_flag
+ 124, 138, 94,
+ // cbf_luma
+ 153, 111,
+ // cbf_cb, cbf_cr
+ 149, 107, 167, 154,
+ // transform_skip_flag
+ 139, 139,
+ // last_significant_coeff_x_prefix
+ 125, 110, 94, 110, 95, 79, 125, 111, 110, 78, 110, 111, 111, 95,
+ 94, 108, 123, 108,
+ // last_significant_coeff_y_prefix
+ 125, 110, 94, 110, 95, 79, 125, 111, 110, 78, 110, 111, 111, 95,
+ 94, 108, 123, 108,
+ // significant_coeff_group_flag
+ 121, 140, 61, 154,
+ // significant_coeff_flag
+ 155, 154, 139, 153, 139, 123, 123, 63, 153, 166, 183, 140, 136, 153,
+ 154, 166, 183, 140, 136, 153, 154, 166, 183, 140, 136, 153, 154, 170,
+ 153, 123, 123, 107, 121, 107, 121, 167, 151, 183, 140, 151, 183, 140,
+ // coeff_abs_level_greater1_flag
+ 154, 196, 196, 167, 154, 152, 167, 182, 182, 134, 149, 136, 153, 121,
+ 136, 137, 169, 194, 166, 167, 154, 167, 137, 182,
+ // coeff_abs_level_greater2_flag
+ 107, 167, 91, 122, 107, 167, },
+ { // sao_merge_flag
+ 153,
+ // sao_type_idx
+ 160,
+ // split_coding_unit_flag
+ 107, 139, 126,
+ // cu_transquant_bypass_flag
+ 154,
+ // skip_flag
+ 197, 185, 201,
+ // cu_qp_delta
+ 154, 154, 154,
+ // pred_mode
+ 134,
+ // part_mode
+ 154, 139, 154, 154,
+ // prev_intra_luma_pred_mode
+ 183,
+ // intra_chroma_pred_mode
+ 152, 139,
+ // merge_flag
+ 154,
+ // merge_idx
+ 137,
+ // inter_pred_idc
+ 95, 79, 63, 31, 31,
+ // ref_idx_l0
+ 153, 153,
+ // ref_idx_l1
+ 153, 153,
+ // abs_mvd_greater1_flag
+ 169, 198,
+ // abs_mvd_greater1_flag
+ 169, 198,
+ // mvp_lx_flag
+ 168,
+ // no_residual_data_flag
+ 79,
+ // split_transform_flag
+ 224, 167, 122,
+ // cbf_luma
+ 153, 111,
+ // cbf_cb, cbf_cr
+ 149, 92, 167, 154,
+ // transform_skip_flag
+ 139, 139,
+ // last_significant_coeff_x_prefix
+ 125, 110, 124, 110, 95, 94, 125, 111, 111, 79, 125, 126, 111, 111,
+ 79, 108, 123, 93,
+ // last_significant_coeff_y_prefix
+ 125, 110, 124, 110, 95, 94, 125, 111, 111, 79, 125, 126, 111, 111,
+ 79, 108, 123, 93,
+ // significant_coeff_group_flag
+ 121, 140, 61, 154,
+ // significant_coeff_flag
+ 170, 154, 139, 153, 139, 123, 123, 63, 124, 166, 183, 140, 136, 153,
+ 154, 166, 183, 140, 136, 153, 154, 166, 183, 140, 136, 153, 154, 170,
+ 153, 138, 138, 122, 121, 122, 121, 167, 151, 183, 140, 151, 183, 140,
+ // coeff_abs_level_greater1_flag
+ 154, 196, 167, 167, 154, 152, 167, 182, 182, 134, 149, 136, 153, 121,
+ 136, 122, 169, 208, 166, 167, 154, 152, 167, 182,
+ // coeff_abs_level_greater2_flag
+ 107, 167, 91, 107, 107, 167, },
+};
+
+void ff_hevc_save_states(HEVCContext *s, int ctb_addr_ts)
+{
+ if (s->pps->entropy_coding_sync_enabled_flag &&
+ (ctb_addr_ts % s->sps->ctb_width == 2 ||
+ (s->sps->ctb_width == 2 &&
+ ctb_addr_ts % s->sps->ctb_width == 0))) {
+ memcpy(s->cabac_state, s->HEVClc.cabac_state, HEVC_CONTEXTS);
+ }
+}
+
+static void load_states(HEVCContext *s)
+{
+ memcpy(s->HEVClc.cabac_state, s->cabac_state, HEVC_CONTEXTS);
+}
+
+static void cabac_reinit(HEVCLocalContext *lc)
+{
+ skip_bytes(&lc->cc, 0);
+}
+
+static void cabac_init_decoder(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc.gb;
+ skip_bits(gb, 1);
+ align_get_bits(gb);
+ ff_init_cabac_decoder(&s->HEVClc.cc,
+ gb->buffer + get_bits_count(gb) / 8,
+ (get_bits_left(gb) + 7) / 8);
+}
+
+static void cabac_init_state(HEVCContext *s)
+{
+ int init_type = 2 - s->sh.slice_type;
+ int i;
+
+ if (s->sh.cabac_init_flag && s->sh.slice_type != I_SLICE)
+ init_type ^= 3;
+
+ for (i = 0; i < HEVC_CONTEXTS; i++) {
+ int init_value = init_values[init_type][i];
+ int m = (init_value >> 4) * 5 - 45;
+ int n = ((init_value & 15) << 3) - 16;
+ int pre = 2 * (((m * av_clip_c(s->sh.slice_qp, 0, 51)) >> 4) + n) - 127;
+
+ pre ^= pre >> 31;
+ if (pre > 124)
+ pre = 124 + (pre & 1);
+ s->HEVClc.cabac_state[i] = pre;
+ }
+}
+
+void ff_hevc_cabac_init(HEVCContext *s, int ctb_addr_ts)
+{
+ if (ctb_addr_ts == s->pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]) {
+ cabac_init_decoder(s);
+ if (s->sh.dependent_slice_segment_flag == 0 ||
+ (s->pps->tiles_enabled_flag &&
+ s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]))
+ cabac_init_state(s);
+
+ if (!s->sh.first_slice_in_pic_flag &&
+ s->pps->entropy_coding_sync_enabled_flag) {
+ if (ctb_addr_ts % s->sps->ctb_width == 0) {
+ if (s->sps->ctb_width == 1)
+ cabac_init_state(s);
+ else if (s->sh.dependent_slice_segment_flag == 1)
+ load_states(s);
+ }
+ }
+ } else {
+ if (s->pps->tiles_enabled_flag &&
+ s->pps->tile_id[ctb_addr_ts] != s->pps->tile_id[ctb_addr_ts - 1]) {
+ cabac_reinit(&s->HEVClc);
+ cabac_init_state(s);
+ }
+ if (s->pps->entropy_coding_sync_enabled_flag) {
+ if (ctb_addr_ts % s->sps->ctb_width == 0) {
+ get_cabac_terminate(&s->HEVClc.cc);
+ cabac_reinit(&s->HEVClc);
+
+ if (s->sps->ctb_width == 1)
+ cabac_init_state(s);
+ else
+ load_states(s);
+ }
+ }
+ }
+}
+
+#define GET_CABAC(ctx) get_cabac(&s->HEVClc.cc, &s->HEVClc.cabac_state[ctx])
+
+int ff_hevc_sao_merge_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[SAO_MERGE_FLAG]);
+}
+
+int ff_hevc_sao_type_idx_decode(HEVCContext *s)
+{
+ if (!GET_CABAC(elem_offset[SAO_TYPE_IDX]))
+ return 0;
+
+ if (!get_cabac_bypass(&s->HEVClc.cc))
+ return SAO_BAND;
+ return SAO_EDGE;
+}
+
+int ff_hevc_sao_band_position_decode(HEVCContext *s)
+{
+ int i;
+ int value = get_cabac_bypass(&s->HEVClc.cc);
+
+ for (i = 0; i < 4; i++)
+ value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc);
+ return value;
+}
+
+int ff_hevc_sao_offset_abs_decode(HEVCContext *s)
+{
+ int i = 0;
+ int length = (1 << (FFMIN(s->sps->bit_depth, 10) - 5)) - 1;
+
+ while (i < length && get_cabac_bypass(&s->HEVClc.cc))
+ i++;
+ return i;
+}
+
+int ff_hevc_sao_offset_sign_decode(HEVCContext *s)
+{
+ return get_cabac_bypass(&s->HEVClc.cc);
+}
+
+int ff_hevc_sao_eo_class_decode(HEVCContext *s)
+{
+ int ret = get_cabac_bypass(&s->HEVClc.cc) << 1;
+ ret |= get_cabac_bypass(&s->HEVClc.cc);
+ return ret;
+}
+
+int ff_hevc_end_of_slice_flag_decode(HEVCContext *s)
+{
+ return get_cabac_terminate(&s->HEVClc.cc);
+}
+
+int ff_hevc_cu_transquant_bypass_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[CU_TRANSQUANT_BYPASS_FLAG]);
+}
+
+int ff_hevc_skip_flag_decode(HEVCContext *s, int x0, int y0, int x_cb, int y_cb)
+{
+ int min_cb_width = s->sps->min_cb_width;
+ int inc = 0;
+ int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+
+ if (s->HEVClc.ctb_left_flag || x0b)
+ inc = !!SAMPLE_CTB(s->skip_flag, x_cb - 1, y_cb);
+ if (s->HEVClc.ctb_up_flag || y0b)
+ inc += !!SAMPLE_CTB(s->skip_flag, x_cb, y_cb - 1);
+
+ return GET_CABAC(elem_offset[SKIP_FLAG] + inc);
+}
+
+int ff_hevc_cu_qp_delta_abs(HEVCContext *s)
+{
+ int prefix_val = 0;
+ int suffix_val = 0;
+ int inc = 0;
+
+ while (prefix_val < 5 && GET_CABAC(elem_offset[CU_QP_DELTA] + inc)) {
+ prefix_val++;
+ inc = 1;
+ }
+ if (prefix_val >= 5) {
+ int k = 0;
+ while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc)) {
+ suffix_val += 1 << k;
+ k++;
+ }
+ if (k == CABAC_MAX_BIN)
+ av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
+
+ while (k--)
+ suffix_val += get_cabac_bypass(&s->HEVClc.cc) << k;
+ }
+ return prefix_val + suffix_val;
+}
+
+int ff_hevc_cu_qp_delta_sign_flag(HEVCContext *s)
+{
+ return get_cabac_bypass(&s->HEVClc.cc);
+}
+
+int ff_hevc_pred_mode_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[PRED_MODE_FLAG]);
+}
+
+int ff_hevc_split_coding_unit_flag_decode(HEVCContext *s, int ct_depth, int x0, int y0)
+{
+ int inc = 0, depth_left = 0, depth_top = 0;
+ int x0b = x0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int y0b = y0 & ((1 << s->sps->log2_ctb_size) - 1);
+ int x_cb = x0 >> s->sps->log2_min_cb_size;
+ int y_cb = y0 >> s->sps->log2_min_cb_size;
+
+ if (s->HEVClc.ctb_left_flag || x0b)
+ depth_left = s->tab_ct_depth[(y_cb) * s->sps->min_cb_width + x_cb - 1];
+ if (s->HEVClc.ctb_up_flag || y0b)
+ depth_top = s->tab_ct_depth[(y_cb - 1) * s->sps->min_cb_width + x_cb];
+
+ inc += (depth_left > ct_depth);
+ inc += (depth_top > ct_depth);
+
+ return GET_CABAC(elem_offset[SPLIT_CODING_UNIT_FLAG] + inc);
+}
+
+int ff_hevc_part_mode_decode(HEVCContext *s, int log2_cb_size)
+{
+ if (GET_CABAC(elem_offset[PART_MODE])) // 1
+ return PART_2Nx2N;
+ if (log2_cb_size == s->sps->log2_min_cb_size) {
+ if (s->HEVClc.cu.pred_mode == MODE_INTRA) // 0
+ return PART_NxN;
+ if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01
+ return PART_2NxN;
+ if (log2_cb_size == 3) // 00
+ return PART_Nx2N;
+ if (GET_CABAC(elem_offset[PART_MODE] + 2)) // 001
+ return PART_Nx2N;
+ return PART_NxN; // 000
+ }
+
+ if (!s->sps->amp_enabled_flag) {
+ if (GET_CABAC(elem_offset[PART_MODE] + 1)) // 01
+ return PART_2NxN;
+ return PART_Nx2N;
+ }
+
+ if (GET_CABAC(elem_offset[PART_MODE] + 1)) { // 01X, 01XX
+ if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 011
+ return PART_2NxN;
+ if (get_cabac_bypass(&s->HEVClc.cc)) // 0101
+ return PART_2NxnD;
+ return PART_2NxnU; // 0100
+ }
+
+ if (GET_CABAC(elem_offset[PART_MODE] + 3)) // 001
+ return PART_Nx2N;
+ if (get_cabac_bypass(&s->HEVClc.cc)) // 0001
+ return PART_nRx2N;
+ return PART_nLx2N; // 0000
+}
+
+int ff_hevc_pcm_flag_decode(HEVCContext *s)
+{
+ return get_cabac_terminate(&s->HEVClc.cc);
+}
+
+int ff_hevc_prev_intra_luma_pred_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[PREV_INTRA_LUMA_PRED_FLAG]);
+}
+
+int ff_hevc_mpm_idx_decode(HEVCContext *s)
+{
+ int i = 0;
+ while (i < 2 && get_cabac_bypass(&s->HEVClc.cc))
+ i++;
+ return i;
+}
+
+int ff_hevc_rem_intra_luma_pred_mode_decode(HEVCContext *s)
+{
+ int i;
+ int value = get_cabac_bypass(&s->HEVClc.cc);
+
+ for (i = 0; i < 4; i++)
+ value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc);
+ return value;
+}
+
+int ff_hevc_intra_chroma_pred_mode_decode(HEVCContext *s)
+{
+ int ret;
+ if (!GET_CABAC(elem_offset[INTRA_CHROMA_PRED_MODE]))
+ return 4;
+
+ ret = get_cabac_bypass(&s->HEVClc.cc) << 1;
+ ret |= get_cabac_bypass(&s->HEVClc.cc);
+ return ret;
+}
+
+int ff_hevc_merge_idx_decode(HEVCContext *s)
+{
+ int i = GET_CABAC(elem_offset[MERGE_IDX]);
+
+ if (i != 0) {
+ while (i < s->sh.max_num_merge_cand-1 && get_cabac_bypass(&s->HEVClc.cc))
+ i++;
+ }
+ return i;
+}
+
+int ff_hevc_merge_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[MERGE_FLAG]);
+}
+
+int ff_hevc_inter_pred_idc_decode(HEVCContext *s, int nPbW, int nPbH)
+{
+ if (nPbW + nPbH == 12)
+ return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4);
+ if (GET_CABAC(elem_offset[INTER_PRED_IDC] + s->HEVClc.ct.depth))
+ return PRED_BI;
+
+ return GET_CABAC(elem_offset[INTER_PRED_IDC] + 4);
+}
+
+int ff_hevc_ref_idx_lx_decode(HEVCContext *s, int num_ref_idx_lx)
+{
+ int i = 0;
+ int max = num_ref_idx_lx - 1;
+ int max_ctx = FFMIN(max, 2);
+
+ while (i < max_ctx && GET_CABAC(elem_offset[REF_IDX_L0] + i))
+ i++;
+ if (i == 2) {
+ while (i < max && get_cabac_bypass(&s->HEVClc.cc))
+ i++;
+ }
+
+ return i;
+}
+
+int ff_hevc_mvp_lx_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[MVP_LX_FLAG]);
+}
+
+int ff_hevc_no_residual_syntax_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[NO_RESIDUAL_DATA_FLAG]);
+}
+
+int ff_hevc_abs_mvd_greater0_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[ABS_MVD_GREATER0_FLAG]);
+}
+
+int ff_hevc_abs_mvd_greater1_flag_decode(HEVCContext *s)
+{
+ return GET_CABAC(elem_offset[ABS_MVD_GREATER1_FLAG] + 1);
+}
+
+int ff_hevc_mvd_decode(HEVCContext *s)
+{
+ int ret = 2;
+ int k = 1;
+
+ while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc.cc)) {
+ ret += 1 << k;
+ k++;
+ }
+ if (k == CABAC_MAX_BIN)
+ av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);
+ while (k--)
+ ret += get_cabac_bypass(&s->HEVClc.cc) << k;
+ return get_cabac_bypass_sign(&s->HEVClc.cc, -ret);
+}
+
+int ff_hevc_mvd_sign_flag_decode(HEVCContext *s)
+{
+ return get_cabac_bypass_sign(&s->HEVClc.cc, -1);
+}
+
+int ff_hevc_split_transform_flag_decode(HEVCContext *s, int log2_trafo_size)
+{
+ return GET_CABAC(elem_offset[SPLIT_TRANSFORM_FLAG] + 5 - log2_trafo_size);
+}
+
+int ff_hevc_cbf_cb_cr_decode(HEVCContext *s, int trafo_depth)
+{
+ return GET_CABAC(elem_offset[CBF_CB_CR] + trafo_depth);
+}
+
+int ff_hevc_cbf_luma_decode(HEVCContext *s, int trafo_depth)
+{
+ return GET_CABAC(elem_offset[CBF_LUMA] + !trafo_depth);
+}
+
+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;
+
+int ff_hevc_last_significant_coeff_x_prefix_decode(HEVCContext *s, int c_idx,
+ int log2_size)
+{
+ LAST_SIG_COEFF(LAST_SIGNIFICANT_COEFF_X_PREFIX)
+}
+
+int ff_hevc_last_significant_coeff_y_prefix_decode(HEVCContext *s, int c_idx,
+ int log2_size)
+{
+ LAST_SIG_COEFF(LAST_SIGNIFICANT_COEFF_Y_PREFIX)
+}
+
+int ff_hevc_last_significant_coeff_suffix_decode(HEVCContext *s,
+ int last_significant_coeff_prefix)
+{
+ int i;
+ int length = (last_significant_coeff_prefix >> 1) - 1;
+ int value = get_cabac_bypass(&s->HEVClc.cc);
+
+ for (i = 1; i < length; i++)
+ value = (value << 1) | get_cabac_bypass(&s->HEVClc.cc);
+ return value;
+}
+
+int ff_hevc_significant_coeff_group_flag_decode(HEVCContext *s, int c_idx, int ctx_cg)
+{
+ int inc;
+
+ 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 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
+ };
+ int x_cg = x_c >> 2;
+ int y_cg = y_c >> 2;
+ int sig_ctx, 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;
+
+ return GET_CABAC(elem_offset[SIGNIFICANT_COEFF_FLAG] + inc);
+}
+
+int ff_hevc_coeff_abs_level_greater1_flag_decode(HEVCContext *s, int c_idx, int inc)
+{
+
+ if (c_idx > 0)
+ inc += 16;
+
+ 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 inc)
+{
+ 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 base_level, int rc_rice_param)
+{
+ int prefix = 0;
+ int suffix = 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 < rc_rice_param; i++)
+ suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc.cc);
+ last_coeff_abs_level_remaining = (prefix << rc_rice_param) + suffix;
+ } else {
+ int prefix_minus3 = prefix - 3;
+ for (i = 0; i < prefix_minus3 + rc_rice_param; i++)
+ suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc.cc);
+ last_coeff_abs_level_remaining = (((1 << prefix_minus3) + 3 - 1)
+ << rc_rice_param) + suffix;
+ }
+ return last_coeff_abs_level_remaining;
+}
+
+int ff_hevc_coeff_sign_flag(HEVCContext *s, uint8_t nb)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < nb; i++)
+ ret = (ret << 1) | get_cabac_bypass(&s->HEVClc.cc);
+ return ret;
+}