From a8fbab8697c77dc82013862e0a9c7f82b6402db8 Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Wed, 30 Nov 2011 16:25:00 -0800 Subject: [PATCH] enabled 8x8 intra prediction modes on inter frames This commit enabled the usage of 8x8 intra prediction modes on inter frames. There are a few TODO items related to this: 1)baseline entropy need be calibrated; 2)cost of UV need to be done more properly rather than using decision only relying on Y; 3)Threshold for allowing picking 8x8 intra prediction should be lowered to lower than the B_PRED. Even with all the TODOs, tests showed consistent gain on derf set ~0.1% (PSNR:0.08% and SSIM:0.14%). It is assumed that 8x8 intra prediction will help more on large resolution clips, especially with above TODOs addressed. Change-Id: I398ada49dfc32575cfab962a569c2885111ae3ba --- vp8/common/entropymode.c | 17 +++++-- vp8/common/findnearmv.h | 1 - vp8/common/invtrans.c | 3 ++ vp8/common/loopfilter.c | 14 +++++- vp8/common/loopfilter.h | 3 +- vp8/decoder/decodemv.c | 21 ++++++-- vp8/decoder/decodframe.c | 19 +++++++- vp8/decoder/detokenize.c | 3 ++ vp8/decoder/onyxd_if.c | 3 +- vp8/decoder/threading.c | 3 ++ vp8/encoder/bitstream.c | 10 ++++ vp8/encoder/encodeframe.c | 11 +++-- vp8/encoder/encodemb.c | 13 +++++ vp8/encoder/onyx_if.c | 48 ++++++++++++++++-- vp8/encoder/onyx_int.h | 10 +++- vp8/encoder/quantize.c | 6 +++ vp8/encoder/rdopt.c | 100 +++++++++++++++++++++++++++++--------- vp8/encoder/tokenize.c | 6 ++- 18 files changed, 246 insertions(+), 45 deletions(-) diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c index 45af600ca..8b9934461 100644 --- a/vp8/common/entropymode.c +++ b/vp8/common/entropymode.c @@ -29,7 +29,8 @@ const unsigned int kf_y_mode_cts[8][VP8_YMODES] = #else static const unsigned int kf_y_mode_cts[VP8_YMODES] = { 49, 22, 23, 11, 23, 128}; #endif -static const unsigned int y_mode_cts [VP8_YMODES] = { 8080, 1908, 1582, 1007, 0, 5874}; +/* TODO: calibrate the baseline distribution */ +static const unsigned int y_mode_cts [VP8_YMODES] = { 8080, 1908, 1582, 1007, 2000, 5874}; #else static const unsigned int kf_y_mode_cts[VP8_YMODES] = { 1607, 915, 812, 811, 5455}; static const unsigned int y_mode_cts [VP8_YMODES] = { 8080, 1908, 1582, 1007, 5874}; @@ -168,15 +169,16 @@ const vp8_tree_index vp8_bmode_tree[18] = /* INTRAMODECONTEXTNODE value */ /* Again, these trees use the same probability indices as their explicitly-programmed predecessors. */ -const vp8_tree_index vp8_ymode_tree[8] = +#if CONFIG_I8X8 +const vp8_tree_index vp8_ymode_tree[10] = { -DC_PRED, 2, 4, 6, -V_PRED, -H_PRED, - -TM_PRED, -B_PRED + -TM_PRED, 8, + -B_PRED, -I8X8_PRED }; -#if CONFIG_I8X8 const vp8_tree_index vp8_kf_ymode_tree[10] = { -B_PRED, 2, @@ -193,6 +195,13 @@ const vp8_tree_index vp8_i8x8_mode_tree[6] = -H_PRED, -TM_PRED }; #else +const vp8_tree_index vp8_ymode_tree[8] = +{ + -DC_PRED, 2, + 4, 6, + -V_PRED, -H_PRED, + -TM_PRED, -B_PRED +}; const vp8_tree_index vp8_kf_ymode_tree[8] = { diff --git a/vp8/common/findnearmv.h b/vp8/common/findnearmv.h index 4a5b0f3a4..b07a54b5c 100644 --- a/vp8/common/findnearmv.h +++ b/vp8/common/findnearmv.h @@ -145,7 +145,6 @@ static B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) return B_DC_PRED; } } - return (cur_mb->bmi + b - 1)->as_mode; } diff --git a/vp8/common/invtrans.c b/vp8/common/invtrans.c index d361b654a..c734df42f 100644 --- a/vp8/common/invtrans.c +++ b/vp8/common/invtrans.c @@ -77,6 +77,9 @@ void vp8_inverse_transform_mb(const vp8_idct_rtcd_vtable_t *rtcd, MACROBLOCKD *x int i; if (x->mode_info_context->mbmi.mode != B_PRED && +#if CONFIG_I8X8 + x->mode_info_context->mbmi.mode != I8X8_PRED && +#endif x->mode_info_context->mbmi.mode != SPLITMV) { /* do 2nd order transform on the dc block */ diff --git a/vp8/common/loopfilter.c b/vp8/common/loopfilter.c index 98657fcc3..11853310d 100644 --- a/vp8/common/loopfilter.c +++ b/vp8/common/loopfilter.c @@ -137,7 +137,9 @@ static void lf_init_lut(loop_filter_info_n *lfi) lfi->mode_lf_lut[H_PRED] = 1; lfi->mode_lf_lut[TM_PRED] = 1; lfi->mode_lf_lut[B_PRED] = 0; - +#if CONFIG_I8X8 + lfi->mode_lf_lut[I8X8_PRED]=0; +#endif lfi->mode_lf_lut[ZEROMV] = 1; lfi->mode_lf_lut[NEARESTMV] = 2; lfi->mode_lf_lut[NEARMV] = 2; @@ -321,6 +323,9 @@ void vp8_loop_filter_frame for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { int skip_lf = (mode_info_context->mbmi.mode != B_PRED && +#if CONFIG_I8X8 + mode_info_context->mbmi.mode != I8X8_PRED && +#endif mode_info_context->mbmi.mode != SPLITMV && mode_info_context->mbmi.mb_skip_coeff); @@ -432,6 +437,10 @@ void vp8_loop_filter_frame_yonly for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { int skip_lf = (mode_info_context->mbmi.mode != B_PRED && +#if CONFIG_I8X8 + mode_info_context->mbmi.mode != I8X8_PRED && +#endif + mode_info_context->mbmi.mode != SPLITMV && mode_info_context->mbmi.mb_skip_coeff); @@ -569,6 +578,9 @@ void vp8_loop_filter_partial_frame for (mb_col = 0; mb_col < mb_cols; mb_col++) { int skip_lf = (mode_info_context->mbmi.mode != B_PRED && +#if CONFIG_I8X8 + mode_info_context->mbmi.mode != I8X8_PRED && +#endif mode_info_context->mbmi.mode != SPLITMV && mode_info_context->mbmi.mb_skip_coeff); diff --git a/vp8/common/loopfilter.h b/vp8/common/loopfilter.h index 9887cf55b..0ae2b9a1b 100644 --- a/vp8/common/loopfilter.h +++ b/vp8/common/loopfilter.h @@ -14,6 +14,7 @@ #include "vpx_ports/mem.h" #include "vpx_config.h" +#include "blockd.h" #define MAX_LOOP_FILTER 63 @@ -40,7 +41,7 @@ typedef struct DECLARE_ALIGNED(SIMD_WIDTH, unsigned char, hev_thr[4][SIMD_WIDTH]); unsigned char lvl[4][4][4]; unsigned char hev_thr_lut[2][MAX_LOOP_FILTER + 1]; - unsigned char mode_lf_lut[10]; + unsigned char mode_lf_lut[MB_MODE_COUNT]; } loop_filter_info_n; typedef struct diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 683f40a5b..68044f4d5 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -144,8 +144,6 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, { int i; int mode8x8; - //printf("F%3d:%d:%d:", - pbi->common.current_video_frame, mb_row, mb_col); for(i=0;i<4;i++) { int ib = vp8_i8x8_block[i]; @@ -155,8 +153,6 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, m->bmi[ib+4].as_mode= mode8x8; m->bmi[ib+5].as_mode= mode8x8; } - //printf("%2d%2d%2d%2d\n", m->bmi[0].as_mode,m->bmi[2].as_mode, - // m->bmi[8].as_mode,m->bmi[10].as_mode); } else #endif @@ -724,6 +720,23 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, while (++j < 16); } +#if CONFIG_I8X8 + if(mbmi->mode == I8X8_PRED) + { + int i; + int mode8x8; + for(i=0;i<4;i++) + { + int ib = vp8_i8x8_block[i]; + mode8x8 = vp8_read_i8x8_mode(bc, pbi->common.i8x8_mode_prob); + mi->bmi[ib+0].as_mode= mode8x8; + mi->bmi[ib+1].as_mode= mode8x8; + mi->bmi[ib+4].as_mode= mode8x8; + mi->bmi[ib+5].as_mode= mode8x8; + } + } + else +#endif mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, pbi->common.fc.uv_mode_prob); } diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index a3421ef89..5e8925286 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -43,6 +43,7 @@ #include #include + #ifdef DEC_DEBUG int dec_debug = 0; #endif @@ -134,6 +135,7 @@ static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd) 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); + } #ifdef DEC_DEBUG if (dec_debug) { int i, j; @@ -144,7 +146,7 @@ static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd) } } #endif - } + } static void clamp_mv_to_umv_border(MV *mv, const MACROBLOCKD *xd) @@ -271,6 +273,19 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, return; } +#ifdef DEC_DEBUG + if (dec_debug) { + int i, j; + printf("Generating predictors\n"); + for (i=0;i<16;i++) { + for (j=0;j<16;j++) printf("%3d ", xd->dst.y_buffer[i*xd->dst.y_stride+j]); + printf("\n"); + } + } +#endif + + + if (xd->segmentation_enabled) mb_init_dequantizer(pbi, xd); @@ -597,7 +612,7 @@ decode_mb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mb_row, MACROBLOCKD *xd) } #ifdef DEC_DEBUG - dec_debug = (pc->current_video_frame==0 && mb_row==1 && mb_col==11); + dec_debug = (pc->current_video_frame==1 && mb_row==4 && mb_col==0); #endif decode_macroblock(pbi, xd, mb_row * pc->mb_cols + mb_col); diff --git a/vp8/decoder/detokenize.c b/vp8/decoder/detokenize.c index f2a5db8f1..ef57b4f4e 100644 --- a/vp8/decoder/detokenize.c +++ b/vp8/decoder/detokenize.c @@ -90,6 +90,9 @@ void vp8_reset_mb_tokens_context(MACROBLOCKD *x) { /* Clear entropy contexts for Y2 blocks */ if (x->mode_info_context->mbmi.mode != B_PRED && +#if CONFIG_I8X8 + x->mode_info_context->mbmi.mode != I8X8_PRED && +#endif x->mode_info_context->mbmi.mode != SPLITMV) { vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index f103bd788..a45d692d0 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -80,7 +80,6 @@ void vp8_recon_write_yuv_frame(char *name, YV12_BUFFER_CONFIG *s) fclose(yuv_file); } #endif - #if WRITE_RECON_BUFFER void write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) { @@ -581,6 +580,8 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign #if WRITE_RECON_BUFFER if(cm->show_frame) write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame); + else + write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame+1000); #endif if(cm->filter_level) diff --git a/vp8/decoder/threading.c b/vp8/decoder/threading.c index e6d31008d..09dffe269 100644 --- a/vp8/decoder/threading.c +++ b/vp8/decoder/threading.c @@ -894,6 +894,9 @@ void vp8mt_decode_mb_rows( VP8D_COMP *pbi, MACROBLOCKD *xd) if (pbi->common.filter_level) { int skip_lf = (xd->mode_info_context->mbmi.mode != B_PRED && +#if CONFIG_I8X8 + xd->mode_info_context->mbmi.mode != I8X8_PRED && +#endif xd->mode_info_context->mbmi.mode != SPLITMV && xd->mode_info_context->mbmi.mb_skip_coeff); diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 07077208a..6171492c6 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -1104,6 +1104,16 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob); while (++j < 16); } +#if CONFIG_I8X8 + if(mode == I8X8_PRED) + { + write_i8x8_mode(w, m->bmi[0].as_mode, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[2].as_mode, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[8].as_mode, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[10].as_mode, pc->i8x8_mode_prob); + } + else +#endif write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob); } diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 22d53302a..a6a09247a 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -617,8 +617,7 @@ void encode_mb_row(VP8_COMP *cpi, for (mb_col = 0; mb_col < cm->mb_cols; mb_col++) { #ifdef ENC_DEBUG - //enc_debug = (cpi->count==29 && mb_row==5 && mb_col==0); - enc_debug = (cpi->count==4 && mb_row==17 && mb_col==13); + enc_debug = (cpi->common.current_video_frame ==1 && mb_row==4 && mb_col==0); mb_col_debug=mb_col; mb_row_debug=mb_row; #endif @@ -1553,12 +1552,18 @@ int vp8cx_encode_inter_macroblock vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x); vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x); } +#if CONFIG_I8X8 + else if(xd->mode_info_context->mbmi.mode == I8X8_PRED) + { + vp8_encode_intra8x8mby(IF_RTCD(&cpi->rtcd), x); + vp8_encode_intra8x8mbuv(IF_RTCD(&cpi->rtcd), x); + } +#endif else { vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x); vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x); } - sum_intra_stats(cpi, x); } else diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c index 483ec768f..2178e5bae 100644 --- a/vp8/encoder/encodemb.c +++ b/vp8/encoder/encodemb.c @@ -719,6 +719,9 @@ static void optimize_mb(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) tl = (ENTROPY_CONTEXT *)&t_left; has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED +#if CONFIG_I8X8 + &&x->e_mbd.mode_info_context->mbmi.mode != I8X8_PRED +#endif && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC; @@ -768,6 +771,9 @@ void vp8_optimize_mby(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) tl = (ENTROPY_CONTEXT *)&t_left; has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED +#if CONFIG_I8X8 + &&x->e_mbd.mode_info_context->mbmi.mode != I8X8_PRED +#endif && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC; @@ -1082,6 +1088,10 @@ void optimize_mb_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) tl = (ENTROPY_CONTEXT *)&t_left; has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED +#if CONFIG_I8X8 + &&x->e_mbd.mode_info_context->mbmi.mode != I8X8_PRED +#endif + && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); type = has_2nd_order ? 0 : 3; @@ -1180,6 +1190,9 @@ void vp8_optimize_mby_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) tl = (ENTROPY_CONTEXT *)&t_left; has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED +#if CONFIG_I8X8 + && x->e_mbd.mode_info_context->mbmi.mode != I8X8_PRED +#endif && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); type = has_2nd_order ? 0 : 3; diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 265c2dd4c..867c4bdec 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -810,6 +810,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_V_PRED ] = 1000; sf->thresh_mult[THR_H_PRED ] = 1000; sf->thresh_mult[THR_B_PRED ] = 2000; +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = 2000; +#endif sf->thresh_mult[THR_TM ] = 1000; sf->thresh_mult[THR_NEWMV ] = 1000; @@ -833,6 +836,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_V_PRED ] = 1000; sf->thresh_mult[THR_H_PRED ] = 1000; sf->thresh_mult[THR_B_PRED ] = 2500; +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = 2500; +#endif sf->thresh_mult[THR_TM ] = 1000; sf->thresh_mult[THR_NEARESTG ] = 1000; @@ -902,7 +908,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_V_PRED ] = 1500; sf->thresh_mult[THR_H_PRED ] = 1500; sf->thresh_mult[THR_B_PRED ] = 5000; - +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = 5000; +#endif if (cpi->ref_frame_flags & VP8_LAST_FLAG) { sf->thresh_mult[THR_NEWMV ] = 2000; @@ -938,6 +946,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_V_PRED ] = 2000; sf->thresh_mult[THR_H_PRED ] = 2000; sf->thresh_mult[THR_B_PRED ] = 7500; +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = 7500; +#endif if (cpi->ref_frame_flags & VP8_LAST_FLAG) { @@ -981,6 +992,10 @@ void vp8_set_speed_features(VP8_COMP *cpi) cpi->mode_check_freq[THR_V_PRED] = 0; cpi->mode_check_freq[THR_H_PRED] = 0; cpi->mode_check_freq[THR_B_PRED] = 0; +#if CONFIG_I8X8 + cpi->mode_check_freq[THR_I8X8_PRED] = 0; +#endif + cpi->mode_check_freq[THR_NEARG] = 0; cpi->mode_check_freq[THR_NEWG] = 0; cpi->mode_check_freq[THR_NEARA] = 0; @@ -999,6 +1014,10 @@ void vp8_set_speed_features(VP8_COMP *cpi) cpi->mode_check_freq[THR_V_PRED] = 2; cpi->mode_check_freq[THR_H_PRED] = 2; cpi->mode_check_freq[THR_B_PRED] = 2; +#if CONFIG_I8X8 + cpi->mode_check_freq[THR_I8X8_PRED]=2; +#endif + if (cpi->ref_frame_flags & VP8_GOLD_FLAG) { @@ -1044,6 +1063,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_V_PRED ] = 1000; sf->thresh_mult[THR_H_PRED ] = 1000; sf->thresh_mult[THR_B_PRED ] = 2500; +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = 2500; +#endif sf->thresh_mult[THR_NEARESTG ] = 1000; sf->thresh_mult[THR_ZEROG ] = 1000; sf->thresh_mult[THR_NEARG ] = 1000; @@ -1069,6 +1091,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_V_PRED ] = 2000; sf->thresh_mult[THR_H_PRED ] = 2000; sf->thresh_mult[THR_B_PRED ] = 5000; +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = 5000; +#endif if (cpi->ref_frame_flags & VP8_LAST_FLAG) { @@ -1115,7 +1140,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_V_PRED ] = 2000; sf->thresh_mult[THR_H_PRED ] = 2000; sf->thresh_mult[THR_B_PRED ] = 5000; - +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = 5000; +#endif if (cpi->ref_frame_flags & VP8_LAST_FLAG) { sf->thresh_mult[THR_NEWMV ] = 2000; @@ -1149,6 +1176,10 @@ void vp8_set_speed_features(VP8_COMP *cpi) cpi->mode_check_freq[THR_V_PRED] = 2; cpi->mode_check_freq[THR_H_PRED] = 2; cpi->mode_check_freq[THR_B_PRED] = 2; +#if CONFIG_I8X8 + cpi->mode_check_freq[THR_I8X8_PRED]=2; +#endif + if (cpi->ref_frame_flags & VP8_GOLD_FLAG) { @@ -1187,7 +1218,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) cpi->mode_check_freq[THR_V_PRED] = 4; cpi->mode_check_freq[THR_H_PRED] = 4; cpi->mode_check_freq[THR_B_PRED] = 4; - +#if CONFIG_I8X8 + cpi->mode_check_freq[THR_I8X8_PRED]=4; +#endif if (cpi->ref_frame_flags & VP8_GOLD_FLAG) { cpi->mode_check_freq[THR_NEARG] = 2; @@ -1202,6 +1235,10 @@ void vp8_set_speed_features(VP8_COMP *cpi) sf->thresh_mult[THR_TM ] = 2000; sf->thresh_mult[THR_B_PRED ] = 5000; +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = 5000; +#endif + if (cpi->ref_frame_flags & VP8_GOLD_FLAG) { @@ -1224,6 +1261,9 @@ void vp8_set_speed_features(VP8_COMP *cpi) { // Disable split MB intra prediction mode sf->thresh_mult[THR_B_PRED] = INT_MAX; +#if CONFIG_I8X8 + sf->thresh_mult[THR_I8X8_PRED] = INT_MAX; +#endif } if (Speed > 6) @@ -4473,6 +4513,8 @@ static void encode_frame_to_data_rate #if WRITE_RECON_BUFFER if(cm->show_frame) write_cx_frame_to_file(cm->frame_to_show, cm->current_video_frame); + else + write_cx_frame_to_file(cm->frame_to_show, cm->current_video_frame+1000); #endif #if CONFIG_MULTITHREAD diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 622f25068..160f22d05 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -42,8 +42,11 @@ #define AF_THRESH 25 #define AF_THRESH2 100 #define ARF_DECAY_THRESH 12 +#if CONFIG_I8X8 +#define MAX_MODES 21 +#else #define MAX_MODES 20 - +#endif #define MIN_THRESHMULT 32 #define MAX_THRESHMULT 512 @@ -74,7 +77,7 @@ typedef struct int uv_modes[VP8_UV_MODES]; int i8x8_modes[VP8_I8X8_MODES]; int b_modes[10]; - int inter_y_modes[10]; + int inter_y_modes[MB_MODE_COUNT]; int inter_uv_modes[VP8_UV_MODES]; int inter_b_modes[10]; #endif @@ -186,6 +189,9 @@ typedef enum THR_SPLITA = 18, THR_B_PRED = 19, +#if CONFIG_I8X8 + THR_I8X8_PRED = 20, +#endif } THR_MODES; diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 2e2a8dcbf..78f7dd4c6 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -286,6 +286,9 @@ void vp8_quantize_mby_c(MACROBLOCK *x) { int i; int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED +#if CONFIG_I8X8 + && x->e_mbd.mode_info_context->mbmi.mode != I8X8_PRED +#endif && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); for (i = 0; i < 16; i++) @@ -299,6 +302,9 @@ void vp8_quantize_mb_c(MACROBLOCK *x) { int i; int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED +#if CONFIG_I8X8 + && x->e_mbd.mode_info_context->mbmi.mode != I8X8_PRED +#endif && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); for (i = 0; i < 24+has_2nd_order; i++) diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index ff0018be5..00a395845 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -103,6 +103,9 @@ const MB_PREDICTION_MODE vp8_mode_order[MAX_MODES] = SPLITMV, B_PRED, +#if CONFIG_I8X8 + I8X8_PRED, +#endif }; const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES] = @@ -135,6 +138,9 @@ const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES] = ALTREF_FRAME, INTRA_FRAME, +#if CONFIG_I8X8 + INTRA_FRAME, +#endif }; static void fill_token_costs( @@ -1941,6 +1947,29 @@ static void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv) } } +#if CONFIG_I8X8 +static void set_i8x8_block_modes(MACROBLOCK *x, int *modes) +{ + int i; + MACROBLOCKD *xd = &x->e_mbd; + for(i=0;i<4;i++) + { + int ib = vp8_i8x8_block[i]; + x->e_mbd.mode_info_context->bmi[ib+0].as_mode= modes[i]; + x->e_mbd.mode_info_context->bmi[ib+1].as_mode= modes[i]; + x->e_mbd.mode_info_context->bmi[ib+4].as_mode= modes[i]; + x->e_mbd.mode_info_context->bmi[ib+5].as_mode= modes[i]; + } + + for (i = 0; i < 16; i++) + { + xd->block[i].bmi = xd->mode_info_context->bmi[i]; + } +} +#endif + + + void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra) { BLOCK *b = &x->block[0]; @@ -1955,6 +1984,9 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int MB_PREDICTION_MODE this_mode; int num00; int best_mode_index = 0; +#if CONFIG_I8X8 + int mode8x8[4]; +#endif unsigned char segment_id = xd->mode_info_context->mbmi.segment_id; int i; @@ -2182,6 +2214,37 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int } } break; +#if CONFIG_I8X8 + case I8X8_PRED: + { + int tmp_rd; + tmp_rd = rd_pick_intra8x8mby_modes(cpi, + x, &rate, &rate_y, &distortion, best_yrd); + rate2 += rate; + distortion2 += distortion; + + mode8x8[0]= x->e_mbd.mode_info_context->bmi[0].as_mode; + mode8x8[1]= x->e_mbd.mode_info_context->bmi[2].as_mode; + mode8x8[2]= x->e_mbd.mode_info_context->bmi[8].as_mode; + mode8x8[3]= x->e_mbd.mode_info_context->bmi[10].as_mode; + + /* TODO: uv rate maybe over-estimated here since there is UV intra + mode coded in I8X8_PRED prediction */ + if(tmp_rd < best_yrd) + { + rate2 += uv_intra_rate; + rate_uv = uv_intra_rate_tokenonly; + distortion2 += uv_intra_distortion; + distortion_uv = uv_intra_distortion; + } + else + { + this_rd = INT_MAX; + disable_skip = 1; + } + } + break; +#endif case SPLITMV: { @@ -2552,7 +2615,11 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int vpx_memcpy(&best_mbmode, &x->e_mbd.mode_info_context->mbmi, sizeof(MB_MODE_INFO)); vpx_memcpy(&best_partition, x->partition_info, sizeof(PARTITION_INFO)); - if ((this_mode == B_PRED) || (this_mode == SPLITMV)) + if ((this_mode == B_PRED) +#if CONFIG_I8X8 + ||(this_mode == I8X8_PRED) +#endif + || (this_mode == SPLITMV)) for (i = 0; i < 16; i++) { best_bmodes[i] = x->e_mbd.block[i].bmi; @@ -2637,9 +2704,19 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int if (best_mbmode.mode == B_PRED) { for (i = 0; i < 16; i++) + { xd->mode_info_context->bmi[i].as_mode = best_bmodes[i].as_mode; + xd->block[i].bmi.as_mode = xd->mode_info_context->bmi[i].as_mode; + } } +#if CONFIG_I8X8 + if (best_mbmode.mode == I8X8_PRED) + { + set_i8x8_block_modes(x, mode8x8); + } +#endif + if (best_mbmode.mode == SPLITMV) { for (i = 0; i < 16; i++) @@ -2657,27 +2734,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int } -#if CONFIG_I8X8 -static void set_i8x8_block_modes(MACROBLOCK *x, int *modes) -{ - int i; - MACROBLOCKD *xd = &x->e_mbd; - for(i=0;i<4;i++) - { - int ib = vp8_i8x8_block[i]; - x->e_mbd.mode_info_context->bmi[ib+0].as_mode= modes[i]; - x->e_mbd.mode_info_context->bmi[ib+1].as_mode= modes[i]; - x->e_mbd.mode_info_context->bmi[ib+4].as_mode= modes[i]; - x->e_mbd.mode_info_context->bmi[ib+5].as_mode= modes[i]; - } - - for (i = 0; i < 16; i++) - { - xd->block[i].bmi = xd->mode_info_context->bmi[i]; - } -} -#endif - void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_) { MACROBLOCKD *xd = &x->e_mbd; diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c index 304bb4f98..0f8525e20 100644 --- a/vp8/encoder/tokenize.c +++ b/vp8/encoder/tokenize.c @@ -1028,7 +1028,11 @@ void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) void vp8_fix_contexts(MACROBLOCKD *x) { /* Clear entropy contexts for Y2 blocks */ - if (x->mode_info_context->mbmi.mode != B_PRED && x->mode_info_context->mbmi.mode != SPLITMV) + if (x->mode_info_context->mbmi.mode != B_PRED +#if CONFIG_I8X8 + && x->mode_info_context->mbmi.mode != I8X8_PRED +#endif + && x->mode_info_context->mbmi.mode != SPLITMV) { vpx_memset(x->above_context, 0, sizeof(ENTROPY_CONTEXT_PLANES)); vpx_memset(x->left_context, 0, sizeof(ENTROPY_CONTEXT_PLANES));