Commit acf5d20c authored by Yaowu Xu's avatar Yaowu Xu
Browse files

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
parent a8fbab86
......@@ -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 */
......
......@@ -854,4 +854,4 @@ void vp8_decode_mode_mvs(VP8D_COMP *pbi)
#endif
}
}
\ No newline at end of file
......@@ -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
{
......
......@@ -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)
......
......@@ -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
......
......@@ -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)
......
......@@ -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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment