Commit 239f06b3 authored by Zoe Liu's avatar Zoe Liu

Add new compound modes using single reference

The hookup with the encoder-decoder pipeline will be in the following
CLs. This is under the experiment of compound-singleref, with ext-
inter enabled.

Change-Id: I6523a1a6525539eb7c6aa6c5e11724a694e8bf6c
parent fb9e6656
......@@ -119,7 +119,11 @@ typedef struct {
static INLINE int is_inter_singleref_mode(PREDICTION_MODE mode) {
return mode >= NEARESTMV && mode <= NEWMV;
}
#if CONFIG_COMPOUND_SINGLEREF
static INLINE int is_inter_singleref_comp_mode(PREDICTION_MODE mode) {
return mode >= SR_NEAREST_NEARMV && mode <= SR_NEW_NEWMV;
}
#endif // CONFIG_COMPOUND_SINGLEREF
static INLINE int is_inter_compound_mode(PREDICTION_MODE mode) {
return mode >= NEAREST_NEARESTMV && mode <= NEW_NEWMV;
}
......@@ -143,16 +147,23 @@ static INLINE PREDICTION_MODE compound_ref0_mode(PREDICTION_MODE mode) {
MB_MODE_COUNT, // NEARMV
MB_MODE_COUNT, // ZEROMV
MB_MODE_COUNT, // NEWMV
NEARESTMV, // NEAREST_NEARESTMV
NEARESTMV, // NEAREST_NEARMV
NEARMV, // NEAR_NEARESTMV
NEARMV, // NEAR_NEARMV
NEARESTMV, // NEAREST_NEWMV
NEWMV, // NEW_NEARESTMV
NEARMV, // NEAR_NEWMV
NEWMV, // NEW_NEARMV
ZEROMV, // ZERO_ZEROMV
NEWMV, // NEW_NEWMV
#if CONFIG_COMPOUND_SINGLEREF
NEARESTMV, // SR_NEAREST_NEARMV
NEARESTMV, // SR_NEAREST_NEWMV
NEARMV, // SR_NEAR_NEWMV
ZEROMV, // SR_ZERO_NEWMV
NEWMV, // SR_NEW_NEWMV
#endif // CONFIG_COMPOUND_SINGLEREF
NEARESTMV, // NEAREST_NEARESTMV
NEARESTMV, // NEAREST_NEARMV
NEARMV, // NEAR_NEARESTMV
NEARMV, // NEAR_NEARMV
NEARESTMV, // NEAREST_NEWMV
NEWMV, // NEW_NEARESTMV
NEARMV, // NEAR_NEWMV
NEWMV, // NEW_NEARMV
ZEROMV, // ZERO_ZEROMV
NEWMV, // NEW_NEWMV
};
assert(is_inter_compound_mode(mode));
return lut[mode];
......@@ -177,16 +188,23 @@ static INLINE PREDICTION_MODE compound_ref1_mode(PREDICTION_MODE mode) {
MB_MODE_COUNT, // NEARMV
MB_MODE_COUNT, // ZEROMV
MB_MODE_COUNT, // NEWMV
NEARESTMV, // NEAREST_NEARESTMV
NEARMV, // NEAREST_NEARMV
NEARESTMV, // NEAR_NEARESTMV
NEARMV, // NEAR_NEARMV
NEWMV, // NEAREST_NEWMV
NEARESTMV, // NEW_NEARESTMV
NEWMV, // NEAR_NEWMV
NEARMV, // NEW_NEARMV
ZEROMV, // ZERO_ZEROMV
NEWMV, // NEW_NEWMV
#if CONFIG_COMPOUND_SINGLEREF
NEARMV, // SR_NEAREST_NEARMV
NEWMV, // SR_NEAREST_NEWMV
NEWMV, // SR_NEAR_NEWMV
NEWMV, // SR_ZERO_NEWMV
NEWMV, // SR_NEW_NEWMV
#endif // CONFIG_COMPOUND_SINGLEREF
NEARESTMV, // NEAREST_NEARESTMV
NEARMV, // NEAREST_NEARMV
NEARESTMV, // NEAR_NEARESTMV
NEARMV, // NEAR_NEARMV
NEWMV, // NEAREST_NEWMV
NEARESTMV, // NEW_NEARESTMV
NEWMV, // NEAR_NEWMV
NEARMV, // NEW_NEARMV
ZEROMV, // ZERO_ZEROMV
NEWMV, // NEW_NEWMV
};
assert(is_inter_compound_mode(mode));
return lut[mode];
......
......@@ -772,6 +772,21 @@ static const aom_prob default_inter_compound_mode_probs
{ 25, 29, 50, 192, 64, 192, 128, 180, 180 }, // 6 = two intra neighbours
};
#if CONFIG_COMPOUND_SINGLEREF
// TODO(zoeliu): Default values to be further adjusted based on the collected
// stats.
static const aom_prob default_inter_singleref_comp_mode_probs
[INTER_MODE_CONTEXTS][INTER_SINGLEREF_COMP_MODES - 1] = {
{ 2, 173, 68, 180 }, // 0 = both zero mv
{ 7, 145, 160, 180 }, // 1 = 1 zero + 1 predicted
{ 7, 166, 126, 180 }, // 2 = two predicted mvs
{ 7, 94, 132, 180 }, // 3 = 1 pred/zero, 1 new
{ 8, 64, 64, 180 }, // 4 = two new mvs
{ 17, 81, 52, 180 }, // 5 = one intra neighbour
{ 25, 29, 50, 180 }, // 6 = two intra neighbours
};
#endif // CONFIG_COMPOUND_SINGLEREF
#if CONFIG_COMPOUND_SEGMENT && CONFIG_WEDGE
static const aom_prob
default_compound_type_probs[BLOCK_SIZES][COMPOUND_TYPES - 1] = {
......@@ -992,6 +1007,17 @@ const aom_tree_index av1_inter_compound_mode_tree
-INTER_COMPOUND_OFFSET(NEAR_NEWMV), -INTER_COMPOUND_OFFSET(NEW_NEARMV)
};
#if CONFIG_COMPOUND_SINGLEREF
const aom_tree_index av1_inter_singleref_comp_mode_tree
[TREE_SIZE(INTER_SINGLEREF_COMP_MODES)] = {
-INTER_SINGLEREF_COMP_OFFSET(SR_ZERO_NEWMV), 2,
-INTER_SINGLEREF_COMP_OFFSET(SR_NEAREST_NEARMV), 4,
6, -INTER_SINGLEREF_COMP_OFFSET(SR_NEW_NEWMV),
-INTER_SINGLEREF_COMP_OFFSET(SR_NEAREST_NEWMV),
-INTER_SINGLEREF_COMP_OFFSET(SR_NEAR_NEWMV)
};
#endif // CONFIG_COMPOUND_SINGLEREF
#if CONFIG_COMPOUND_SEGMENT && CONFIG_WEDGE
const aom_tree_index av1_compound_type_tree[TREE_SIZE(COMPOUND_TYPES)] = {
-COMPOUND_AVERAGE, 2, -COMPOUND_WEDGE, -COMPOUND_SEG
......@@ -1066,6 +1092,14 @@ static const aom_prob default_single_ref_p[REF_CONTEXTS][SINGLE_REFS - 1] = {
#endif // CONFIG_EXT_REFS
};
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
// TODO(zoeliu): Default values to be further adjusted based on the collected
// stats.
static const aom_prob default_comp_inter_mode_p[COMP_INTER_MODE_CONTEXTS] = {
41, 119, 187, 225
};
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#if CONFIG_PALETTE
// Tree to code palette size (number of colors in a palette) and the
......@@ -3226,6 +3260,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->comp_bwdref_prob, default_comp_bwdref_p);
#endif // CONFIG_EXT_REFS
av1_copy(fc->single_ref_prob, default_single_ref_p);
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
av1_copy(fc->comp_inter_mode_prob, default_comp_inter_mode_p);
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
av1_copy(fc->tx_size_probs, default_tx_size_prob);
#if CONFIG_VAR_TX
av1_copy(fc->txfm_partition_prob, default_txfm_partition_probs);
......@@ -3246,6 +3283,10 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_EXT_INTER
av1_copy(fc->inter_compound_mode_probs, default_inter_compound_mode_probs);
#if CONFIG_COMPOUND_SINGLEREF
av1_copy(fc->inter_singleref_comp_mode_probs,
default_inter_singleref_comp_mode_probs);
#endif // CONFIG_COMPOUND_SINGLEREF
av1_copy(fc->compound_type_prob, default_compound_type_probs);
av1_copy(fc->interintra_prob, default_interintra_prob);
av1_copy(fc->interintra_mode_prob, default_interintra_mode_prob);
......@@ -3420,6 +3461,7 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
fc->intra_inter_prob[i] = av1_mode_mv_merge_probs(
pre_fc->intra_inter_prob[i], counts->intra_inter[i]);
for (i = 0; i < COMP_INTER_CONTEXTS; i++)
fc->comp_inter_prob[i] = av1_mode_mv_merge_probs(pre_fc->comp_inter_prob[i],
counts->comp_inter[i]);
......@@ -3445,6 +3487,13 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
fc->single_ref_prob[i][j] = av1_mode_mv_merge_probs(
pre_fc->single_ref_prob[i][j], counts->single_ref[i][j]);
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
for (i = 0; i < COMP_INTER_MODE_CONTEXTS; i++)
fc->comp_inter_mode_prob[i] = av1_mode_mv_merge_probs(
pre_fc->comp_inter_mode_prob[i], counts->comp_inter_mode[i]);
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#if CONFIG_REF_MV
for (i = 0; i < NEWMV_MODE_CONTEXTS; ++i)
fc->newmv_prob[i] =
......@@ -3490,6 +3539,13 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
aom_tree_merge_probs(
av1_inter_compound_mode_tree, pre_fc->inter_compound_mode_probs[i],
counts->inter_compound_mode[i], fc->inter_compound_mode_probs[i]);
#if CONFIG_COMPOUND_SINGLEREF
for (i = 0; i < INTER_MODE_CONTEXTS; i++)
aom_tree_merge_probs(av1_inter_singleref_comp_mode_tree,
pre_fc->inter_singleref_comp_mode_probs[i],
counts->inter_singleref_comp_mode[i],
fc->inter_singleref_comp_mode_probs[i]);
#endif // CONFIG_COMPOUND_SINGLEREF
for (i = 0; i < BLOCK_SIZE_GROUPS; ++i) {
if (is_interintra_allowed_bsize_group(i))
fc->interintra_prob[i] = av1_mode_mv_merge_probs(
......
......@@ -34,6 +34,9 @@ extern "C" {
#define INTER_OFFSET(mode) ((mode)-NEARESTMV)
#if CONFIG_EXT_INTER
#if CONFIG_COMPOUND_SINGLEREF
#define INTER_SINGLEREF_COMP_OFFSET(mode) ((mode)-SR_NEAREST_NEARMV)
#endif // CONFIG_COMPOUND_SINGLEREF
#define INTER_COMPOUND_OFFSET(mode) ((mode)-NEAREST_NEARESTMV)
#endif // CONFIG_EXT_INTER
......@@ -193,6 +196,10 @@ typedef struct frame_contexts {
#if CONFIG_EXT_INTER
aom_prob inter_compound_mode_probs[INTER_MODE_CONTEXTS]
[INTER_COMPOUND_MODES - 1];
#if CONFIG_COMPOUND_SINGLEREF
aom_prob inter_singleref_comp_mode_probs[INTER_MODE_CONTEXTS]
[INTER_SINGLEREF_COMP_MODES - 1];
#endif // CONFIG_COMPOUND_SINGLEREF
aom_prob compound_type_prob[BLOCK_SIZES][COMPOUND_TYPES - 1];
aom_prob interintra_prob[BLOCK_SIZE_GROUPS];
aom_prob interintra_mode_prob[BLOCK_SIZE_GROUPS][INTERINTRA_MODES - 1];
......@@ -213,6 +220,9 @@ typedef struct frame_contexts {
#else
aom_prob comp_ref_prob[REF_CONTEXTS][COMP_REFS - 1];
#endif // CONFIG_EXT_REFS
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
aom_prob comp_inter_mode_prob[COMP_INTER_MODE_CONTEXTS];
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
aom_prob tx_size_probs[MAX_TX_DEPTH][TX_SIZE_CONTEXTS][MAX_TX_DEPTH];
#if CONFIG_VAR_TX
aom_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
......@@ -360,6 +370,10 @@ typedef struct FRAME_COUNTS {
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
#if CONFIG_EXT_INTER
unsigned int inter_compound_mode[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
#if CONFIG_COMPOUND_SINGLEREF
unsigned int inter_singleref_comp_mode[INTER_MODE_CONTEXTS]
[INTER_SINGLEREF_COMP_MODES];
#endif // CONFIG_COMPOUND_SINGLEREF
unsigned int interintra[BLOCK_SIZE_GROUPS][2];
unsigned int interintra_mode[BLOCK_SIZE_GROUPS][INTERINTRA_MODES];
unsigned int wedge_interintra[BLOCK_SIZES][2];
......@@ -380,6 +394,9 @@ typedef struct FRAME_COUNTS {
#else
unsigned int comp_ref[REF_CONTEXTS][COMP_REFS - 1][2];
#endif // CONFIG_EXT_REFS
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
unsigned int comp_inter_mode[COMP_INTER_MODE_CONTEXTS][2];
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
// TODO(any): tx_size_totals is only used by the encoder to decide whether
// to use forward updates for the coeff probs, and as such it does not really
// belong into this structure.
......@@ -475,6 +492,10 @@ extern const aom_tree_index
av1_interintra_mode_tree[TREE_SIZE(INTERINTRA_MODES)];
extern const aom_tree_index
av1_inter_compound_mode_tree[TREE_SIZE(INTER_COMPOUND_MODES)];
#if CONFIG_COMPOUND_SINGLEREF
extern const aom_tree_index
av1_inter_singleref_comp_mode_tree[TREE_SIZE(INTER_SINGLEREF_COMP_MODES)];
#endif // CONFIG_COMPOUND_SINGLEREF
extern const aom_tree_index av1_compound_type_tree[TREE_SIZE(COMPOUND_TYPES)];
#endif // CONFIG_EXT_INTER
extern const aom_tree_index av1_partition_tree[TREE_SIZE(PARTITION_TYPES)];
......
......@@ -321,6 +321,15 @@ typedef enum ATTRIBUTE_PACKED {
ZEROMV,
NEWMV,
#if CONFIG_EXT_INTER
#if CONFIG_COMPOUND_SINGLEREF
// Single ref compound modes
SR_NEAREST_NEARMV,
SR_NEAREST_NEWMV,
SR_NEAR_NEWMV,
SR_ZERO_NEWMV,
SR_NEW_NEWMV,
#endif // CONFIG_COMPOUND_SINGLEREF
// Compound ref compound modes
NEAREST_NEARESTMV,
NEAREST_NEARMV,
NEAR_NEARESTMV,
......@@ -401,6 +410,10 @@ typedef enum {
#define INTER_MODES (1 + NEWMV - NEARESTMV)
#if CONFIG_EXT_INTER
#if CONFIG_COMPOUND_SINGLEREF
#define INTER_SINGLEREF_COMP_MODES (1 + SR_NEW_NEWMV - SR_NEAREST_NEARMV)
#endif // CONFIG_COMPOUND_SINGLEREF
#define INTER_COMPOUND_MODES (1 + NEW_NEWMV - NEAREST_NEARESTMV)
#endif // CONFIG_EXT_INTER
......@@ -454,6 +467,9 @@ typedef enum {
#define INTRA_INTER_CONTEXTS 4
#define COMP_INTER_CONTEXTS 5
#define REF_CONTEXTS 5
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#define COMP_INTER_MODE_CONTEXTS 4
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#if CONFIG_VAR_TX
#define TXFM_PARTITION_CONTEXTS ((TX_SIZES - TX_8X8) * 6 - 2)
......
......@@ -64,6 +64,13 @@ static const int mode_2_counter[MB_MODE_COUNT] = {
3, // ZEROMV
1, // NEWMV
#if CONFIG_EXT_INTER
#if CONFIG_COMPOUND_SINGLEREF
0, // SR_NEAREST_NEARMV
1, // SR_NEAREST_NEWMV
1, // SR_NEAR_NEWMV
3, // SR_ZERO_NEWMV
1, // SR_NEW_NEWMV
#endif // CONFIG_COMPOUND_SINGLEREF
0, // NEAREST_NEARESTMV
0, // NEAREST_NEARMV
0, // NEAR_NEARESTMV
......
......@@ -177,6 +177,35 @@ int av1_get_intra_inter_context(const MACROBLOCKD *xd) {
}
}
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
// The compound/single mode info data structure has one element border above and
// to the left of the entries corresponding to real macroblocks.
// The prediction flags in these dummy entries are initialized to 0.
// 0 - single/single
// 1 - single/--, --/single, --/--
// 2 - single/comp, comp/single
// 3 - comp/comp, comp/--, --/comp
int av1_get_inter_mode_context(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 has_above = xd->up_available;
const int has_left = xd->left_available;
if (has_above && has_left) { // both edges available (0/2/3)
const int above_inter_comp_mode = is_inter_compound_mode(above_mbmi->mode);
const int left_inter_comp_mode = is_inter_compound_mode(left_mbmi->mode);
return (above_inter_comp_mode && left_inter_comp_mode)
? 3
: (above_inter_comp_mode || left_inter_comp_mode) * 2;
} else if (has_above || has_left) { // one edge available (1/3)
const MB_MODE_INFO *const edge_mbmi = has_above ? above_mbmi : left_mbmi;
return is_inter_compound_mode(edge_mbmi->mode) ? 3 : 1;
} else { // no edge available (1)
return 1;
}
}
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#if CONFIG_EXT_REFS
#define CHECK_BACKWARD_REFS(ref_frame) \
(((ref_frame) >= BWDREF_FRAME) && ((ref_frame) <= ALTREF_FRAME))
......
......@@ -168,6 +168,15 @@ static INLINE aom_prob av1_get_pred_prob_single_ref_p5(const AV1_COMMON *cm,
}
#endif // CONFIG_EXT_REFS
#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
int av1_get_inter_mode_context(const MACROBLOCKD *xd);
static INLINE aom_prob av1_get_inter_mode_prob(const AV1_COMMON *cm,
const MACROBLOCKD *xd) {
return cm->fc->comp_inter_mode_prob[av1_get_inter_mode_context(xd)];
}
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
// Returns a context number for the given MB prediction signal
// The mode info data structure has a one element border above and to the
// left of the entries corresponding to real blocks.
......
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