summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYaowu Xu <yaowu@google.com>2011-11-30 16:36:46 -0800
committerYaowu Xu <yaowu@google.com>2011-12-02 14:43:33 -0800
commitacf5d20ce5811ff8b6eb561f09c5751b25539fb8 (patch)
tree4020b7c7722e58eec1f43f05d8dd1fc4dfb7c165
parenta8fbab8697c77dc82013862e0a9c7f82b6402db8 (diff)
downloadlibvpx-acf5d20ce5811ff8b6eb561f09c5751b25539fb8.tar
libvpx-acf5d20ce5811ff8b6eb561f09c5751b25539fb8.tar.gz
libvpx-acf5d20ce5811ff8b6eb561f09c5751b25539fb8.tar.bz2
libvpx-acf5d20ce5811ff8b6eb561f09c5751b25539fb8.zip
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
-rw-r--r--vp8/common/onyxc_int.h4
-rw-r--r--vp8/decoder/decodemv.c2
-rw-r--r--vp8/decoder/decodframe.c25
-rw-r--r--vp8/decoder/onyxd_if.c18
-rw-r--r--vp8/encoder/bitstream.c3
-rw-r--r--vp8/encoder/onyx_if.c40
-rw-r--r--vp8/encoder/ratectrl.c15
7 files changed, 95 insertions, 12 deletions
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index d85cad0a2..7329e3869 100644
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -199,7 +199,9 @@ typedef struct VP8Common
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 */
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 68044f4d5..7e3137fd2 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -854,4 +854,4 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
#endif
-}
+} \ No newline at end of file
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index 5e8925286..f3da2d0b5 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -830,9 +830,16 @@ static void init_frame(VP8D_COMP *pbi)
*/
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 @@ int vp8_decode_frame(VP8D_COMP *pbi)
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 @@ int vp8_decode_frame(VP8D_COMP *pbi)
{
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
{
diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c
index a45d692d0..7862cbf90 100644
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -80,6 +80,7 @@ void vp8_recon_write_yuv_frame(char *name, YV12_BUFFER_CONFIG *s)
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,21 +94,24 @@ void write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
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);
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);
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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign
#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)
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 6171492c6..b19d58e3c 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -2222,10 +2222,11 @@ void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
//************************************************
// 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
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 867c4bdec..829906a1c 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -3364,7 +3364,7 @@ static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest,
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,21 +3378,24 @@ void write_cx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame)
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);
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);
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 @@ static void encode_frame_to_data_rate
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 @@ static void encode_frame_to_data_rate
#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 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
}
+
+
+#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)
diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c
index 9a7907e65..de6ccaf0f 100644
--- a/vp8/encoder/ratectrl.c
+++ b/vp8/encoder/ratectrl.c
@@ -247,7 +247,22 @@ void vp8_setup_key_frame(VP8_COMP *cpi)
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,