From: John Koleszar Date: Tue, 15 Jan 2013 23:57:11 +0000 (-0800) Subject: Generalize and increase frame coding contexts X-Git-Tag: v1.3.0~1151^2~240^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4b65837bc6d7d341e7c4be078d5a26e0bb717eeb;p=libvpx 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 --- diff --git a/vp9/common/vp9_onyxc_int.h b/vp9/common/vp9_onyxc_int.h index 33ac3f236..46a9ff781 100644 --- a/vp9/common/vp9_onyxc_int.h +++ b/vp9/common/vp9_onyxc_int.h @@ -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]; diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 9e77d202e..ca7b31f71 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -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 diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index af8fa495f..c02ae1b65 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -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) diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 2b9b662a4..0f087df1e 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -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 diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 0acd6513d..b5e5fec2f 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -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)); }