From a9df4183a6587719c9530d45d5dbd81530be9e7b Mon Sep 17 00:00:00 2001 From: Paul Wilkins <paulwilkins@google.com> Date: Fri, 4 Nov 2011 18:29:51 +0000 Subject: [PATCH] Segment signaling of TX size Initial attempt at using new segment feature signaling to indicate 4x4 or 8x8 transform. needs --enable-experimental --enable-t8x8 Note this is work in progress. Change-Id: Ib160d46a5d810307bfcbc79853ce1a65b5b870b7 --- vp8/common/seg_common.c | 7 +++++++ vp8/common/seg_common.h | 1 + vp8/decoder/decodframe.c | 16 +++++++++++----- vp8/encoder/encodeframe.c | 34 ++++++++++++++++++++-------------- vp8/encoder/encodeintra.c | 27 +++++++++++++++++++-------- vp8/encoder/encodemb.c | 28 +++++++++++++++++++++------- vp8/encoder/onyx_if.c | 23 +++++++++++++---------- vp8/encoder/rdopt.c | 7 ++++++- vp8/encoder/tokenize.c | 12 ++++++++---- 9 files changed, 106 insertions(+), 49 deletions(-) diff --git a/vp8/common/seg_common.c b/vp8/common/seg_common.c index bd16c34078..ee9ead4a5a 100644 --- a/vp8/common/seg_common.c +++ b/vp8/common/seg_common.c @@ -107,4 +107,11 @@ int check_segref_inter(MACROBLOCKD *xd, int segment_id) ~(1 << INTRA_FRAME) ) ? 1 : 0; } +int get_seg_tx_type(MACROBLOCKD *xd, int segment_id) +{ + if ( segfeature_active(xd, segment_id, SEG_LVL_TRANSFORM) ) + return get_segdata(xd, segment_id, SEG_LVL_TRANSFORM); + else + return TX_4X4; +} // TBD? Functions to read and write segment data with range / validity checking diff --git a/vp8/common/seg_common.h b/vp8/common/seg_common.h index b0498edf55..876b806ada 100644 --- a/vp8/common/seg_common.h +++ b/vp8/common/seg_common.h @@ -55,6 +55,7 @@ int check_segref( MACROBLOCKD *xd, int check_segref_inter(MACROBLOCKD *xd, int segment_id); +int get_seg_tx_type(MACROBLOCKD *xd, int segment_id); #endif /* __INC_SEG_COMMON_H__ */ diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 4fdc3ea3d1..aa079d8bd2 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -78,7 +78,6 @@ void mb_init_dequantizer(VP8D_COMP *pbi, MACROBLOCKD *xd) VP8_COMMON *const pc = & pbi->common; int segment_id = xd->mode_info_context->mbmi.segment_id; - // Set the Q baseline allowing for any segment level adjustment //#if CONFIG_SEGFEATURES if ( segfeature_active( xd, segment_id, SEG_LVL_ALT_Q ) ) @@ -210,6 +209,11 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, MB_PREDICTION_MODE mode; int i; +#if CONFIG_T8X8 + int tx_type = get_seg_tx_type(xd, xd->mode_info_context->mbmi.segment_id); +#endif + + if (xd->mode_info_context->mbmi.mb_skip_coeff) { vp8_reset_mb_tokens_context(xd); @@ -223,8 +227,10 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, xd->block[i].eob = 0; xd->eobs[i] = 0; } - if (xd->mode_info_context->mbmi.segment_id >= 2) + if ( tx_type == TX_8X8 ) + { eobtotal = vp8_decode_mb_tokens_8x8(pbi, xd); + } else #endif eobtotal = vp8_decode_mb_tokens(pbi, xd); @@ -392,7 +398,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, else if (mode == SPLITMV) { #if CONFIG_T8X8 - if(xd->mode_info_context->mbmi.segment_id >= 2) + if ( tx_type == TX_8X8 ) { DEQUANT_INVOKE (&pbi->dequant, idct_add_y_block_8x8) (xd->qcoeff, xd->block[0].dequant, @@ -416,7 +422,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, /* do 2nd order transform on the dc block */ #if CONFIG_T8X8 - if(xd->mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) { DEQUANT_INVOKE(&pbi->dequant, block_8x8)(b); #ifdef DEC_DEBUG @@ -474,7 +480,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, } } #if CONFIG_T8X8 - if(xd->mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) { DEQUANT_INVOKE (&pbi->dequant, idct_add_uv_block_8x8)// (xd->qcoeff+16*16, xd->block[16].dequant, diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 4def6339ff..eab6c817aa 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -247,6 +247,7 @@ double Compute_Wtd_SSE_SubEntropy(MACROBLOCK *x) -sse_4*log(sse_4))/log(2); } } + if(variance_8[0]+variance_8[1]+variance_8[2]+variance_8[3]) return (entropy_8[0]*variance_8[0]+ entropy_8[1]*variance_8[1]+ @@ -1567,8 +1568,11 @@ int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t) sum_intra_stats(cpi, x); vp8_tokenize_mb(cpi, &x->e_mbd, t); #if CONFIG_T8X8 - if( x->e_mbd.mode_info_context->mbmi.segment_id >=2) + if ( get_seg_tx_type(&x->e_mbd, + x->e_mbd.mode_info_context->mbmi.segment_id) ) + { cpi->t8x8_count++; + } else cpi->t4x4_count++; #endif @@ -1590,12 +1594,12 @@ int vp8cx_encode_inter_macroblock int intra_error = 0; int rate; int distortion; - int segment_id = xd->mode_info_context->mbmi.segment_id; + unsigned char *segment_id = &xd->mode_info_context->mbmi.segment_id; x->skip = 0; if (xd->segmentation_enabled) - x->encode_breakout = cpi->segment_encode_breakout[segment_id]; + x->encode_breakout = cpi->segment_encode_breakout[*segment_id]; else x->encode_breakout = cpi->oxcf.encode_breakout; @@ -1657,11 +1661,11 @@ int vp8cx_encode_inter_macroblock if (cpi->cyclic_refresh_mode_enabled) { // Clear segment_id back to 0 if not coded (last frame 0,0) - if ( (segment_id == 1) && + if ( (*segment_id == 1) && ( (xd->mode_info_context->mbmi.ref_frame != LAST_FRAME) || (xd->mode_info_context->mbmi.mode != ZEROMV) ) ) { - xd->mode_info_context->mbmi.segment_id = 0; + *segment_id = 0; /* segment_id changed, so update */ vp8cx_mb_init_quantizer(cpi, x); @@ -1678,7 +1682,7 @@ int vp8cx_encode_inter_macroblock statsfile = fopen("segmap2.stt", "a"); fprintf(statsfile, "%2d%2d%2d ", - xd->mode_info_context->mbmi.segment_id, + *segment_id, xd->mode_info_context->mbmi.ref_frame, xd->mode_info_context->mbmi.mode ); @@ -1722,11 +1726,11 @@ int vp8cx_encode_inter_macroblock // probabilities. NOTE: At the moment we dont support custom trees // for the reference frame coding for each segment but this is a // possible future action. - if ( !segfeature_active( xd, segment_id, SEG_LVL_REF_FRAME ) || - ( ( check_segref( xd, segment_id, INTRA_FRAME ) + - check_segref( xd, segment_id, LAST_FRAME ) + - check_segref( xd, segment_id, GOLDEN_FRAME ) + - check_segref( xd, segment_id, ALTREF_FRAME ) ) > 1 ) ) + if ( !segfeature_active( xd, *segment_id, SEG_LVL_REF_FRAME ) || + ( ( check_segref( xd, *segment_id, INTRA_FRAME ) + + check_segref( xd, *segment_id, LAST_FRAME ) + + check_segref( xd, *segment_id, GOLDEN_FRAME ) + + check_segref( xd, *segment_id, ALTREF_FRAME ) ) > 1 ) ) { cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame]++; } @@ -1747,7 +1751,7 @@ int vp8cx_encode_inter_macroblock { #if CONFIG_T8X8 if (xd->segmentation_enabled) - xd->mode_info_context->mbmi.segment_id |= (vp8_8x8_selection_intra(x) << 1); + *segment_id |= (vp8_8x8_selection_intra(x) << 1); #endif vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x); vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x); @@ -1760,7 +1764,7 @@ int vp8cx_encode_inter_macroblock int ref_fb_idx; #if CONFIG_T8X8 if (xd->segmentation_enabled) - xd->mode_info_context->mbmi.segment_id |= (vp8_8x8_selection_inter(x) << 1); + *segment_id |= (vp8_8x8_selection_inter(x) << 1); #endif if (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME) @@ -1790,8 +1794,10 @@ int vp8cx_encode_inter_macroblock } #if CONFIG_T8X8 - if (x->e_mbd.mode_info_context->mbmi.segment_id >=2) + if ( get_seg_tx_type( xd, *segment_id ) == TX_8X8 ) + { cpi->t8x8_count++; + } else cpi->t4x4_count++; #endif diff --git a/vp8/encoder/encodeintra.c b/vp8/encoder/encodeintra.c index 424dc72dbd..ee1e878471 100644 --- a/vp8/encoder/encodeintra.c +++ b/vp8/encoder/encodeintra.c @@ -97,18 +97,24 @@ void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) { BLOCK *b = &x->block[0]; +#if CONFIG_T8X8 + int tx_type = get_seg_tx_type(&x->e_mbd, + x->e_mbd.mode_info_context->mbmi.segment_id); +#endif + RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mby)(&x->e_mbd); ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride); + #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) vp8_transform_intra_mby_8x8(x); else #endif vp8_transform_intra_mby(x); #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if(tx_type == TX_8X8) vp8_quantize_mby_8x8(x); else #endif @@ -117,7 +123,7 @@ void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) if (x->optimize) { #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) vp8_optimize_mby_8x8(x, rtcd); else #endif @@ -125,7 +131,7 @@ void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) } #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if(tx_type == TX_8X8) vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd); else #endif @@ -169,18 +175,23 @@ void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) { +#if CONFIG_T8X8 + int tx_type = get_seg_tx_type(&x->e_mbd, + x->e_mbd.mode_info_context->mbmi.segment_id); +#endif + RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mbuv)(&x->e_mbd); ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride); #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if(tx_type == TX_8X8) vp8_transform_mbuv_8x8(x); else #endif vp8_transform_mbuv(x); #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if(tx_type == TX_8X8) vp8_quantize_mbuv_8x8(x); else #endif @@ -220,7 +231,7 @@ void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) if (x->optimize) { #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if(tx_type == TX_8X8) vp8_optimize_mbuv_8x8(x, rtcd); else #endif @@ -228,7 +239,7 @@ void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) } #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if(tx_type == TX_8X8) vp8_inverse_transform_mbuv_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd); else #endif diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c index ce03e58363..dcfe24f004 100644 --- a/vp8/encoder/encodemb.c +++ b/vp8/encoder/encodemb.c @@ -1247,19 +1247,24 @@ void vp8_optimize_mbuv_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) { +#if CONFIG_T8X8 + int tx_type = get_seg_tx_type(&x->e_mbd, + x->e_mbd.mode_info_context->mbmi.segment_id); +#endif + vp8_build_inter_predictors_mb(&x->e_mbd); vp8_subtract_mb(rtcd, x); #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) vp8_transform_mb_8x8(x); else #endif transform_mb(x); #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) vp8_quantize_mb_8x8(x); else #endif @@ -1268,7 +1273,7 @@ void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) if (x->optimize) { #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) optimize_mb_8x8(x, rtcd); else #endif @@ -1276,12 +1281,15 @@ void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) } #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd); else #endif vp8_inverse_transform_mb(IF_RTCD(&rtcd->common->idct), &x->e_mbd); - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) { + +#if CONFIG_T8X8 + if( tx_type == TX_8X8 ) + { #ifdef ENC_DEBUG if (enc_debug) { @@ -1311,6 +1319,7 @@ void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) } #endif } +#endif RECON_INVOKE(&rtcd->common->recon, recon_mb) (IF_RTCD(&rtcd->common->recon), &x->e_mbd); @@ -1336,6 +1345,11 @@ void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) /* this function is used by first pass only */ void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) { +#if CONFIG_T8X8 + int tx_type = get_seg_tx_type(&x->e_mbd, + x->e_mbd.mode_info_context->mbmi.segment_id); +#endif + BLOCK *b = &x->block[0]; vp8_build_inter16x16_predictors_mby(&x->e_mbd); @@ -1343,7 +1357,7 @@ void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride); #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) vp8_transform_mby_8x8(x); else #endif @@ -1351,7 +1365,7 @@ void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) vp8_quantize_mby(x); #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd); else #endif diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 94ba5484bf..9c171b869c 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -481,16 +481,6 @@ static void init_seg_features(VP8_COMP *cpi) (cpi->cq_target_quality > 16 ) ) || (cpi->ni_av_qi > 32); -#if CONFIG_T8X8 - // TODO - // For now 8x8TX mode just set segments up for 8x8 and 4x4 modes and exit. - //enable_segfeature(xd, 0, SEG_LVL_TRANSFORM); - //set_segdata( xd, 0, SEG_LVL_TRANSFORM, TX_4X4 ); - //enable_segfeature(xd, 1, SEG_LVL_TRANSFORM); - //set_segdata( xd, 1, SEG_LVL_TRANSFORM, TX_8X8 ); - return; -#endif - // For now at least dont enable seg features alongside cyclic refresh. if ( cpi->cyclic_refresh_mode_enabled || (cpi->pass != 2) ) @@ -500,6 +490,19 @@ static void init_seg_features(VP8_COMP *cpi) return; } +#if CONFIG_T8X8 + // TODO + // For now 8x8TX mode just set segments up for 8x8 and 4x4 modes and exit. + enable_segfeature(xd, 0, SEG_LVL_TRANSFORM); + set_segdata( xd, 0, SEG_LVL_TRANSFORM, TX_4X4 ); + enable_segfeature(xd, 2, SEG_LVL_TRANSFORM); + set_segdata( xd, 2, SEG_LVL_TRANSFORM, TX_8X8 ); + + // Turn on segmentation + vp8_enable_segmentation((VP8_PTR)cpi); + return; +#endif + // Disable and clear down for KF if ( cm->frame_type == KEY_FRAME ) { diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index b8ae6c0660..f701435c6d 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1041,12 +1041,17 @@ static int rd_cost_mbuv(MACROBLOCK *mb) static int rd_inter16x16_uv(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *distortion, int fullpixel) { +#if CONFIG_T8X8 + int tx_type = get_seg_tx_type(&x->e_mbd, + x->e_mbd.mode_info_context->mbmi.segment_id); +#endif + vp8_build_inter16x16_predictors_mbuv(&x->e_mbd); ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride); #if CONFIG_T8X8 - if(x->e_mbd.mode_info_context->mbmi.segment_id >= 2) + if( tx_type == TX_8X8 ) vp8_transform_mbuv_8x8(x); else #endif diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c index 362d9bfafd..e01093ef7d 100644 --- a/vp8/encoder/tokenize.c +++ b/vp8/encoder/tokenize.c @@ -479,6 +479,10 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) int has_y2_block; int b; +#if CONFIG_T8X8 + int tx_type = get_seg_tx_type(x, x->mode_info_context->mbmi.segment_id); +#endif + //#if CONFIG_SEGFEATURES // If the MB is going to be skipped because of a segment level flag // exclude this from the skip count stats used to calculate the @@ -502,7 +506,7 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) x->mode_info_context->mbmi.mb_skip_coeff = #if CONFIG_T8X8 - (x->mode_info_context->mbmi.segment_id >= 2 ? + (( tx_type == TX_8X8 ) ? mb_is_skippable_8x8(x) : mb_is_skippable(x, has_y2_block)); #else @@ -516,7 +520,7 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) if (!cpi->common.mb_no_coeff_skip) { #if CONFIG_T8X8 - if (x->mode_info_context->mbmi.segment_id >= 2) + if ( tx_type == TX_8X8 ) vp8_stuff_mb_8x8(cpi, x, t) ; else #endif @@ -536,7 +540,7 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) if(has_y2_block) { #if CONFIG_T8X8 - if (x->mode_info_context->mbmi.segment_id >= 2) + if ( tx_type == TX_8X8 ) { ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context; ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context; @@ -551,7 +555,7 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) } #if CONFIG_T8X8 - if (x->mode_info_context->mbmi.segment_id >= 2) + if ( tx_type == TX_8X8 ) { ENTROPY_CONTEXT * A = (ENTROPY_CONTEXT *)x->above_context; ENTROPY_CONTEXT * L = (ENTROPY_CONTEXT *)x->left_context; -- GitLab