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
This commit is contained in:
Родитель
a8fbab8697
Коммит
acf5d20ce5
|
@ -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
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче