Commit 97ad058e authored by Zoe Liu's avatar Zoe Liu

Add support to the experiment of altref2

This CL adds an extra alt-ref reference frame, namely ALTREF2_FRAME,
and designs the contexts for ALTREF2_FRAME.

Change-Id: I12fe8629b868aebf6c2b54260fca5abc38f90ae6
parent 40b9e7fe
......@@ -45,7 +45,8 @@ struct loopfilter {
uint8_t mode_ref_delta_update;
// 0 = Intra, Last, Last2+Last3(CONFIG_EXT_REFS),
// GF, BRF(CONFIG_EXT_REFS), ARF
// GF, BRF(CONFIG_EXT_REFS),
// ARF2(CONFIG_EXT_REFS+CONFIG_ALTREF2), ARF
signed char ref_deltas[TOTAL_REFS_PER_FRAME];
signed char last_ref_deltas[TOTAL_REFS_PER_FRAME];
......
......@@ -1220,12 +1220,22 @@ static const aom_prob default_comp_ref_p[REF_CONTEXTS][FWD_REFS - 1] = {
{ 238, 131, 136 }
#endif // !CONFIG_EXT_COMP_REFS
};
static const aom_prob default_comp_bwdref_p[REF_CONTEXTS][BWD_REFS - 1] = {
#if CONFIG_ALTREF2
// TODO(zoeliu): ALTREF2 to work with EXT_COMP_REFS and NEW_MULTISYMBOL.
{ 50, 50 },
{ 130, 130 },
{ 210, 210 },
{ 128, 128 },
{ 128, 128 }
#else // !CONFIG_ALTREF2
#if !CONFIG_EXT_COMP_REFS
{ 16 }, { 74 }, { 142 }, { 170 }, { 247 }
#else // CONFIG_EXT_COMP_REFS
{ 7 }, { 56 }, { 29 }, { 230 }, { 220 }
#endif // CONFIG_EXT_COMP_REFS
#endif // CONFIG_ALTREF2
};
#if CONFIG_NEW_MULTISYMBOL
......@@ -1265,6 +1275,7 @@ static const aom_cdf_prob
{ AOM_ICDF(136 * 128), AOM_ICDF(32768), 0 } }
#endif // !CONFIG_EXT_COMP_REFS
};
static const aom_cdf_prob
default_comp_bwdref_cdf[REF_CONTEXTS][BWD_REFS - 1][CDF_SIZE(2)] = {
#if !CONFIG_EXT_COMP_REFS
......@@ -1282,7 +1293,9 @@ static const aom_cdf_prob
#endif // !CONFIG_EXT_COMP_REFS
};
#endif // CONFIG_NEW_MULTISYMBOL
#else // !CONFIG_EXT_REFS
#else // !CONFIG_EXT_REFS
static const aom_prob default_comp_ref_p[REF_CONTEXTS][COMP_REFS - 1] = {
{ 43 }, { 100 }, { 137 }, { 212 }, { 229 },
};
......@@ -1300,6 +1313,14 @@ static const aom_cdf_prob
static const aom_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
#if CONFIG_EXT_REFS
#if CONFIG_ALTREF2
// TODO(zoeliu): ALTREF2 to work with EXT_COMP_REFS and NEW_MULTISYMBOL.
{ 33, 50, 16, 16, 16, 50 },
{ 77, 130, 74, 74, 74, 130 },
{ 142, 210, 142, 142, 142, 210 },
{ 172, 128, 170, 170, 170, 128 },
{ 238, 128, 247, 247, 247, 128 }
#else // !CONFIG_ALTREF2
#if !CONFIG_EXT_COMP_REFS
{ 33, 16, 16, 16, 16 },
{ 77, 74, 74, 74, 74 },
......@@ -1313,6 +1334,7 @@ static const aom_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
{ 128, 174, 189, 216, 101 },
{ 233, 252, 228, 246, 200 }
#endif // !CONFIG_EXT_COMP_REFS
#endif // CONFIG_ALTREF2
#else // !CONFIG_EXT_REFS
{ 31, 25 }, { 72, 80 }, { 147, 148 }, { 197, 191 }, { 235, 247 },
#endif // CONFIG_EXT_REFS
......@@ -5560,6 +5582,9 @@ static void set_default_lf_deltas(struct loopfilter *lf) {
lf->ref_deltas[BWDREF_FRAME] = lf->ref_deltas[LAST_FRAME];
#endif // CONFIG_EXT_REFS
lf->ref_deltas[GOLDEN_FRAME] = -1;
#if CONFIG_ALTREF2
lf->ref_deltas[ALTREF2_FRAME] = -1;
#endif // CONFIG_ALTREF2
lf->ref_deltas[ALTREF_FRAME] = -1;
lf->mode_deltas[0] = 0;
......
......@@ -302,9 +302,15 @@ typedef enum {
AOM_LAST3_FLAG = 1 << 2,
AOM_GOLD_FLAG = 1 << 3,
AOM_BWD_FLAG = 1 << 4,
#if CONFIG_ALTREF2
AOM_ALT2_FLAG = 1 << 5,
AOM_ALT_FLAG = 1 << 6,
AOM_REFFRAME_ALL = (1 << 7) - 1
#else // !CONFIG_ALTREF2
AOM_ALT_FLAG = 1 << 5,
AOM_REFFRAME_ALL = (1 << 6) - 1
#else
#endif // CONFIG_ALTREF2
#else // !CONFIG_EXT_REFS
AOM_GOLD_FLAG = 1 << 1,
AOM_ALT_FLAG = 1 << 2,
AOM_REFFRAME_ALL = (1 << 3) - 1
......@@ -562,9 +568,16 @@ typedef uint8_t TXFM_CONTEXT;
#define LAST3_FRAME 3
#define GOLDEN_FRAME 4
#define BWDREF_FRAME 5
#if CONFIG_ALTREF2
#define ALTREF2_FRAME 6
#define ALTREF_FRAME 7
#else // !CONFIG_ALTREF2
#define ALTREF_FRAME 6
#endif // CONFIG_ALTREF2
#define LAST_REF_FRAMES (LAST3_FRAME - LAST_FRAME + 1)
#else
#else // !CONFIG_EXT_REFS
#define GOLDEN_FRAME 2
#define ALTREF_FRAME 3
#endif // CONFIG_EXT_REFS
......
......@@ -284,6 +284,11 @@ static MV_REFERENCE_FRAME ref_frame_map[COMP_REFS][2] = {
{ LAST_FRAME, BWDREF_FRAME }, { LAST2_FRAME, BWDREF_FRAME },
{ LAST3_FRAME, BWDREF_FRAME }, { GOLDEN_FRAME, BWDREF_FRAME },
#if CONFIG_ALTREF2
{ LAST_FRAME, ALTREF2_FRAME }, { LAST2_FRAME, ALTREF2_FRAME },
{ LAST3_FRAME, ALTREF2_FRAME }, { GOLDEN_FRAME, ALTREF2_FRAME },
#endif // CONFIG_ALTREF2
{ LAST_FRAME, ALTREF_FRAME }, { LAST2_FRAME, ALTREF_FRAME },
{ LAST3_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME }
......@@ -291,6 +296,8 @@ static MV_REFERENCE_FRAME ref_frame_map[COMP_REFS][2] = {
#if CONFIG_EXT_COMP_REFS
, { LAST_FRAME, LAST2_FRAME }, { LAST_FRAME, LAST3_FRAME },
{ LAST_FRAME, GOLDEN_FRAME }, { BWDREF_FRAME, ALTREF_FRAME }
// TODO(zoeliu): When ALTREF2 is enabled, we may add:
// {BWDREF_FRAME, ALTREF2_FRAME}
#endif // CONFIG_EXT_COMP_REFS
#else // !CONFIG_EXT_REFS
{ LAST_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME }
......
......@@ -517,6 +517,9 @@ static INLINE void ref_cnt_fb(RefCntBuffer *bufs, int *idx, int new_idx) {
#define LAST3_IS_VALID(cm) ((cm)->frame_refs[LAST3_FRAME - 1].is_valid)
#define GOLDEN_IS_VALID(cm) ((cm)->frame_refs[GOLDEN_FRAME - 1].is_valid)
#define BWDREF_IS_VALID(cm) ((cm)->frame_refs[BWDREF_FRAME - 1].is_valid)
#if CONFIG_ALTREF2
#define ALTREF2_IS_VALID(cm) ((cm)->frame_refs[ALTREF2_FRAME - 1].is_valid)
#endif // CONFIG_ALTREF2
#define ALTREF_IS_VALID(cm) ((cm)->frame_refs[ALTREF_FRAME - 1].is_valid)
#define L_OR_L2(cm) (LAST_IS_VALID(cm) || LAST2_IS_VALID(cm))
......@@ -527,6 +530,10 @@ static INLINE void ref_cnt_fb(RefCntBuffer *bufs, int *idx, int new_idx) {
#define L3_OR_G(cm) (LAST3_IS_VALID(cm) || GOLDEN_IS_VALID(cm))
#define L3_AND_G(cm) (LAST3_IS_VALID(cm) && GOLDEN_IS_VALID(cm))
#if CONFIG_ALTREF2
#define BWD_OR_ALT2(cm) (BWDREF_IS_VALID(cm) || ALTREF2_IS_VALID(cm))
#define BWD_AND_ALT2(cm) (BWDREF_IS_VALID(cm) && ALTREF2_IS_VALID(cm))
#endif // CONFIG_ALTREF2
#define BWD_OR_ALT(cm) (BWDREF_IS_VALID(cm) || ALTREF_IS_VALID(cm))
#define BWD_AND_ALT(cm) (BWDREF_IS_VALID(cm) && ALTREF_IS_VALID(cm))
#endif // CONFIG_VAR_REFS
......
......@@ -887,6 +887,110 @@ int av1_get_pred_context_comp_ref_p2(const AV1_COMMON *cm,
return pred_context;
}
#if CONFIG_ALTREF2
// Obtain contexts to signal a reference frame be either BWDREF/ALTREF2, or
// ALTREF.
int av1_get_pred_context_brfarf2_or_arf(const MACROBLOCKD *xd) {
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available;
// Counts of BWDREF, ALTREF2, or ALTREF frames (B, A2, or A)
int bwdref_counts[ALTREF_FRAME - BWDREF_FRAME + 1] = { 0 };
if (above_in_image && is_inter_block(above_mbmi)) {
if (above_mbmi->ref_frame[0] >= BWDREF_FRAME)
++bwdref_counts[above_mbmi->ref_frame[0] - BWDREF_FRAME];
if (has_second_ref(above_mbmi)) {
if (above_mbmi->ref_frame[1] >= BWDREF_FRAME)
++bwdref_counts[above_mbmi->ref_frame[1] - BWDREF_FRAME];
}
}
if (left_in_image && is_inter_block(left_mbmi)) {
if (left_mbmi->ref_frame[0] >= BWDREF_FRAME)
++bwdref_counts[left_mbmi->ref_frame[0] - BWDREF_FRAME];
if (has_second_ref(left_mbmi)) {
if (left_mbmi->ref_frame[1] >= BWDREF_FRAME)
++bwdref_counts[left_mbmi->ref_frame[1] - BWDREF_FRAME];
}
}
const int brfarf2_count = bwdref_counts[BWDREF_FRAME - BWDREF_FRAME] +
bwdref_counts[ALTREF2_FRAME - BWDREF_FRAME];
const int arf_count = bwdref_counts[ALTREF_FRAME - BWDREF_FRAME];
const int pred_context =
(brfarf2_count == arf_count) ? 1 : ((brfarf2_count < arf_count) ? 0 : 2);
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
return pred_context;
}
// Obtain contexts to signal a reference frame be either BWDREF or ALTREF2.
int av1_get_pred_context_brf_or_arf2(const MACROBLOCKD *xd) {
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int above_in_image = xd->up_available;
const int left_in_image = xd->left_available;
// Count of BWDREF frames (B)
int brf_count = 0;
// Count of ALTREF2 frames (A2)
int arf2_count = 0;
if (above_in_image && is_inter_block(above_mbmi)) {
if (above_mbmi->ref_frame[0] == BWDREF_FRAME)
++brf_count;
else if (above_mbmi->ref_frame[0] == ALTREF2_FRAME)
++arf2_count;
if (has_second_ref(above_mbmi)) {
if (above_mbmi->ref_frame[1] == BWDREF_FRAME)
++brf_count;
else if (above_mbmi->ref_frame[1] == ALTREF2_FRAME)
++arf2_count;
}
}
if (left_in_image && is_inter_block(left_mbmi)) {
if (left_mbmi->ref_frame[0] == BWDREF_FRAME)
++brf_count;
else if (left_mbmi->ref_frame[0] == ALTREF2_FRAME)
++arf2_count;
if (has_second_ref(left_mbmi)) {
if (left_mbmi->ref_frame[1] == BWDREF_FRAME)
++brf_count;
else if (left_mbmi->ref_frame[1] == ALTREF2_FRAME)
++arf2_count;
}
}
const int pred_context =
(brf_count == arf2_count) ? 1 : ((brf_count < arf2_count) ? 0 : 2);
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
return pred_context;
}
// Signal the 2nd reference frame for a compound mode be either
// ALTREF, or ALTREF2/BWDREF.
int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
(void)cm;
return av1_get_pred_context_brfarf2_or_arf(xd);
}
// Signal the 2nd reference frame for a compound mode be either
// ALTREF2 or BWDREF.
int av1_get_pred_context_comp_bwdref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
(void)cm;
return av1_get_pred_context_brf_or_arf2(xd);
}
#else // !CONFIG_ALTREF2
// Returns a context number for the given MB prediction signal
int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
......@@ -1009,8 +1113,9 @@ int av1_get_pred_context_comp_bwdref_p(const AV1_COMMON *cm,
return pred_context;
}
#endif // CONFIG_ALTREF2
#else // CONFIG_EXT_REFS
#else // !CONFIG_EXT_REFS
// Returns a context number for the given MB prediction signal
int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
......@@ -1099,10 +1204,8 @@ int av1_get_pred_context_comp_ref_p(const AV1_COMMON *cm,
#if CONFIG_EXT_REFS
// For the bit to signal whether the single reference is a ALTREF_FRAME
// or a BWDREF_FRAME.
//
// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF/BWDREF.
// For the bit to signal whether the single reference is a forward reference
// frame or a backward reference frame.
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
......@@ -1164,11 +1267,12 @@ int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
}
// For the bit to signal whether the single reference is ALTREF_FRAME or
// BWDREF_FRAME, knowing that it shall be either of these 2 choices.
//
// NOTE(zoeliu): The probability of ref_frame[0] is ALTREF_FRAME, conditioning
// on it is either ALTREF_FRAME/BWDREF_FRAME.
// non-ALTREF backward reference frame, knowing that it shall be either of
// these 2 choices.
int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
#if CONFIG_ALTREF2
return av1_get_pred_context_brfarf2_or_arf(xd);
#else // !CONFIG_ALTREF2
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
......@@ -1255,13 +1359,11 @@ int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd) {
assert(pred_context >= 0 && pred_context < REF_CONTEXTS);
return pred_context;
#endif // CONFIG_ALTREF2
}
// For the bit to signal whether the single reference is LAST3/GOLDEN or
// LAST2/LAST, knowing that it shall be either of these 2 choices.
//
// NOTE(zoeliu): The probability of ref_frame[0] is LAST3/GOLDEN, conditioning
// on it is either LAST3/GOLDEN/LAST2/LAST.
int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd) {
int pred_context;
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
......@@ -1538,7 +1640,15 @@ int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd) {
return pred_context;
}
#else // CONFIG_EXT_REFS
#if CONFIG_ALTREF2
// For the bit to signal whether the single reference is ALTREF2_FRAME or
// BWDREF_FRAME, knowing that it shall be either of these 2 choices.
int av1_get_pred_context_single_ref_p6(const MACROBLOCKD *xd) {
return av1_get_pred_context_brf_or_arf2(xd);
}
#endif // CONFIG_ALTREF2
#else // !CONFIG_EXT_REFS
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd) {
int pred_context;
......
......@@ -201,7 +201,7 @@ static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p1(
const int pred_context = av1_get_pred_context_comp_ref_p1(cm, xd);
return xd->tile_ctx->comp_ref_cdf[pred_context][1];
}
#endif
#endif // CONFIG_NEW_MULTISYMBOL
static INLINE aom_prob av1_get_pred_prob_comp_ref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
......@@ -218,7 +218,7 @@ static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_ref_p2(
const int pred_context = av1_get_pred_context_comp_ref_p2(cm, xd);
return xd->tile_ctx->comp_ref_cdf[pred_context][2];
}
#endif
#endif // CONFIG_NEW_MULTISYMBOL
static INLINE aom_prob av1_get_pred_prob_comp_ref_p2(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
......@@ -236,11 +236,24 @@ static INLINE aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p(
return xd->tile_ctx->comp_bwdref_cdf[pred_context][0];
}
#endif // CONFIG_NEW_MULTISYMBOL
static INLINE aom_prob av1_get_pred_prob_comp_bwdref_p(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_bwdref_p(cm, xd);
return cm->fc->comp_bwdref_prob[pred_context][0];
}
#if CONFIG_ALTREF2
// TODO(zoeliu): ALTREF2 to work with NEW_MULTISYMBOL
int av1_get_pred_context_comp_bwdref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_pred_prob_comp_bwdref_p1(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
const int pred_context = av1_get_pred_context_comp_bwdref_p1(cm, xd);
return cm->fc->comp_bwdref_prob[pred_context][1];
}
#endif // CONFIG_ALTREF2
#endif // CONFIG_EXT_REFS
int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
......@@ -278,6 +291,15 @@ 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];
}
#if CONFIG_ALTREF2
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];
}
#endif // CONFIG_ALTREF2
#endif // CONFIG_EXT_REFS
#if CONFIG_NEW_MULTISYMBOL
......
......@@ -9850,7 +9850,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
int best_skip2 = 0;
uint8_t ref_frame_skip_mask[2] = { 0 };
uint16_t ref_frame_skip_mask[2] = { 0 };
uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
......
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