diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 4ab09c596a28f4e928f68324f12d5b68f69713ef..003babbbcb59d85b570f719e3990b6d095707514 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -109,32 +109,12 @@ void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd) #define RTCD_VTABLE(x) NULL #endif -/* skip_recon_mb() is Modified: Instead of writing the result to predictor buffer and then copying it - * to dst buffer, we can write the result directly to dst buffer. This eliminates unnecessary copy. - */ -static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd) -{ - if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) - { - RECON_INVOKE(&pbi->common.rtcd.recon, build_intra_predictors_mbuv_s)(xd); - RECON_INVOKE(&pbi->common.rtcd.recon, - build_intra_predictors_mby_s)(xd); - } - else - { - vp8_build_inter16x16_predictors_mb(xd, xd->dst.y_buffer, - xd->dst.u_buffer, xd->dst.v_buffer, - xd->dst.y_stride, xd->dst.uv_stride); - } -} - static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, unsigned int mb_idx) { - int eobtotal = 0; - int throw_residual = 0; MB_PREDICTION_MODE mode; int i; + int corruption_detected = 0; if (xd->mode_info_context->mbmi.mb_skip_coeff) { @@ -142,27 +122,51 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, } else if (!vp8dx_bool_error(xd->current_bc)) { + int eobtotal; eobtotal = vp8_decode_mb_tokens(pbi, xd); + + /* Special case: Force the loopfilter to skip when eobtotal is zero */ + xd->mode_info_context->mbmi.mb_skip_coeff = (eobtotal==0); } + mode = xd->mode_info_context->mbmi.mode; + if (xd->segmentation_enabled) + mb_init_dequantizer(pbi, xd); - mode = xd->mode_info_context->mbmi.mode; - if (eobtotal == 0 && mode != B_PRED && mode != SPLITMV && - !vp8dx_bool_error(xd->current_bc)) +#if CONFIG_ERROR_CONCEALMENT + + if(pbi->ec_active) { - /* Special case: Force the loopfilter to skip when eobtotal and - * mb_skip_coeff are zero. - * */ - xd->mode_info_context->mbmi.mb_skip_coeff = 1; + int throw_residual; + /* When we have independent partitions we can apply residual even + * though other partitions within the frame are corrupt. + */ + throw_residual = (!pbi->independent_partitions && + pbi->frame_corrupt_residual); + throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc)); - skip_recon_mb(pbi, xd); - return; + if ((mb_idx >= pbi->mvs_corrupt_from_mb || throw_residual)) + { + /* MB with corrupt residuals or corrupt mode/motion vectors. + * Better to use the predictor as reconstruction. + */ + pbi->frame_corrupt_residual = 1; + vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff)); + vp8_conceal_corrupt_mb(xd); + + + corruption_detected = 1; + + /* force idct to be skipped for B_PRED and use the + * prediction only for reconstruction + * */ + vpx_memset(xd->eobs, 0, 25); + } } +#endif - if (xd->segmentation_enabled) - mb_init_dequantizer(pbi, xd); /* do prediction */ if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) @@ -173,121 +177,117 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, { RECON_INVOKE(&pbi->common.rtcd.recon, build_intra_predictors_mby_s)(xd); - } else { + } + else + { + /* clear out residual eob info */ + if(xd->mode_info_context->mbmi.mb_skip_coeff) + vpx_memset(xd->eobs, 0, 25); + vp8_intra_prediction_down_copy(xd); + + for (i = 0; i < 16; i++) + { + BLOCKD *b = &xd->block[i]; + int b_mode = xd->mode_info_context->bmi[i].as_mode; + + RECON_INVOKE(RTCD_VTABLE(recon), intra4x4_predict) + ( *(b->base_dst) + b->dst, b->dst_stride, b_mode, + *(b->base_dst) + b->dst, b->dst_stride ); + + if (xd->eobs[i]) + { + if (xd->eobs[i] > 1) + { + DEQUANT_INVOKE(&pbi->common.rtcd.dequant, idct_add) + (b->qcoeff, b->dequant, + *(b->base_dst) + b->dst, b->dst_stride); + } + else + { + IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar_add) + (b->qcoeff[0] * b->dequant[0], + *(b->base_dst) + b->dst, b->dst_stride, + *(b->base_dst) + b->dst, b->dst_stride); + ((int *)b->qcoeff)[0] = 0; + } + } + } } } else { vp8_build_inter_predictors_mb(xd); } - /* When we have independent partitions we can apply residual even - * though other partitions within the frame are corrupt. - */ - throw_residual = (!pbi->independent_partitions && - pbi->frame_corrupt_residual); - throw_residual = (throw_residual || vp8dx_bool_error(xd->current_bc)); + #if CONFIG_ERROR_CONCEALMENT - if (pbi->ec_active && - (mb_idx >= pbi->mvs_corrupt_from_mb || throw_residual)) + if (corruption_detected) { - /* MB with corrupt residuals or corrupt mode/motion vectors. - * Better to use the predictor as reconstruction. - */ - pbi->frame_corrupt_residual = 1; - vpx_memset(xd->qcoeff, 0, sizeof(xd->qcoeff)); - vp8_conceal_corrupt_mb(xd); return; } #endif - /* dequantization and idct */ - if (mode == B_PRED) + if(!xd->mode_info_context->mbmi.mb_skip_coeff) { - for (i = 0; i < 16; i++) + /* dequantization and idct */ + if (mode != B_PRED) { - BLOCKD *b = &xd->block[i]; - int b_mode = xd->mode_info_context->bmi[i].as_mode; + short *DQC = xd->block[0].dequant; - RECON_INVOKE(RTCD_VTABLE(recon), intra4x4_predict) - ( *(b->base_dst) + b->dst, b->dst_stride, b_mode, - *(b->base_dst) + b->dst, b->dst_stride ); + /* save the dc dequant constant in case it is overridden */ + short dc_dequant_temp = DQC[0]; - if (xd->eobs[i] ) + if (mode != SPLITMV) { - if (xd->eobs[i] > 1) + BLOCKD *b = &xd->block[24]; + + /* do 2nd order transform on the dc block */ + if (xd->eobs[24] > 1) { - DEQUANT_INVOKE(&pbi->common.rtcd.dequant, idct_add) - (b->qcoeff, b->dequant, - *(b->base_dst) + b->dst, b->dst_stride); + DEQUANT_INVOKE(&pbi->common.rtcd.dequant, block)(b); + + IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], + xd->qcoeff); + ((int *)b->qcoeff)[0] = 0; + ((int *)b->qcoeff)[1] = 0; + ((int *)b->qcoeff)[2] = 0; + ((int *)b->qcoeff)[3] = 0; + ((int *)b->qcoeff)[4] = 0; + ((int *)b->qcoeff)[5] = 0; + ((int *)b->qcoeff)[6] = 0; + ((int *)b->qcoeff)[7] = 0; } else { - IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar_add) - (b->qcoeff[0] * b->dequant[0], - *(b->base_dst) + b->dst, b->dst_stride, - *(b->base_dst) + b->dst, b->dst_stride); + b->dqcoeff[0] = b->qcoeff[0] * b->dequant[0]; + IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], + xd->qcoeff); ((int *)b->qcoeff)[0] = 0; } - } - } - } - else - { - short *DQC = xd->block[0].dequant; - - /* save the dc dequant constant in case it is overridden */ - short dc_dequant_temp = DQC[0]; - - if (mode != SPLITMV) - { - BLOCKD *b = &xd->block[24]; - /* do 2nd order transform on the dc block */ - if (xd->eobs[24] > 1) - { - DEQUANT_INVOKE(&pbi->common.rtcd.dequant, block)(b); - - IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], - xd->qcoeff); - ((int *)b->qcoeff)[0] = 0; - ((int *)b->qcoeff)[1] = 0; - ((int *)b->qcoeff)[2] = 0; - ((int *)b->qcoeff)[3] = 0; - ((int *)b->qcoeff)[4] = 0; - ((int *)b->qcoeff)[5] = 0; - ((int *)b->qcoeff)[6] = 0; - ((int *)b->qcoeff)[7] = 0; - } - else - { - b->dqcoeff[0] = b->qcoeff[0] * b->dequant[0]; - IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], - xd->qcoeff); - ((int *)b->qcoeff)[0] = 0; + /* override the dc dequant constant in order to preserve the + * dc components + */ + DQC[0] = 1; } - /* override the dc dequant constant */ - DQC[0] = 1; - } + DEQUANT_INVOKE (&pbi->common.rtcd.dequant, idct_add_y_block) + (xd->qcoeff, xd->block[0].dequant, + xd->dst.y_buffer, + xd->dst.y_stride, xd->eobs); - DEQUANT_INVOKE (&pbi->common.rtcd.dequant, idct_add_y_block) - (xd->qcoeff, xd->block[0].dequant, - xd->dst.y_buffer, - xd->dst.y_stride, xd->eobs); + /* restore the dc dequant constant */ + DQC[0] = dc_dequant_temp; + } - /* restore the dc dequant constant */ - DQC[0] = dc_dequant_temp; + DEQUANT_INVOKE (&pbi->common.rtcd.dequant, idct_add_uv_block) + (xd->qcoeff+16*16, xd->block[16].dequant, + xd->dst.u_buffer, xd->dst.v_buffer, + xd->dst.uv_stride, xd->eobs+16); } - - DEQUANT_INVOKE (&pbi->common.rtcd.dequant, idct_add_uv_block) - (xd->qcoeff+16*16, xd->block[16].dequant, - xd->dst.u_buffer, xd->dst.v_buffer, - xd->dst.uv_stride, xd->eobs+16); } - static int get_delta_q(vp8_reader *bc, int prev, int *q_update) { int ret_val = 0;