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:
parent
897192be43
commit
ec8864a8bf
@ -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,
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user