summaryrefslogtreecommitdiff
path: root/vp8/decoder/decodframe.c
diff options
context:
space:
mode:
authorYaowu Xu <yaowu@google.com>2011-08-04 16:30:27 -0700
committerYaowu Xu <yaowu@google.com>2011-09-16 15:55:19 -0700
commitca6b85aa4eae6047315ac01eef44b0ebaef58da3 (patch)
tree3113a87f1b48378a940223b43bf4d6cb86c4de92 /vp8/decoder/decodframe.c
parent62371d382a4fb2570c60e0a0948bd32e91790f2a (diff)
downloadlibvpx-ca6b85aa4eae6047315ac01eef44b0ebaef58da3.tar
libvpx-ca6b85aa4eae6047315ac01eef44b0ebaef58da3.tar.gz
libvpx-ca6b85aa4eae6047315ac01eef44b0ebaef58da3.tar.bz2
libvpx-ca6b85aa4eae6047315ac01eef44b0ebaef58da3.zip
add 8x8 intra prediction modes
Patch 1 to Patch 3 is an initial implementation of 8x8 intra prediction modes, here are with the following assumptions: a. 8x8 has 4 prediction modes DC, H, V and TM b. UV 4x4 block use the same mode as corresponding 8x8 area c. i8x8 modes are enabled for key frame only for now Patch 4: d. removed debug code from previous patches Patch 5: e. added stats code to collect entropy stats and further cleaned up Patch 6: f. changed mode stats code to collect finer stats of modes Patch 7: g. normalized i8x8 modes distribution to total at 256 (8bits). Patch 8: h. fixed a bug in decoder and removed debug printf output. Patch 9: i. more cleanups to address paul's comment Patch 10: j. messy rebase/merges to bring the commit up to date. Tests on HD clips encoded with all key frame showing consistent gain on all clips and all metrics:~0.5%(psnr) and 0.6%(ssim): http://www.corp.google.com/~yaowu/no_crawl/i8x8hd_allkey_fixedq.html To build and test, configure with: --enable-experimental --enable-i8x8 Change-Id: I9813fe07ae48cab5fdb5d904bca022514ad01e7f
Diffstat (limited to 'vp8/decoder/decodframe.c')
-rw-r--r--vp8/decoder/decodframe.c75
1 files changed, 72 insertions, 3 deletions
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index 523352c69..cbbcd20f5 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -199,7 +199,10 @@ void clamp_mvs(MACROBLOCKD *xd)
}
}
+#if CONFIG_I8X8
+extern const int vp8_i8x8_block[4];
+#endif
static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
unsigned int mb_idx)
{
@@ -246,8 +249,12 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
mode = xd->mode_info_context->mbmi.mode;
- if (eobtotal == 0 && mode != B_PRED && mode != SPLITMV &&
- !vp8dx_bool_error(xd->current_bc))
+ if (eobtotal == 0 && mode != B_PRED && mode != SPLITMV
+#if CONFIG_I8X8
+ && mode != I8X8_PRED
+#endif
+ &&!vp8dx_bool_error(xd->current_bc)
+ )
{
/* Special case: Force the loopfilter to skip when eobtotal and
* mb_skip_coeff are zero.
@@ -264,6 +271,10 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
/* do prediction */
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME)
{
+#if CONFIG_I8X8
+ if(mode != I8X8_PRED)
+ {
+#endif
RECON_INVOKE(&pbi->common.rtcd.recon, build_intra_predictors_mbuv)(xd);
if (mode != B_PRED)
@@ -273,6 +284,9 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
} else {
vp8_intra_prediction_down_copy(xd);
}
+#if CONFIG_I8X8
+ }
+#endif
}
else
{
@@ -301,6 +315,56 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
#endif
/* dequantization and idct */
+#if CONFIG_I8X8
+ if (mode == I8X8_PRED)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ int ib = vp8_i8x8_block[i];
+ const int iblock[4]={0,1,4,5};
+ int j;
+ int i8x8mode;
+ BLOCKD *b;
+
+ b = &xd->block[ib];
+ i8x8mode= b->bmi.as_mode;
+ RECON_INVOKE(RTCD_VTABLE(recon), intra8x8_predict)
+ (b, i8x8mode, b->predictor);
+
+ for(j = 0; j < 4; j++)
+ {
+ b = &xd->block[ib+iblock[j]];
+ if (xd->eobs[ib+iblock[j]] > 1)
+ {
+ DEQUANT_INVOKE(&pbi->dequant, idct_add)
+ (b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 16, b->dst_stride);
+ }
+ else
+ {
+ IDCT_INVOKE(RTCD_VTABLE(idct), idct1_scalar_add)
+ (b->qcoeff[0] * b->dequant[0], b->predictor,
+ *(b->base_dst) + b->dst, 16, b->dst_stride);
+ ((int *)b->qcoeff)[0] = 0;
+ }
+ }
+
+ b = &xd->block[16+i];
+ RECON_INVOKE(RTCD_VTABLE(recon), intra_uv4x4_predict)
+ (b, i8x8mode, b->predictor);
+ DEQUANT_INVOKE(&pbi->dequant, idct_add)
+ (b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 8, b->dst_stride);
+ b = &xd->block[20+i];
+ RECON_INVOKE(RTCD_VTABLE(recon), intra_uv4x4_predict)
+ (b, i8x8mode, b->predictor);
+ DEQUANT_INVOKE(&pbi->dequant, idct_add)
+ (b->qcoeff, b->dequant, b->predictor,
+ *(b->base_dst) + b->dst, 8, b->dst_stride);
+ }
+ }
+ else
+#endif
if (mode == B_PRED)
{
for (i = 0; i < 16; i++)
@@ -420,7 +484,9 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
}
else
#endif
-
+#if CONFIG_I8X8
+ if(xd->mode_info_context->mbmi.mode!=I8X8_PRED)
+#endif
DEQUANT_INVOKE (&pbi->dequant, idct_add_uv_block)
(xd->qcoeff+16*16, xd->block[16].dequant,
xd->predictor+16*16, xd->dst.u_buffer, xd->dst.v_buffer,
@@ -511,6 +577,9 @@ decode_mb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mb_row, MACROBLOCKD *xd)
}
#endif
+#if CONFIG_I8X8
+ update_blockd_bmi(xd);
+#endif
xd->dst.y_buffer = pc->yv12_fb[dst_fb_idx].y_buffer + recon_yoffset;
xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;