Commit 3d30b4b6 authored by Hui Su's avatar Hui Su

Remove probability model for single ref frames

-Use the CDF values to calculate the cost for ref frame signaling
-Update the cost per superblock
-Fix some errors in the default CDF

Test on midres speed-1 30 frames shows ~0.1% coding gain.

Change-Id: I6f3e5896ef1cae9b515fc8287bc7565d68d05a57
parent acf12f6a
......@@ -1464,14 +1464,6 @@ static const aom_cdf_prob
{ { AOM_CDF2(32768) }, { AOM_CDF2(32768) } }
};
static const aom_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
{ 36, 16, 32, 57, 11, 14 },
{ 68, 128, 73, 128, 49, 124 },
{ 136, 236, 127, 170, 81, 238 },
{ 128, 128, 191, 211, 115, 128 },
{ 224, 128, 230, 242, 208, 128 }
};
static const aom_cdf_prob default_single_ref_cdf[REF_CONTEXTS][SINGLE_REFS - 1]
[CDF_SIZE(2)] = {
{ { AOM_CDF2(4623) },
......@@ -1492,18 +1484,18 @@ static const aom_cdf_prob default_single_ref_cdf[REF_CONTEXTS][SINGLE_REFS - 1]
{ AOM_CDF2(21702) },
{ AOM_CDF2(10365) },
{ AOM_CDF2(30486) } },
{ { AOM_CDF2(32768) },
{ AOM_CDF2(32768) },
{ { AOM_CDF2(16384) },
{ AOM_CDF2(16384) },
{ AOM_CDF2(24426) },
{ AOM_CDF2(26972) },
{ AOM_CDF2(14760) },
{ AOM_CDF2(32768) } },
{ AOM_CDF2(16384) } },
{ { AOM_CDF2(28634) },
{ AOM_CDF2(32768) },
{ AOM_CDF2(16384) },
{ AOM_CDF2(29425) },
{ AOM_CDF2(30969) },
{ AOM_CDF2(26676) },
{ AOM_CDF2(32768) } }
{ AOM_CDF2(16384) } }
};
// TODO(huisu): tune these cdfs
......@@ -3344,7 +3336,6 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#endif
av1_copy(fc->comp_bwdref_prob, default_comp_bwdref_p);
av1_copy(fc->comp_bwdref_cdf, default_comp_bwdref_cdf);
av1_copy(fc->single_ref_prob, default_single_ref_p);
av1_copy(fc->single_ref_cdf, default_single_ref_cdf);
av1_copy(fc->txfm_partition_cdf, default_txfm_partition_cdf);
#if CONFIG_JNT_COMP
......@@ -3431,11 +3422,6 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
for (j = 0; j < (BWD_REFS - 1); j++)
fc->comp_bwdref_prob[i][j] = mode_mv_merge_probs(
pre_fc->comp_bwdref_prob[i][j], counts->comp_bwdref[i][j]);
for (i = 0; i < REF_CONTEXTS; i++)
for (j = 0; j < (SINGLE_REFS - 1); j++)
fc->single_ref_prob[i][j] = av1_mode_mv_merge_probs(
pre_fc->single_ref_prob[i][j], counts->single_ref[i][j]);
}
static void set_default_lf_deltas(struct loopfilter *lf) {
......
......@@ -167,7 +167,6 @@ typedef struct frame_contexts {
aom_cdf_prob uni_comp_ref_cdf[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1]
[CDF_SIZE(2)];
#endif // CONFIG_EXT_COMP_REFS
aom_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS - 1];
aom_prob comp_ref_prob[REF_CONTEXTS][FWD_REFS - 1];
aom_prob comp_bwdref_prob[REF_CONTEXTS][BWD_REFS - 1];
aom_cdf_prob comp_ref_cdf[REF_CONTEXTS][FWD_REFS - 1][CDF_SIZE(2)];
......@@ -326,7 +325,9 @@ typedef struct FRAME_COUNTS {
unsigned int comp_ref_type[COMP_REF_TYPE_CONTEXTS][2];
unsigned int uni_comp_ref[UNI_COMP_REF_CONTEXTS][UNIDIR_COMP_REFS - 1][2];
#endif // CONFIG_EXT_COMP_REFS
#if CONFIG_ENTROPY_STATS
unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS - 1][2];
#endif // CONFIG_ENTROPY_STATS
unsigned int comp_ref[REF_CONTEXTS][FWD_REFS - 1][2];
unsigned int comp_bwdref[REF_CONTEXTS][BWD_REFS - 1][2];
unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
......
......@@ -331,46 +331,16 @@ static INLINE aom_prob av1_get_pred_prob_comp_bwdref_p1(const AV1_COMMON *cm,
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p1(xd)][0];
}
int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p2(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p2(xd)][1];
}
int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p3(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p3(xd)][2];
}
int av1_get_pred_context_single_ref_p4(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p4(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p4(xd)][3];
}
int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p5(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p5(xd)][4];
}
int av1_get_pred_context_single_ref_p6(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_single_ref_p6(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->single_ref_prob[av1_get_pred_context_single_ref_p6(xd)][5];
}
static INLINE aom_cdf_prob *av1_get_pred_cdf_single_ref_p1(
const AV1_COMMON *cm, const MACROBLOCKD *xd) {
(void)cm;
......
......@@ -3142,8 +3142,6 @@ static void debug_check_frame_counts(const AV1_COMMON *const cm) {
assert(!memcmp(cm->counts.uni_comp_ref, zero_counts.uni_comp_ref,
sizeof(cm->counts.uni_comp_ref)));
#endif // CONFIG_EXT_COMP_REFS
assert(!memcmp(cm->counts.single_ref, zero_counts.single_ref,
sizeof(cm->counts.single_ref)));
assert(!memcmp(cm->counts.comp_ref, zero_counts.comp_ref,
sizeof(cm->counts.comp_ref)));
assert(!memcmp(cm->counts.comp_bwdref, zero_counts.comp_bwdref,
......
......@@ -1406,35 +1406,22 @@ static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
ref_frame[idx] = cm->comp_bwd_ref[2];
}
} else if (mode == SINGLE_REFERENCE) {
const int ctx0 = av1_get_pred_context_single_ref_p1(xd);
const int bit0 = READ_REF_BIT(single_ref_p1);
if (counts) ++counts->single_ref[ctx0][0][bit0];
if (bit0) {
const int ctx1 = av1_get_pred_context_single_ref_p2(xd);
const int bit1 = READ_REF_BIT(single_ref_p2);
if (counts) ++counts->single_ref[ctx1][1][bit1];
if (!bit1) {
const int ctx5 = av1_get_pred_context_single_ref_p6(xd);
const int bit5 = READ_REF_BIT(single_ref_p6);
if (counts) ++counts->single_ref[ctx5][5][bit5];
ref_frame[0] = bit5 ? ALTREF2_FRAME : BWDREF_FRAME;
} else {
ref_frame[0] = ALTREF_FRAME;
}
} else {
const int ctx2 = av1_get_pred_context_single_ref_p3(xd);
const int bit2 = READ_REF_BIT(single_ref_p3);
if (counts) ++counts->single_ref[ctx2][2][bit2];
if (bit2) {
const int ctx4 = av1_get_pred_context_single_ref_p5(xd);
const int bit4 = READ_REF_BIT(single_ref_p5);
if (counts) ++counts->single_ref[ctx4][4][bit4];
ref_frame[0] = bit4 ? GOLDEN_FRAME : LAST3_FRAME;
} else {
const int ctx3 = av1_get_pred_context_single_ref_p4(xd);
const int bit3 = READ_REF_BIT(single_ref_p4);
if (counts) ++counts->single_ref[ctx3][3][bit3];
ref_frame[0] = bit3 ? LAST2_FRAME : LAST_FRAME;
}
}
......
......@@ -284,6 +284,7 @@ struct macroblock {
int drl_mode_cost0[DRL_MODE_CONTEXTS][2];
int comp_inter_cost[COMP_INTER_CONTEXTS][2];
int single_ref_cost[REF_CONTEXTS][SINGLE_REFS - 1][2];
int inter_compound_mode_cost[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
#if CONFIG_JNT_COMP
int compound_type_cost[BLOCK_SIZES_ALL][COMPOUND_TYPES - 1];
......
......@@ -939,25 +939,57 @@ static void update_stats(const AV1_COMMON *const cm, TileDataEnc *tile_data,
#endif // CONFIG_EXT_COMP_REFS
} else {
const int bit = (ref0 >= BWDREF_FRAME);
if (allow_update_cdf)
update_cdf(av1_get_pred_cdf_single_ref_p1(cm, xd), bit, 2);
#if CONFIG_ENTROPY_STATS
counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
#endif // CONFIG_ENTROPY_STATS
if (bit) {
assert(ref0 <= ALTREF_FRAME);
if (allow_update_cdf) {
update_cdf(av1_get_pred_cdf_single_ref_p2(cm, xd),
ref0 == ALTREF_FRAME, 2);
}
#if CONFIG_ENTROPY_STATS
counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
[ref0 == ALTREF_FRAME]++;
if (ref0 != ALTREF_FRAME)
#endif // CONFIG_ENTROPY_STATS
if (ref0 != ALTREF_FRAME) {
if (allow_update_cdf) {
update_cdf(av1_get_pred_cdf_single_ref_p6(cm, xd),
ref0 == ALTREF2_FRAME, 2);
}
#if CONFIG_ENTROPY_STATS
counts->single_ref[av1_get_pred_context_single_ref_p6(xd)][5]
[ref0 == ALTREF2_FRAME]++;
#endif // CONFIG_ENTROPY_STATS
}
} else {
const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
if (allow_update_cdf)
update_cdf(av1_get_pred_cdf_single_ref_p3(cm, xd), bit1, 2);
#if CONFIG_ENTROPY_STATS
counts
->single_ref[av1_get_pred_context_single_ref_p3(xd)][2][bit1]++;
#endif // CONFIG_ENTROPY_STATS
if (!bit1) {
if (allow_update_cdf) {
update_cdf(av1_get_pred_cdf_single_ref_p4(cm, xd),
ref0 != LAST_FRAME, 2);
}
#if CONFIG_ENTROPY_STATS
counts->single_ref[av1_get_pred_context_single_ref_p4(xd)][3]
[ref0 != LAST_FRAME]++;
#endif // CONFIG_ENTROPY_STATS
} else {
if (allow_update_cdf) {
update_cdf(av1_get_pred_cdf_single_ref_p5(cm, xd),
ref0 != LAST3_FRAME, 2);
}
#if CONFIG_ENTROPY_STATS
counts->single_ref[av1_get_pred_context_single_ref_p5(xd)][4]
[ref0 != LAST3_FRAME]++;
#endif // CONFIG_ENTROPY_STATS
}
}
}
......
......@@ -231,6 +231,13 @@ void av1_fill_mode_rates(AV1_COMMON *const cm, MACROBLOCK *x,
NULL);
}
for (i = 0; i < REF_CONTEXTS; ++i) {
for (j = 0; j < SINGLE_REFS - 1; ++j) {
av1_cost_tokens_from_cdf(x->single_ref_cost[i][j],
fc->single_ref_cdf[i][j], NULL);
}
}
for (i = 0; i < INTRA_INTER_CONTEXTS; ++i) {
av1_cost_tokens_from_cdf(x->intra_inter_cost[i], fc->intra_inter_cdf[i],
NULL);
......
......@@ -5811,43 +5811,42 @@ static void estimate_ref_frame_costs(
#if !CONFIG_REF_ADAPT
if (cm->reference_mode != COMPOUND_REFERENCE) {
#endif // !CONFIG_REF_ADAPT
aom_prob ref_single_p1 = av1_get_pred_prob_single_ref_p1(cm, xd);
aom_prob ref_single_p2 = av1_get_pred_prob_single_ref_p2(cm, xd);
aom_prob ref_single_p3 = av1_get_pred_prob_single_ref_p3(cm, xd);
aom_prob ref_single_p4 = av1_get_pred_prob_single_ref_p4(cm, xd);
aom_prob ref_single_p5 = av1_get_pred_prob_single_ref_p5(cm, xd);
aom_prob ref_single_p6 = av1_get_pred_prob_single_ref_p6(cm, xd);
ref_costs_single[LAST_FRAME] = ref_costs_single[LAST2_FRAME] =
ref_costs_single[LAST3_FRAME] = ref_costs_single[BWDREF_FRAME] =
ref_costs_single[ALTREF2_FRAME] = ref_costs_single[GOLDEN_FRAME] =
ref_costs_single[ALTREF_FRAME] = base_cost;
ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p1, 0);
ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p1, 0);
ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p1, 0);
ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p1, 0);
ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
ref_costs_single[ALTREF2_FRAME] += av1_cost_bit(ref_single_p1, 1);
ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p1, 1);
ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p3, 0);
ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p3, 0);
ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p3, 1);
ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p3, 1);
ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p2, 0);
ref_costs_single[ALTREF2_FRAME] += av1_cost_bit(ref_single_p2, 0);
ref_costs_single[ALTREF_FRAME] += av1_cost_bit(ref_single_p2, 1);
ref_costs_single[LAST_FRAME] += av1_cost_bit(ref_single_p4, 0);
ref_costs_single[LAST2_FRAME] += av1_cost_bit(ref_single_p4, 1);
ref_costs_single[LAST3_FRAME] += av1_cost_bit(ref_single_p5, 0);
ref_costs_single[GOLDEN_FRAME] += av1_cost_bit(ref_single_p5, 1);
ref_costs_single[BWDREF_FRAME] += av1_cost_bit(ref_single_p6, 0);
ref_costs_single[ALTREF2_FRAME] += av1_cost_bit(ref_single_p6, 1);
const int ctx_p1 = av1_get_pred_context_single_ref_p1(xd);
const int ctx_p2 = av1_get_pred_context_single_ref_p2(xd);
const int ctx_p3 = av1_get_pred_context_single_ref_p3(xd);
const int ctx_p4 = av1_get_pred_context_single_ref_p4(xd);
const int ctx_p5 = av1_get_pred_context_single_ref_p5(xd);
const int ctx_p6 = av1_get_pred_context_single_ref_p6(xd);
ref_costs_single[LAST_FRAME] += x->single_ref_cost[ctx_p1][0][0];
ref_costs_single[LAST2_FRAME] += x->single_ref_cost[ctx_p1][0][0];
ref_costs_single[LAST3_FRAME] += x->single_ref_cost[ctx_p1][0][0];
ref_costs_single[GOLDEN_FRAME] += x->single_ref_cost[ctx_p1][0][0];
ref_costs_single[BWDREF_FRAME] += x->single_ref_cost[ctx_p1][0][1];
ref_costs_single[ALTREF2_FRAME] += x->single_ref_cost[ctx_p1][0][1];
ref_costs_single[ALTREF_FRAME] += x->single_ref_cost[ctx_p1][0][1];
ref_costs_single[LAST_FRAME] += x->single_ref_cost[ctx_p3][2][0];
ref_costs_single[LAST2_FRAME] += x->single_ref_cost[ctx_p3][2][0];
ref_costs_single[LAST3_FRAME] += x->single_ref_cost[ctx_p3][2][1];
ref_costs_single[GOLDEN_FRAME] += x->single_ref_cost[ctx_p3][2][1];
ref_costs_single[BWDREF_FRAME] += x->single_ref_cost[ctx_p2][1][0];
ref_costs_single[ALTREF2_FRAME] += x->single_ref_cost[ctx_p2][1][0];
ref_costs_single[ALTREF_FRAME] += x->single_ref_cost[ctx_p2][1][1];
ref_costs_single[LAST_FRAME] += x->single_ref_cost[ctx_p4][3][0];
ref_costs_single[LAST2_FRAME] += x->single_ref_cost[ctx_p4][3][1];
ref_costs_single[LAST3_FRAME] += x->single_ref_cost[ctx_p5][4][0];
ref_costs_single[GOLDEN_FRAME] += x->single_ref_cost[ctx_p5][4][1];
ref_costs_single[BWDREF_FRAME] += x->single_ref_cost[ctx_p6][5][0];
ref_costs_single[ALTREF2_FRAME] += x->single_ref_cost[ctx_p6][5][1];
#if !CONFIG_REF_ADAPT
} else {
ref_costs_single[LAST_FRAME] = 512;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment