ref: 4b65837bc6d7d341e7c4be078d5a26e0bb717eeb
parent: da832a80e435a6656b15f889bf81df8be22d34a7
author: John Koleszar <jkoleszar@google.com>
date: Tue Jan 15 10:57:11 EST 2013
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
--- a/vp9/common/vp9_onyxc_int.h
+++ b/vp9/common/vp9_onyxc_int.h
@@ -40,6 +40,9 @@
#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 @@
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];
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -1255,6 +1255,7 @@
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,9 +1288,10 @@
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));
vpx_memset(pc->mip, 0,
@@ -1636,13 +1638,6 @@
/* 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 @@
}
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 @@
}
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
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1820,6 +1820,8 @@
}
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)
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -3939,10 +3939,8 @@
}
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
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -241,6 +241,8 @@
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,9 +264,11 @@
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));
vpx_memset(cm->mip, 0,
@@ -285,15 +289,15 @@
}
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));
}