Compound intra prediction (b_pred/4x4 only, for now),
authorRonald S. Bultje <rbultje@google.com>
Wed, 29 Feb 2012 01:12:08 +0000 (17:12 -0800)
committerRonald S. Bultje <rbultje@google.com>
Wed, 29 Feb 2012 01:41:03 +0000 (17:41 -0800)
Also remove duplicate build_intra_predictors_mby/uv().

Change-Id: I78607e7304952a9b962a5b25af9bb9c48692187b

15 files changed:
configure
vp8/common/blockd.h
vp8/common/debugmodes.c
vp8/common/findnearmv.h
vp8/common/generic/systemdependent.c
vp8/common/postproc.c
vp8/common/recon.h
vp8/common/reconintra.c
vp8/common/reconintra4x4.c
vp8/decoder/decodemv.c
vp8/decoder/decodframe.c
vp8/encoder/bitstream.c
vp8/encoder/encodeframe.c
vp8/encoder/encodeintra.c
vp8/encoder/rdopt.c

index fa5ef22..9c2c4e7 100755 (executable)
--- a/configure
+++ b/configure
@@ -223,6 +223,7 @@ EXPERIMENT_LIST="
     featureupdates
     high_precision_mv
     sixteenth_subpel_uv
+    comp_intra_pred
 "
 CONFIG_LIST="
     external_build
index 4b3d40c..30ea8c0 100644 (file)
@@ -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;
index 46064e6..6d30657 100644 (file)
@@ -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 ");
 
index ff25b27..523000b 100644 (file)
@@ -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
index 90ff889..0adefe5 100644 (file)
@@ -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;
index 14c3b7b..d88b419 100644 (file)
@@ -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);
index decd114..9fb12c8 100644 (file)
 #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
index 21a5b3f..501eaca 100644 (file)
@@ -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
index 12e2e60..ab8be48 100644 (file)
@@ -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.
  */
index fc1098a..3a74fd8 100644 (file)
@@ -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
     }
 
 }
index 06673b4..3e3f75e 100644 (file)
@@ -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)
             {
index 1a62e44..f57114c 100644 (file)
@@ -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
index 6c9c4f0..352a6f4 100644 (file)
@@ -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
 
index 062f31c..63a1465 100644 (file)
@@ -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);
 
@@ -179,7 +201,18 @@ 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);
     }
 }
index 87e1d93..0d3c8fa 100644 (file)
@@ -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;
         }