ref: acf5d20ce5811ff8b6eb561f09c5751b25539fb8
parent: a8fbab8697c77dc82013862e0a9c7f82b6402db8
author: Yaowu Xu <yaowu@google.com>
date: Wed Nov 30 11:36:46 EST 2011
added separate entropy context for alt_ref This commit added code to keep track of separate entropy contexts for normal frames and alt ref frames. The underly assumption was that the two type of frames have different entropy characteristics given they typically have quite different quantization levels. By keeping entropy contexts separate, it helps the entropy context distribution to be more closely adapted to each frame type. Tests on derf set showed a good and very consistent gain on all clips on all metrics, avg psnr: 0.89%, overall psnr: 0.84% and ssim 0.93%. http://www.corp.google.com/~yaowu/no_crawl/mulcontext.html Change-Id: I15bc9697f6ff7829042911fe0c62930585d7e65d
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -199,7 +199,9 @@
vp8_prob i8x8_mode_prob [VP8_UV_MODES-1];
#endif
-
+#if CONFIG_MULCONTEXT
+ FRAME_CONTEXT lfc_a; /* last alt ref entropy */
+#endif
FRAME_CONTEXT lfc; /* last frame entropy */
FRAME_CONTEXT fc; /* this frame entropy */
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -854,4 +854,4 @@
#endif
-}
+}
\ No newline at end of file
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -830,9 +830,16 @@
*/
pc->ref_frame_sign_bias[GOLDEN_FRAME] = 0;
pc->ref_frame_sign_bias[ALTREF_FRAME] = 0;
+
+#if CONFIG_MULCONTEXT
+ vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
+ vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
+#endif
+
}
else
{
+
if (!pc->use_bilinear_mc_filter)
pc->mcomp_filter_type = SIXTAP;
else
@@ -1206,6 +1213,13 @@
pc->refresh_alt_ref_frame = 0;
#endif
+#if CONFIG_MULCONTEXT
+ if(pc->refresh_alt_ref_frame)
+ vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc));
+ else
+ vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
+#endif
+
/* Buffer to buffer copy flags. */
pc->copy_buffer_to_gf = 0;
@@ -1391,12 +1405,21 @@
{
pc->last_kf_gf_q = pc->base_qindex;
}
-
+#if CONFIG_MULCONTEXT
+ if(pc->refresh_entropy_probs)
+ {
+ if(pc->refresh_alt_ref_frame)
+ vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
+ else
+ vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
+ }
+#else
if (pc->refresh_entropy_probs == 0)
{
vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
pbi->independent_partitions = prev_independent_partitions;
}
+#endif
#ifdef PACKET_TESTING
{
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -80,6 +80,7 @@
fclose(yuv_file);
}
#endif
+//#define WRITE_RECON_BUFFER 1
#if WRITE_RECON_BUFFER
void write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
{
@@ -93,7 +94,8 @@
yframe = fopen(filename, "wb");
for (i = 0; i < frame->y_height; i++)
- fwrite(frame->y_buffer + i * frame->y_stride, frame->y_width, 1, yframe);
+ fwrite(frame->y_buffer + i * frame->y_stride,
+ frame->y_width, 1, yframe);
fclose(yframe);
sprintf(filename, "dx\\u%04d.raw", this_frame);
@@ -100,7 +102,8 @@
yframe = fopen(filename, "wb");
for (i = 0; i < frame->uv_height; i++)
- fwrite(frame->u_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+ fwrite(frame->u_buffer + i * frame->uv_stride,
+ frame->uv_width, 1, yframe);
fclose(yframe);
sprintf(filename, "dx\\v%04d.raw", this_frame);
@@ -107,7 +110,8 @@
yframe = fopen(filename, "wb");
for (i = 0; i < frame->uv_height; i++)
- fwrite(frame->v_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+ fwrite(frame->v_buffer + i * frame->uv_stride,
+ frame->uv_width, 1, yframe);
fclose(yframe);
}
@@ -579,9 +583,17 @@
#if WRITE_RECON_BUFFER
if(cm->show_frame)
+<<<<<<< HEAD
write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
else
write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame+1000);
+=======
+ write_dx_frame_to_file(cm->frame_to_show,
+ cm->current_video_frame);
+ else
+ write_dx_frame_to_file(cm->frame_to_show,
+ cm->current_video_frame+1000);
+>>>>>>> added separate entropy context for alt_ref
#endif
if(cm->filter_level)
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -2222,10 +2222,11 @@
//************************************************
// save a copy for later refresh
+#if !CONFIG_MULCONTEXT
{
vpx_memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc));
}
-
+#endif
update_coef_probs(cpi);
#ifdef ENTROPY_STATS
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -3364,7 +3364,7 @@
vp8_first_pass(cpi);
}
#endif
-
+//#define WRITE_RECON_BUFFER 1
#if WRITE_RECON_BUFFER
void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
{
@@ -3378,7 +3378,8 @@
yframe = fopen(filename, "wb");
for (i = 0; i < frame->y_height; i++)
- fwrite(frame->y_buffer + i * frame->y_stride, frame->y_width, 1, yframe);
+ fwrite(frame->y_buffer + i * frame->y_stride,
+ frame->y_width, 1, yframe);
fclose(yframe);
sprintf(filename, "cx\\u%04d.raw", this_frame);
@@ -3385,7 +3386,8 @@
yframe = fopen(filename, "wb");
for (i = 0; i < frame->uv_height; i++)
- fwrite(frame->u_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+ fwrite(frame->u_buffer + i * frame->uv_stride,
+ frame->uv_width, 1, yframe);
fclose(yframe);
sprintf(filename, "cx\\v%04d.raw", this_frame);
@@ -3392,7 +3394,8 @@
yframe = fopen(filename, "wb");
for (i = 0; i < frame->uv_height; i++)
- fwrite(frame->v_buffer + i * frame->uv_stride, frame->uv_width, 1, yframe);
+ fwrite(frame->v_buffer + i * frame->uv_stride,
+ frame->uv_width, 1, yframe);
fclose(yframe);
}
@@ -4154,7 +4157,13 @@
resize_key_frame(cpi);
vp8_setup_key_frame(cpi);
}
-
+#if CONFIG_MULCONTEXT
+ else
+ {
+ /* setup entropy for nonkey frame */
+ vp8_setup_inter_frame(cpi);
+ }
+#endif
// transform / motion compensation build reconstruction frame
vp8_encode_frame(cpi);
@@ -4512,9 +4521,17 @@
#if WRITE_RECON_BUFFER
if(cm->show_frame)
+<<<<<<< HEAD
write_cx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
else
write_cx_frame_to_file(cm->frame_to_show, cm->current_video_frame+1000);
+=======
+ write_cx_frame_to_file(cm->frame_to_show,
+ cm->current_video_frame);
+ else
+ write_cx_frame_to_file(cm->frame_to_show,
+ cm->current_video_frame+1000);
+>>>>>>> added separate entropy context for alt_ref
#endif
#if CONFIG_MULTITHREAD
@@ -5309,10 +5326,23 @@
}
+
+
+#if CONFIG_MULCONTEXT
+ if(cm->refresh_entropy_probs)
+ {
+ if(cm->refresh_alt_ref_frame)
+ vpx_memcpy(&cm->lfc_a, &cm->fc, sizeof(cm->fc));
+ else
+ vpx_memcpy(&cm->lfc, &cm->fc, sizeof(cm->fc));
+ }
+#else
if (cm->refresh_entropy_probs == 0)
{
vpx_memcpy(&cm->fc, &cm->lfc, sizeof(cm->fc));
}
+#endif
+
// if its a dropped frame honor the requests on subsequent frames
if (*size > 0)
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -247,7 +247,22 @@
cpi->common.refresh_golden_frame = TRUE;
cpi->common.refresh_alt_ref_frame = TRUE;
+
+#if CONFIG_MULCONTEXT
+ vpx_memcpy(&cpi->common.lfc, &cpi->common.fc, sizeof(cpi->common.fc));
+ vpx_memcpy(&cpi->common.lfc_a, &cpi->common.fc, sizeof(cpi->common.fc));
+#endif
+
}
+#if CONFIG_MULCONTEXT
+void vp8_setup_inter_frame(VP8_COMP *cpi)
+{
+ if(cpi->common.refresh_alt_ref_frame)
+ vpx_memcpy(&cpi->common.fc, &cpi->common.lfc_a, sizeof(cpi->common.fc));
+ else
+ vpx_memcpy(&cpi->common.fc, &cpi->common.lfc, sizeof(cpi->common.fc));
+}
+#endif
static int estimate_bits_at_q(int frame_kind, int Q, int MBs,
--
⑨