diff --git a/configure b/configure index fa5ef22f2245087e9afc2fa61d6a1a7f0eb7f030..9c2c4e73c7a44bd887ef4dc96dabeb7e0bcad232 100755 --- a/configure +++ b/configure @@ -223,6 +223,7 @@ EXPERIMENT_LIST=" featureupdates high_precision_mv sixteenth_subpel_uv + comp_intra_pred " CONFIG_LIST=" external_build diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index 4b3d40cd6c6856745463ef5d23625725757eb7c5..30ea8c05bbd5f88da25a3973b735abc0c46fef4f 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -158,7 +158,12 @@ typedef enum union b_mode_info { - B_PREDICTION_MODE as_mode; + struct { + B_PREDICTION_MODE first; +#if CONFIG_COMP_INTRA_PRED + B_PREDICTION_MODE second; +#endif + } as_mode; int_mv mv; }; @@ -174,6 +179,9 @@ typedef enum typedef struct { MB_PREDICTION_MODE mode, uv_mode; +#if CONFIG_COMP_INTRA_PRED + MB_PREDICTION_MODE second_mode, second_uv_mode; +#endif MV_REFERENCE_FRAME ref_frame, second_ref_frame; #if CONFIG_T8X8 TX_SIZE txfm_size; diff --git a/vp8/common/debugmodes.c b/vp8/common/debugmodes.c index 46064e61d536d1e6212fcb40ebea90cab9350eee..6d306578b68dc96d2fcabd23d2995ade056995e7 100644 --- a/vp8/common/debugmodes.c +++ b/vp8/common/debugmodes.c @@ -97,7 +97,12 @@ void vp8_print_modes_and_motion_vectors(MODE_INFO *mi, int rows, int cols, int f bindex = (b_row & 3) * 4 + (b_col & 3); if (mi[mb_index].mbmi.mode == B_PRED) - fprintf(mvs, "%2d ", mi[mb_index].bmi[bindex].as_mode); + { + fprintf(mvs, "%2d ", mi[mb_index].bmi[bindex].as_mode.first); +#if CONFIG_COMP_INTRA_PRED + fprintf(mvs, "%2d ", mi[mb_index].bmi[bindex].as_mode.second); +#endif + } else fprintf(mvs, "xx "); diff --git a/vp8/common/findnearmv.h b/vp8/common/findnearmv.h index ff25b27eafbee15f0fb4635dd5ea5c34161caa58..523000b55cec51bc8c5b000f17d33ca40680ce3e 100644 --- a/vp8/common/findnearmv.h +++ b/vp8/common/findnearmv.h @@ -137,12 +137,12 @@ static B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) return B_TM_PRED; case I8X8_PRED: case B_PRED: - return (cur_mb->bmi + b + 3)->as_mode; + return (cur_mb->bmi + b + 3)->as_mode.first; default: return B_DC_PRED; } } - return (cur_mb->bmi + b - 1)->as_mode; + return (cur_mb->bmi + b - 1)->as_mode.first; } static B_PREDICTION_MODE above_block_mode(const MODE_INFO @@ -165,13 +165,13 @@ static B_PREDICTION_MODE above_block_mode(const MODE_INFO return B_TM_PRED; case I8X8_PRED: case B_PRED: - return (cur_mb->bmi + b + 12)->as_mode; + return (cur_mb->bmi + b + 12)->as_mode.first; default: return B_DC_PRED; } } - return (cur_mb->bmi + b - 4)->as_mode; + return (cur_mb->bmi + b - 4)->as_mode.first; } #endif diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c index 90ff889fa75c196e4dadee8f7eae0820b9873f61..0adefe54cea0661a5fd4eef82449a5b1721afb3b 100644 --- a/vp8/common/generic/systemdependent.c +++ b/vp8/common/generic/systemdependent.c @@ -48,18 +48,38 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) rtcd->recon.recon_mby = vp8_recon_mby_c; rtcd->recon.build_intra_predictors_mby = vp8_build_intra_predictors_mby; +#if CONFIG_COMP_INTRA_PRED + rtcd->recon.build_comp_intra_predictors_mby = + vp8_build_comp_intra_predictors_mby; +#endif rtcd->recon.build_intra_predictors_mby_s = vp8_build_intra_predictors_mby_s; rtcd->recon.build_intra_predictors_mbuv = vp8_build_intra_predictors_mbuv; rtcd->recon.build_intra_predictors_mbuv_s = vp8_build_intra_predictors_mbuv_s; +#if CONFIG_COMP_INTRA_PRED + rtcd->recon.build_comp_intra_predictors_mbuv = + vp8_build_comp_intra_predictors_mbuv; +#endif rtcd->recon.intra4x4_predict = vp8_intra4x4_predict; +#if CONFIG_COMP_INTRA_PRED + rtcd->recon.comp_intra4x4_predict = + vp8_comp_intra4x4_predict; +#endif rtcd->recon.intra8x8_predict = vp8_intra8x8_predict; +#if CONFIG_COMP_INTRA_PRED + rtcd->recon.comp_intra8x8_predict = + vp8_comp_intra8x8_predict; +#endif rtcd->recon.intra_uv4x4_predict = vp8_intra_uv4x4_predict; +#if CONFIG_COMP_INTRA_PRED + rtcd->recon.comp_intra_uv4x4_predict = + vp8_comp_intra_uv4x4_predict; +#endif rtcd->subpix.sixtap16x16 = vp8_sixtap_predict16x16_c; rtcd->subpix.sixtap8x8 = vp8_sixtap_predict8x8_c; diff --git a/vp8/common/postproc.c b/vp8/common/postproc.c index 14c3b7bf354d6c1b7f5bbf586f648125a64cfe08..d88b419bcbe4412288a55611385991a4c3bdb6d6 100644 --- a/vp8/common/postproc.c +++ b/vp8/common/postproc.c @@ -1024,9 +1024,9 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t if ((ppflags->display_b_modes_flag & (1<<mi->mbmi.mode)) || (ppflags->display_mb_modes_flag & B_PRED)) { - Y = B_PREDICTION_MODE_colors[bmi->as_mode][0]; - U = B_PREDICTION_MODE_colors[bmi->as_mode][1]; - V = B_PREDICTION_MODE_colors[bmi->as_mode][2]; + Y = B_PREDICTION_MODE_colors[bmi->as_mode.first][0]; + U = B_PREDICTION_MODE_colors[bmi->as_mode.first][1]; + V = B_PREDICTION_MODE_colors[bmi->as_mode.first][2]; POSTPROC_INVOKE(RTCD_VTABLE(oci), blend_b) (yl+bx, ul+(bx>>1), vl+(bx>>1), Y, U, V, 0xc000, y_stride); diff --git a/vp8/common/recon.h b/vp8/common/recon.h index decd114793e0d38dce1d697cb47e8419a515f6c9..9fb12c85de7a914a726729cfa81e0924eb2c99e4 100644 --- a/vp8/common/recon.h +++ b/vp8/common/recon.h @@ -29,6 +29,11 @@ #define prototype_intra4x4_predict(sym) \ void sym(BLOCKD *x, int b_mode, unsigned char *predictor) +#if CONFIG_COMP_INTRA_PRED +#define prototype_comp_intra4x4_predict(sym) \ + void sym(BLOCKD *x, int b_mode, int mode2, unsigned char *predictor) +#endif + struct vp8_recon_rtcd_vtable; #if ARCH_X86 || ARCH_X86_64 @@ -101,6 +106,14 @@ extern prototype_recon_macroblock(vp8_recon_recon_mby); extern prototype_build_intra_predictors\ (vp8_recon_build_intra_predictors_mby); +#if CONFIG_COMP_INTRA_PRED +#ifndef vp8_recon_build_comp_intra_predictors_mby +#define vp8_recon_build_comp_intra_predictors_mby vp8_build_comp_intra_predictors_mby +#endif +extern prototype_build_intra_predictors\ + (vp8_recon_build_comp_intra_predictors_mby); +#endif + #ifndef vp8_recon_build_intra8x8_predictors_mby #define vp8_recon_build_intra8x8_predictors_mby vp8_build_intra8x8_predictors_mby #endif @@ -131,29 +144,64 @@ extern prototype_build_intra_predictors\ extern prototype_build_intra_predictors\ (vp8_recon_build_intra_predictors_mbuv_s); +#if CONFIG_COMP_INTRA_PRED +#ifndef vp8_recon_build_comp_intra_predictors_mbuv +#define vp8_recon_build_comp_intra_predictors_mbuv vp8_build_comp_intra_predictors_mbuv +#endif +extern prototype_build_intra_predictors\ + (vp8_recon_build_comp_intra_predictors_mbuv); +#endif + #ifndef vp8_recon_intra4x4_predict #define vp8_recon_intra4x4_predict vp8_intra4x4_predict #endif extern prototype_intra4x4_predict\ (vp8_recon_intra4x4_predict); +#if CONFIG_COMP_INTRA_PRED +#ifndef vp8_recon_comp_intra4x4_predict +#define vp8_recon_comp_intra4x4_predict vp8_comp_intra4x4_predict +#endif +extern prototype_comp_intra4x4_predict\ + (vp8_recon_comp_intra4x4_predict); +#endif + #ifndef vp8_recon_intra8x8_predict #define vp8_recon_intra8x8_predict vp8_intra8x8_predict #endif extern prototype_intra4x4_predict\ (vp8_recon_intra8x8_predict); +#if CONFIG_COMP_INTRA_PRED +#ifndef vp8_recon_comp_intra8x8_predict +#define vp8_recon_comp_intra8x8_predict vp8_comp_intra8x8_predict +#endif +extern prototype_comp_intra4x4_predict\ + (vp8_recon_comp_intra8x8_predict); +#endif + #ifndef vp8_recon_intra_uv4x4_predict #define vp8_recon_intra_uv4x4_predict vp8_intra_uv4x4_predict #endif extern prototype_intra4x4_predict\ (vp8_recon_intra_uv4x4_predict); +#if CONFIG_COMP_INTRA_PRED +#ifndef vp8_recon_comp_intra_uv4x4_predict +#define vp8_recon_comp_intra_uv4x4_predict vp8_comp_intra_uv4x4_predict +#endif +extern prototype_comp_intra4x4_predict\ + (vp8_recon_comp_intra_uv4x4_predict); +#endif + typedef prototype_copy_block((*vp8_copy_block_fn_t)); typedef prototype_recon_block((*vp8_recon_fn_t)); typedef prototype_recon_macroblock((*vp8_recon_mb_fn_t)); typedef prototype_build_intra_predictors((*vp8_build_intra_pred_fn_t)); typedef prototype_intra4x4_predict((*vp8_intra4x4_pred_fn_t)); +#if CONFIG_COMP_INTRA_PRED +typedef prototype_comp_intra4x4_predict((*vp8_comp_intra4x4_pred_fn_t)); +#endif typedef struct vp8_recon_rtcd_vtable { vp8_copy_block_fn_t copy16x16; @@ -169,11 +217,26 @@ typedef struct vp8_recon_rtcd_vtable vp8_recon_mb_fn_t recon_mby; vp8_build_intra_pred_fn_t build_intra_predictors_mby_s; vp8_build_intra_pred_fn_t build_intra_predictors_mby; +#if CONFIG_COMP_INTRA_PRED + vp8_build_intra_pred_fn_t build_comp_intra_predictors_mby; +#endif vp8_build_intra_pred_fn_t build_intra_predictors_mbuv_s; vp8_build_intra_pred_fn_t build_intra_predictors_mbuv; +#if CONFIG_COMP_INTRA_PRED + vp8_build_intra_pred_fn_t build_comp_intra_predictors_mbuv; +#endif vp8_intra4x4_pred_fn_t intra4x4_predict; +#if CONFIG_COMP_INTRA_PRED + vp8_comp_intra4x4_pred_fn_t comp_intra4x4_predict; +#endif vp8_intra4x4_pred_fn_t intra8x8_predict; +#if CONFIG_COMP_INTRA_PRED + vp8_comp_intra4x4_pred_fn_t comp_intra8x8_predict; +#endif vp8_intra4x4_pred_fn_t intra_uv4x4_predict; +#if CONFIG_COMP_INTRA_PRED + vp8_comp_intra4x4_pred_fn_t comp_intra_uv4x4_predict; +#endif } vp8_recon_rtcd_vtable_t; #if CONFIG_RUNTIME_CPU_DETECT diff --git a/vp8/common/reconintra.c b/vp8/common/reconintra.c index 21a5b3f53b6bd57da689f2c432c778465ed2ad51..501eacab2345c793cc73c37e54fc123a0da17862 100644 --- a/vp8/common/reconintra.c +++ b/vp8/common/reconintra.c @@ -28,13 +28,12 @@ void vp8_recon_intra_mbuv(const vp8_recon_rtcd_vtable_t *rtcd, MACROBLOCKD *x) } } -void vp8_build_intra_predictors_mby(MACROBLOCKD *x) +void vp8_build_intra_predictors_mby_internal(MACROBLOCKD *x, unsigned char *ypred_ptr, int y_stride, int mode) { unsigned char *yabove_row = x->dst.y_buffer - x->dst.y_stride; unsigned char yleft_col[16]; unsigned char ytop_left = yabove_row[-1]; - unsigned char *ypred_ptr = x->predictor; int r, c, i; for (i = 0; i < 16; i++) @@ -43,127 +42,7 @@ void vp8_build_intra_predictors_mby(MACROBLOCKD *x) } /* for Y */ - switch (x->mode_info_context->mbmi.mode) - { - case DC_PRED: - { - int expected_dc; - int i; - int shift; - int average = 0; - - - if (x->up_available || x->left_available) - { - if (x->up_available) - { - for (i = 0; i < 16; i++) - { - average += yabove_row[i]; - } - } - - if (x->left_available) - { - - for (i = 0; i < 16; i++) - { - average += yleft_col[i]; - } - } - shift = 3 + x->up_available + x->left_available; - expected_dc = (average + (1 << (shift - 1))) >> shift; - } - else - { - expected_dc = 128; - } - - vpx_memset(ypred_ptr, expected_dc, 256); - } - break; - case V_PRED: - { - - for (r = 0; r < 16; r++) - { - - ((int *)ypred_ptr)[0] = ((int *)yabove_row)[0]; - ((int *)ypred_ptr)[1] = ((int *)yabove_row)[1]; - ((int *)ypred_ptr)[2] = ((int *)yabove_row)[2]; - ((int *)ypred_ptr)[3] = ((int *)yabove_row)[3]; - ypred_ptr += 16; - } - } - break; - case H_PRED: - { - - for (r = 0; r < 16; r++) - { - - vpx_memset(ypred_ptr, yleft_col[r], 16); - ypred_ptr += 16; - } - - } - break; - case TM_PRED: - { - - for (r = 0; r < 16; r++) - { - for (c = 0; c < 16; c++) - { - int pred = yleft_col[r] + yabove_row[ c] - ytop_left; - - if (pred < 0) - pred = 0; - - if (pred > 255) - pred = 255; - - ypred_ptr[c] = pred; - } - - ypred_ptr += 16; - } - - } - break; -#if CONIFG_I8X8 - case I8X8_PRED: -#endif - case B_PRED: - case NEARESTMV: - case NEARMV: - case ZEROMV: - case NEWMV: - case SPLITMV: - case MB_MODE_COUNT: - break; - } -} - -void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) -{ - - unsigned char *yabove_row = x->dst.y_buffer - x->dst.y_stride; - unsigned char yleft_col[16]; - unsigned char ytop_left = yabove_row[-1]; - unsigned char *ypred_ptr = x->predictor; - int r, c, i; - - int y_stride = x->dst.y_stride; - ypred_ptr = x->dst.y_buffer; /*x->predictor;*/ - - for (i = 0; i < 16; i++) - { - yleft_col[i] = x->dst.y_buffer [i* x->dst.y_stride -1]; - } - - /* for Y */ - switch (x->mode_info_context->mbmi.mode) + switch (mode) { case DC_PRED: { @@ -190,9 +69,7 @@ void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) { average += yleft_col[i]; } - } - shift = 3 + x->up_available + x->left_available; expected_dc = (average + (1 << (shift - 1))) >> shift; } @@ -201,7 +78,6 @@ void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) expected_dc = 128; } - /*vpx_memset(ypred_ptr, expected_dc, 256);*/ for (r = 0; r < 16; r++) { vpx_memset(ypred_ptr, expected_dc, 16); @@ -219,7 +95,7 @@ void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) ((int *)ypred_ptr)[1] = ((int *)yabove_row)[1]; ((int *)ypred_ptr)[2] = ((int *)yabove_row)[2]; ((int *)ypred_ptr)[3] = ((int *)yabove_row)[3]; - ypred_ptr += y_stride; /*16;*/ + ypred_ptr += y_stride; } } break; @@ -230,7 +106,7 @@ void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) { vpx_memset(ypred_ptr, yleft_col[r], 16); - ypred_ptr += y_stride; /*16;*/ + ypred_ptr += y_stride; } } @@ -253,11 +129,14 @@ void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) ypred_ptr[c] = pred; } - ypred_ptr += y_stride; /*16;*/ + ypred_ptr += y_stride; } } break; +#if CONIFG_I8X8 + case I8X8_PRED: +#endif case B_PRED: case NEARESTMV: case NEARMV: @@ -269,145 +148,41 @@ void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) } } -void vp8_build_intra_predictors_mbuv(MACROBLOCKD *x) +void vp8_build_intra_predictors_mby(MACROBLOCKD *x) { - unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride; - unsigned char uleft_col[16]; - unsigned char utop_left = uabove_row[-1]; - unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride; - unsigned char vleft_col[20]; - unsigned char vtop_left = vabove_row[-1]; - unsigned char *upred_ptr = &x->predictor[256]; - unsigned char *vpred_ptr = &x->predictor[320]; - int i, j; - - for (i = 0; i < 8; i++) - { - uleft_col[i] = x->dst.u_buffer [i* x->dst.uv_stride -1]; - vleft_col[i] = x->dst.v_buffer [i* x->dst.uv_stride -1]; - } - - switch (x->mode_info_context->mbmi.uv_mode) - { - case DC_PRED: - { - int expected_udc; - int expected_vdc; - int i; - int shift; - int Uaverage = 0; - int Vaverage = 0; - - if (x->up_available) - { - for (i = 0; i < 8; i++) - { - Uaverage += uabove_row[i]; - Vaverage += vabove_row[i]; - } - } - - if (x->left_available) - { - for (i = 0; i < 8; i++) - { - Uaverage += uleft_col[i]; - Vaverage += vleft_col[i]; - } - } - - if (!x->up_available && !x->left_available) - { - expected_udc = 128; - expected_vdc = 128; - } - else - { - shift = 2 + x->up_available + x->left_available; - expected_udc = (Uaverage + (1 << (shift - 1))) >> shift; - expected_vdc = (Vaverage + (1 << (shift - 1))) >> shift; - } - - - vpx_memset(upred_ptr, expected_udc, 64); - vpx_memset(vpred_ptr, expected_vdc, 64); + vp8_build_intra_predictors_mby_internal(x, x->predictor, 16, + x->mode_info_context->mbmi.mode); +} +void vp8_build_intra_predictors_mby_s(MACROBLOCKD *x) +{ + vp8_build_intra_predictors_mby_internal(x, x->dst.y_buffer, x->dst.y_stride, + x->mode_info_context->mbmi.mode); +} - } - break; - case V_PRED: - { - int i; +#if CONFIG_COMP_INTRA_PRED +void vp8_build_comp_intra_predictors_mby(MACROBLOCKD *x) +{ + unsigned char predictor[2][256]; + int i; - for (i = 0; i < 8; i++) - { - vpx_memcpy(upred_ptr, uabove_row, 8); - vpx_memcpy(vpred_ptr, vabove_row, 8); - upred_ptr += 8; - vpred_ptr += 8; - } + vp8_build_intra_predictors_mby_internal(x, predictor[0], 16, + x->mode_info_context->mbmi.mode); + vp8_build_intra_predictors_mby_internal(x, predictor[1], 16, + x->mode_info_context->mbmi.second_mode); - } - break; - case H_PRED: + for (i = 0; i < 256; i++) { - int i; - - for (i = 0; i < 8; i++) - { - vpx_memset(upred_ptr, uleft_col[i], 8); - vpx_memset(vpred_ptr, vleft_col[i], 8); - upred_ptr += 8; - vpred_ptr += 8; - } - } - - break; - case TM_PRED: - { - int i; - - for (i = 0; i < 8; i++) - { - for (j = 0; j < 8; j++) - { - int predu = uleft_col[i] + uabove_row[j] - utop_left; - int predv = vleft_col[i] + vabove_row[j] - vtop_left; - - if (predu < 0) - predu = 0; - - if (predu > 255) - predu = 255; - - if (predv < 0) - predv = 0; - - if (predv > 255) - predv = 255; - - upred_ptr[j] = predu; - vpred_ptr[j] = predv; - } - - upred_ptr += 8; - vpred_ptr += 8; - } - - } - break; - case B_PRED: - case NEARESTMV: - case NEARMV: - case ZEROMV: - case NEWMV: - case SPLITMV: - case MB_MODE_COUNT: - break; + x->predictor[i] = (predictor[0][i] + predictor[1][i] + 1) >> 1; } } +#endif -void vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x) +void vp8_build_intra_predictors_mbuv_internal(MACROBLOCKD *x, + unsigned char *upred_ptr, + unsigned char *vpred_ptr, + int uv_stride, + int mode) { unsigned char *uabove_row = x->dst.u_buffer - x->dst.uv_stride; unsigned char uleft_col[16]; @@ -415,9 +190,6 @@ void vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x) unsigned char *vabove_row = x->dst.v_buffer - x->dst.uv_stride; unsigned char vleft_col[20]; unsigned char vtop_left = vabove_row[-1]; - unsigned char *upred_ptr = x->dst.u_buffer; /*&x->predictor[256];*/ - unsigned char *vpred_ptr = x->dst.v_buffer; /*&x->predictor[320];*/ - int uv_stride = x->dst.uv_stride; int i, j; @@ -427,7 +199,7 @@ void vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x) vleft_col[i] = x->dst.v_buffer [i* x->dst.uv_stride -1]; } - switch (x->mode_info_context->mbmi.uv_mode) + switch (mode) { case DC_PRED: { @@ -551,6 +323,43 @@ void vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x) break; } } + +void vp8_build_intra_predictors_mbuv(MACROBLOCKD *x) +{ + vp8_build_intra_predictors_mbuv_internal(x, + &x->predictor[256], + &x->predictor[320], + 8, + x->mode_info_context->mbmi.uv_mode); +} + +void vp8_build_intra_predictors_mbuv_s(MACROBLOCKD *x) +{ + vp8_build_intra_predictors_mbuv_internal(x, + x->dst.u_buffer, + x->dst.v_buffer, + x->dst.uv_stride, + x->mode_info_context->mbmi.uv_mode); +} + +#if CONFIG_COMP_INTRA_PRED +void vp8_build_comp_intra_predictors_mbuv(MACROBLOCKD *x) +{ + unsigned char predictor[2][2][64]; + int i; + + vp8_build_intra_predictors_mbuv_internal(x, predictor[0][0], predictor[1][0], 8, + x->mode_info_context->mbmi.uv_mode); + vp8_build_intra_predictors_mbuv_internal(x, predictor[0][1], predictor[1][1], 8, + x->mode_info_context->mbmi.second_uv_mode); + for (i = 0; i < 64; i++) + { + x->predictor[256 + i] = (predictor[0][0][i] + predictor[0][1][i] + 1) >> 1; + x->predictor[256 + 64 + i] = (predictor[1][0][i] + predictor[1][1][i] + 1) >> 1; + } +} +#endif + void vp8_intra8x8_predict(BLOCKD *x, int mode, unsigned char *predictor) @@ -638,6 +447,28 @@ void vp8_intra8x8_predict(BLOCKD *x, } } +#if CONFIG_COMP_INTRA_PRED +void vp8_comp_intra8x8_predict(BLOCKD *x, + int mode, int second_mode, + unsigned char *out_predictor) +{ + + unsigned char predictor[2][8*16]; + int i, j; + + vp8_intra8x8_predict(x, mode, predictor[0]); + vp8_intra8x8_predict(x, second_mode, predictor[1]); + + for (i = 0; i < 8*16; i += 16) + { + for (j = i; j < i + 8; j++) + { + out_predictor[j] = (predictor[0][j] + predictor[1][j] + 1) >> 1; + } + } +} +#endif + void vp8_intra_uv4x4_predict(BLOCKD *x, int mode, unsigned char *predictor) @@ -725,6 +556,26 @@ void vp8_intra_uv4x4_predict(BLOCKD *x, } } +#if CONFIG_COMP_INTRA_PRED +void vp8_comp_intra_uv4x4_predict(BLOCKD *x, + int mode, int mode2, + unsigned char *out_predictor) +{ + unsigned char predictor[2][8*4]; + int i, j; + + vp8_intra_uv4x4_predict(x, mode, predictor[0]); + vp8_intra_uv4x4_predict(x, mode2, predictor[1]); + + for (i = 0; i < 4*8; i += 8) + { + for (j = i; j < i + 4; j++) + { + out_predictor[j] = (predictor[0][j] + predictor[1][j] + 1) >> 1; + } + } +} +#endif /* TODO: try different ways of use Y-UV mode correlation Current code assumes that a uv 4x4 block use same mode diff --git a/vp8/common/reconintra4x4.c b/vp8/common/reconintra4x4.c index 12e2e60c7ceb3901db99f9c01629793da41fe78e..ab8be48157dcbbae5eccc816dc93e33d021c7873 100644 --- a/vp8/common/reconintra4x4.c +++ b/vp8/common/reconintra4x4.c @@ -295,6 +295,28 @@ void vp8_intra4x4_predict(BLOCKD *x, } } + +#if CONFIG_COMP_INTRA_PRED +void vp8_comp_intra4x4_predict(BLOCKD *x, + int b_mode, int b_mode2, + unsigned char *out_predictor) +{ + unsigned char predictor[2][4*16]; + int i, j; + + vp8_intra4x4_predict(x, b_mode, predictor[0]); + vp8_intra4x4_predict(x, b_mode2, predictor[1]); + + for (i = 0; i < 16*4; i += 16) + { + for (j = i; j < i + 4; j++) + { + out_predictor[j] = (predictor[0][j] + predictor[1][j] + 1) >> 1; + } + } +} +#endif + /* 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. */ diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index fc1098a44dc92dccbcfd258b283cd3ddc7dd6cdd..3a74fd83ece11ff7c1ba71464ccf38ccc17fd012 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -125,6 +125,9 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode( bc, pbi->common.kf_ymode_prob); #endif +#if CONFIG_COMP_INTRA_PRED + m->mbmi.second_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); +#endif m->mbmi.ref_frame = INTRA_FRAME; @@ -135,10 +138,25 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, { const B_PREDICTION_MODE A = above_block_mode(m, i, mis); const B_PREDICTION_MODE L = left_block_mode(m, i); +#if CONFIG_COMP_INTRA_PRED + int use_comp_pred = vp8_read(bc, 128); +#endif - m->bmi[i].as_mode = + m->bmi[i].as_mode.first = (B_PREDICTION_MODE) vp8_read_bmode( bc, pbi->common.kf_bmode_prob [A] [L]); +#if CONFIG_COMP_INTRA_PRED + if (use_comp_pred) + { + m->bmi[i].as_mode.second = + (B_PREDICTION_MODE) vp8_read_bmode( + bc, pbi->common.kf_bmode_prob [A] [L]); + } + else + { + m->bmi[i].as_mode.second = (B_PREDICTION_MODE) (B_DC_PRED - 1); + } +#endif } while (++i < 16); } @@ -150,10 +168,16 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, { int ib = vp8_i8x8_block[i]; mode8x8 = vp8_read_i8x8_mode(bc, pbi->common.i8x8_mode_prob); - m->bmi[ib+0].as_mode= mode8x8; - m->bmi[ib+1].as_mode= mode8x8; - m->bmi[ib+4].as_mode= mode8x8; - m->bmi[ib+5].as_mode= mode8x8; + m->bmi[ib+0].as_mode.first= mode8x8; + m->bmi[ib+1].as_mode.first= mode8x8; + m->bmi[ib+4].as_mode.first= mode8x8; + m->bmi[ib+5].as_mode.first= mode8x8; +#if CONFIG_COMP_INTRA_PRED + m->bmi[ib+0].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); + m->bmi[ib+1].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); + m->bmi[ib+4].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); + m->bmi[ib+5].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); +#endif } } else @@ -164,6 +188,9 @@ static void vp8_kfread_modes(VP8D_COMP *pbi, m->mbmi.uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, pbi->common.kf_uv_mode_prob); #endif +#if CONFIG_COMP_INTRA_PRED + m->mbmi.second_uv_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); +#endif } static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc) @@ -899,6 +926,9 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mbmi->mode = (MB_PREDICTION_MODE) vp8_read_ymode(bc, pbi->common.fc.ymode_prob); } +#if CONFIG_COMP_INTRA_PRED + mbmi->second_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); +#endif // If MB mode is BPRED read the block modes if (mbmi->mode == B_PRED) @@ -906,7 +936,20 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, int j = 0; do { - mi->bmi[j].as_mode = (B_PREDICTION_MODE)vp8_read_bmode(bc, pbi->common.fc.bmode_prob); +#if CONFIG_COMP_INTRA_PRED + int use_comp_pred = vp8_read(bc, 128); +#endif + mi->bmi[j].as_mode.first = (B_PREDICTION_MODE)vp8_read_bmode(bc, pbi->common.fc.bmode_prob); +#if CONFIG_COMP_INTRA_PRED + if (use_comp_pred) + { + mi->bmi[j].as_mode.second = (B_PREDICTION_MODE)vp8_read_bmode(bc, pbi->common.fc.bmode_prob); + } + else + { + mi->bmi[j].as_mode.second = (B_PREDICTION_MODE) (B_DC_PRED - 1); + } +#endif } while (++j < 16); } @@ -919,10 +962,16 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, { 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; + mi->bmi[ib+0].as_mode.first= mode8x8; + mi->bmi[ib+1].as_mode.first= mode8x8; + mi->bmi[ib+4].as_mode.first= mode8x8; + mi->bmi[ib+5].as_mode.first= mode8x8; +#if CONFIG_COMP_INTRA_PRED + mi->bmi[ib+0].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); + mi->bmi[ib+1].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); + mi->bmi[ib+4].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); + mi->bmi[ib+5].as_mode.second= (MB_PREDICTION_MODE) (DC_PRED - 1); +#endif } } else @@ -933,6 +982,9 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, pbi->common.fc.uv_mode_prob); #endif /*CONFIG_UVINTRA*/ +#if CONFIG_COMP_INTRA_PRED + mbmi->second_uv_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); +#endif } } diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index 06673b4c2d3a599d26f1563fe62fa1a2209efc0a..3e3f75e3274f90dc788bd1c1182565e44b31a4f1 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -275,7 +275,7 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, BLOCKD *b; b = &xd->block[ib]; - i8x8mode= b->bmi.as_mode; + i8x8mode= b->bmi.as_mode.first; RECON_INVOKE(RTCD_VTABLE(recon), intra8x8_predict) (b, i8x8mode, b->predictor); @@ -316,10 +316,23 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, for (i = 0; i < 16; i++) { BLOCKD *b = &xd->block[i]; - int b_mode = xd->mode_info_context->bmi[i].as_mode; + int b_mode = xd->mode_info_context->bmi[i].as_mode.first; +#if CONFIG_COMP_INTRA_PRED + int b_mode2 = xd->mode_info_context->bmi[i].as_mode.second; + if (b_mode2 == (B_PREDICTION_MODE) (B_DC_PRED - 1)) + { +#endif RECON_INVOKE(RTCD_VTABLE(recon), intra4x4_predict) (b, b_mode, b->predictor); +#if CONFIG_COMP_INTRA_PRED + } + else + { + RECON_INVOKE(RTCD_VTABLE(recon), comp_intra4x4_predict) + (b, b_mode, b_mode2, b->predictor); + } +#endif if (xd->eobs[i] > 1) { diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 1a62e44ae6e1b84c82d6b93aedd657174aa48e99..f57114cabd9f917ecdb9df50241c2dfa924e01b4 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -759,17 +759,27 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { int j = 0; - do - write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob); - while (++j < 16); + do { +#if CONFIG_COMP_INTRA_PRED + int mode2 = m->bmi[j].as_mode.second; + vp8_encode_bool(w, mode2 != (B_PREDICTION_MODE) (B_DC_PRED - 1), 128); +#endif + write_bmode(w, m->bmi[j].as_mode.first, pc->fc.bmode_prob); +#if CONFIG_COMP_INTRA_PRED + if (mode2 != (B_PREDICTION_MODE) (B_DC_PRED - 1)) + { + write_bmode(w, mode2, pc->fc.bmode_prob); + } +#endif + } while (++j < 16); } 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); + write_i8x8_mode(w, m->bmi[0].as_mode.first, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[2].as_mode.first, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[8].as_mode.first, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[10].as_mode.first, pc->i8x8_mode_prob); } else { @@ -1118,16 +1128,26 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { int j = 0; - do - write_bmode(w, m->bmi[j].as_mode, pc->fc.bmode_prob); - while (++j < 16); + do { +#if CONFIG_COMP_INTRA_PRED + B_PREDICTION_MODE mode2 = m->bmi[j].as_mode.second; + vp8_write(w, mode2 != (B_PREDICTION_MODE) (B_DC_PRED - 1), 128); +#endif + write_bmode(w, m->bmi[j].as_mode.first, pc->fc.bmode_prob); +#if CONFIG_COMP_INTRA_PRED + if (mode2 != (B_PREDICTION_MODE) (B_DC_PRED - 1)) + { + write_bmode(w, mode2, pc->fc.bmode_prob); + } +#endif + } while (++j < 16); } 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); + write_i8x8_mode(w, m->bmi[0].as_mode.first, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[2].as_mode.first, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[8].as_mode.first, pc->i8x8_mode_prob); + write_i8x8_mode(w, m->bmi[10].as_mode.first, pc->i8x8_mode_prob); } else { @@ -1385,23 +1405,35 @@ static void write_kfmodes(VP8_COMP *cpi) { const B_PREDICTION_MODE A = above_block_mode(m, i, mis); const B_PREDICTION_MODE L = left_block_mode(m, i); - const int bm = m->bmi[i].as_mode; + const int bm = m->bmi[i].as_mode.first; +#if CONFIG_COMP_INTRA_PRED + const int bm2 = m->bmi[i].as_mode.second; +#endif #ifdef ENTROPY_STATS ++intra_mode_stats [A] [L] [bm]; #endif +#if CONFIG_COMP_INTRA_PRED + vp8_write(bc, bm2 != (B_PREDICTION_MODE) (B_DC_PRED - 1), 128); +#endif write_bmode(bc, bm, c->kf_bmode_prob [A] [L]); +#if CONFIG_COMP_INTRA_PRED + if (bm2 != (B_PREDICTION_MODE) (B_DC_PRED - 1)) + { + write_bmode(bc, bm2, c->kf_bmode_prob [A] [L]); + } +#endif } while (++i < 16); } if(ym == I8X8_PRED) { - write_i8x8_mode(bc, m->bmi[0].as_mode, c->i8x8_mode_prob); - write_i8x8_mode(bc, m->bmi[2].as_mode, c->i8x8_mode_prob); - write_i8x8_mode(bc, m->bmi[8].as_mode, c->i8x8_mode_prob); - write_i8x8_mode(bc, m->bmi[10].as_mode, c->i8x8_mode_prob); + write_i8x8_mode(bc, m->bmi[0].as_mode.first, c->i8x8_mode_prob); + write_i8x8_mode(bc, m->bmi[2].as_mode.first, c->i8x8_mode_prob); + write_i8x8_mode(bc, m->bmi[8].as_mode.first, c->i8x8_mode_prob); + write_i8x8_mode(bc, m->bmi[10].as_mode.first, c->i8x8_mode_prob); } else #if CONFIG_UVINTRA @@ -1493,22 +1525,34 @@ static void write_kfmodes(VP8_COMP *cpi) { const B_PREDICTION_MODE A = above_block_mode(m, i, mis); const B_PREDICTION_MODE L = left_block_mode(m, i); - const int bm = m->bmi[i].as_mode; + const int bm = m->bmi[i].as_mode.first; +#if CONFIG_COMP_INTRA_PRED + const int bm2 = m->bmi[i].as_mode.second; +#endif #ifdef ENTROPY_STATS ++intra_mode_stats [A] [L] [bm]; #endif +#if CONFIG_COMP_INTRA_PRED + vp8_write(bc, bm2 != (B_PREDICTION_MODE) (B_DC_PRED - 1), 128); +#endif write_bmode(bc, bm, c->kf_bmode_prob [A] [L]); +#if CONFIG_COMP_INTRA_PRED + if (bm2 != (B_PREDICTION_MODE) (B_DC_PRED - 1)) + { + write_bmode(bc, bm2, c->kf_bmode_prob [A] [L]); + } +#endif } while (++i < 16); } if(ym == I8X8_PRED) { - write_i8x8_mode(bc, m->bmi[0].as_mode, c->i8x8_mode_prob); - write_i8x8_mode(bc, m->bmi[2].as_mode, c->i8x8_mode_prob); - write_i8x8_mode(bc, m->bmi[8].as_mode, c->i8x8_mode_prob); - write_i8x8_mode(bc, m->bmi[10].as_mode, c->i8x8_mode_prob); + write_i8x8_mode(bc, m->bmi[0].as_mode.first, c->i8x8_mode_prob); + write_i8x8_mode(bc, m->bmi[2].as_mode.first, c->i8x8_mode_prob); + write_i8x8_mode(bc, m->bmi[8].as_mode.first, c->i8x8_mode_prob); + write_i8x8_mode(bc, m->bmi[10].as_mode.first, c->i8x8_mode_prob); m++; } else diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 6c9c4f0420c7dd267438ad40040e0fdcd2702fcc..352a6f4c8f851839f637fbaed0d1f17c54c65f94 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -1425,17 +1425,17 @@ static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x) do { - ++ bct[xd->block[b].bmi.as_mode]; + ++ bct[xd->block[b].bmi.as_mode.first]; } while (++b < 16); } if(m==I8X8_PRED) { - i8x8_modes[xd->block[0].bmi.as_mode]++; - i8x8_modes[xd->block[2].bmi.as_mode]++; - i8x8_modes[xd->block[8].bmi.as_mode]++; - i8x8_modes[xd->block[10].bmi.as_mode]++; + i8x8_modes[xd->block[0].bmi.as_mode.first]++; + i8x8_modes[xd->block[2].bmi.as_mode.first]++; + i8x8_modes[xd->block[8].bmi.as_mode.first]++; + i8x8_modes[xd->block[10].bmi.as_mode.first]++; } #endif diff --git a/vp8/encoder/encodeintra.c b/vp8/encoder/encodeintra.c index 062f31ca7a71f8a450cb98081921cf5230d67318..63a1465512c91ed5a1069e8a02f2778308dd6be5 100644 --- a/vp8/encoder/encodeintra.c +++ b/vp8/encoder/encodeintra.c @@ -42,6 +42,9 @@ int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) if (use_16x16_pred) { x->e_mbd.mode_info_context->mbmi.mode = DC_PRED; +#if CONFIG_COMP_INTRA_PRED + x->e_mbd.mode_info_context->mbmi.second_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); +#endif x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; @@ -51,7 +54,7 @@ int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) { for (i = 0; i < 16; i++) { - x->e_mbd.block[i].bmi.as_mode = B_DC_PRED; + x->e_mbd.block[i].bmi.as_mode.first = B_DC_PRED; vp8_encode_intra4x4block(IF_RTCD(&cpi->rtcd), x, i); } } @@ -67,8 +70,20 @@ void vp8_encode_intra4x4block(const VP8_ENCODER_RTCD *rtcd, BLOCKD *b = &x->e_mbd.block[ib]; BLOCK *be = &x->block[ib]; +#if CONFIG_COMP_INTRA_PRED + if (b->bmi.as_mode.second == (B_PREDICTION_MODE) (B_DC_PRED - 1)) + { +#endif RECON_INVOKE(&rtcd->common->recon, intra4x4_predict) - (b, b->bmi.as_mode, b->predictor); + (b, b->bmi.as_mode.first, b->predictor); +#if CONFIG_COMP_INTRA_PRED + } + else + { + RECON_INVOKE(&rtcd->common->recon, comp_intra4x4_predict) + (b, b->bmi.as_mode.first, b->bmi.as_mode.second, b->predictor); + } +#endif ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16); @@ -103,7 +118,14 @@ void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) int tx_type = x->e_mbd.mode_info_context->mbmi.txfm_size; #endif +#if CONFIG_COMP_INTRA_PRED + if (x->e_mbd.mode_info_context->mbmi.second_mode == (MB_PREDICTION_MODE) (DC_PRED - 1)) +#endif RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mby)(&x->e_mbd); +#if CONFIG_COMP_INTRA_PRED + else + RECON_INVOKE(&rtcd->common->recon, build_comp_intra_predictors_mby)(&x->e_mbd); +#endif ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride); @@ -178,8 +200,19 @@ void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) { #if CONFIG_T8X8 int tx_type = x->e_mbd.mode_info_context->mbmi.txfm_size; +#endif +#if CONFIG_COMP_INTRA_PRED + if (x->e_mbd.mode_info_context->mbmi.second_uv_mode == (MB_PREDICTION_MODE) (DC_PRED - 1)) + { #endif RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mbuv)(&x->e_mbd); +#if CONFIG_COMP_INTRA_PRED + } + else + { + RECON_INVOKE(&rtcd->common->recon, build_comp_intra_predictors_mbuv)(&x->e_mbd); + } +#endif 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 @@ -255,8 +288,20 @@ void vp8_encode_intra8x8(const VP8_ENCODER_RTCD *rtcd, const int iblock[4]={0,1,4,5}; int i; +#if CONFIG_COMP_INTRA_PRED + if (b->bmi.as_mode.second == (MB_PREDICTION_MODE) (DC_PRED - 1)) + { +#endif RECON_INVOKE(&rtcd->common->recon, intra8x8_predict) - (b, b->bmi.as_mode, b->predictor); + (b, b->bmi.as_mode.first, b->predictor); +#if CONFIG_COMP_INTRA_PRED + } + else + { + RECON_INVOKE(&rtcd->common->recon, comp_intra8x8_predict) + (b, b->bmi.as_mode.first, b->bmi.as_mode.second, b->predictor); + } +#endif for(i=0;i<4;i++) { @@ -287,13 +332,25 @@ void vp8_encode_intra8x8mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) void vp8_encode_intra_uv4x4(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x, int ib, - int mode) + int mode, int second) { BLOCKD *b = &x->e_mbd.block[ib]; BLOCK *be = &x->block[ib]; +#if CONFIG_COMP_INTRA_PRED + if (second == -1) + { +#endif RECON_INVOKE(&rtcd->common->recon, intra_uv4x4_predict) (b, mode, b->predictor); +#if CONFIG_COMP_INTRA_PRED + } + else + { + RECON_INVOKE(&rtcd->common->recon, comp_intra_uv4x4_predict) + (b, mode, second, b->predictor); + } +#endif ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 8); @@ -311,16 +368,21 @@ void vp8_encode_intra_uv4x4(const VP8_ENCODER_RTCD *rtcd, void vp8_encode_intra8x8mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) { - int i, ib, mode; + int i, ib, mode, second; BLOCKD *b; for(i=0;i<4;i++) { ib = vp8_i8x8_block[i]; b = &x->e_mbd.block[ib]; - mode = b->bmi.as_mode; + mode = b->bmi.as_mode.first; +#if CONFIG_COMP_INTRA_PRED + second = b->bmi.as_mode.second; +#else + second = -1; +#endif /*u */ - vp8_encode_intra_uv4x4(rtcd, x, i+16, mode); + vp8_encode_intra_uv4x4(rtcd, x, i+16, mode, second); /*v */ - vp8_encode_intra_uv4x4(rtcd, x, i+20, mode); + vp8_encode_intra_uv4x4(rtcd, x, i+20, mode, second); } } diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 87e1d93da004b75e474d8553bb040d05f63b0e08..0d3c8fa33d2b976aee49e6d1fa2a2aa29a99cd56 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -828,6 +828,9 @@ static int rd_pick_intra4x4block( BLOCK *be, BLOCKD *b, B_PREDICTION_MODE *best_mode, +#if CONFIG_COMP_INTRA_PRED + B_PREDICTION_MODE *best_second_mode, +#endif unsigned int *bmode_costs, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, @@ -837,6 +840,9 @@ static int rd_pick_intra4x4block( int *bestdistortion) { B_PREDICTION_MODE mode; +#if CONFIG_COMP_INTRA_PRED + B_PREDICTION_MODE mode2; +#endif int best_rd = INT_MAX; int rate = 0; int distortion; @@ -853,6 +859,10 @@ static int rd_pick_intra4x4block( for (mode = B_DC_PRED; mode <= B_HU_PRED; mode++) { +#if CONFIG_COMP_INTRA_PRED + for (mode2 = B_DC_PRED - 1; mode2 != B_HU_PRED + 1; mode2++) + { +#endif int this_rd; int ratey; @@ -863,8 +873,23 @@ static int rd_pick_intra4x4block( #endif rate = bmode_costs[mode]; +#if CONFIG_COMP_INTRA_PRED + if (mode2 == (B_PREDICTION_MODE) (B_DC_PRED - 1)) + { +#endif RECON_INVOKE(&cpi->rtcd.common->recon, intra4x4_predict) (b, mode, b->predictor); +#if CONFIG_COMP_INTRA_PRED + rate += vp8_cost_bit(128, 0); + } + else + { + RECON_INVOKE(&cpi->rtcd.common->recon, comp_intra4x4_predict) + (b, mode, mode2, b->predictor); + rate += vp8_cost_bit(128, 1); + rate += bmode_costs[mode2]; + } +#endif ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), subb)(be, b, 16); x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32); x->quantize_b(be, b); @@ -885,13 +910,22 @@ static int rd_pick_intra4x4block( *bestdistortion = distortion; best_rd = this_rd; *best_mode = mode; +#if CONFIG_COMP_INTRA_PRED + *best_second_mode = mode2; +#endif *a = tempa; *l = templ; copy_predictor(best_predictor, b->predictor); vpx_memcpy(best_dqcoeff, b->dqcoeff, 32); +#if CONFIG_COMP_INTRA_PRED + } +#endif } } - b->bmi.as_mode = (B_PREDICTION_MODE)(*best_mode); + b->bmi.as_mode.first = (B_PREDICTION_MODE)(*best_mode); +#if CONFIG_COMP_INTRA_PRED + b->bmi.as_mode.second = (B_PREDICTION_MODE)(*best_second_mode); +#endif IDCT_INVOKE(IF_RTCD(&cpi->rtcd.common->idct), idct16)(best_dqcoeff, b->diff, 32); RECON_INVOKE(IF_RTCD(&cpi->rtcd.common->recon), recon)(best_predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride); @@ -930,6 +964,9 @@ static int rd_pick_intra4x4mby_modes(VP8_COMP *cpi, MACROBLOCK *mb, int *Rate, MODE_INFO *const mic = xd->mode_info_context; const int mis = xd->mode_info_stride; B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode); +#if CONFIG_COMP_INTRA_PRED + B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_second_mode); +#endif int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(ry), UNINITIALIZED_IS_SAFE(d); if (mb->e_mbd.frame_type == KEY_FRAME) @@ -941,15 +978,21 @@ static int rd_pick_intra4x4mby_modes(VP8_COMP *cpi, MACROBLOCK *mb, int *Rate, } total_rd += rd_pick_intra4x4block( - cpi, mb, mb->block + i, xd->block + i, &best_mode, bmode_costs, - ta + vp8_block2above[i], + cpi, mb, mb->block + i, xd->block + i, &best_mode, +#if CONFIG_COMP_INTRA_PRED + &best_second_mode, +#endif + bmode_costs, ta + vp8_block2above[i], tl + vp8_block2left[i], &r, &ry, &d); cost += r; distortion += d; tot_rate_y += ry; - mic->bmi[i].as_mode = best_mode; + mic->bmi[i].as_mode.first = best_mode; +#if CONFIG_COMP_INTRA_PRED + mic->bmi[i].as_mode.second = best_second_mode; +#endif if(total_rd >= (int64_t)best_rd) break; @@ -974,6 +1017,10 @@ static int rd_pick_intra16x16mby_mode(VP8_COMP *cpi, { MB_PREDICTION_MODE mode; MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected); +#if CONFIG_COMP_INTRA_PRED + MB_PREDICTION_MODE mode2; + MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode2_selected); +#endif int rate, ratey; int distortion; int best_rd = INT_MAX; @@ -983,11 +1030,27 @@ static int rd_pick_intra16x16mby_mode(VP8_COMP *cpi, for (mode = DC_PRED; mode <= TM_PRED; mode++) { x->e_mbd.mode_info_context->mbmi.mode = mode; - +#if CONFIG_COMP_INTRA_PRED + for (mode2 = DC_PRED - 1; mode2 != TM_PRED + 1; mode2++) + { + x->e_mbd.mode_info_context->mbmi.second_mode = mode2; + if (mode2 == (MB_PREDICTION_MODE) (DC_PRED - 1)) + { +#endif RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby) (&x->e_mbd); +#if CONFIG_COMP_INTRA_PRED + } + else + { + continue; // i.e. disable for now + RECON_INVOKE(&cpi->common.rtcd.recon, build_comp_intra_predictors_mby)(&x->e_mbd); + } +#endif macro_block_yrd(x, &ratey, &distortion, IF_RTCD(&cpi->rtcd.encodemb)); + // FIXME add compoundmode cost + // FIXME add rate for mode2 rate = ratey + x->mbmode_cost[x->e_mbd.frame_type] [x->e_mbd.mode_info_context->mbmi.mode]; @@ -996,14 +1059,23 @@ static int rd_pick_intra16x16mby_mode(VP8_COMP *cpi, if (this_rd < best_rd) { mode_selected = mode; +#if CONFIG_COMP_INTRA_PRED + mode2_selected = mode2; +#endif best_rd = this_rd; *Rate = rate; *rate_y = ratey; *Distortion = distortion; } +#if CONFIG_COMP_INTRA_PRED + } +#endif } x->e_mbd.mode_info_context->mbmi.mode = mode_selected; +#if CONFIG_COMP_INTRA_PRED + x->e_mbd.mode_info_context->mbmi.second_mode = mode2_selected; +#endif return best_rd; } static int rd_pick_intra8x8block( @@ -1011,6 +1083,9 @@ static int rd_pick_intra8x8block( MACROBLOCK *x, int ib, B_PREDICTION_MODE *best_mode, +#if CONFIG_COMP_INTRA_PRED + B_PREDICTION_MODE *best_second_mode, +#endif unsigned int *mode_costs, ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l, @@ -1019,6 +1094,9 @@ static int rd_pick_intra8x8block( int *bestdistortion) { MB_PREDICTION_MODE mode; +#if CONFIG_COMP_INTRA_PRED + MB_PREDICTION_MODE mode2; +#endif MACROBLOCKD *xd = &x->e_mbd; int best_rd = INT_MAX; int rate = 0; @@ -1040,13 +1118,31 @@ static int rd_pick_intra8x8block( for (mode = DC_PRED; mode <= TM_PRED; mode++) { +#if CONFIG_COMP_INTRA_PRED + for (mode2 = DC_PRED - 1; mode2 != TM_PRED + 1; mode2++) + { +#endif int this_rd; int rate_t; + // FIXME rate for compound mode and second intrapred mode rate = mode_costs[mode]; +#if CONFIG_COMP_INTRA_PRED + if (mode2 == (MB_PREDICTION_MODE) (DC_PRED - 1)) + { +#endif RECON_INVOKE(&cpi->rtcd.common->recon, intra8x8_predict) (b, mode, b->predictor); +#if CONFIG_COMP_INTRA_PRED + } + else + { + continue; // i.e. disable for now + RECON_INVOKE(&cpi->rtcd.common->recon, comp_intra8x8_predict) + (b, mode, mode2, b->predictor); + } +#endif vp8_subtract_4b_c(be, b, 16); @@ -1092,12 +1188,21 @@ static int rd_pick_intra8x8block( bestl1 = tl1; best_rd = this_rd; *best_mode = mode; +#if CONFIG_COMP_INTRA_PRED + *best_second_mode = mode2; +#endif copy_predictor_8x8(best_predictor, b->predictor); vpx_memcpy(best_dqcoeff, b->dqcoeff, 64); vpx_memcpy(best_dqcoeff+32, b->dqcoeff+64, 64); +#if CONFIG_COMP_INTRA_PRED + } +#endif } } - b->bmi.as_mode = (*best_mode); + b->bmi.as_mode.first = (*best_mode); +#if CONFIG_COMP_INTRA_PRED + b->bmi.as_mode.second = (*best_second_mode); +#endif vp8_encode_intra8x8 (IF_RTCD(&cpi->rtcd), x, ib); *(a + vp8_block2above[ib]) = besta0; *(a + vp8_block2above[ib+1]) = besta1; @@ -1137,16 +1242,25 @@ int rd_pick_intra8x8mby_modes(VP8_COMP *cpi, { MODE_INFO *const mic = xd->mode_info_context; B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode); +#if CONFIG_COMP_INTRA_PRED + B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_second_mode); +#endif int UNINITIALIZED_IS_SAFE(r), UNINITIALIZED_IS_SAFE(ry), UNINITIALIZED_IS_SAFE(d); ib = vp8_i8x8_block[i]; total_rd += rd_pick_intra8x8block( - cpi, mb, ib, &best_mode, i8x8mode_costs, - ta, tl, &r, &ry, &d); + cpi, mb, ib, &best_mode, +#if CONFIG_COMP_INTRA_PRED + &best_second_mode, +#endif + i8x8mode_costs, ta, tl, &r, &ry, &d); cost += r; distortion += d; tot_rate_y += ry; - mic->bmi[ib].as_mode = best_mode; + mic->bmi[ib].as_mode.first = best_mode; +#if CONFIG_COMP_INTRA_PRED + mic->bmi[ib].as_mode.second = best_second_mode; +#endif } *Rate = cost; *rate_y += tot_rate_y; @@ -1253,19 +1367,42 @@ static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int { MB_PREDICTION_MODE mode; MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected); +#if CONFIG_COMP_INTRA_PRED + MB_PREDICTION_MODE mode2; + MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode2_selected); +#endif int best_rd = INT_MAX; int UNINITIALIZED_IS_SAFE(d), UNINITIALIZED_IS_SAFE(r); int rate_to; for (mode = DC_PRED; mode <= TM_PRED; mode++) { +#if CONFIG_COMP_INTRA_PRED + for (mode2 = DC_PRED - 1; mode2 != TM_PRED + 1; mode2++) + { +#endif int rate; int distortion; int this_rd; x->e_mbd.mode_info_context->mbmi.uv_mode = mode; +#if CONFIG_COMP_INTRA_PRED + x->e_mbd.mode_info_context->mbmi.second_uv_mode = mode2; + if (mode2 == (MB_PREDICTION_MODE) (DC_PRED - 1)) + { +#endif RECON_INVOKE(&cpi->rtcd.common->recon, build_intra_predictors_mbuv) (&x->e_mbd); +#if CONFIG_COMP_INTRA_PRED + } + else + { + continue; + RECON_INVOKE(&cpi->rtcd.common->recon, build_comp_intra_predictors_mbuv) + (&x->e_mbd); + } +#endif + 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); @@ -1286,6 +1423,10 @@ static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int r = rate; *rate_tokenonly = rate_to; mode_selected = mode; +#if CONFIG_COMP_INTRA_PRED + mode2_selected = mode2; + } +#endif } } @@ -1293,6 +1434,9 @@ static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate, int *distortion = d; x->e_mbd.mode_info_context->mbmi.uv_mode = mode_selected; +#if CONFIG_COMP_INTRA_PRED + x->e_mbd.mode_info_context->mbmi.second_uv_mode = mode2_selected; +#endif } int vp8_cost_mv_ref(VP8_COMMON *pc, @@ -2214,17 +2358,26 @@ static void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv) } } -static void set_i8x8_block_modes(MACROBLOCK *x, int *modes) +static void set_i8x8_block_modes(MACROBLOCK *x, int modes[2][4]) { 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]; + x->e_mbd.mode_info_context->bmi[ib+0].as_mode.first= modes[0][i]; + x->e_mbd.mode_info_context->bmi[ib+1].as_mode.first= modes[0][i]; + x->e_mbd.mode_info_context->bmi[ib+4].as_mode.first= modes[0][i]; + x->e_mbd.mode_info_context->bmi[ib+5].as_mode.first= modes[0][i]; +#if CONFIG_COMP_INTRA_PRED + x->e_mbd.mode_info_context->bmi[ib+0].as_mode.second= modes[1][i]; + x->e_mbd.mode_info_context->bmi[ib+1].as_mode.second= modes[1][i]; + x->e_mbd.mode_info_context->bmi[ib+4].as_mode.second= modes[1][i]; + x->e_mbd.mode_info_context->bmi[ib+5].as_mode.second= modes[1][i]; +#endif + //printf("%d,%d,%d,%d %d,%d,%d,%d\n", + // modes[0][0], modes[0][1], modes[0][2], modes[0][3], + // modes[1][0], modes[1][1], modes[1][2], modes[1][3]); } for (i = 0; i < 16; i++) @@ -2308,7 +2461,7 @@ 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; - int mode8x8[4]; + int mode8x8[2][4]; unsigned char segment_id = xd->mode_info_context->mbmi.segment_id; int i; @@ -2445,6 +2598,10 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int this_mode = vp8_mode_order[mode_index]; x->e_mbd.mode_info_context->mbmi.mode = this_mode; +#if CONFIG_COMP_INTRA_PRED + x->e_mbd.mode_info_context->mbmi.second_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); + x->e_mbd.mode_info_context->mbmi.second_uv_mode = (MB_PREDICTION_MODE) (DC_PRED - 1); +#endif x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED; x->e_mbd.mode_info_context->mbmi.ref_frame = vp8_ref_frame_order[mode_index]; x->e_mbd.mode_info_context->mbmi.second_ref_frame = vp8_second_ref_frame_order[mode_index]; @@ -2554,10 +2711,16 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int 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; + mode8x8[0][0]= x->e_mbd.mode_info_context->bmi[0].as_mode.first; + mode8x8[0][1]= x->e_mbd.mode_info_context->bmi[2].as_mode.first; + mode8x8[0][2]= x->e_mbd.mode_info_context->bmi[8].as_mode.first; + mode8x8[0][3]= x->e_mbd.mode_info_context->bmi[10].as_mode.first; +#if CONFIG_COMP_INTRA_PRED + mode8x8[1][0]= x->e_mbd.mode_info_context->bmi[0].as_mode.second; + mode8x8[1][1]= x->e_mbd.mode_info_context->bmi[2].as_mode.second; + mode8x8[1][2]= x->e_mbd.mode_info_context->bmi[8].as_mode.second; + mode8x8[1][3]= x->e_mbd.mode_info_context->bmi[10].as_mode.second; +#endif /* TODO: uv rate maybe over-estimated here since there is UV intra mode coded in I8X8_PRED prediction */ @@ -2611,6 +2774,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int case H_PRED: case TM_PRED: x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; + // FIXME compound intra prediction RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby) (&x->e_mbd); #if CONFIG_T8X8 @@ -3280,6 +3444,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int if (best_mbmode.mode == I8X8_PRED) { + //printf("inter\n"); set_i8x8_block_modes(x, mode8x8); } @@ -3325,7 +3490,7 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_) int error8x8, rate8x8_tokenonly=0; int rate8x8, dist8x8; int mode16x16; - int mode8x8[4]; + int mode8x8[2][4]; x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; @@ -3340,10 +3505,16 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_) error8x8 = rd_pick_intra8x8mby_modes(cpi, x, &rate8x8, &rate8x8_tokenonly, &dist8x8, error16x16); - 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; + mode8x8[0][0]= x->e_mbd.mode_info_context->bmi[0].as_mode.first; + mode8x8[0][1]= x->e_mbd.mode_info_context->bmi[2].as_mode.first; + mode8x8[0][2]= x->e_mbd.mode_info_context->bmi[8].as_mode.first; + mode8x8[0][3]= x->e_mbd.mode_info_context->bmi[10].as_mode.first; +#if CONFIG_COMP_INTRA_PRED + mode8x8[1][0]= x->e_mbd.mode_info_context->bmi[0].as_mode.second; + mode8x8[1][1]= x->e_mbd.mode_info_context->bmi[2].as_mode.second; + mode8x8[1][2]= x->e_mbd.mode_info_context->bmi[8].as_mode.second; + mode8x8[1][3]= x->e_mbd.mode_info_context->bmi[10].as_mode.second; +#endif error4x4 = rd_pick_intra4x4mby_modes(cpi, x, &rate4x4, &rate4x4_tokenonly, @@ -3374,6 +3545,7 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_) { x->e_mbd.mode_info_context->mbmi.mode = I8X8_PRED; + //printf("intra\n"); set_i8x8_block_modes(x, mode8x8); rate += rate8x8; }