From: Ronald S. Bultje Date: Thu, 25 Oct 2012 19:05:37 +0000 (-0700) Subject: Fix 4x4 intra prediction on the edge of SB rows. X-Git-Tag: v1.3.0~1217^2~182 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fbf2ac111e2bf104cefe6080e822c626f65753f2;p=libvpx Fix 4x4 intra prediction on the edge of SB rows. Change-Id: I87d571008c73f0a8514e0a864405aadb82fd1bc0 --- diff --git a/vp8/common/reconintra4x4.c b/vp8/common/reconintra4x4.c index dfbaf137b..1e40168ec 100644 --- a/vp8/common/reconintra4x4.c +++ b/vp8/common/reconintra4x4.c @@ -295,7 +295,7 @@ void vp8_comp_intra4x4_predict_c(BLOCKD *x, /* copy 4 bytes from the above right down so that the 4x4 prediction modes using pixels above and * to the right prediction have filled in pixels to use. */ -void vp8_intra_prediction_down_copy(MACROBLOCKD *xd) { +void vp8_intra_prediction_down_copy(MACROBLOCKD *xd, int extend_edge) { unsigned char *above_right = *(xd->block[0].base_dst) + xd->block[0].dst - xd->block[0].dst_stride + 16; unsigned int *src_ptr = (unsigned int *) @@ -309,6 +309,10 @@ void vp8_intra_prediction_down_copy(MACROBLOCKD *xd) { unsigned int *dst_ptr3 = (unsigned int *)(above_right + 12 * xd->block[0].dst_stride); + if (extend_edge) { + *src_ptr = ((uint8_t *) src_ptr)[-1] * 0x01010101U; + } + *dst_ptr0 = *src_ptr; *dst_ptr1 = *src_ptr; *dst_ptr2 = *src_ptr; diff --git a/vp8/common/reconintra4x4.h b/vp8/common/reconintra4x4.h index a8cdea47c..771e0b2eb 100644 --- a/vp8/common/reconintra4x4.h +++ b/vp8/common/reconintra4x4.h @@ -12,6 +12,6 @@ #ifndef __INC_RECONINTRA4x4_H #define __INC_RECONINTRA4x4_H -extern void vp8_intra_prediction_down_copy(MACROBLOCKD *xd); +extern void vp8_intra_prediction_down_copy(MACROBLOCKD *xd, int extend_edge); #endif diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 2f0af2925..d78fea2ec 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -202,15 +202,15 @@ static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd) { } static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, - unsigned int mb_col, + int mb_row, unsigned int mb_col, BOOL_DECODER* const bc) { int eobtotal = 0; MB_PREDICTION_MODE mode; int i; int tx_size; TX_TYPE tx_type; -#if CONFIG_SUPERBLOCKS VP8_COMMON *pc = &pbi->common; +#if CONFIG_SUPERBLOCKS int orig_skip_flag = xd->mode_info_context->mbmi.mb_skip_coeff; #endif @@ -355,7 +355,8 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, b->dst_stride); } } else if (mode == B_PRED) { - vp8_intra_prediction_down_copy(xd); + vp8_intra_prediction_down_copy(xd, mb_col == pc->mb_cols - 1 && + !(mb_row & 1)); for (i = 0; i < 16; i++) { BLOCKD *b = &xd->block[i]; int b_mode = xd->mode_info_context->bmi[i].as_mode.first; @@ -659,7 +660,7 @@ decode_sb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mbrow, MACROBLOCKD *xd, mi[pc->mode_info_stride + 1] = mi[0]; } #endif - decode_macroblock(pbi, xd, mb_col, bc); + decode_macroblock(pbi, xd, mb_row, mb_col, bc); #if CONFIG_SUPERBLOCKS if (xd->mode_info_context->mbmi.encoded_as_sb) { mi[1].mbmi.txfm_size = mi[0].mbmi.txfm_size; diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 0910cfd35..893a33817 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -19,6 +19,7 @@ #include "vp8/common/quant_common.h" #include "segmentation.h" #include "vp8/common/setupintrarecon.h" +#include "vp8/common/reconintra4x4.h" #include "encodeintra.h" #include "vp8/common/reconinter.h" #include "vp8/common/invtrans.h" @@ -614,6 +615,9 @@ static void pick_mb_modes(VP8_COMP *cpi, cpi->update_context = 0; // TODO Do we need this now?? + vp8_intra_prediction_down_copy(xd, mb_col == cm->mb_cols - 1 && + (mb_row & 1) == 0); + // Find best coding mode & reconstruct the MB so it is available // as a predictor for MBs that follow in the SB if (cm->frame_type == KEY_FRAME) { @@ -1911,7 +1915,6 @@ void vp8cx_encode_intra_macro_block(VP8_COMP *cpi, vp8_encode_intra8x8mby(IF_RTCD(&cpi->rtcd), x); vp8_encode_intra8x8mbuv(IF_RTCD(&cpi->rtcd), x); } else if (mbmi->mode == B_PRED) { - vp8_intra_prediction_down_copy(&x->e_mbd); vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x); } else { vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x); @@ -2009,7 +2012,6 @@ void vp8cx_encode_inter_macroblock (VP8_COMP *cpi, MACROBLOCK *x, if (mbmi->ref_frame == INTRA_FRAME) { if (mbmi->mode == B_PRED) { - vp8_intra_prediction_down_copy(xd); vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x); vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x); } else if (mbmi->mode == I8X8_PRED) { diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index b8e3efb01..b2207cb1f 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1212,8 +1212,6 @@ static int64_t rd_pick_intra4x4mby_modes(VP8_COMP *cpi, MACROBLOCK *mb, int *Rat xd->mode_info_context->mbmi.mode = B_PRED; bmode_costs = mb->inter_bmode_costs; - vp8_intra_prediction_down_copy(xd); - for (i = 0; i < 16; i++) { MODE_INFO *const mic = xd->mode_info_context; const int mis = xd->mode_info_stride;