Commit 5f8f7a16 authored by Wei-Ting Lin's avatar Wei-Ting Lin Committed by Yue Chen

ncobmc-adapt-weight: update motion mode on the second pass

This patch allows ncobmc-adapt-weight to replace warped-causal,
and also remove transmitting ncobmc_mode_prob in the frame header.

Change-Id: I2713b3abbd28eef8b203637e432eca6a782e3b9a
parent 9d924596
......@@ -1160,7 +1160,7 @@ static const aom_cdf_prob
{ AOM_ICDF(32640), AOM_ICDF(32740), AOM_ICDF(32767), AOM_ICDF(32768), 0 }
};
const aom_tree_index av1_ncobmc_tree[TREE_SIZE(MOTION_MODES)] = {
const aom_tree_index av1_ncobmc_tree[TREE_SIZE(OBMC_FAMILY_MODES)] = {
-SIMPLE_TRANSLATION, 2, -OBMC_CAUSAL, -NCOBMC_ADAPT_WEIGHT
};
......@@ -5328,7 +5328,12 @@ void av1_adapt_inter_frame_probs(AV1_COMMON *cm) {
for (i = 0; i < ADAPT_OVERLAP_BLOCKS; ++i)
aom_tree_merge_probs(av1_ncobmc_mode_tree, pre_fc->ncobmc_mode_prob[i],
counts->ncobmc_mode[i], fc->ncobmc_mode_prob[i]);
#if CONFIG_WARPED_MOTION
for (i = BLOCK_8X8; i < BLOCK_SIZES_ALL; ++i)
aom_tree_merge_probs(av1_ncobmc_tree, pre_fc->ncobmc_prob[i],
counts->ncobmc[i], fc->ncobmc_prob[i]);
#endif
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
for (i = BLOCK_8X8; i < BLOCK_SIZES_ALL; ++i)
fc->obmc_prob[i] =
......
......@@ -589,9 +589,12 @@ extern const aom_tree_index av1_ext_tx_tree[TREE_SIZE(TX_TYPES)];
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
extern const aom_tree_index av1_motion_mode_tree[TREE_SIZE(MOTION_MODES)];
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
#if CONFIG_NCOBMC_ADAPT_WEIGHT
extern const aom_tree_index av1_ncobmc_mode_tree[TREE_SIZE(MAX_NCOBMC_MODES)];
#endif
#if CONFIG_WARPED_MOTION
extern const aom_tree_index av1_ncobmc_tree[TREE_SIZE(OBMC_FAMILY_MODES)];
#endif // CONFIG_WARPED_MOTION
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
#if CONFIG_LOOP_RESTORATION
#define RESTORE_NONE_SGRPROJ_PROB 64
#define RESTORE_NONE_BILATERAL_PROB 16
......
......@@ -4187,7 +4187,7 @@ void av1_get_ori_blk_pred(const AV1_COMMON *cm, MACROBLOCKD *xd, int bsize,
for (i = 0; i < MAX_MB_PLANE; ++i) {
const struct macroblockd_plane *pd = &xd->plane[i];
build_inter_predictors(cm, xd, i, mi, 0, 0, bw >> pd->subsampling_x,
build_inter_predictors(cm, xd, i, mi, 1, 0, bw >> pd->subsampling_x,
bh >> pd->subsampling_y, 0, 0,
bw >> pd->subsampling_x, bh >> pd->subsampling_y,
#if CONFIG_SUPERTX && CONFIG_EXT_INTER
......
......@@ -4958,13 +4958,6 @@ static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
#endif // CONFIG_INTERINTRA
#endif // CONFIG_EXT_INTER
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
for (i = 0; i < ADAPT_OVERLAP_BLOCKS; ++i) {
for (int j = 0; j < MAX_NCOBMC_MODES - 1; ++j)
av1_diff_update_prob(&r, &fc->ncobmc_mode_prob[i][j], ACCT_STR);
}
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
#if !CONFIG_NEW_MULTISYMBOL
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
av1_diff_update_prob(&r, &fc->intra_inter_prob[i], ACCT_STR);
......
......@@ -95,11 +95,6 @@ static struct av1_token interintra_mode_encodings[INTERINTRA_MODES];
static struct av1_token compound_type_encodings[COMPOUND_TYPES];
#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_NCOBMC_ADAPT_WEIGHT
static struct av1_token ncobmc_mode_encodings[MAX_NCOBMC_MODES];
#endif
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_LOOP_RESTORATION
static struct av1_token switchable_restore_encodings[RESTORE_SWITCHABLE_TYPES];
static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm,
......@@ -146,11 +141,6 @@ void av1_encode_token_init(void) {
av1_tokens_from_tree(compound_type_encodings, av1_compound_type_tree);
#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_NCOBMC_ADAPT_WEIGHT
av1_tokens_from_tree(ncobmc_mode_encodings, av1_ncobmc_mode_tree);
#endif
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_LOOP_RESTORATION
av1_tokens_from_tree(switchable_restore_encodings,
av1_switchable_restore_tree);
......@@ -311,23 +301,6 @@ static void encode_unsigned_max(struct aom_write_bit_buffer *wb, int data,
aom_wb_write_literal(wb, data, get_unsigned_bits(max));
}
#if CONFIG_NCOBMC_ADAPT_WEIGHT
static void prob_diff_update(const aom_tree_index *tree,
aom_prob probs[/*n - 1*/],
const unsigned int counts[/* n */], int n,
int probwt, aom_writer *w) {
int i;
unsigned int branch_ct[32][2];
// Assuming max number of probabilities <= 32
assert(n <= 32);
av1_tree_probs_from_distribution(tree, branch_ct, counts);
for (i = 0; i < n - 1; ++i)
av1_cond_prob_diff_update(w, &probs[i], branch_ct[i], probwt);
}
#endif
#if CONFIG_VAR_TX
static void write_tx_size_vartx(const AV1_COMMON *cm, MACROBLOCKD *xd,
const MB_MODE_INFO *mbmi, TX_SIZE tx_size,
......@@ -4687,16 +4660,6 @@ static uint32_t write_compressed_header(AV1_COMP *cpi, uint8_t *data) {
#endif // CONFIG_INTERINTRA
#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_NCOBMC_ADAPT_WEIGHT
for (i = ADAPT_OVERLAP_BLOCK_8X8; i < ADAPT_OVERLAP_BLOCKS; ++i) {
prob_diff_update(av1_ncobmc_mode_tree, fc->ncobmc_mode_prob[i],
counts->ncobmc_mode[i], MAX_NCOBMC_MODES, probwt,
header_bc);
}
#endif
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if !CONFIG_NEW_MULTISYMBOL
for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
av1_cond_prob_diff_update(header_bc, &fc->intra_inter_prob[i],
......
......@@ -2150,8 +2150,7 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
#if CONFIG_NCOBMC_ADAPT_WEIGHT
if (dry_run == OUTPUT_ENABLED && !frame_is_intra_only(&cpi->common)) {
// we also need to handle inter-intra
if (motion_allowed == NCOBMC_ADAPT_WEIGHT && is_inter_block(mbmi)) {
if (motion_allowed >= NCOBMC_ADAPT_WEIGHT && is_inter_block(mbmi)) {
get_ncobmc_intrpl_pred(cpi, td, mi_row, mi_col, bsize);
av1_check_ncobmc_adapt_weight_rd(cpi, x, mi_row, mi_col);
}
......
......@@ -12671,6 +12671,16 @@ int64_t get_prediction_rd_cost(const struct AV1_COMP *cpi, struct macroblock *x,
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
BLOCK_SIZE bsize = mbmi->sb_type;
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_WARPED_MOTION
const MOTION_MODE motion_allowed = motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION
0, xd->global_motion,
#endif // CONFIG_GLOBAL_MOTION
#if CONFIG_WARPED_MOTION
xd,
#endif
xd->mi[0]);
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_WARPED_MOTION
RD_STATS rd_stats_y, rd_stats_uv;
int rate_skip0 = av1_cost_bit(av1_get_skip_prob(cm, xd), 0);
int rate_skip1 = av1_cost_bit(av1_get_skip_prob(cm, xd), 1);
......@@ -12759,9 +12769,22 @@ int64_t get_prediction_rd_cost(const struct AV1_COMP *cpi, struct macroblock *x,
this_rd = RDCOST(x->rdmult, (rd_stats_y.rate + rd_stats_uv.rate),
(rd_stats_y.dist + rd_stats_uv.dist));
this_rd +=
RDCOST(x->rdmult, x->motion_mode_cost[bsize][mbmi->motion_mode], 0);
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_WARPED_MOTION
if (motion_allowed == NCOBMC_ADAPT_WEIGHT) {
assert(mbmi->motion_mode <= NCOBMC_ADAPT_WEIGHT);
this_rd +=
RDCOST(x->rdmult, x->motion_mode_cost2[bsize][mbmi->motion_mode], 0);
} else if (motion_allowed == OBMC_CAUSAL) {
assert(mbmi->motion_mode <= OBMC_CAUSAL);
this_rd +=
RDCOST(x->rdmult, x->motion_mode_cost1[bsize][mbmi->motion_mode], 0);
} else {
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_WARPED_MOTION
this_rd +=
RDCOST(x->rdmult, x->motion_mode_cost[bsize][mbmi->motion_mode], 0);
#if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_WARPED_MOTION
}
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_WARPED_MOTION
return this_rd;
}
......@@ -12776,14 +12799,26 @@ void av1_check_ncobmc_adapt_weight_rd(const struct AV1_COMP *cpi,
const int n4 = bsize_to_num_blk(bsize);
uint8_t st_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
uint8_t obmc_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
uint8_t ncobmc_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE * 8];
#endif
MB_MODE_INFO st_mbmi, obmc_mbmi;
int skip_blk, st_skip, obmc_skip;
MB_MODE_INFO st_mbmi, obmc_mbmi, ncobmc_mbmi;
int st_skip, obmc_skip, ncobmc_skip;
int64_t st_rd, obmc_rd, ncobmc_rd;
#if CONFIG_WARPED_MOTION
const AV1_COMMON *const cm = &cpi->common;
const int is_warp_motion = mbmi->motion_mode == WARPED_CAUSAL;
const int rs = RDCOST(x->rdmult, av1_get_switchable_rate(cm, x, xd), 0);
MB_MODE_INFO warp_mbmi;
int64_t warp_rd;
int warp_skip;
#endif
// Recompute the rd for the motion mode decided in rd loop
mbmi->motion_mode = SIMPLE_TRANSLATION;
st_rd = get_prediction_rd_cost(cpi, x, mi_row, mi_col, &st_skip, &st_mbmi);
#if CONFIG_WARPED_MOTION
st_rd += rs;
#endif
#if CONFIG_VAR_TX
memcpy(st_blk_skip, x->blk_skip[0], sizeof(st_blk_skip[0]) * n4);
#endif
......@@ -12791,13 +12826,20 @@ void av1_check_ncobmc_adapt_weight_rd(const struct AV1_COMP *cpi,
mbmi->motion_mode = OBMC_CAUSAL;
obmc_rd =
get_prediction_rd_cost(cpi, x, mi_row, mi_col, &obmc_skip, &obmc_mbmi);
#if CONFIG_WARPED_MOTION
obmc_rd += rs;
#endif
#if CONFIG_VAR_TX
memcpy(obmc_blk_skip, x->blk_skip[0], sizeof(obmc_blk_skip[0]) * n4);
#endif
// Compute the rd cost for ncobmc adaptive weight
mbmi->motion_mode = NCOBMC_ADAPT_WEIGHT;
ncobmc_rd = get_prediction_rd_cost(cpi, x, mi_row, mi_col, &skip_blk, NULL);
ncobmc_rd = get_prediction_rd_cost(cpi, x, mi_row, mi_col, &ncobmc_skip,
&ncobmc_mbmi);
#if CONFIG_WARPED_MOTION
ncobmc_rd += rs;
#endif
// Calculate the ncobmc mode costs
{
ADAPT_OVERLAP_BLOCK aob = adapt_overlap_block_lookup[bsize];
......@@ -12807,21 +12849,54 @@ void av1_check_ncobmc_adapt_weight_rd(const struct AV1_COMP *cpi,
ncobmc_rd +=
RDCOST(x->rdmult, x->ncobmc_mode_cost[aob][mbmi->ncobmc_mode[1]], 0);
}
#if CONFIG_VAR_TX
memcpy(ncobmc_blk_skip, x->blk_skip[0], sizeof(ncobmc_blk_skip[0]) * n4);
#endif
#if CONFIG_WARPED_MOTION
if (is_warp_motion) {
mbmi->motion_mode = WARPED_CAUSAL;
warp_rd =
get_prediction_rd_cost(cpi, x, mi_row, mi_col, &warp_skip, &warp_mbmi);
} else {
warp_rd = INT64_MAX;
}
#endif
#if CONFIG_WARPED_MOTION
if (AOMMIN(ncobmc_rd, warp_rd) < AOMMIN(st_rd, obmc_rd)) {
if (ncobmc_rd < warp_rd) {
x->skip = ncobmc_skip;
*mbmi = ncobmc_mbmi;
#if CONFIG_VAR_TX
memcpy(x->blk_skip[0], ncobmc_blk_skip, sizeof(ncobmc_blk_skip[0]) * n4);
#endif
} else {
x->skip = warp_skip;
*mbmi = warp_mbmi;
}
#else
if (ncobmc_rd < AOMMIN(st_rd, obmc_rd)) {
x->skip = skip_blk;
} else if (obmc_rd < st_rd) {
*mbmi = obmc_mbmi;
x->skip = obmc_skip;
x->skip = ncobmc_skip;
*mbmi = ncobmc_mbmi;
#if CONFIG_VAR_TX
memcpy(x->blk_skip[0], obmc_blk_skip, sizeof(obmc_blk_skip[0]) * n4);
memcpy(x->blk_skip[0], ncobmc_blk_skip, sizeof(ncobmc_blk_skip[0]) * n4);
#endif
#endif // CONFIG_WARPED_MOTION
} else {
*mbmi = st_mbmi;
x->skip = st_skip;
if (obmc_rd < st_rd) {
*mbmi = obmc_mbmi;
x->skip = obmc_skip;
#if CONFIG_VAR_TX
memcpy(x->blk_skip[0], st_blk_skip, sizeof(st_blk_skip[0]) * n4);
memcpy(x->blk_skip[0], obmc_blk_skip, sizeof(obmc_blk_skip[0]) * n4);
#endif
} else {
*mbmi = st_mbmi;
x->skip = st_skip;
#if CONFIG_VAR_TX
memcpy(x->blk_skip[0], st_blk_skip, sizeof(st_blk_skip[0]) * n4);
#endif
}
}
}
......
......@@ -152,7 +152,6 @@ int64_t get_prediction_rd_cost(const struct AV1_COMP *cpi, struct macroblock *x,
void av1_check_ncobmc_adapt_weight_rd(const struct AV1_COMP *cpi,
struct macroblock *x, int mi_row,
int mi_col);
int get_ncobmc_mode(const AV1_COMP *const cpi, MACROBLOCK *const x,
MACROBLOCKD *xd, int mi_row, int mi_col, int bsize);
......
......@@ -557,7 +557,19 @@ int main(int argc, const char **argv) {
"static const aom_cdf_prob\n"
"default_ncobmc_mode_cdf[ADAPT_OVERLAP_BLOCKS]"
"[CDF_SIZE(MAX_NCOBMC_MODES)]");
#if CONFIG_WARPED_MOTION
cts_each_dim[0] = BLOCK_SIZES_ALL;
cts_each_dim[1] = OBMC_FAMILY_MODES;
optimize_entropy_table(
&fc.ncobmc[0][0], probsfile, 2, cts_each_dim, av1_ncobmc_tree, 0,
"static const aom_prob default_ncobmc_prob[BLOCK_SIZES_ALL]"
"[OBMC_FAMILY_MODES - 1]");
optimize_cdf_table(&fc.ncobmc[0][0], probsfile, 2, cts_each_dim,
"static const aom_cdf_prob\n"
"default_ncobmc_cdf[BLOCK_SIZES_ALL]"
"[CDF_SIZE(OBMC_FAMILY_MODES)]");
#endif
#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
/* Intra/inter flag */
......
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