From 67e41fe2f6f23029b78eede549a1a2223f91eccb Mon Sep 17 00:00:00 2001 From: James Zern Date: Wed, 16 Oct 2013 18:33:43 +0200 Subject: [PATCH] vp9 com/dec: avoid reading unavailable above/left in most cases at least the left column was a harmless race as it was left unused later in the code. Change-Id: I43211df66fb157c6feecf08c681add4fcf18b644 --- vp9/common/vp9_pred_common.c | 96 ++++++++++++++++++++++++-------------------- vp9/common/vp9_pred_common.h | 31 +++++++++----- vp9/decoder/vp9_decodemv.c | 11 ++--- 3 files changed, 78 insertions(+), 60 deletions(-) diff --git a/vp9/common/vp9_pred_common.c b/vp9/common/vp9_pred_common.c index 9453d02..be42c56 100644 --- a/vp9/common/vp9_pred_common.c +++ b/vp9/common/vp9_pred_common.c @@ -16,12 +16,20 @@ #include "vp9/common/vp9_seg_common.h" #include "vp9/common/vp9_treecoder.h" +static INLINE const MB_MODE_INFO *get_above_mbmi(const MODE_INFO *const above) { + return (above != NULL) ? &above->mbmi : NULL; +} + +static INLINE const MB_MODE_INFO *get_left_mbmi(const MODE_INFO *const left) { + return (left != NULL) ? &left->mbmi : NULL; +} + // Returns a context number for the given MB prediction signal unsigned char vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) { - const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const int left_in_image = xd->left_available && left_mi; - const int above_in_image = xd->up_available && above_mi; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const int above_in_image = above_mi != NULL; + const int left_in_image = left_mi != NULL; // Note: // The mode info data structure has a one element border above and to the // left of the entries correpsonding to real macroblocks. @@ -53,14 +61,14 @@ unsigned char vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) { } // Returns a context number for the given MB prediction signal unsigned char vp9_get_pred_context_intra_inter(const MACROBLOCKD *xd) { - const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0; - const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0; - const int left_in_image = xd->left_available && left_mi; - const int above_in_image = xd->up_available && above_mi; - const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); + const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); + const int above_in_image = above_mi != NULL; + const int left_in_image = left_mi != NULL; const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1; + const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; // The mode info data structure has a one element border above and to the // left of the entries corresponding to real macroblocks. @@ -81,12 +89,12 @@ unsigned char vp9_get_pred_context_intra_inter(const MACROBLOCKD *xd) { unsigned char vp9_get_pred_context_comp_inter_inter(const VP9_COMMON *cm, const MACROBLOCKD *xd) { int pred_context; - const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0; - const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0; - const int left_in_image = xd->left_available && left_mi; - const int above_in_image = xd->up_available && above_mi; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); + const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); + const int above_in_image = above_mi != NULL; + const int left_in_image = left_mi != NULL; // Note: // The mode info data structure has a one element border above and to the // left of the entries correpsonding to real macroblocks. @@ -126,14 +134,14 @@ unsigned char vp9_get_pred_context_comp_inter_inter(const VP9_COMMON *cm, unsigned char vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm, const MACROBLOCKD *xd) { int pred_context; - const MODE_INFO * const above_mi = xd->mi_8x8[-cm->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0; - const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0; - const int left_in_image = xd->left_available && left_mi; - const int above_in_image = xd->up_available && above_mi; - const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); + const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); + const int above_in_image = above_mi != NULL; + const int left_in_image = left_mi != NULL; const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1; + const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; // Note: // The mode info data structure has a one element border above and to the // left of the entries correpsonding to real macroblocks. @@ -206,14 +214,14 @@ unsigned char vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm, } unsigned char vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) { int pred_context; - const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0; - const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0; - const int left_in_image = xd->left_available && left_mi; - const int above_in_image = xd->up_available && above_mi; - const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); + const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); + const int above_in_image = above_mi != NULL; + const int left_in_image = left_mi != NULL; const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1; + const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; // Note: // The mode info data structure has a one element border above and to the // left of the entries correpsonding to real macroblocks. @@ -272,14 +280,14 @@ unsigned char vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) { unsigned char vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) { int pred_context; - const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0; - const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0; - const int left_in_image = xd->left_available && left_mi; - const int above_in_image = xd->up_available && above_mi; - const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); + const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); + const int above_in_image = above_mi != NULL; + const int left_in_image = left_mi != NULL; const int above_intra = above_in_image ? !is_inter_block(above_mbmi) : 1; + const int left_intra = left_in_image ? !is_inter_block(left_mbmi) : 1; // Note: // The mode info data structure has a one element border above and to the @@ -361,12 +369,12 @@ unsigned char vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) { // left of the entries corresponding to real blocks. // The prediction flags in these dummy entries are initialized to 0. unsigned char vp9_get_pred_context_tx_size(const MACROBLOCKD *xd) { - const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const MB_MODE_INFO *const above_mbmi = above_mi ? &above_mi->mbmi : 0; - const MB_MODE_INFO *const left_mbmi = left_mi ? &left_mi->mbmi : 0; - const int left_in_image = xd->left_available && left_mi; - const int above_in_image = xd->up_available && above_mi; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const MB_MODE_INFO *const above_mbmi = get_above_mbmi(above_mi); + const MB_MODE_INFO *const left_mbmi = get_left_mbmi(left_mi); + const int above_in_image = above_mi != NULL; + const int left_in_image = left_mi != NULL; const int max_tx_size = max_txsize_lookup[xd->mi_8x8[0]->mbmi.sb_type]; int above_context = max_tx_size; int left_context = max_tx_size; diff --git a/vp9/common/vp9_pred_common.h b/vp9/common/vp9_pred_common.h index 1fdd4da..a869dc0 100644 --- a/vp9/common/vp9_pred_common.h +++ b/vp9/common/vp9_pred_common.h @@ -14,17 +14,25 @@ #include "vp9/common/vp9_blockd.h" #include "vp9/common/vp9_onyxc_int.h" +static INLINE const MODE_INFO *get_above_mi(const MACROBLOCKD *const xd) { + return xd->up_available ? xd->mi_8x8[-xd->mode_info_stride] : NULL; +} + +static INLINE const MODE_INFO *get_left_mi(const MACROBLOCKD *const xd) { + return xd->left_available ? xd->mi_8x8[-1] : NULL; +} + int vp9_get_segment_id(VP9_COMMON *cm, const uint8_t *segment_ids, BLOCK_SIZE bsize, int mi_row, int mi_col); - static INLINE int vp9_get_pred_context_seg_id(const MACROBLOCKD *xd) { - const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const int above_sip = above_mi ? above_mi->mbmi.seg_id_predicted : 0; - const int left_sip = left_mi ? left_mi->mbmi.seg_id_predicted : 0; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const int above_sip = (above_mi != NULL) ? + above_mi->mbmi.seg_id_predicted : 0; + const int left_sip = (left_mi != NULL) ? left_mi->mbmi.seg_id_predicted : 0; - return above_sip + (xd->left_available ? left_sip : 0); + return above_sip + left_sip; } static INLINE vp9_prob vp9_get_pred_prob_seg_id(struct segmentation *seg, @@ -35,12 +43,13 @@ static INLINE vp9_prob vp9_get_pred_prob_seg_id(struct segmentation *seg, void vp9_set_pred_flag_seg_id(MACROBLOCKD *xd, uint8_t pred_flag); static INLINE int vp9_get_pred_context_mbskip(const MACROBLOCKD *xd) { - const MODE_INFO * const above_mi = xd->mi_8x8[-xd->mode_info_stride]; - const MODE_INFO * const left_mi = xd->mi_8x8[-1]; - const int above_skip_coeff = above_mi ? above_mi->mbmi.skip_coeff : 0; - const int left_skip_coeff = left_mi ? left_mi->mbmi.skip_coeff : 0; + const MODE_INFO *const above_mi = get_above_mi(xd); + const MODE_INFO *const left_mi = get_left_mi(xd); + const int above_skip_coeff = (above_mi != NULL) ? + above_mi->mbmi.skip_coeff : 0; + const int left_skip_coeff = (left_mi != NULL) ? left_mi->mbmi.skip_coeff : 0; - return above_skip_coeff + (xd->left_available ? left_skip_coeff : 0); + return above_skip_coeff + left_skip_coeff; } static INLINE vp9_prob vp9_get_pred_prob_mbskip(const VP9_COMMON *cm, diff --git a/vp9/decoder/vp9_decodemv.c b/vp9/decoder/vp9_decodemv.c index 6cf4f15..8a8f7d5 100644 --- a/vp9/decoder/vp9_decodemv.c +++ b/vp9/decoder/vp9_decodemv.c @@ -173,7 +173,6 @@ static void read_intra_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *m, MB_MODE_INFO *const mbmi = &m->mbmi; const BLOCK_SIZE bsize = mbmi->sb_type; const MODE_INFO *above_mi = xd->mi_8x8[-cm->mode_info_stride]; - const MODE_INFO *left_mi = xd->mi_8x8[-1]; mbmi->segment_id = read_intra_segment_id(pbi, mi_row, mi_col, r); mbmi->skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r); @@ -183,8 +182,9 @@ static void read_intra_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *m, if (bsize >= BLOCK_8X8) { const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, 0); - const MB_PREDICTION_MODE L = xd->left_available ? - left_block_mode(m, left_mi, 0) : DC_PRED; + const MB_PREDICTION_MODE L = xd->left_available + ? left_block_mode(m, xd->mi_8x8[-1], 0) + : DC_PRED; mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]); } else { // Only 4x4, 4x8, 8x4 blocks @@ -196,8 +196,9 @@ static void read_intra_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *m, for (idx = 0; idx < 2; idx += num_4x4_w) { const int ib = idy * 2 + idx; const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, ib); - const MB_PREDICTION_MODE L = (xd->left_available || idx) ? - left_block_mode(m, left_mi, ib) : DC_PRED; + const MB_PREDICTION_MODE L = (xd->left_available || idx) + ? left_block_mode(m, xd->mi_8x8[-1], ib) + : DC_PRED; const MB_PREDICTION_MODE b_mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]); m->bmi[ib].as_mode = b_mode; -- 2.7.4