Commit 131bbed1 authored by Yue Chen's avatar Yue Chen

Add bitstream syntax and entropy coding of motion mode

Change-Id: I5d30e8f07373482d7d7a4aff5a2026e4314e32b1
parent d2202a10
......@@ -94,6 +94,9 @@ typedef struct {
// Only for INTER blocks
InterpFilter interp_filter;
MV_REFERENCE_FRAME ref_frame[2];
#if CONFIG_MOTION_VAR
MOTION_MODE motion_mode;
#endif // CONFIG_MOTION_VAR
TX_TYPE tx_type;
#if CONFIG_REF_MV
......@@ -297,6 +300,20 @@ static INLINE void reset_skip_context(MACROBLOCKD *xd, BLOCK_SIZE bsize) {
}
}
#if CONFIG_MOTION_VAR
static INLINE int is_motion_variation_allowed_bsize(BLOCK_SIZE bsize) {
return (bsize >= BLOCK_8X8);
}
static INLINE int is_motion_variation_allowed(const MB_MODE_INFO *mbmi) {
return is_motion_variation_allowed_bsize(mbmi->sb_type);
}
static INLINE int is_neighbor_overlappable(const MB_MODE_INFO *mbmi) {
return (is_inter_block(mbmi));
}
#endif // CONFIG_MOTION_VAR
typedef void (*foreach_transformed_block_visitor)(int plane, int block,
int blk_row, int blk_col,
BLOCK_SIZE plane_bsize,
......
......@@ -237,6 +237,23 @@ const aom_tree_index av1_inter_mode_tree[TREE_SIZE(INTER_MODES)] = {
-INTER_OFFSET(NEWMV)
};
#if CONFIG_MOTION_VAR
const aom_tree_index av1_motion_mode_tree[TREE_SIZE(MOTION_MODES)] = {
-SIMPLE_TRANSLATION, -OBMC_CAUSAL
};
// clang-format off
static const aom_prob
default_motion_mode_prob[BLOCK_SIZES][MOTION_MODES - 1] = {
{ 255 },
{ 255 }, { 255 }, { 151 },
{ 153 }, { 144 }, { 178 },
{ 165 }, { 160 }, { 207 },
{ 195 }, { 168 }, { 244 },
};
// clang-format on
#endif // CONFIG_MOTION_VAR
const aom_tree_index av1_partition_tree[TREE_SIZE(PARTITION_TYPES)] = {
-PARTITION_NONE, 2, -PARTITION_HORZ, 4, -PARTITION_VERT, -PARTITION_SPLIT
};
......@@ -343,6 +360,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->drl_prob, default_drl_prob);
#endif
av1_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_MOTION_VAR
av1_copy(fc->motion_mode_prob, default_motion_mode_prob);
#endif // CONFIG_MOTION_VAR
#if CONFIG_MISC_FIXES
av1_copy(fc->seg.tree_probs, default_seg_probs.tree_probs);
av1_copy(fc->seg.pred_probs, default_seg_probs.pred_probs);
......@@ -406,6 +426,11 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
aom_tree_merge_probs(av1_inter_mode_tree, pre_fc->inter_mode_probs[i],
counts->inter_mode[i], fc->inter_mode_probs[i]);
#endif
#if CONFIG_MOTION_VAR
for (i = 0; i < BLOCK_SIZES; i++)
aom_tree_merge_probs(av1_motion_mode_tree, pre_fc->motion_mode_prob[i],
counts->motion_mode[i], fc->motion_mode_prob[i]);
#endif // CONFIG_MOTION_VAR
for (i = 0; i < BLOCK_SIZE_GROUPS; i++)
aom_tree_merge_probs(av1_intra_mode_tree, pre_fc->y_mode_prob[i],
......
......@@ -66,6 +66,9 @@ typedef struct frame_contexts {
#endif
aom_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1];
#if CONFIG_MOTION_VAR
aom_prob motion_mode_prob[BLOCK_SIZES][MOTION_MODES - 1];
#endif // CONFIG_MOTION_VAR
aom_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
aom_prob comp_inter_prob[COMP_INTER_CONTEXTS];
aom_prob single_ref_prob[REF_CONTEXTS][2];
......@@ -104,6 +107,9 @@ typedef struct FRAME_COUNTS {
#endif
unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
#if CONFIG_MOTION_VAR
unsigned int motion_mode[BLOCK_SIZES][MOTION_MODES];
#endif // CONFIG_MOTION_VAR
unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
unsigned int single_ref[REF_CONTEXTS][2][2];
......@@ -127,6 +133,9 @@ extern const aom_prob
extern const aom_tree_index av1_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
extern const aom_tree_index av1_inter_mode_tree[TREE_SIZE(INTER_MODES)];
#if CONFIG_MOTION_VAR
extern const aom_tree_index av1_motion_mode_tree[TREE_SIZE(MOTION_MODES)];
#endif // CONFIG_MOTION_VAR
extern const aom_tree_index av1_partition_tree[TREE_SIZE(PARTITION_TYPES)];
extern const aom_tree_index
av1_switchable_interp_tree[TREE_SIZE(SWITCHABLE_FILTERS)];
......
......@@ -131,6 +131,14 @@ typedef uint8_t PREDICTION_MODE;
#define INTER_MODES (1 + NEWMV - NEARESTMV)
#if CONFIG_MOTION_VAR
typedef enum {
SIMPLE_TRANSLATION = 0, // regular block based motion compensation
OBMC_CAUSAL = 1, // 2-sided overlapped block prediction
MOTION_MODES = 2
} MOTION_MODE;
#endif // CONFIG_MOTION_VAR
#define SKIP_CONTEXTS 3
#if CONFIG_REF_MV
......
......@@ -380,6 +380,12 @@ void av1_accumulate_frame_counts(AV1_COMMON *cm, FRAME_COUNTS *counts,
for (j = 0; j < INTER_MODES; j++)
cm->counts.inter_mode[i][j] += counts->inter_mode[i][j];
#if CONFIG_MOTION_VAR
for (i = 0; i < BLOCK_SIZES; ++i)
for (j = 0; j < MOTION_MODES; ++j)
cm->counts.motion_mode[i][j] += counts->motion_mode[i][j];
#endif // CONFIG_MOTION_VAR
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
for (j = 0; j < 2; j++)
cm->counts.intra_inter[i][j] += counts->intra_inter[i][j];
......
......@@ -1900,6 +1900,14 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
#endif
read_inter_mode_probs(fc, &r);
#if CONFIG_MOTION_VAR
for (j = 0; j < BLOCK_SIZES; ++j)
if (is_motion_variation_allowed_bsize(j)) {
for (i = 0; i < MOTION_MODES - 1; ++i)
av1_diff_update_prob(&r, &fc->motion_mode_prob[j][i]);
}
#endif // CONFIG_MOTION_VAR
if (cm->interp_filter == SWITCHABLE) read_switchable_interp_probs(fc, &r);
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
......@@ -1957,6 +1965,10 @@ static void debug_check_frame_counts(const AV1_COMMON *const cm) {
sizeof(cm->counts.switchable_interp)));
assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode,
sizeof(cm->counts.inter_mode)));
#if CONFIG_MOTION_VAR
assert(!memcmp(cm->counts.motion_mode, zero_counts.motion_mode,
sizeof(cm->counts.motion_mode)));
#endif // CONFIG_MOTION_VAR
assert(!memcmp(cm->counts.intra_inter, zero_counts.intra_inter,
sizeof(cm->counts.intra_inter)));
assert(!memcmp(cm->counts.comp_inter, zero_counts.comp_inter,
......
......@@ -144,6 +144,23 @@ static void read_drl_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
}
#endif
#if CONFIG_MOTION_VAR
static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
MB_MODE_INFO *mbmi, aom_reader *r) {
if (is_motion_variation_allowed(mbmi)) {
int motion_mode;
FRAME_COUNTS *counts = xd->counts;
motion_mode = aom_read_tree(r, av1_motion_mode_tree,
cm->fc->motion_mode_prob[mbmi->sb_type]);
if (counts) ++counts->motion_mode[mbmi->sb_type][motion_mode];
return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
} else {
return SIMPLE_TRANSLATION;
}
}
#endif // CONFIG_MOTION_VAR
static int read_segment_id(aom_reader *r,
const struct segmentation_probs *segp) {
return aom_read_tree(r, av1_segment_tree, segp->tree_probs);
......@@ -695,7 +712,7 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
mbmi->mode = ZEROMV;
if (bsize < BLOCK_8X8) {
aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
"Invalid usage of segement feature on small blocks");
"Invalid usage of segment feature on small blocks");
return;
}
} else {
......@@ -819,6 +836,9 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
xd->corrupted |= !assign_mv(cm, xd, mbmi->mode, 0, mbmi->mv, nearestmv,
nearestmv, nearmv, is_compound, allow_hp, r);
}
#if CONFIG_MOTION_VAR
mbmi->motion_mode = read_motion_mode(cm, xd, mbmi, r);
#endif // CONFIG_MOTION_VAR
}
static void read_inter_frame_mode_info(AV1Decoder *const pbi,
......
......@@ -48,6 +48,9 @@ static struct av1_token partition_encodings[PARTITION_TYPES];
#if !CONFIG_REF_MV
static struct av1_token inter_mode_encodings[INTER_MODES];
#endif
#if CONFIG_MOTION_VAR
static struct av1_token motion_mode_encodings[MOTION_MODES];
#endif // CONFIG_MOTION_VAR
static struct av1_token ext_tx_encodings[TX_TYPES];
void av1_encode_token_init() {
......@@ -57,6 +60,9 @@ void av1_encode_token_init() {
#if !CONFIG_REF_MV
av1_tokens_from_tree(inter_mode_encodings, av1_inter_mode_tree);
#endif
#if CONFIG_MOTION_VAR
av1_tokens_from_tree(motion_mode_encodings, av1_motion_mode_tree);
#endif // CONFIG_MOTION_VAR
av1_tokens_from_tree(ext_tx_encodings, av1_ext_tx_tree);
}
......@@ -142,6 +148,16 @@ static void write_drl_idx(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi,
}
#endif
#if CONFIG_MOTION_VAR
static void write_motion_mode(const AV1_COMMON *cm, const MB_MODE_INFO *mbmi,
aom_writer *w) {
if (is_motion_variation_allowed(mbmi))
av1_write_token(w, av1_motion_mode_tree,
cm->fc->motion_mode_prob[mbmi->sb_type],
&motion_mode_encodings[mbmi->motion_mode]);
}
#endif // CONFIG_MOTION_VAR
static void encode_unsigned_max(struct aom_write_bit_buffer *wb, int data,
int max) {
aom_wb_write_literal(wb, data, get_unsigned_bits(max));
......@@ -541,6 +557,9 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
}
}
}
#if CONFIG_MOTION_VAR
write_motion_mode(cm, mbmi, w);
#endif // CONFIG_MOTION_VAR
}
if (mbmi->tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
......@@ -1528,6 +1547,12 @@ static size_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) {
prob_diff_update(av1_inter_mode_tree, cm->fc->inter_mode_probs[i],
counts->inter_mode[i], INTER_MODES, &header_bc);
#endif
#if CONFIG_MOTION_VAR
for (i = 0; i < BLOCK_SIZES; ++i)
if (is_motion_variation_allowed_bsize(i))
prob_diff_update(av1_motion_mode_tree, cm->fc->motion_mode_prob[i],
counts->motion_mode[i], MOTION_MODES, &header_bc);
#endif // CONFIG_MOTION_VAR
if (cm->interp_filter == SWITCHABLE)
update_switchable_interp_probs(cm, &header_bc, counts);
......
......@@ -1020,6 +1020,11 @@ static void update_state(AV1_COMP *cpi, ThreadData *td, PICK_MODE_CONTEXT *ctx,
const int ctx = av1_get_pred_context_switchable_interp(xd);
++td->counts->switchable_interp[ctx][mbmi->interp_filter];
}
#if CONFIG_MOTION_VAR
if (is_motion_variation_allowed(mbmi))
++td->counts->motion_mode[bsize][mbmi->motion_mode];
#endif // CONFIG_MOTION_VAR
}
rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
......
......@@ -3214,6 +3214,9 @@ void av1_rd_pick_inter_mode_sb(AV1_COMP *cpi, TileDataEnc *tile_data,
mbmi->interp_filter =
cm->interp_filter == SWITCHABLE ? EIGHTTAP : cm->interp_filter;
mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
#if CONFIG_MOTION_VAR
mbmi->motion_mode = SIMPLE_TRANSLATION;
#endif // CONFIG_MOTION_VAR
x->skip = 0;
set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
......@@ -3779,6 +3782,9 @@ void av1_rd_pick_inter_mode_sb_seg_skip(AV1_COMP *cpi, TileDataEnc *tile_data,
mbmi->ref_frame[0] = LAST_FRAME;
mbmi->ref_frame[1] = NONE;
mbmi->mv[0].as_int = 0;
#if CONFIG_MOTION_VAR
mbmi->motion_mode = SIMPLE_TRANSLATION;
#endif // CONFIG_MOTION_VAR
x->skip = 1;
#if CONFIG_REF_MV
......@@ -4024,6 +4030,9 @@ void av1_rd_pick_inter_mode_sub8x8(AV1_COMP *cpi, TileDataEnc *tile_data,
// them for this frame.
mbmi->interp_filter =
cm->interp_filter == SWITCHABLE ? EIGHTTAP : cm->interp_filter;
#if CONFIG_MOTION_VAR
mbmi->motion_mode = SIMPLE_TRANSLATION;
#endif // CONFIG_MOTION_VAR
x->skip = 0;
set_ref_ptrs(cm, xd, ref_frame, second_ref_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