diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-01-21 15:42:51 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-02-23 16:42:21 +0100 |
commit | 2368d08e701acf7942bf6d70a40a3e70186199ea (patch) | |
tree | 33dc8bc79cf603e85e02a949f2c2c0755d6b0aa2 /libavcodec/hevc.c | |
parent | ea7ccf3748452b614b6ae81fa814303a49733fc2 (diff) | |
download | ffmpeg-2368d08e701acf7942bf6d70a40a3e70186199ea.tar.gz |
Merge commit 'e22ebd04bcab7f86548794556c28ecca46d9c2ac'
* commit 'e22ebd04bcab7f86548794556c28ecca46d9c2ac':
hevc: Bound check cu_qp_delta
Conflicts:
libavcodec/hevc.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit a69dd1163b1a91978e596af551c9561d121aeedf)
Conflicts:
libavcodec/hevc.c
Diffstat (limited to 'libavcodec/hevc.c')
-rw-r--r-- | libavcodec/hevc.c | 78 |
1 files changed, 54 insertions, 24 deletions
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 1d1a578a02..f8438d4bc3 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -743,11 +743,10 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry) #undef SET_SAO #undef CTB - -static void 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, - int trafo_depth, int blk_idx) +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, + int trafo_depth, int blk_idx) { HEVCLocalContext *lc = s->HEVClc; @@ -781,6 +780,18 @@ static void hls_transform_unit(HEVCContext *s, int x0, int y0, if (ff_hevc_cu_qp_delta_sign_flag(s) == 1) lc->tu.cu_qp_delta = -lc->tu.cu_qp_delta; lc->tu.is_cu_qp_delta_coded = 1; + + if (lc->tu.cu_qp_delta < -(26 + s->sps->qp_bd_offset / 2) || + lc->tu.cu_qp_delta > (25 + s->sps->qp_bd_offset / 2)) { + av_log(s->avctx, AV_LOG_ERROR, + "The cu_qp_delta %d is outside the valid range " + "[%d, %d].\n", + lc->tu.cu_qp_delta, + -(26 + s->sps->qp_bd_offset / 2), + (25 + s->sps->qp_bd_offset / 2)); + return AVERROR_INVALIDDATA; + } + ff_hevc_set_qPy(s, x0, y0, cb_xBase, cb_yBase, log2_cb_size); } @@ -816,6 +827,7 @@ static void hls_transform_unit(HEVCContext *s, int x0, int y0, ff_hevc_hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 2); } } + return 0; } static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_size) @@ -833,13 +845,14 @@ static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_si s->is_pcm[i + j * min_pu_width] = 2; } -static void hls_transform_tree(HEVCContext *s, int x0, int y0, - int xBase, int yBase, int cb_xBase, int cb_yBase, - int log2_cb_size, int log2_trafo_size, - int trafo_depth, int blk_idx) +static int hls_transform_tree(HEVCContext *s, int x0, int y0, + int xBase, int yBase, int cb_xBase, int cb_yBase, + int log2_cb_size, int log2_trafo_size, + int trafo_depth, int blk_idx) { HEVCLocalContext *lc = s->HEVClc; uint8_t split_transform_flag; + int ret; if (trafo_depth > 0 && log2_trafo_size == 2) { SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) = @@ -892,14 +905,26 @@ static void hls_transform_tree(HEVCContext *s, int x0, int y0, int x1 = x0 + ((1 << log2_trafo_size) >> 1); int y1 = y0 + ((1 << log2_trafo_size) >> 1); - hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size, - log2_trafo_size - 1, trafo_depth + 1, 0); - hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size, - log2_trafo_size - 1, trafo_depth + 1, 1); - hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size, - log2_trafo_size - 1, trafo_depth + 1, 2); - hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size, - log2_trafo_size - 1, trafo_depth + 1, 3); + ret = hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size - 1, + trafo_depth + 1, 0); + if (ret < 0) + return ret; + ret = hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size - 1, + trafo_depth + 1, 1); + if (ret < 0) + return ret; + ret = hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size - 1, + trafo_depth + 1, 2); + if (ret < 0) + return ret; + ret = hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size - 1, + trafo_depth + 1, 3); + if (ret < 0) + return ret; } else { int min_tu_size = 1 << s->sps->log2_min_tb_size; int log2_min_tu_size = s->sps->log2_min_tb_size; @@ -911,9 +936,11 @@ static void hls_transform_tree(HEVCContext *s, int x0, int y0, lc->tt.cbf_luma = ff_hevc_cbf_luma_decode(s, trafo_depth); } - hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase, - log2_cb_size, log2_trafo_size, trafo_depth, blk_idx); - + ret = hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size, trafo_depth, + blk_idx); + if (ret < 0) + return ret; // TODO: store cbf_luma somewhere else if (lc->tt.cbf_luma) { int i, j; @@ -932,6 +959,7 @@ static void hls_transform_tree(HEVCContext *s, int x0, int y0, set_deblocking_bypass(s, x0, y0, log2_trafo_size); } } + return 0; } static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) @@ -1520,7 +1548,7 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) int min_cb_width = s->sps->min_cb_width; int x_cb = x0 >> log2_min_cb_size; int y_cb = y0 >> log2_min_cb_size; - int x, y; + int x, y, ret; lc->cu.x = x0; lc->cu.y = y0; @@ -1577,7 +1605,6 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) lc->cu.pcm_flag = ff_hevc_pcm_flag_decode(s); } if (lc->cu.pcm_flag) { - int ret; intra_prediction_unit_default_value(s, x0, y0, log2_cb_size); ret = hls_pcm_sample(s, x0, y0, log2_cb_size); if (s->sps->pcm.loop_filter_disable_flag) @@ -1636,8 +1663,11 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ? s->sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag : s->sps->max_transform_hierarchy_depth_inter; - hls_transform_tree(s, x0, y0, x0, y0, x0, y0, log2_cb_size, - log2_cb_size, 0, 0); + ret = hls_transform_tree(s, x0, y0, x0, y0, x0, y0, + log2_cb_size, + log2_cb_size, 0, 0); + if (ret < 0) + return ret; } else { if (!s->sh.disable_deblocking_filter_flag) ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size, |