Added MACRO for reference frame encoding

This CL introduces a few macros plus code cleaning on the encoding of
the reference frames. Coding performance remains unchanged.

For the encoding of either the compound reference or the single reference
case, since each bit has different contexts, the tree structure may not
be applied to treat the combined bits as one symbol. It is possible we may
explore the sharing of the same context for all the bits to introduce
the use of tree structure for the next step.

Change-Id: I6916ae53c66be1a0b23e6273811c0139515484df
This commit is contained in:
Zoe Liu 2015-09-11 14:57:31 -07:00
parent 897192be43
commit ec8864a8bf
8 changed files with 93 additions and 106 deletions

View File

@ -66,6 +66,14 @@ extern "C" {
#define COMP_INTER_CONTEXTS 5
#define REF_CONTEXTS 5
#if CONFIG_MULTI_REF
#define SINGLE_REFS 4
#define COMP_REFS 3
#else
#define SINGLE_REFS 3
#define COMP_REFS 2
#endif // CONFIG_MULTI_REF
typedef enum {
PLANE_TYPE_Y = 0,
PLANE_TYPE_UV = 1,

View File

@ -415,36 +415,60 @@ static const vp9_prob default_comp_inter_p[COMP_INTER_CONTEXTS] = {
239, 183, 119, 96, 41
};
static const vp9_prob default_single_ref_probs[REF_CONTEXTS][SINGLE_REFS - 1] =
{
#if CONFIG_MULTI_REF
// TODO(zoeliu): To adjust the initial prob values.
static const vp9_prob default_comp_ref_p[REF_CONTEXTS][2] = {
{ 33, 16 },
{ 77, 74 },
{ 142, 142 },
{ 172, 170 },
{ 238, 247 }
};
static const vp9_prob default_single_ref_p[REF_CONTEXTS][3] = {
// TODO(zoeliu): To adjust the initial prob values.
{ 33, 16, 16 },
{ 77, 74, 74 },
{ 142, 142, 142 },
{ 172, 170, 170 },
{ 238, 247, 247 }
};
#else
static const vp9_prob default_comp_ref_p[REF_CONTEXTS] = {
50, 126, 123, 221, 226
};
static const vp9_prob default_single_ref_p[REF_CONTEXTS][2] = {
{ 33, 16 },
{ 77, 74 },
{ 142, 142 },
{ 172, 170 },
{ 238, 247 }
};
#endif // CONFIG_MULTI_REF
};
static const vp9_prob default_comp_ref_probs[REF_CONTEXTS][COMP_REFS - 1] = {
#if CONFIG_MULTI_REF
// TODO(zoeliu): To adjust the initial prob values.
{ 33, 16 },
{ 77, 74 },
{ 142, 142 },
{ 172, 170 },
{ 238, 247 }
#else
{ 50 }, { 126 }, { 123 }, { 221 }, { 226 }
#endif // CONFIG_MULTI_REF
};
/*
// TODO(zoeliu): Tree structure may be introduced when all bits of the encoding
// of either the compound or the single references share the same contexts.
const vp9_tree_index vp9_comp_ref_tree[TREE_SIZE(COMP_REFS)] = {
#if CONFIG_MULTI_REF
-REF_OFFSET(GOLDEN_FRAME), 2,
-REF_OFFSET(LAST_FRAME), -REF_OFFSET(LAST2_FRAME)
#else
-REF_OFFSET(GOLDEN_FRAME), -REF_OFFSET(LAST_FRAME)
#endif // CONFIG_MULTI_REF
};
const vp9_tree_index vp9_single_ref_tree[TREE_SIZE(SINGLE_REFS)] = {
#if CONFIG_MULTI_REF
2, 4,
-REF_OFFSET(ALTREF_FRAME), -REF_OFFSET(GOLDEN_FRAME),
-REF_OFFSET(LAST2_FRAME), -REF_OFFSET(LAST_FRAME)
#else
2, -REF_OFFSET(LAST_FRAME),
-REF_OFFSET(ALTREF_FRAME), -REF_OFFSET(GOLDEN_FRAME)
#endif // CONFIG_MULTI_REF
};
*/
static const struct tx_probs default_tx_probs = {
#if CONFIG_TX64X64
@ -1000,8 +1024,8 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
vp9_copy(fc->partition_prob, default_partition_probs);
vp9_copy(fc->intra_inter_prob, default_intra_inter_p);
vp9_copy(fc->comp_inter_prob, default_comp_inter_p);
vp9_copy(fc->comp_ref_prob, default_comp_ref_p);
vp9_copy(fc->single_ref_prob, default_single_ref_p);
vp9_copy(fc->single_ref_probs, default_single_ref_probs);
vp9_copy(fc->comp_ref_probs, default_comp_ref_probs);
fc->tx_probs = default_tx_probs;
vp9_copy(fc->skip_probs, default_skip_probs);
vp9_copy(fc->inter_mode_probs, default_inter_mode_probs);
@ -1083,25 +1107,19 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
fc->comp_inter_prob[i] = adapt_prob(pre_fc->comp_inter_prob[i],
counts->comp_inter[i]);
for (i = 0; i < REF_CONTEXTS; i++) {
#if CONFIG_MULTI_REF
for (j = 0; j < 2; j++)
fc->comp_ref_prob[i][j] = adapt_prob(pre_fc->comp_ref_prob[i][j],
counts->comp_ref[i][j]);
#else
fc->comp_ref_prob[i] = adapt_prob(pre_fc->comp_ref_prob[i],
counts->comp_ref[i]);
#endif // CONFIG_MULTI_REF
for (j = 0; j < (SINGLE_REFS - 1); j++) {
fc->single_ref_probs[i][j] = adapt_prob(pre_fc->single_ref_probs[i][j],
counts->single_ref[i][j]);
}
}
for (i = 0; i < REF_CONTEXTS; i++) {
#if CONFIG_MULTI_REF
for (j = 0; j < 3; j++)
#else
for (j = 0; j < 2; j++)
#endif // CONFIG_MULTI_REF
fc->single_ref_prob[i][j] = adapt_prob(pre_fc->single_ref_prob[i][j],
counts->single_ref[i][j]);
for (j = 0; j < (COMP_REFS - 1); j++) {
fc->comp_ref_probs[i][j] = adapt_prob(pre_fc->comp_ref_probs[i][j],
counts->comp_ref[i][j]);
}
}
for (i = 0; i < INTER_MODE_CONTEXTS; i++)

View File

@ -74,13 +74,8 @@ typedef struct frame_contexts {
#endif // CONFIG_NEW_INTER
vp9_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
vp9_prob comp_inter_prob[COMP_INTER_CONTEXTS];
#if CONFIG_MULTI_REF
vp9_prob single_ref_prob[REF_CONTEXTS][3];
vp9_prob comp_ref_prob[REF_CONTEXTS][2];
#else
vp9_prob single_ref_prob[REF_CONTEXTS][2];
vp9_prob comp_ref_prob[REF_CONTEXTS];
#endif // CONFIG_MULTI_REF
vp9_prob single_ref_probs[REF_CONTEXTS][SINGLE_REFS - 1];
vp9_prob comp_ref_probs[REF_CONTEXTS][COMP_REFS - 1];
struct tx_probs tx_probs;
vp9_prob skip_probs[SKIP_CONTEXTS];
nmv_context nmvc;
@ -159,13 +154,8 @@ typedef struct {
#endif // CONFIG_NEW_INTER
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
#if CONFIG_MULTI_REF
unsigned int single_ref[REF_CONTEXTS][3][2];
unsigned int comp_ref[REF_CONTEXTS][2][2];
#else
unsigned int single_ref[REF_CONTEXTS][2][2];
unsigned int comp_ref[REF_CONTEXTS][2];
#endif // CONFIG_MULTI_REF
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][2];
unsigned int comp_ref[REF_CONTEXTS][COMP_REFS-1][2];
struct tx_counts tx;
unsigned int skip[SKIP_CONTEXTS][2];
nmv_context_counts mv;

View File

@ -127,11 +127,7 @@ int vp9_get_pred_context_comp_ref_p(const VP9_COMMON *cm,
static INLINE vp9_prob vp9_get_pred_prob_comp_ref_p(const VP9_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = vp9_get_pred_context_comp_ref_p(cm, xd);
#if CONFIG_MULTI_REF
return cm->fc.comp_ref_prob[pred_context][0];
#else
return cm->fc.comp_ref_prob[pred_context];
#endif // CONFIG_MULTI_REF
return cm->fc.comp_ref_probs[pred_context][0];
}
#if CONFIG_MULTI_REF
@ -141,7 +137,7 @@ int vp9_get_pred_context_comp_ref_p1(const VP9_COMMON *cm,
static INLINE vp9_prob vp9_get_pred_prob_comp_ref_p1(const VP9_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = vp9_get_pred_context_comp_ref_p1(cm, xd);
return cm->fc.comp_ref_prob[pred_context][1];
return cm->fc.comp_ref_probs[pred_context][1];
}
#endif // CONFIG_MULTI_REF
@ -149,14 +145,14 @@ int vp9_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
static INLINE vp9_prob vp9_get_pred_prob_single_ref_p1(const VP9_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p1(xd)][0];
return cm->fc.single_ref_probs[vp9_get_pred_context_single_ref_p1(xd)][0];
}
int vp9_get_pred_context_single_ref_p2(const MACROBLOCKD *xd);
static INLINE vp9_prob vp9_get_pred_prob_single_ref_p2(const VP9_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p2(xd)][1];
return cm->fc.single_ref_probs[vp9_get_pred_context_single_ref_p2(xd)][1];
}
#if CONFIG_MULTI_REF
@ -164,7 +160,7 @@ int vp9_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
static INLINE vp9_prob vp9_get_pred_prob_single_ref_p3(const VP9_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc.single_ref_prob[vp9_get_pred_context_single_ref_p3(xd)][2];
return cm->fc.single_ref_probs[vp9_get_pred_context_single_ref_p3(xd)][2];
}
#endif // CONFIG_MULTI_REF

View File

@ -164,7 +164,7 @@ static REFERENCE_MODE read_frame_reference_mode(const VP9_COMMON *cm,
static void read_frame_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) {
FRAME_CONTEXT *const fc = &cm->fc;
int i;
int i, j;
if (cm->reference_mode == REFERENCE_MODE_SELECT)
for (i = 0; i < COMP_INTER_CONTEXTS; ++i)
@ -172,21 +172,16 @@ static void read_frame_reference_mode_probs(VP9_COMMON *cm, vp9_reader *r) {
if (cm->reference_mode != COMPOUND_REFERENCE)
for (i = 0; i < REF_CONTEXTS; ++i) {
vp9_diff_update_prob(r, &fc->single_ref_prob[i][0]);
vp9_diff_update_prob(r, &fc->single_ref_prob[i][1]);
#if CONFIG_MULTI_REF
vp9_diff_update_prob(r, &fc->single_ref_prob[i][2]);
#endif // CONFIG_MULTI_REF
for (j = 0; j < (SINGLE_REFS - 1); ++j) {
vp9_diff_update_prob(r, &fc->single_ref_probs[i][j]);
}
}
if (cm->reference_mode != SINGLE_REFERENCE)
for (i = 0; i < REF_CONTEXTS; ++i) {
#if CONFIG_MULTI_REF
vp9_diff_update_prob(r, &fc->comp_ref_prob[i][0]);
vp9_diff_update_prob(r, &fc->comp_ref_prob[i][1]);
#else
vp9_diff_update_prob(r, &fc->comp_ref_prob[i]);
#endif // CONFIG_MULTI_REF
for (j = 0; j < (COMP_REFS - 1); ++j) {
vp9_diff_update_prob(r, &fc->comp_ref_probs[i][j]);
}
}
}

View File

@ -767,25 +767,17 @@ static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
if (mode == COMPOUND_REFERENCE) {
const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
#if CONFIG_MULTI_REF
const int bit = vp9_read(r, fc->comp_ref_prob[ctx][0]);
#else
const int bit = vp9_read(r, fc->comp_ref_prob[ctx]);
#endif // CONFIG_MULTI_REF
const int bit = vp9_read(r, fc->comp_ref_probs[ctx][0]);
if (!cm->frame_parallel_decoding_mode)
#if CONFIG_MULTI_REF
++counts->comp_ref[ctx][0][bit];
#else
++counts->comp_ref[ctx][bit];
#endif // CONFIG_MULTI_REF
ref_frame[idx] = cm->comp_fixed_ref;
#if CONFIG_MULTI_REF
if (!bit) {
const int ctx1 = vp9_get_pred_context_comp_ref_p1(cm, xd);
const int bit1 = vp9_read(r, fc->comp_ref_prob[ctx1][1]);
const int bit1 = vp9_read(r, fc->comp_ref_probs[ctx1][1]);
if (!cm->frame_parallel_decoding_mode)
++counts->comp_ref[ctx1][1][bit1];
@ -800,30 +792,30 @@ static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
} else if (mode == SINGLE_REFERENCE) {
#if CONFIG_MULTI_REF
const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
const int bit0 = vp9_read(r, fc->single_ref_probs[ctx0][0]);
if (!cm->frame_parallel_decoding_mode)
++counts->single_ref[ctx0][0][bit0];
if (bit0) {
const int ctx1 = vp9_get_pred_context_single_ref_p2(xd);
const int bit1 = vp9_read(r, fc->single_ref_prob[ctx1][1]);
const int bit1 = vp9_read(r, fc->single_ref_probs[ctx1][1]);
if (!cm->frame_parallel_decoding_mode)
++counts->single_ref[ctx1][1][bit1];
ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
} else {
const int ctx2 = vp9_get_pred_context_single_ref_p3(xd);
const int bit2 = vp9_read(r, fc->single_ref_prob[ctx2][2]);
const int bit2 = vp9_read(r, fc->single_ref_probs[ctx2][2]);
if (!cm->frame_parallel_decoding_mode)
++counts->single_ref[ctx2][2][bit2];
ref_frame[0] = bit2 ? LAST2_FRAME : LAST_FRAME;
}
#else
const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
const int bit0 = vp9_read(r, fc->single_ref_probs[ctx0][0]);
if (!cm->frame_parallel_decoding_mode)
++counts->single_ref[ctx0][0][bit0];
if (bit0) {
const int ctx1 = vp9_get_pred_context_single_ref_p2(xd);
const int bit1 = vp9_read(r, fc->single_ref_prob[ctx1][1]);
const int bit1 = vp9_read(r, fc->single_ref_probs[ctx1][1]);
if (!cm->frame_parallel_decoding_mode)
++counts->single_ref[ctx1][1][bit1];
ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;

View File

@ -2516,7 +2516,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
#endif // CONFIG_SR_MODE
if (!frame_is_intra_only(cm)) {
int i;
int i, j;
for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
prob_diff_update(vp9_inter_mode_tree, cm->fc.inter_mode_probs[i],
cm->counts.inter_mode[i], INTER_MODES, &header_bc);
@ -2551,28 +2551,19 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
if (cm->reference_mode != COMPOUND_REFERENCE) {
for (i = 0; i < REF_CONTEXTS; i++) {
vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][0],
cm->counts.single_ref[i][0]);
vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][1],
cm->counts.single_ref[i][1]);
#if CONFIG_MULTI_REF
vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][2],
cm->counts.single_ref[i][2]);
#endif // CONFIG_MULTI_REF
for (j = 0; j < (SINGLE_REFS - 1); j++) {
vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_probs[i][j],
cm->counts.single_ref[i][j]);
}
}
}
if (cm->reference_mode != SINGLE_REFERENCE) {
for (i = 0; i < REF_CONTEXTS; i++) {
#if CONFIG_MULTI_REF
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i][0],
cm->counts.comp_ref[i][0]);
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i][1],
cm->counts.comp_ref[i][1]);
#else
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
cm->counts.comp_ref[i]);
#endif // CONFIG_MULTI_REF
for (j = 0; j < (COMP_REFS - 1); j++) {
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_probs[i][j],
cm->counts.comp_ref[i][j]);
}
}
}

View File

@ -1522,16 +1522,13 @@ static void update_stats(VP9_COMMON *cm, const MACROBLOCK *x) {
[has_second_ref(mbmi)]++;
if (has_second_ref(mbmi)) {
#if CONFIG_MULTI_REF
counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)][0]
[ref0 == GOLDEN_FRAME]++;
#if CONFIG_MULTI_REF
if (ref0 != GOLDEN_FRAME) {
counts->comp_ref[vp9_get_pred_context_comp_ref_p1(cm, xd)][1]
[ref0 == LAST_FRAME]++;
}
#else
counts->comp_ref[vp9_get_pred_context_comp_ref_p(cm, xd)]
[ref0 == GOLDEN_FRAME]++;
#endif // CONFIG_MULTI_REF
} else {
#if CONFIG_MULTI_REF