Generalize and increase frame coding contexts

Previously there were two frame coding contexts tracked, one for normal
frames and one for alt-ref frames. Generalize this by signalling the
context to use in the bitstream, rather than tieing it to the alt ref
refresh bit. Also increase the number of contexts available to 4, which
may be useful for temporal scalability.

Change-Id: I7b66daaddd55c535c20cd16713541fab182b1662
This commit is contained in:
John Koleszar 2013-01-15 15:57:11 -08:00
parent da832a80e4
commit 4b65837bc6
5 changed files with 33 additions and 34 deletions

View File

@ -40,6 +40,9 @@ void vp9_initialize_common(void);
#define NUM_REF_FRAMES 3
#define NUM_YV12_BUFFERS (NUM_REF_FRAMES + 1)
#define NUM_FRAME_CONTEXTS_LG2 2
#define NUM_FRAME_CONTEXTS (1 << NUM_FRAME_CONTEXTS_LG2)
#define COMP_PRED_CONTEXTS 2
typedef struct frame_contexts {
@ -245,9 +248,9 @@ typedef struct VP9Common {
vp9_prob mbskip_pred_probs[MBSKIP_CONTEXTS];
FRAME_CONTEXT lfc_a; /* last alt ref entropy */
FRAME_CONTEXT lfc; /* last frame entropy */
FRAME_CONTEXT fc; /* this frame entropy */
FRAME_CONTEXT frame_contexts[NUM_FRAME_CONTEXTS];
unsigned int frame_context_idx; /* Context to use/update */
unsigned int current_video_frame;
int near_boffset[3];

View File

@ -1255,6 +1255,7 @@ static void init_frame(VP9D_COMP *pbi) {
MACROBLOCKD *const xd = &pbi->mb;
if (pc->frame_type == KEY_FRAME) {
int i;
if (pc->last_frame_seg_map)
vpx_memset(pc->last_frame_seg_map, 0, (pc->mb_rows * pc->mb_cols));
@ -1287,8 +1288,9 @@ static void init_frame(VP9D_COMP *pbi) {
pc->ref_frame_sign_bias[ALTREF_FRAME] = 0;
vp9_init_mode_contexts(&pbi->common);
vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
for (i = 0; i < NUM_FRAME_CONTEXTS; i++)
vpx_memcpy(&pc->frame_contexts[i], &pc->fc, sizeof(pc->fc));
vpx_memset(pc->prev_mip, 0,
(pc->mb_cols + 1) * (pc->mb_rows + 1)* sizeof(MODE_INFO));
@ -1636,13 +1638,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
/* Should the GF or ARF be updated from the current frame */
pbi->refresh_frame_flags = vp9_read_literal(&header_bc, NUM_REF_FRAMES);
/* TODO(jkoleszar): What's the right thing to do here with more refs? */
if (pbi->refresh_frame_flags & 0x4) {
vpx_memcpy(&pc->fc, &pc->lfc_a, sizeof(pc->fc));
} else {
vpx_memcpy(&pc->fc, &pc->lfc, sizeof(pc->fc));
}
pc->ref_frame_sign_bias[GOLDEN_FRAME] = vp9_read_bit(&header_bc);
pc->ref_frame_sign_bias[ALTREF_FRAME] = vp9_read_bit(&header_bc);
@ -1662,9 +1657,9 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
}
pc->refresh_entropy_probs = vp9_read_bit(&header_bc);
if (pc->refresh_entropy_probs == 0) {
vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
}
pc->frame_context_idx = vp9_read_literal(&header_bc, NUM_FRAME_CONTEXTS_LG2);
vpx_memcpy(&pc->fc, &pc->frame_contexts[pc->frame_context_idx],
sizeof(pc->fc));
// Read inter mode probability context updates
if (pc->frame_type != KEY_FRAME) {
@ -1820,11 +1815,8 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
}
if (pc->refresh_entropy_probs) {
/* TODO(jkoleszar): What's the right thing to do here with more refs? */
if (pbi->refresh_frame_flags & 0x4)
vpx_memcpy(&pc->lfc_a, &pc->fc, sizeof(pc->fc));
else
vpx_memcpy(&pc->lfc, &pc->fc, sizeof(pc->fc));
vpx_memcpy(&pc->frame_contexts[pc->frame_context_idx], &pc->fc,
sizeof(pc->fc));
}
#ifdef PACKET_TESTING

View File

@ -1820,6 +1820,8 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
}
vp9_write_bit(&header_bc, pc->refresh_entropy_probs);
vp9_write_literal(&header_bc, pc->frame_context_idx,
NUM_FRAME_CONTEXTS_LG2);
#ifdef ENTROPY_STATS
if (pc->frame_type == INTER_FRAME)

View File

@ -3939,10 +3939,8 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
}
if (cm->refresh_entropy_probs) {
if (cpi->refresh_alt_ref_frame)
vpx_memcpy(&cm->lfc_a, &cm->fc, sizeof(cm->fc));
else
vpx_memcpy(&cm->lfc, &cm->fc, sizeof(cm->fc));
vpx_memcpy(&cm->frame_contexts[cm->frame_context_idx], &cm->fc,
sizeof(cm->fc));
}
// if its a dropped frame honor the requests on subsequent frames

View File

@ -241,6 +241,8 @@ void vp9_restore_coding_context(VP9_COMP *cpi) {
void vp9_setup_key_frame(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
int i;
// Setup for Key frame:
vp9_default_coef_probs(& cpi->common);
vp9_kf_default_bmode_probs(cpi->common.kf_bmode_prob);
@ -262,8 +264,10 @@ void vp9_setup_key_frame(VP9_COMP *cpi) {
cpi->refresh_alt_ref_frame = TRUE;
vp9_init_mode_contexts(&cpi->common);
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));
for (i = 0; i < NUM_FRAME_CONTEXTS; i++)
vpx_memcpy(&cpi->common.frame_contexts[i], &cpi->common.fc,
sizeof(cpi->common.fc));
vpx_memset(cm->prev_mip, 0,
(cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
@ -285,15 +289,15 @@ void vp9_setup_key_frame(VP9_COMP *cpi) {
}
void vp9_setup_inter_frame(VP9_COMP *cpi) {
if (cpi->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));
}
/* Choose which entropy context to use. Currently there are only two
* contexts used, one for normal frames and one for alt ref frames.
*/
cpi->common.frame_context_idx = cpi->refresh_alt_ref_frame;
assert(cpi->common.frame_context_idx < NUM_FRAME_CONTEXTS);
vpx_memcpy(&cpi->common.fc,
&cpi->common.frame_contexts[cpi->common.frame_context_idx],
sizeof(cpi->common.fc));
}