summaryrefslogtreecommitdiff
path: root/vp8/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/encoder')
-rw-r--r--vp8/encoder/bitstream.c21
-rw-r--r--vp8/encoder/block.h3
-rw-r--r--vp8/encoder/encodeframe.c32
-rw-r--r--vp8/encoder/encodeintra.c80
-rw-r--r--vp8/encoder/encodemb.c19
-rw-r--r--vp8/encoder/modecosts.c6
-rw-r--r--vp8/encoder/onyx_if.c20
-rw-r--r--vp8/encoder/onyx_int.h18
-rw-r--r--vp8/encoder/ratectrl.c6
-rw-r--r--vp8/encoder/rdopt.c236
-rw-r--r--vp8/encoder/tokenize.c3
11 files changed, 418 insertions, 26 deletions
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index e872a433d..39a72bcdd 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -151,6 +151,12 @@ static void kfwrite_ymode(vp8_writer *bc, int m, const vp8_prob *p)
vp8_write_token(bc, vp8_kf_ymode_tree, p, vp8_kf_ymode_encodings + m);
}
+#if CONFIG_I8X8
+static void write_i8x8_mode(vp8_writer *bc, int m, const vp8_prob *p)
+{
+ vp8_write_token(bc,vp8_i8x8_mode_tree, p, vp8_i8x8_mode_encodings + m);
+}
+#endif
static void write_uv_mode(vp8_writer *bc, int m, const vp8_prob *p)
{
vp8_write_token(bc, vp8_uv_mode_tree, p, vp8_uv_mode_encodings + m);
@@ -1188,7 +1194,6 @@ static void write_kfmodes(VP8_COMP *cpi)
vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
kfwrite_ymode(bc, ym, c->kf_ymode_prob);
-
if (ym == B_PRED)
{
const int mis = c->mode_info_stride;
@@ -1208,10 +1213,20 @@ static void write_kfmodes(VP8_COMP *cpi)
}
while (++i < 16);
}
-
+#if CONFIG_I8X8
+ 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);
+ m++;
+ }
+ else
+#endif
write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob);
}
-
+ //printf("\n");
m++; // skip L prediction border
}
}
diff --git a/vp8/encoder/block.h b/vp8/encoder/block.h
index 8a95db798..f7390a8fd 100644
--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -98,6 +98,9 @@ typedef struct
int mbmode_cost[2][MB_MODE_COUNT];
int intra_uv_mode_cost[2][MB_MODE_COUNT];
unsigned int bmode_costs[10][10][10];
+#if CONFIG_I8X8
+ unsigned int i8x8_mode_costs[MB_MODE_COUNT];
+#endif
unsigned int inter_bmode_costs[B_MODE_COUNT];
// These define limits to motion vector components to prevent them from extending outside the UMV borders
diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c
index 1ccf134af..d1cb0acab 100644
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -70,11 +70,12 @@ static void adjust_act_zbin( VP8_COMP *cpi, MACROBLOCK *x );
#ifdef MODE_STATS
unsigned int inter_y_modes[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-unsigned int inter_uv_modes[4] = {0, 0, 0, 0};
-unsigned int inter_b_modes[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-unsigned int y_modes[5] = {0, 0, 0, 0, 0};
-unsigned int uv_modes[4] = {0, 0, 0, 0};
-unsigned int b_modes[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned int inter_uv_modes[VP8_UV_MODES] = {0, 0, 0, 0};
+unsigned int inter_b_modes[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+unsigned int y_modes[VP8_YMODES] = {0, 0, 0, 0, 0};
+unsigned int i8x8_modes[VP8_I8X8_MODES]={0};
+unsigned int uv_modes[VP8_UV_MODES] = {0, 0, 0, 0};
+unsigned int b_modes[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#endif
@@ -1427,7 +1428,15 @@ static void sum_intra_stats(VP8_COMP *cpi, MACROBLOCK *x)
}
while (++b < 16);
}
-
+#if CONFIG_I8X8
+ 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]++;
+ }
+#endif
#endif
++cpi->ymode_count[m];
@@ -1476,6 +1485,14 @@ int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
vp8_update_zbin_extra(cpi, x);
}
+#if CONFIG_I8X8
+ if(x->e_mbd.mode_info_context->mbmi.mode == I8X8_PRED)
+ {
+ vp8_encode_intra8x8mby(IF_RTCD(&cpi->rtcd), x);
+ vp8_encode_intra8x8mbuv(IF_RTCD(&cpi->rtcd), x);
+ }
+ else
+#endif
if (x->e_mbd.mode_info_context->mbmi.mode == B_PRED)
vp8_encode_intra4x4mby(IF_RTCD(&cpi->rtcd), x);
else
@@ -1486,6 +1503,9 @@ int vp8cx_encode_intra_macro_block(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t)
#endif
vp8_encode_intra16x16mby(IF_RTCD(&cpi->rtcd), x);
}
+#if CONFIG_I8X8
+ if(x->e_mbd.mode_info_context->mbmi.mode != I8X8_PRED)
+#endif
vp8_encode_intra16x16mbuv(IF_RTCD(&cpi->rtcd), x);
sum_intra_stats(cpi, x);
vp8_tokenize_mb(cpi, &x->e_mbd, t);
diff --git a/vp8/encoder/encodeintra.c b/vp8/encoder/encodeintra.c
index 10afed3ec..424dc72db 100644
--- a/vp8/encoder/encodeintra.c
+++ b/vp8/encoder/encodeintra.c
@@ -236,3 +236,83 @@ void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
}
+
+#if CONFIG_I8X8
+void vp8_encode_intra8x8(const VP8_ENCODER_RTCD *rtcd,
+ MACROBLOCK *x, int ib)
+{
+ BLOCKD *b = &x->e_mbd.block[ib];
+ BLOCK *be = &x->block[ib];
+ const int iblock[4]={0,1,4,5};
+ int i;
+
+ RECON_INVOKE(&rtcd->common->recon, intra8x8_predict)
+ (b, b->bmi.as_mode, b->predictor);
+
+ for(i=0;i<4;i++)
+ {
+ b = &x->e_mbd.block[ib + iblock[i]];
+ be = &x->block[ib + iblock[i]];
+ ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);
+ x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);
+ x->quantize_b(be, b);
+ vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 32);
+ RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor,
+ b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+ }
+
+}
+
+extern const int vp8_i8x8_block[4];
+void vp8_encode_intra8x8mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+ int i, ib;
+
+ for(i=0;i<4;i++)
+ {
+ ib = vp8_i8x8_block[i];
+ vp8_encode_intra8x8(rtcd, x, ib);
+ }
+
+}
+
+void vp8_encode_intra_uv4x4(const VP8_ENCODER_RTCD *rtcd,
+ MACROBLOCK *x, int ib,
+ int mode)
+{
+ BLOCKD *b = &x->e_mbd.block[ib];
+ BLOCK *be = &x->block[ib];
+
+ RECON_INVOKE(&rtcd->common->recon, intra_uv4x4_predict)
+ (b, mode, b->predictor);
+
+ ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 8);
+
+ x->vp8_short_fdct4x4(be->src_diff, be->coeff, 16);
+
+ x->quantize_b(be, b);
+
+ vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 16);
+
+ RECON_INVOKE(&rtcd->common->recon, recon_uv)(b->predictor,
+ b->diff, *(b->base_dst) + b->dst, b->dst_stride);
+}
+
+
+
+void vp8_encode_intra8x8mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
+{
+ int i, ib, mode;
+ BLOCKD *b;
+ for(i=0;i<4;i++)
+ {
+ ib = vp8_i8x8_block[i];
+ b = &x->e_mbd.block[ib];
+ mode = b->bmi.as_mode;
+ /*u */
+ vp8_encode_intra_uv4x4(rtcd, x, i+16, mode);
+ /*v */
+ vp8_encode_intra_uv4x4(rtcd, x, i+20, mode);
+ }
+}
+#endif
diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c
index 8722cf8ae..c0e0bc4fd 100644
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -53,6 +53,25 @@ void vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch)
}
}
+void vp8_subtract_4b_c(BLOCK *be, BLOCKD *bd, int pitch)
+{
+ unsigned char *src_ptr = (*(be->base_src) + be->src);
+ short *diff_ptr = be->src_diff;
+ unsigned char *pred_ptr = bd->predictor;
+ int src_stride = be->src_stride;
+ int r, c;
+ for (r = 0; r < 8; r++)
+ {
+ for (c = 0; c < 8; c++)
+ {
+ diff_ptr[c] = src_ptr[c] - pred_ptr[c];
+ }
+ diff_ptr += pitch;
+ pred_ptr += pitch;
+ src_ptr += src_stride;
+ }
+}
+
void vp8_subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride)
{
short *udiff = diff + 256;
diff --git a/vp8/encoder/modecosts.c b/vp8/encoder/modecosts.c
index c636c482b..892fe9f71 100644
--- a/vp8/encoder/modecosts.c
+++ b/vp8/encoder/modecosts.c
@@ -44,4 +44,10 @@ void vp8_init_mode_costs(VP8_COMP *c)
vp8_cost_tokens(c->mb.intra_uv_mode_cost[1], x->fc.uv_mode_prob, vp8_uv_mode_tree);
vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], x->kf_uv_mode_prob, vp8_uv_mode_tree);
+#if CONFIG_I8X8
+ vp8_cost_tokens(c->mb.i8x8_mode_costs,
+ x->i8x8_mode_prob,vp8_i8x8_mode_tree);
+#endif
+
+
}
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index c97e10825..62df2e228 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -101,6 +101,7 @@ extern double vp8_calc_ssimg
#endif
+//#define OUTPUT_YUV_REC
#ifdef OUTPUT_YUV_SRC
FILE *yuv_file;
@@ -137,9 +138,10 @@ unsigned int cnt_ef = 0;
extern unsigned __int64 Sectionbits[500];
#endif
#ifdef MODE_STATS
-extern unsigned __int64 Sectionbits[50];
-extern int y_modes[5] ;
-extern int uv_modes[4] ;
+extern INT64 Sectionbits[500];
+extern int y_modes[VP8_YMODES] ;
+extern int i8x8_modes[VP8_I8X8_MODES];
+extern int uv_modes[VP8_UV_MODES] ;
extern int b_modes[10] ;
extern int inter_y_modes[10] ;
extern int inter_uv_modes[4] ;
@@ -2305,10 +2307,18 @@ void vp8_remove_compressor(VP8_PTR *ptr)
#ifdef MODE_STATS
{
extern int count_mb_seg[4];
- FILE *f = fopen("modes.stt", "w");
+ char modes_stats_file[250];
+ FILE *f;
double dr = (double)cpi->oxcf.frame_rate * (double)cpi->bytes * (double)8 / (double)cpi->count / (double)1000 ;
+ sprintf(modes_stats_file, "modes_q%03d.stt",cpi->common.base_qindex);
+ f = fopen(modes_stats_file, "w");
fprintf(f, "intra_mode in Intra Frames:\n");
+#if CONFIG_I8X8
+ fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], y_modes[2], y_modes[3], y_modes[4], y_modes[5]);
+ fprintf(f, "I8:%8d, %8d, %8d, %8d\n", i8x8_modes[0], i8x8_modes[1], i8x8_modes[2], i8x8_modes[3]);
+#else
fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], y_modes[2], y_modes[3], y_modes[4]);
+#endif
fprintf(f, "UV:%8d, %8d, %8d, %8d\n", uv_modes[0], uv_modes[1], uv_modes[2], uv_modes[3]);
fprintf(f, "B: ");
{
@@ -4622,7 +4632,7 @@ static void encode_frame_to_data_rate
fclose(recon_file);
}
#endif
-#ifdef OUTPUT_YUV_REC
+#if OUTPUT_YUV_REC
vp8_write_yuv_rec_frame(cm);
#endif
diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h
index 00e7788f9..fd89b3301 100644
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -70,18 +70,20 @@ typedef struct
#ifdef MODE_STATS
// Stats
- int y_modes[5];
- int uv_modes[4];
+ int y_modes[VP8_YMODES];
+ int uv_modes[VP8_UV_MODES];
+ int i8x8_modes[VP8_I8X8_MODES];
int b_modes[10];
int inter_y_modes[10];
- int inter_uv_modes[4];
+ int inter_uv_modes[VP8_UV_MODES];
int inter_b_modes[10];
#endif
-
- vp8_prob ymode_prob[4], uv_mode_prob[3]; /* interframe intra mode probs */
- vp8_prob kf_ymode_prob[4], kf_uv_mode_prob[3]; /* keyframe "" */
-
- int ymode_count[5], uv_mode_count[4]; /* intra MB type cts this frame */
+ /* interframe intra mode probs */
+ vp8_prob ymode_prob[VP8_YMODES-1], uv_mode_prob[VP8_UV_MODES-1];
+ /* keyframe intra mode probs */
+ vp8_prob kf_ymode_prob[VP8_YMODES-1], kf_uv_mode_prob[VP8_UV_MODES-1];
+ /* intra MB type cts this frame */
+ int ymode_count[VP8_YMODES], uv_mode_count[VP8_UV_MODES];
int count_mb_ref_frame_usage[MAX_REF_FRAMES];
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index f3dccfd05..d6c50213c 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -33,12 +33,12 @@ extern const MV_REFERENCE_FRAME vp8_ref_frame_order[MAX_MODES];
#ifdef MODE_STATS
-extern int y_modes[5];
-extern int uv_modes[4];
+extern int y_modes[VP8_YMODES];
+extern int uv_modes[VP8_UV_MODES];
extern int b_modes[10];
extern int inter_y_modes[10];
-extern int inter_uv_modes[4];
+extern int inter_uv_modes[VP8_UV_MODES];
extern int inter_b_modes[10];
#endif
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 416235d2b..c899cf869 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -657,6 +657,29 @@ static void copy_predictor(unsigned char *dst, const unsigned char *predictor)
d[8] = p[8];
d[12] = p[12];
}
+
+static void copy_predictor_8x8(unsigned char *dst, const unsigned char *predictor)
+{
+ const unsigned int *p = (const unsigned int *)predictor;
+ unsigned int *d = (unsigned int *)dst;
+ d[0] = p[0];
+ d[1] = p[1];
+ d[4] = p[4];
+ d[5] = p[5];
+ d[8] = p[8];
+ d[9] = p[9];
+ d[12] = p[12];
+ d[13] = p[13];
+ d[16] = p[16];
+ d[17] = p[17];
+ d[20] = p[20];
+ d[21] = p[21];
+ d[24] = p[24];
+ d[25] = p[25];
+ d[28] = p[28];
+ d[29] = p[29];
+}
+
static int rd_pick_intra4x4block(
VP8_COMP *cpi,
MACROBLOCK *x,
@@ -834,6 +857,156 @@ static int rd_pick_intra16x16mby_mode(VP8_COMP *cpi,
x->e_mbd.mode_info_context->mbmi.mode = mode_selected;
return best_rd;
}
+#if CONFIG_I8X8
+static int rd_pick_intra8x8block(
+ VP8_COMP *cpi,
+ MACROBLOCK *x,
+ int ib,
+ B_PREDICTION_MODE *best_mode,
+ unsigned int *mode_costs,
+ ENTROPY_CONTEXT *a,
+ ENTROPY_CONTEXT *l,
+ int *bestrate,
+ int *bestratey,
+ int *bestdistortion)
+{
+ MB_PREDICTION_MODE mode;
+ MACROBLOCKD *xd = &x->e_mbd;
+ int best_rd = INT_MAX;
+ int rate = 0;
+ int distortion;
+ BLOCK *be=x->block + ib;
+ BLOCKD *b=x->e_mbd.block + ib;
+ ENTROPY_CONTEXT ta0, ta1, besta0, besta1;
+ ENTROPY_CONTEXT tl0, tl1, bestl0, bestl1;
+
+
+ /*
+ * The predictor buffer is a 2d buffer with a stride of 16. Create
+ * a temp buffer that meets the stride requirements, but we are only
+ * interested in the left 8x8 block
+ * */
+
+ DECLARE_ALIGNED_ARRAY(16, unsigned char, best_predictor, 16*8);
+ DECLARE_ALIGNED_ARRAY(16, short, best_dqcoeff, 16*4);
+
+ for (mode = DC_PRED; mode <= TM_PRED; mode++)
+ {
+ int this_rd;
+ int rate_t;
+
+ rate = mode_costs[mode];
+
+ RECON_INVOKE(&cpi->rtcd.common->recon, intra8x8_predict)
+ (b, mode, b->predictor);
+
+ vp8_subtract_4b_c(be, b, 16);
+
+ x->vp8_short_fdct8x4(be->src_diff, be->coeff, 32);
+ x->vp8_short_fdct8x4(be->src_diff + 64, be->coeff + 64, 32);
+
+ x->quantize_b_pair(x->block+ib, x->block+ib+1,
+ xd->block+ib, xd->block+ib+1);
+ x->quantize_b_pair(x->block+ib+4, x->block+ib+5,
+ xd->block+ib+4, xd->block+ib+5);
+
+ distortion = ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), berr)
+ ((x->block+ib)->coeff,(xd->block+ib)->dqcoeff)>>2;
+ distortion += ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), berr)
+ ((x->block+ib+1)->coeff,(xd->block+ib+1)->dqcoeff)>>2;
+ distortion += ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), berr)
+ ((x->block+ib+4)->coeff,(xd->block+ib+4)->dqcoeff)>>2;
+ distortion += ENCODEMB_INVOKE(IF_RTCD(&cpi->rtcd.encodemb), berr)
+ ((x->block+ib+5)->coeff,(xd->block+ib+5)->dqcoeff)>>2;
+
+ ta0 = *(a + vp8_block2above[ib]);
+ ta1 = *(a + vp8_block2above[ib+1]);
+ tl0 = *(l + vp8_block2above[ib]);
+ tl1 = *(l + vp8_block2above[ib+4]);
+ rate_t = cost_coeffs(x, xd->block+ib, PLANE_TYPE_Y_WITH_DC,
+ &ta0, &tl0);
+ rate_t += cost_coeffs(x, xd->block+ib+1, PLANE_TYPE_Y_WITH_DC,
+ &ta1, &tl0);
+ rate_t += cost_coeffs(x, xd->block+ib+4, PLANE_TYPE_Y_WITH_DC,
+ &ta0, &tl1);
+ rate_t += cost_coeffs(x, xd->block+ib+5, PLANE_TYPE_Y_WITH_DC,
+ &ta1, &tl1);
+ rate += rate_t;
+ this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
+ if (this_rd < best_rd)
+ {
+ *bestrate = rate;
+ *bestratey = rate_t;
+ *bestdistortion = distortion;
+ besta0 = ta0;
+ besta1 = ta1;
+ bestl0 = tl0;
+ bestl1 = tl1;
+ best_rd = this_rd;
+ *best_mode = mode;
+ copy_predictor_8x8(best_predictor, b->predictor);
+ vpx_memcpy(best_dqcoeff, b->dqcoeff, 64);
+ vpx_memcpy(best_dqcoeff+32, b->dqcoeff+64, 64);
+ }
+ }
+ b->bmi.as_mode = (*best_mode);
+ vp8_encode_intra8x8 (IF_RTCD(&cpi->rtcd), x, ib);
+ *(a + vp8_block2above[ib]) = besta0;
+ *(a + vp8_block2above[ib+1]) = besta1;
+ *(l + vp8_block2above[ib]) = bestl0;
+ *(l + vp8_block2above[ib+4]) = bestl1;
+ return best_rd;
+}
+
+const int vp8_i8x8_block[4]={0, 2, 8, 10};
+int rd_pick_intra8x8mby_modes(VP8_COMP *cpi,
+ MACROBLOCK *mb,
+ int *Rate,
+ int *rate_y,
+ int *Distortion,
+ int best_rd)
+{
+ MACROBLOCKD *const xd = &mb->e_mbd;
+ int i,ib;
+ int cost = mb->mbmode_cost [xd->frame_type] [I8X8_PRED];
+ int distortion = 0;
+ int tot_rate_y = 0;
+ long long total_rd = 0;
+ ENTROPY_CONTEXT_PLANES t_above, t_left;
+ ENTROPY_CONTEXT *ta;
+ ENTROPY_CONTEXT *tl;
+ unsigned int *i8x8mode_costs;
+
+ vpx_memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
+ vpx_memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
+
+ ta = (ENTROPY_CONTEXT *)&t_above;
+ tl = (ENTROPY_CONTEXT *)&t_left;
+
+ i8x8mode_costs = mb->i8x8_mode_costs;
+
+ for (i = 0; i < 4; i++)
+ {
+ MODE_INFO *const mic = xd->mode_info_context;
+ const int mis = xd->mode_info_stride;
+ B_PREDICTION_MODE UNINITIALIZED_IS_SAFE(best_mode);
+ 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);
+ cost += r;
+ distortion += d;
+ tot_rate_y += ry;
+ mic->bmi[ib].as_mode = best_mode;
+ }
+ *Rate = cost;
+ *rate_y += tot_rate_y;
+ *Distortion = distortion;
+ return RDCOST(mb->rdmult, mb->rddiv, cost, distortion);
+}
+#endif
static int rd_cost_mbuv(MACROBLOCK *mb)
{
@@ -2502,6 +2675,27 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
}
+#if CONFIG_I8X8
+static void set_i8x8_block_modes(MACROBLOCK *x, int *modes)
+{
+ int i;
+ MACROBLOCKD *xd = &x->e_mbd;
+ for(i=0;i<4;i++)
+ {
+ int ib = vp8_i8x8_block[i];
+ x->e_mbd.mode_info_context->bmi[ib+0].as_mode= modes[i];
+ x->e_mbd.mode_info_context->bmi[ib+1].as_mode= modes[i];
+ x->e_mbd.mode_info_context->bmi[ib+4].as_mode= modes[i];
+ x->e_mbd.mode_info_context->bmi[ib+5].as_mode= modes[i];
+ }
+
+ for (i = 0; i < 16; i++)
+ {
+ xd->block[i].bmi = xd->mode_info_context->bmi[i];
+ }
+}
+#endif
+
void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_)
{
int error4x4, error16x16;
@@ -2511,6 +2705,12 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_)
int rate4x4_tokenonly = 0;
int rate16x16_tokenonly = 0;
int rateuv_tokenonly = 0;
+#if CONFIG_I8X8
+ int error8x8, rate8x8_tokenonly=0;
+ int rate8x8, dist8x8;
+ int mode16x16;
+ int mode8x8[4];
+#endif
x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
@@ -2520,11 +2720,24 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_)
error16x16 = rd_pick_intra16x16mby_mode(cpi, x,
&rate16x16, &rate16x16_tokenonly,
&dist16x16);
-
+#if CONFIG_I8X8
+ mode16x16 = x->e_mbd.mode_info_context->mbmi.mode;
+ 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;
+#endif
error4x4 = rd_pick_intra4x4mby_modes(cpi, x,
&rate4x4, &rate4x4_tokenonly,
&dist4x4, error16x16);
+#if CONFIG_I8X8
+ if(error8x8> error16x16)
+ {
+#endif
if (error4x4 < error16x16)
{
x->e_mbd.mode_info_context->mbmi.mode = B_PRED;
@@ -2532,8 +2745,29 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_)
}
else
{
+#if CONFIG_I8X8
+ x->e_mbd.mode_info_context->mbmi.mode = mode16x16;
+#endif
rate += rate16x16;
+
}
+#if CONFIG_I8X8
+ }
+ else
+ {
+ if (error4x4 < error8x8)
+ {
+ x->e_mbd.mode_info_context->mbmi.mode = B_PRED;
+ rate += rate4x4;
+ }
+ else
+ {
+ x->e_mbd.mode_info_context->mbmi.mode = I8X8_PRED;
+ set_i8x8_block_modes(x, mode8x8);
+ rate += rate8x8;
+ }
+ }
+#endif
*rate_ = rate;
}
diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c
index e1e124844..3e07f625c 100644
--- a/vp8/encoder/tokenize.c
+++ b/vp8/encoder/tokenize.c
@@ -454,6 +454,9 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
int b;
has_y2_block = (x->mode_info_context->mbmi.mode != B_PRED
+#if CONFIG_I8X8
+ && x->mode_info_context->mbmi.mode != I8X8_PRED
+#endif
&& x->mode_info_context->mbmi.mode != SPLITMV);
x->mode_info_context->mbmi.mb_skip_coeff =