CWG-F142: Extend the MV range from 15bits to 17bits
1) MV range is extended to 17bits;
2) Encoder control flag to enable high or low motion
Motion search window would be adjusted based on high or low motion control flag
STATS_CHANGED
diff --git a/aom/aom_encoder.h b/aom/aom_encoder.h
index 582b7f3..44c44c0 100644
--- a/aom/aom_encoder.h
+++ b/aom/aom_encoder.h
@@ -321,6 +321,12 @@
*/
unsigned int enable_mv_traj;
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ /*!\brief Enable a large motion search window (Encoder only)
+ *
+ */
+ unsigned int enable_high_motion;
+#endif // CONFIG_MV_RANGE_EXTENSION
/*!\brief enable block adaptive weighted prediction
*
*/
diff --git a/apps/aomenc.c b/apps/aomenc.c
index 5a1049f..7b5f613 100644
--- a/apps/aomenc.c
+++ b/apps/aomenc.c
@@ -448,6 +448,9 @@
#if CONFIG_TMVP_SIMPLIFICATIONS_F085
&g_av1_codec_arg_defs.enable_mv_traj,
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ &g_av1_codec_arg_defs.enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
&g_av1_codec_arg_defs.enable_bawp,
#if CONFIG_ENABLE_MHCCP
&g_av1_codec_arg_defs.enable_mhccp,
@@ -663,6 +666,12 @@
config->enable_extended_sdp = 1;
config->enable_mrls = 1;
config->enable_tip = 1;
+#if CONFIG_TMVP_SIMPLIFICATIONS_F085
+ config->enable_mv_traj = 1;
+#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ config->enable_high_motion = 0;
+#endif // CONFIG_MV_RANGE_EXTENSION
config->enable_bawp = 1;
config->enable_cwp = 1;
#if CONFIG_D071_IMP_MSK_BLD
@@ -1626,6 +1635,10 @@
fprintf(stdout, " : MV traj (%d)\n",
encoder_cfg->enable_mv_traj);
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ fprintf(stdout, " : HighMotion (%d)\n",
+ encoder_cfg->enable_high_motion);
+#endif // CONFIG_MV_RANGE_EXTENSION
fprintf(stdout, " : BAWP (%d)\n",
encoder_cfg->enable_bawp);
fprintf(stdout, " : CWP (%d)\n",
diff --git a/av1/arg_defs.c b/av1/arg_defs.c
index accc4f4..6d61c91 100644
--- a/av1/arg_defs.c
+++ b/av1/arg_defs.c
@@ -433,7 +433,11 @@
"(0: disable MV traj tracking, "
" 1: enable MV traj tracking (default))"),
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
-
+#if CONFIG_MV_RANGE_EXTENSION
+ .enable_high_motion = ARG_DEF(NULL, "enable-high-motion", 1,
+ "Enable a large motion search window"
+ "(0: false (default), 1: true"),
+#endif // CONFIG_MV_RANGE_EXTENSION
.enable_bawp = ARG_DEF(NULL, "enable-bawp", 1,
"Enable block adaptive weighted prediction (BAWP)"
"(0: false, 1: true (default))"),
diff --git a/av1/arg_defs.h b/av1/arg_defs.h
index d68b26b..0dddfd2 100644
--- a/av1/arg_defs.h
+++ b/av1/arg_defs.h
@@ -162,6 +162,9 @@
#if CONFIG_TMVP_SIMPLIFICATIONS_F085
arg_def_t enable_mv_traj;
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ arg_def_t enable_high_motion;
+#endif // CONFIG_MV_RANGE_EXTENSION
arg_def_t enable_bawp;
arg_def_t enable_cwp;
#if CONFIG_D071_IMP_MSK_BLD
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 617e588..59962de 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -131,8 +131,11 @@
#if CONFIG_TMVP_SIMPLIFICATIONS_F085
int enable_mv_traj; // enable MV trajectory tracking
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
- int enable_bawp; // enable block adaptive weighted prediction
- int enable_cwp; // enable compound weighted prediction
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion; // Enable a large motion search window
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int enable_bawp; // enable block adaptive weighted prediction
+ int enable_cwp; // enable compound weighted prediction
#if CONFIG_D071_IMP_MSK_BLD
int enable_imp_msk_bld;
#endif // CONFIG_D071_IMP_MSK_BLD
@@ -489,6 +492,9 @@
#if CONFIG_TMVP_SIMPLIFICATIONS_F085
1, // enable mv trajectory tracking
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ 0, // enable a large motion search window
+#endif // CONFIG_MV_RANGE_EXTENSION
1, // enable block adaptive weighted prediction (BAWP)
1, // enable compound weighted prediction (CWP)
#if CONFIG_D071_IMP_MSK_BLD
@@ -1022,6 +1028,9 @@
#if CONFIG_TMVP_SIMPLIFICATIONS_F085
cfg->enable_mv_traj = extra_cfg->enable_mv_traj;
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ cfg->enable_high_motion = extra_cfg->enable_high_motion;
+#endif // CONFIG_MV_RANGE_EXTENSION
cfg->enable_bawp = extra_cfg->enable_bawp;
cfg->enable_cwp = extra_cfg->enable_cwp;
#if CONFIG_D071_IMP_MSK_BLD
@@ -1165,6 +1174,9 @@
#if CONFIG_TMVP_SIMPLIFICATIONS_F085
extra_cfg->enable_mv_traj = cfg->enable_mv_traj;
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ extra_cfg->enable_high_motion = cfg->enable_high_motion;
+#endif // CONFIG_MV_RANGE_EXTENSION
extra_cfg->enable_bawp = cfg->enable_bawp;
extra_cfg->enable_cwp = cfg->enable_cwp;
#if CONFIG_D071_IMP_MSK_BLD
@@ -1584,6 +1596,10 @@
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
}
+#if CONFIG_MV_RANGE_EXTENSION
+ tool_cfg->enable_high_motion = extra_cfg->enable_high_motion;
+#endif // CONFIG_MV_RANGE_EXTENSION
+
#if CONFIG_FRAME_HEADER_SIGNAL_OPT
if (extra_cfg->enable_order_hint) {
tool_cfg->enable_opfl_refine = extra_cfg->enable_opfl_refine;
@@ -4195,6 +4211,11 @@
err_string)) {
extra_cfg.enable_mv_traj = arg_parse_int_helper(&arg, err_string);
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ } else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_high_motion,
+ argv, err_string)) {
+ extra_cfg.enable_high_motion = arg_parse_int_helper(&arg, err_string);
+#endif // CONFIG_MV_RANGE_EXTENSION
} else if (arg_match_helper(&arg, &g_av1_codec_arg_defs.enable_bawp, argv,
err_string)) {
extra_cfg.enable_bawp = arg_parse_int_helper(&arg, err_string);
@@ -4782,6 +4803,9 @@
#if CONFIG_TMVP_SIMPLIFICATIONS_F085
1, // MV traj
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ 0, // enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
1, 1,
#if CONFIG_D071_IMP_MSK_BLD
1,
diff --git a/av1/common/entropy.c b/av1/common/entropy.c
index 1e08b78..659797d 100644
--- a/av1/common/entropy.c
+++ b/av1/common/entropy.c
@@ -121,12 +121,30 @@
int num_mv_class_0, num_mv_class_1;
split_num_shell_class(num_mv_class, &num_mv_class_0, &num_mv_class_1);
RESET_CDF_COUNTER(nmv->joint_shell_class_cdf_0[prec], num_mv_class_0);
- RESET_CDF_COUNTER(nmv->joint_shell_class_cdf_1[prec], num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ RESET_CDF_COUNTER(nmv->joint_shell_class_cdf_1[prec], num_mv_class_1 - 1);
+ RESET_CDF_COUNTER(nmv->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ RESET_CDF_COUNTER(nmv->joint_shell_class_cdf_1[prec], num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
for (int prec = 0; prec < NUM_MV_PRECISIONS; prec++) {
int num_mv_class = get_default_num_shell_class(prec);
- RESET_CDF_COUNTER(nmv->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ RESET_CDF_COUNTER(nmv->joint_shell_class_cdf[prec], num_mv_class - 1);
+ RESET_CDF_COUNTER(nmv->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ RESET_CDF_COUNTER(nmv->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#endif // CONFIG_REDUCE_SYMBOL_SIZE
RESET_CDF_COUNTER(nmv->shell_offset_low_class_cdf, 2);
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 8944c9d..ac17f6e 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -7475,15 +7475,39 @@
CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_class_cdf_0[prec],
nmv_tr->joint_shell_class_cdf_0[prec],
num_mv_class_0);
- CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
- nmv_tr->joint_shell_class_cdf_1[prec],
- num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
+ nmv_tr->joint_shell_class_cdf_1[prec],
+ num_mv_class_1 - 1);
+ CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_last_two_classes_cdf,
+ nmv_tr->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
+ nmv_tr->joint_shell_class_cdf_1[prec],
+ num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
for (int prec = 0; prec < NUM_MV_PRECISIONS; prec++) {
int num_mv_class = get_default_num_shell_class(prec);
- CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
- nmv_tr->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
+ nmv_tr->joint_shell_class_cdf[prec],
+ num_mv_class - 1);
+ CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_last_two_classes_cdf,
+ nmv_tr->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ CUMULATIVE_AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
+ nmv_tr->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#endif // CONFIG_REDUCE_SYMBOL_SIZE
CUMULATIVE_AVERAGE_CDF(nmv_left->shell_offset_low_class_cdf,
@@ -7973,12 +7997,30 @@
int num_mv_class_0, num_mv_class_1;
split_num_shell_class(num_mv_class, &num_mv_class_0, &num_mv_class_1);
SHIFT_CDF(nmv_ptr->joint_shell_class_cdf_0[prec], num_mv_class_0);
- SHIFT_CDF(nmv_ptr->joint_shell_class_cdf_1[prec], num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ SHIFT_CDF(nmv_ptr->joint_shell_class_cdf_1[prec], num_mv_class_1 - 1);
+ SHIFT_CDF(nmv_ptr->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ SHIFT_CDF(nmv_ptr->joint_shell_class_cdf_1[prec], num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
for (int prec = 0; prec < NUM_MV_PRECISIONS; prec++) {
int num_mv_class = get_default_num_shell_class(prec);
- SHIFT_CDF(nmv_ptr->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ SHIFT_CDF(nmv_ptr->joint_shell_class_cdf[prec], num_mv_class - 1);
+ SHIFT_CDF(nmv_ptr->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ SHIFT_CDF(nmv_ptr->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#endif // CONFIG_REDUCE_SYMBOL_SIZE
SHIFT_CDF(nmv_ptr->shell_offset_low_class_cdf, 2);
@@ -8328,14 +8370,36 @@
split_num_shell_class(num_mv_class, &num_mv_class_0, &num_mv_class_1);
AVERAGE_CDF(nmv_left->joint_shell_class_cdf_0[prec],
nmv_tr->joint_shell_class_cdf_0[prec], num_mv_class_0);
- AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
- nmv_tr->joint_shell_class_cdf_1[prec], num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
+ nmv_tr->joint_shell_class_cdf_1[prec], num_mv_class_1 - 1);
+ AVERAGE_CDF(nmv_left->joint_shell_last_two_classes_cdf,
+ nmv_tr->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
+ nmv_tr->joint_shell_class_cdf_1[prec], num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
for (int prec = 0; prec < NUM_MV_PRECISIONS; prec++) {
int num_mv_class = get_default_num_shell_class(prec);
- AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
- nmv_tr->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
+ nmv_tr->joint_shell_class_cdf[prec], num_mv_class - 1);
+ AVERAGE_CDF(nmv_left->joint_shell_last_two_classes_cdf,
+ nmv_tr->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
+ nmv_tr->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#endif // CONFIG_REDUCE_SYMBOL_SIZE
AVERAGE_CDF(nmv_left->shell_offset_low_class_cdf,
diff --git a/av1/common/entropymv.c b/av1/common/entropymv.c
index 6281c08..13e4562 100644
--- a/av1/common/entropymv.c
+++ b/av1/common/entropymv.c
@@ -19,6 +19,26 @@
#else
#if CONFIG_REDUCE_SYMBOL_SIZE
{ AOM_CDF2(24576), 0 }, // joint_shell_set_cdf
+#if CONFIG_MV_RANGE_EXTENSION
+ {
+ { AOM_CDF5(6847, 15990, 24873, 32100), 0 },
+ { AOM_CDF6(8452, 19730, 26138, 30154, 32100), 0 },
+ { AOM_CDF6(6553, 13106, 19659, 26212, 32100), 0 },
+ { AOM_CDF7(5062, 12676, 19127, 24565, 29511, 32100), 0 },
+ { AOM_CDF7(4553, 16572, 24700, 28964, 31428, 32100), 0 },
+ { AOM_CDF8(2750, 12194, 20615, 25661, 28862, 31157, 32100), 0 },
+ { AOM_CDF8(7886, 19300, 26400, 29900, 31400, 32100, 32740), 0 },
+ }, // joint_shell_class_cdf_0
+ {
+ { AOM_CDF6(17356, 28590, 32415, 32740, 32760), 0 },
+ { AOM_CDF6(21505, 30000, 31700, 31819, 32100), 0 },
+ { AOM_CDF7(5461, 10922, 16383, 21844, 27305, 32100), 0 },
+ { AOM_CDF7(21567, 30194, 32730, 32755, 32760, 32764), 0 },
+ { AOM_CDF8(20234, 28560, 30530, 31246, 31694, 32141, 32740), 0 },
+ { AOM_CDF8(18126, 26500, 30750, 32100, 32185, 32400, 32740), 0 },
+ { AOM_CDF8(16384, 24576, 28672, 29696, 29970, 30244, 30518), 0 },
+ }, // joint_shell_class_cdf_1
+#else
{
{ AOM_CDF4(6847, 15990, 24873), 0 },
{ AOM_CDF5(8452, 19730, 26138, 30154), 0 },
@@ -37,8 +57,32 @@
{ AOM_CDF7(18126, 26500, 30750, 32100, 32185, 32400), 0 },
{ AOM_CDF8(16384, 24576, 28672, 29696, 29970, 30244, 30518), 0 },
}, // joint_shell_class_cdf_1
+#endif // CONFIG_MV_RANGE_EXTENSION
#else
{
+#if CONFIG_MV_RANGE_EXTENSION
+ { AOM_CDF11(4820, 11253, 17504, 23064, 28204, 31531, 32664, 32760, 32762,
+ 32764),
+ 30 },
+ { AOM_CDF12(7955, 18569, 24600, 28379, 30839, 32105, 32619, 32753, 32760,
+ 32762, 32764),
+ 7 },
+ { AOM_CDF13(2978, 5956, 8934, 11912, 14890, 17868, 20846, 23824, 26802,
+ 29780, 30839, 32760),
+ 0 },
+ { AOM_CDF14(4710, 11795, 17797, 22857, 27459, 30489, 31939, 32543, 32730,
+ 32755, 32760, 32762, 32764),
+ 0 },
+ { AOM_CDF15(4452, 16202, 24148, 28317, 30726, 32036, 32494, 32680, 32724,
+ 32740, 32750, 32760, 32762, 32764),
+ 1 },
+ { AOM_CDF16(2621, 11620, 19645, 24454, 27504, 29691, 31226, 32079, 32497,
+ 32684, 32750, 32754, 32760, 32762, 32764),
+ 1 },
+ { AOM_CDF16(7771, 19161, 26258, 29752, 31259, 31926, 32289, 32539, 32668,
+ 32738, 32752, 32756, 32760, 32762, 32764),
+ 75 },
+#else
{ AOM_CDF9(4820, 11253, 17504, 23064, 28204, 31531, 32664, 32760), 30 },
{ AOM_CDF10(7955, 18569, 24600, 28379, 30839, 32105, 32619, 32753, 32760),
7 },
@@ -57,8 +101,14 @@
{ AOM_CDF15(7771, 19161, 26258, 29752, 31259, 31926, 32289, 32539, 32668,
32738, 32752, 32756, 32760, 32764),
75 },
+#endif // CONFIG_MV_RANGE_EXTENSION
}, // joint_shell_class_cdf
#endif // CONFIG_REDUCE_SYMBOL_SIZE
+
+#if CONFIG_MV_RANGE_EXTENSION
+ { AOM_CDF2(16384), 0 }, // joint_shell_last_two_classes_cdf
+#endif // CONFIG_MV_RANGE_EXTENSION
+
{
{ AOM_CDF2(3268), 1 },
{ AOM_CDF2(17309), 75 },
@@ -89,6 +139,10 @@
{ AOM_CDF2(29343), 50 },
{ AOM_CDF2(16384), 0 },
{ AOM_CDF2(16384), 0 },
+#if CONFIG_MV_RANGE_EXTENSION
+ { AOM_CDF2(16384), 0 },
+ { AOM_CDF2(16384), 0 },
+#endif // CONFIG_MV_RANGE_EXTENSION
} }, // shell_offset_other_class_cdf
#endif // !CONFIG_CTX_MV_SHELL_OFFSET_OTHER
{
@@ -106,8 +160,35 @@
{ AOM_CDF4(4, 19409, 32748), 1 }, // amvd_joints_cdf
{
{
-
#if !CONFIG_VQ_MVD_CODING
+#if CONFIG_MV_RANGE_EXTENSION
+ {
+ { AOM_CDF11(9045, 14234, 20059, 25670, 29656, 31856, 32661, 32708,
+ 32710, 32712),
+ 76 },
+ { AOM_CDF12(13873, 20198, 26490, 29945, 31547, 32216, 32659,
+ 32704, 32708, 32710, 32712),
+ 1 },
+ { AOM_CDF13(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831,
+ 26810, 29789, 31010, 32012),
+ 0 },
+ { AOM_CDF13(13705, 18604, 23447, 27806, 30775, 32116, 32589,
+ 32700, 32704, 32708, 32710, 32712),
+ 75 },
+ { AOM_CDF13(26824, 30545, 31965, 32526, 32676, 32708, 32712,
+ 32716, 32720, 32724, 32726, 32728),
+ 75 },
+ { AOM_CDF13(25936, 28131, 29757, 31161, 32142, 32545, 32698,
+ 32702, 32706, 32710, 32712, 32714),
+ 75 },
+ { AOM_CDF13(32029, 32523, 32665, 32716, 32720, 32724, 32728,
+ 32732, 32736, 32740, 32742, 32744),
+ 75 },
+ }, // classes_cdf
+ { AOM_CDF13(28615, 31027, 32182, 32608, 32712, 32716, 32720, 32724,
+ 32728, 32732, 32734, 32736),
+ 0 }, // amvd_classes_cdf
+#else
{
{ AOM_CDF9(9045, 14234, 20059, 25670, 29656, 31856, 32661, 32708),
76 },
@@ -129,12 +210,14 @@
{ AOM_CDF11(32029, 32523, 32665, 32716, 32720, 32724, 32728,
32732, 32736, 32740),
75 },
- },
+ }, // classes_cdf
{ AOM_CDF11(28615, 31027, 32182, 32608, 32712, 32716, 32720, 32724,
32728, 32732),
- 0 },
+ 0 }, // amvd_classes_cdf
+#endif // CONFIG_MV_RANGE_EXTENSION
#else
- { AOM_CDF8(7804, 11354, 12626, 18581, 24598, 29144, 31608), 1 },
+ { AOM_CDF8(7804, 11354, 12626, 18581, 24598, 29144, 31608),
+ 1 }, // amvd_indices_cdf
#endif // !CONFIG_VQ_MVD_CODING
#if !CONFIG_VQ_MVD_CODING
@@ -149,20 +232,20 @@
{ AOM_CDF2(11921), 1 },
{ AOM_CDF2(12406), 1 },
},
- },
+ }, // class0_fp_cdf
{
{ AOM_CDF2(18429), 90 },
{ AOM_CDF2(15625), 0 },
{ AOM_CDF2(17117), 75 },
- },
-#endif // !CONFIG_VQ_MVD_CODING
+ }, // fp_cdf
+#endif // !CONFIG_VQ_MVD_CODING
#if !CONFIG_MVD_CDF_REDUCTION
- { AOM_CDF2(16024), 0 },
-#endif //! CONFIG_MVD_CDF_REDUCTION
+ { AOM_CDF2(16024), 0 }, // sign_cdf
+#endif //! CONFIG_MVD_CDF_REDUCTION
#if !CONFIG_VQ_MVD_CODING
- { AOM_CDF2(25929), 90 },
- { AOM_CDF2(11557), 84 },
- { AOM_CDF2(26908), 75 },
+ { AOM_CDF2(25929), 90 }, // class0_hp_cdf
+ { AOM_CDF2(11557), 84 }, // hp_cdf
+ { AOM_CDF2(26908), 75 }, // class0_cdf
{
{ AOM_CDF2(18078), 124 },
{ AOM_CDF2(18254), 124 },
@@ -174,12 +257,43 @@
{ AOM_CDF2(26291), 5 },
{ AOM_CDF2(30118), 100 },
{ AOM_CDF2(16384), 0 },
- },
-#endif // !CONFIG_VQ_MVD_CODING
+#if CONFIG_MV_RANGE_EXTENSION
+ { AOM_CDF2(16384), 0 },
+ { AOM_CDF2(16384), 0 },
+#endif // CONFIG_MV_RANGE_EXTENSION
+ }, // bits_cdf
+#endif // !CONFIG_VQ_MVD_CODING
},
{
-
#if !CONFIG_VQ_MVD_CODING
+#if CONFIG_MV_RANGE_EXTENSION
+ {
+ { AOM_CDF11(8910, 13492, 19259, 24751, 28899, 31567, 32600, 32708,
+ 32710, 32712),
+ 76 },
+ { AOM_CDF12(15552, 21454, 26682, 29649, 31333, 32161, 32591,
+ 32704, 32708, 32710, 32712, 32714, 32716),
+ 76 },
+ { AOM_CDF13(2979, 5958, 8937, 11916, 14895, 17873, 20852, 23831,
+ 26810, 29789, 31010, 32012),
+ 0 },
+ { AOM_CDF13(12301, 18138, 23549, 27708, 30501, 31883, 32463,
+ 32682, 32696, 32700, 32704, 32708),
+ 75 },
+ { AOM_CDF13(26132, 29614, 31375, 32280, 32639, 32708, 32712,
+ 32716, 32720, 32724, 32726, 32728),
+ 75 },
+ { AOM_CDF13(25359, 28443, 30284, 31515, 32242, 32565, 32693,
+ 32700, 32704, 32708, 32710, 32712),
+ 75 },
+ { AOM_CDF13(31842, 32400, 32592, 32694, 32712, 32716, 32720,
+ 32724, 32728, 32732, 32734, 32738),
+ 75 },
+ }, // classes_cdf
+ { AOM_CDF13(29563, 31499, 32361, 32658, 32712, 32716, 32720, 32724,
+ 32728, 32732),
+ 0 }, // amvd_classes_cdf
+#else
{
{ AOM_CDF9(8910, 13492, 19259, 24751, 28899, 31567, 32600, 32708),
76 },
@@ -201,12 +315,14 @@
{ AOM_CDF11(31842, 32400, 32592, 32694, 32712, 32716, 32720,
32724, 32728, 32732),
75 },
- },
+ }, // classes_cdf
{ AOM_CDF11(29563, 31499, 32361, 32658, 32712, 32716, 32720, 32724,
32728, 32732),
- 0 },
+ 0 }, // amvd_classes_cdf
+#endif // CONFIG_MV_RANGE_EXTENSION
#else
- { AOM_CDF8(7392, 11106, 12422, 18167, 24480, 29230, 31714), 1 },
+ { AOM_CDF8(7392, 11106, 12422, 18167, 24480, 29230, 31714),
+ 1 }, // amvd_indices_cdf
#endif // !CONFIG_VQ_MVD_CODING
#if !CONFIG_VQ_MVD_CODING
{
@@ -220,20 +336,20 @@
{ AOM_CDF2(12278), 0 },
{ AOM_CDF2(11913), 1 },
},
- },
+ }, // class0_fp_cdf
{
{ AOM_CDF2(14462), 75 },
{ AOM_CDF2(11379), 75 },
{ AOM_CDF2(6857), 0 },
- },
-#endif // !CONFIG_VQ_MVD_CODING
+ }, // fp_cdf
+#endif // !CONFIG_VQ_MVD_CODING
#if !CONFIG_MVD_CDF_REDUCTION
- { AOM_CDF2(16302), 75 },
-#endif //! CONFIG_MVD_CDF_REDUCTION
+ { AOM_CDF2(16302), 75 }, // sign_cdf
+#endif //! CONFIG_MVD_CDF_REDUCTION
#if !CONFIG_VQ_MVD_CODING
- { AOM_CDF2(24896), 75 },
- { AOM_CDF2(16355), 119 },
- { AOM_CDF2(26968), 75 },
+ { AOM_CDF2(24896), 75 }, // class0_hp_cdf
+ { AOM_CDF2(16355), 119 }, // hp_cdf
+ { AOM_CDF2(26968), 75 }, // class0_cdf
{
{ AOM_CDF2(19196), 124 },
{ AOM_CDF2(17877), 124 },
@@ -245,8 +361,12 @@
{ AOM_CDF2(23432), 77 },
{ AOM_CDF2(29155), 0 },
{ AOM_CDF2(16384), 0 },
- },
-#endif // !CONFIG_VQ_MVD_CODING
+#if CONFIG_MV_RANGE_EXTENSION
+ { AOM_CDF2(16384) },
+ { AOM_CDF2(16384) },
+#endif // CONFIG_MV_RANGE_EXTENSION
+ }, // bits_cdf
+#endif // !CONFIG_VQ_MVD_CODING
},
},
};
diff --git a/av1/common/entropymv.h b/av1/common/entropymv.h
index 2fa1913..6d13cf2 100644
--- a/av1/common/entropymv.h
+++ b/av1/common/entropymv.h
@@ -47,7 +47,6 @@
}
/* Symbols for coding magnitude class of nonzero components */
-#define MV_CLASSES 11
enum {
/* Class specifies the integer pel range */
MV_CLASS_0 = 0, /* When AMVD is applied:(0, 1], {2}. Otherwise:(0, 2] */
@@ -60,13 +59,17 @@
MV_CLASS_7 = 7, /* When AMVD is applied:{256}. Otherwise:(128, 256] */
MV_CLASS_8 = 8, /* When AMVD is applied:{512}. Otherwise:(256, 512] */
MV_CLASS_9 = 9, /* When AMVD is applied:{1024}. Otherwise:(512, 1024] */
- MV_CLASS_10 = 10, /* When AMVD is applied:{2048}. Otherwise:(1024,2048] */
+ MV_CLASS_10 = 10, /* When AMVD is applied:{2048}. Otherwise:(1024, 2048] */
+#if CONFIG_MV_RANGE_EXTENSION
+ MV_CLASS_11 = 11, /* When AMVD is applied:{2048}. Otherwise:(2048, 4096] */
+ MV_CLASS_12 = 12, /* When AMVD is applied:{4096}. Otherwise:(4096, 8192] */
+#endif // CONFIG_MV_RANGE_EXTENSION
+ MV_CLASSES, /* Maximum MV class */
} UENUM1BYTE(MV_CLASS_TYPE);
#define CLASS0_BITS 1 /* bits at integer precision for class 0 */
#define CLASS0_SIZE (1 << CLASS0_BITS)
#define MV_OFFSET_BITS (MV_CLASSES + CLASS0_BITS - 2)
-#define MV_BITS_CONTEXTS 6
#define MV_MAX_BITS (MV_CLASSES + CLASS0_BITS + 2)
#define MV_MAX ((1 << MV_MAX_BITS) - 1)
#define MV_VALS ((MV_MAX << 1) + 1)
@@ -111,9 +114,24 @@
aom_cdf_prob joint_shell_class_cdf_1[NUM_MV_PRECISIONS]
[CDF_SIZE(SECOND_SHELL_CLASS)];
#else
+#if CONFIG_MV_RANGE_EXTENSION
+ // For MV_PRECISION_ONE_EIGHTH_PEL, class 15 and 16 are coded as a
+ // single class, another flag to distinguish them
+ aom_cdf_prob joint_shell_class_cdf[NUM_MV_PRECISIONS]
+ [CDF_SIZE(MAX_NUM_SHELL_CLASS - 1)];
+#else
aom_cdf_prob joint_shell_class_cdf[NUM_MV_PRECISIONS]
[CDF_SIZE(MAX_NUM_SHELL_CLASS)];
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
+
+#if CONFIG_MV_RANGE_EXTENSION
+ // Only MV_PRECISION_ONE_EIGHTH_PEL has shell class 15 and class 16.
+ // For MV_PRECISION_ONE_EIGHTH_PEL, class 15 and 16 are coded as a
+ // single class, then another flag to distinguish them
+ aom_cdf_prob joint_shell_last_two_classes_cdf[CDF_SIZE(2)];
+#endif // CONFIG_MV_RANGE_EXTENSION
+
aom_cdf_prob shell_offset_low_class_cdf[2][CDF_SIZE(2)];
#if CONFIG_MVD_CDF_REDUCTION
diff --git a/av1/common/mv.h b/av1/common/mv.h
index ac35391..fc556f7 100644
--- a/av1/common/mv.h
+++ b/av1/common/mv.h
@@ -23,11 +23,16 @@
extern "C" {
#endif
-#define INVALID_MV 0x80008000
#define GET_MV_RAWPEL(x) (((x) + 3 + ((x) >= 0)) >> 3)
#define GET_MV_SUBPEL(x) ((x) * 8)
+#if CONFIG_MV_RANGE_EXTENSION
+#define INVALID_MV 0x2000020000
+#define MV_IN_USE_BITS 16
+#else
+#define INVALID_MV 0x80008000
#define MV_IN_USE_BITS 14
+#endif // CONFIG_MV_RANGE_EXTENSION
#define MV_UPP (1 << MV_IN_USE_BITS)
#define MV_LOW (-(1 << MV_IN_USE_BITS))
@@ -37,23 +42,35 @@
} while (0);
#define CHECK_MV_EQUAL(x, y) (((x).row == (y).row) && ((x).col == (y).col))
+#if CONFIG_MV_RANGE_EXTENSION
+// Data type of MV component
+#define MV_COMP_DATA_TYPE int32_t
+// Data type of MV
+#define MV_DATA_TYPE uint64_t
+#else
+// Data type of MV component
+#define MV_COMP_DATA_TYPE int16_t
+// Data type of MV
+#define MV_DATA_TYPE uint32_t
+#endif // CONFIG_MV_RANGE_EXTENSION
+
// The motion vector in units of full pixel
typedef struct fullpel_mv {
- int16_t row;
- int16_t col;
+ MV_COMP_DATA_TYPE row;
+ MV_COMP_DATA_TYPE col;
} FULLPEL_MV;
// The motion vector in units of 1/8-pel
typedef struct mv {
- int16_t row;
- int16_t col;
+ MV_COMP_DATA_TYPE row;
+ MV_COMP_DATA_TYPE col;
} MV;
static const MV kZeroMv = { 0, 0 };
static const FULLPEL_MV kZeroFullMv = { 0, 0 };
typedef union int_mv {
- uint32_t as_int;
+ MV_DATA_TYPE as_int;
MV as_mv;
FULLPEL_MV as_fullmv;
} int_mv; /* facilitates faster equality tests and copies */
@@ -116,7 +133,11 @@
((NUM_MV_PRECISIONS) - (MV_PRECISION_HALF_PEL))
#if CONFIG_VQ_MVD_CODING
+#if CONFIG_MV_RANGE_EXTENSION
+#define MAX_NUM_SHELL_CLASS 17
+#else
#define MAX_NUM_SHELL_CLASS 15
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_VQ_MVD_CODING
// The mv limit for fullpel mvs
typedef struct {
@@ -135,8 +156,9 @@
} SubpelMvLimits;
static AOM_INLINE FULLPEL_MV get_fullmv_from_mv(const MV *subpel_mv) {
- const FULLPEL_MV full_mv = { (int16_t)GET_MV_RAWPEL(subpel_mv->row),
- (int16_t)GET_MV_RAWPEL(subpel_mv->col) };
+ const FULLPEL_MV full_mv = { (MV_COMP_DATA_TYPE)GET_MV_RAWPEL(subpel_mv->row),
+ (MV_COMP_DATA_TYPE)GET_MV_RAWPEL(
+ subpel_mv->col) };
return full_mv;
}
@@ -164,8 +186,8 @@
#endif // CONFIG_C071_SUBBLK_WARPMV
static AOM_INLINE MV get_mv_from_fullmv(const FULLPEL_MV *full_mv) {
- const MV subpel_mv = { (int16_t)GET_MV_SUBPEL(full_mv->row),
- (int16_t)GET_MV_SUBPEL(full_mv->col) };
+ const MV subpel_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(full_mv->row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(full_mv->col) };
return subpel_mv;
}
@@ -677,11 +699,11 @@
} WARP_CANDIDATE;
static INLINE int is_zero_mv(const MV *mv) {
- return *((const uint32_t *)mv) == 0;
+ return *((const MV_DATA_TYPE *)mv) == 0;
}
static INLINE int is_equal_mv(const MV *a, const MV *b) {
- return *((const uint32_t *)a) == *((const uint32_t *)b);
+ return *((const MV_DATA_TYPE *)a) == *((const MV_DATA_TYPE *)b);
}
static INLINE void clamp_mv(MV *mv, const SubpelMvLimits *mv_limits) {
@@ -704,6 +726,13 @@
}
#endif // CONFIG_IMPROVE_REFINED_MV
+#if CONFIG_MV_RANGE_EXTENSION
+static INLINE int get_map_shell_class(const int shell_class) {
+ return shell_class >= MAX_NUM_SHELL_CLASS - 2 ? MAX_NUM_SHELL_CLASS - 2
+ : shell_class;
+}
+#endif // CONFIG_MV_RANGE_EXTENSION
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index a284ce8..f93efb0 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -3843,9 +3843,9 @@
#endif // CONFIG_IBC_BV_IMPROVEMENT && CONFIG_IBC_MAX_DRL
CANDIDATE_MV tmp_mv;
tmp_mv.this_mv.as_mv.col =
- (int16_t)GET_MV_SUBPEL(default_ref_bv_list[i][0]);
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(default_ref_bv_list[i][0]);
tmp_mv.this_mv.as_mv.row =
- (int16_t)GET_MV_SUBPEL(default_ref_bv_list[i][1]);
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(default_ref_bv_list[i][1]);
tmp_mv.comp_mv.as_int = 0;
add_to_ref_bv_list(tmp_mv, ref_mv_stack, ref_mv_weight, refmv_count);
}
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h
index 05493f0..9f1be55 100644
--- a/av1/common/mvref_common.h
+++ b/av1/common/mvref_common.h
@@ -661,8 +661,8 @@
const int mv_col = (int)ROUND_POWER_OF_TWO_SIGNED_64(scale_mv_col, 14);
const int clamp_max = MV_UPP - 1;
const int clamp_min = MV_LOW + 1;
- output->row = (int16_t)clamp(mv_row, clamp_min, clamp_max);
- output->col = (int16_t)clamp(mv_col, clamp_min, clamp_max);
+ output->row = (MV_COMP_DATA_TYPE)clamp(mv_row, clamp_min, clamp_max);
+ output->col = (MV_COMP_DATA_TYPE)clamp(mv_col, clamp_min, clamp_max);
}
void av1_setup_frame_buf_refs(AV1_COMMON *cm);
@@ -1436,8 +1436,8 @@
const int mv_col = (int)ROUND_POWER_OF_TWO_SIGNED_64(scale_mv_col, 14);
const int clamp_max = MV_UPP - 1;
const int clamp_min = MV_LOW + 1;
- output->row = (int16_t)clamp(mv_row, clamp_min, clamp_max);
- output->col = (int16_t)clamp(mv_col, clamp_min, clamp_max);
+ output->row = (MV_COMP_DATA_TYPE)clamp(mv_row, clamp_min, clamp_max);
+ output->col = (MV_COMP_DATA_TYPE)clamp(mv_col, clamp_min, clamp_max);
}
// Compute TMVP unit offset related to block mv
@@ -1505,14 +1505,14 @@
tip_mv[0].as_int = 0;
tip_mv[1].as_int = 0;
}
- tip_mv[0].as_mv.row = (int16_t)clamp(tip_mv[0].as_mv.row + block_mv->row,
- MV_LOW + 1, MV_UPP - 1);
- tip_mv[0].as_mv.col = (int16_t)clamp(tip_mv[0].as_mv.col + block_mv->col,
- MV_LOW + 1, MV_UPP - 1);
- tip_mv[1].as_mv.row = (int16_t)clamp(tip_mv[1].as_mv.row + block_mv->row,
- MV_LOW + 1, MV_UPP - 1);
- tip_mv[1].as_mv.col = (int16_t)clamp(tip_mv[1].as_mv.col + block_mv->col,
- MV_LOW + 1, MV_UPP - 1);
+ tip_mv[0].as_mv.row = (MV_COMP_DATA_TYPE)clamp(
+ tip_mv[0].as_mv.row + block_mv->row, MV_LOW + 1, MV_UPP - 1);
+ tip_mv[0].as_mv.col = (MV_COMP_DATA_TYPE)clamp(
+ tip_mv[0].as_mv.col + block_mv->col, MV_LOW + 1, MV_UPP - 1);
+ tip_mv[1].as_mv.row = (MV_COMP_DATA_TYPE)clamp(
+ tip_mv[1].as_mv.row + block_mv->row, MV_LOW + 1, MV_UPP - 1);
+ tip_mv[1].as_mv.col = (MV_COMP_DATA_TYPE)clamp(
+ tip_mv[1].as_mv.col + block_mv->col, MV_LOW + 1, MV_UPP - 1);
}
#ifdef __cplusplus
diff --git a/av1/common/reconinter.h b/av1/common/reconinter.h
index 8af43f0..1c925b1 100644
--- a/av1/common/reconinter.h
+++ b/av1/common/reconinter.h
@@ -1339,13 +1339,13 @@
if (use_optflow_refinement) {
// optflow refinement always returns MVs with 1/16 precision so it is not
// necessary to shift the MV before clamping
- clamped_mv.row = (int16_t)ROUND_POWER_OF_TWO_SIGNED(
+ clamped_mv.row = (MV_COMP_DATA_TYPE)ROUND_POWER_OF_TWO_SIGNED(
src_mv->row * (1 << SUBPEL_BITS), MV_REFINE_PREC_BITS + ss_y);
- clamped_mv.col = (int16_t)ROUND_POWER_OF_TWO_SIGNED(
+ clamped_mv.col = (MV_COMP_DATA_TYPE)ROUND_POWER_OF_TWO_SIGNED(
src_mv->col * (1 << SUBPEL_BITS), MV_REFINE_PREC_BITS + ss_x);
} else {
- clamped_mv.row = (int16_t)(src_mv->row * (1 << (1 - ss_y)));
- clamped_mv.col = (int16_t)(src_mv->col * (1 << (1 - ss_x)));
+ clamped_mv.row = (MV_COMP_DATA_TYPE)(src_mv->row * (1 << (1 - ss_y)));
+ clamped_mv.col = (MV_COMP_DATA_TYPE)(src_mv->col * (1 << (1 - ss_x)));
}
assert(ss_x <= 1);
assert(ss_y <= 1);
diff --git a/av1/common/tip.c b/av1/common/tip.c
index 272d4a8..3730d75 100644
--- a/av1/common/tip.c
+++ b/av1/common/tip.c
@@ -521,11 +521,11 @@
if (weights) {
const int scale_factor = weight_div_mult[weights];
tpl_mfs[blk_pos_in_sb].as_mv.row =
- (int16_t)ROUND_POWER_OF_TWO_SIGNED(sum_mv_row * scale_factor,
- DIV_SHIFT_BITS);
+ (MV_COMP_DATA_TYPE)ROUND_POWER_OF_TWO_SIGNED(
+ sum_mv_row * scale_factor, DIV_SHIFT_BITS);
tpl_mfs[blk_pos_in_sb].as_mv.col =
- (int16_t)ROUND_POWER_OF_TWO_SIGNED(sum_mv_col * scale_factor,
- DIV_SHIFT_BITS);
+ (MV_COMP_DATA_TYPE)ROUND_POWER_OF_TWO_SIGNED(
+ sum_mv_col * scale_factor, DIV_SHIFT_BITS);
} else {
tpl_mfs[blk_pos_in_sb].as_int = INVALID_MV;
}
@@ -558,8 +558,8 @@
const int spel_right = spel_left - SUBPEL_SHIFTS;
const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
const int spel_bottom = spel_top - SUBPEL_SHIFTS;
- MV clamped_mv = { (int16_t)(src_mv->row * (1 << (1 - ss_y))),
- (int16_t)(src_mv->col * (1 << (1 - ss_x))) };
+ MV clamped_mv = { (MV_COMP_DATA_TYPE)(src_mv->row * (1 << (1 - ss_y))),
+ (MV_COMP_DATA_TYPE)(src_mv->col * (1 << (1 - ss_x))) };
assert(ss_x <= 1);
assert(ss_y <= 1);
const SubpelMvLimits mv_limits = {
@@ -1544,14 +1544,18 @@
tip_ref->ref_frames_offset_sf[0]);
tip_get_mv_projection(&mv[1], tpl_mvs->mfmv0.as_mv,
tip_ref->ref_frames_offset_sf[1]);
- mv[0].row = (int16_t)clamp(mv[0].row + cm->tip_global_motion.as_mv.row,
- MV_LOW + 1, MV_UPP - 1);
- mv[0].col = (int16_t)clamp(mv[0].col + cm->tip_global_motion.as_mv.col,
- MV_LOW + 1, MV_UPP - 1);
- mv[1].row = (int16_t)clamp(mv[1].row + cm->tip_global_motion.as_mv.row,
- MV_LOW + 1, MV_UPP - 1);
- mv[1].col = (int16_t)clamp(mv[1].col + cm->tip_global_motion.as_mv.col,
- MV_LOW + 1, MV_UPP - 1);
+ mv[0].row = (MV_COMP_DATA_TYPE)clamp(
+ mv[0].row + cm->tip_global_motion.as_mv.row, MV_LOW + 1,
+ MV_UPP - 1);
+ mv[0].col = (MV_COMP_DATA_TYPE)clamp(
+ mv[0].col + cm->tip_global_motion.as_mv.col, MV_LOW + 1,
+ MV_UPP - 1);
+ mv[1].row = (MV_COMP_DATA_TYPE)clamp(
+ mv[1].row + cm->tip_global_motion.as_mv.row, MV_LOW + 1,
+ MV_UPP - 1);
+ mv[1].col = (MV_COMP_DATA_TYPE)clamp(
+ mv[1].col + cm->tip_global_motion.as_mv.col, MV_LOW + 1,
+ MV_UPP - 1);
} else {
mv[0] = cm->tip_global_motion.as_mv;
mv[1] = cm->tip_global_motion.as_mv;
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index f32f0f5..2887e9d 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -2644,7 +2644,6 @@
#if CONFIG_MVD_CDF_REDUCTION
bit_idx ? aom_read_literal(r, 1, ACCT_INFO("greater_flags")) :
#endif // CONFIG_MVD_CDF_REDUCTION
-
aom_read_symbol(
r, cdf, 2,
ACCT_INFO("greater_flags", "col_mv_greater_flags_cdf"));
@@ -2762,25 +2761,63 @@
shell_set = aom_read_symbol(r, ctx->joint_shell_set_cdf, 2,
ACCT_INFO("shell_set", "joint_shell_set_cdf"));
if (shell_set) {
+#if CONFIG_MV_RANGE_EXTENSION
+ if (precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ shell_class =
+ num_mv_class_0 +
+ aom_read_symbol(
+ r, ctx->joint_shell_class_cdf_1[precision], num_mv_class_1 - 1,
+ ACCT_INFO("shell_class_1", "joint_shell_class_cdf_1"));
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ shell_class += aom_read_symbol(
+ r, ctx->joint_shell_last_two_classes_cdf, 2,
+ ACCT_INFO("shell_class", "joint_shell_last_two_classes_cdf"));
+ }
+ } else {
+ shell_class =
+ num_mv_class_0 +
+ aom_read_symbol(
+ r, ctx->joint_shell_class_cdf_1[precision], num_mv_class_1,
+ ACCT_INFO("shell_class_1", "joint_shell_class_cdf_1"));
+ }
+#else
shell_class =
num_mv_class_0 +
aom_read_symbol(r, ctx->joint_shell_class_cdf_1[precision],
num_mv_class_1,
ACCT_INFO("shell_class_1", "joint_shell_class_cdf_1"));
+#endif // CONFIG_MV_RANGE_EXTENSION
} else {
shell_class = aom_read_symbol(
r, ctx->joint_shell_class_cdf_0[precision], num_mv_class_0,
ACCT_INFO("shell_class_0", "joint_shell_class_cdf_0"));
}
#else
+#if CONFIG_MV_RANGE_EXTENSION
+ int shell_class = 0;
+ if (precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ shell_class = aom_read_symbol(
+ r, ctx->joint_shell_class_cdf[precision], num_mv_class - 1,
+ ACCT_INFO("shell_class", "joint_shell_class_cdf"));
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ shell_class += aom_read_symbol(
+ r, ctx->joint_shell_last_two_classes_cdf, 2,
+ ACCT_INFO("shell_class", "joint_shell_last_two_classes_cdf"));
+ }
+ } else {
+ shell_class =
+ aom_read_symbol(r, ctx->joint_shell_class_cdf[precision], num_mv_class,
+ ACCT_INFO("shell_class", "joint_shell_class_cdf"));
+ }
+#else
const int shell_class =
aom_read_symbol(r, ctx->joint_shell_class_cdf[precision], num_mv_class,
ACCT_INFO("shell_class", "joint_shell_class_cdf"));
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
assert(shell_class < num_mv_class);
// Decode shell class offset
-
int shell_cls_offset = 0;
if (shell_class < 2) {
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index ab454c8..1eff202 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -1423,7 +1423,7 @@
/*! costs to code mvd shell index. */
int nmv_joint_shell_cost[NUM_MV_PRECISIONS][(2 * MV_MAX) + 1];
- /*! costs to code col_mv_greter_flags. */
+ /*! costs to code col_mv_greater_flags. */
int col_mv_greater_flags_costs[NUM_MV_PRECISIONS]
[MAX_COL_TRUNCATED_UNARY_VAL + 1]
[MAX_COL_TRUNCATED_UNARY_VAL + 1];
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index 3572df9..93cd438 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -1345,16 +1345,38 @@
split_num_shell_class(num_mv_class, &num_mv_class_0, &num_mv_class_1);
AVERAGE_CDF(nmv_left->joint_shell_class_cdf_0[prec],
nmv_tr->joint_shell_class_cdf_0[prec], num_mv_class_0);
- AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
- nmv_tr->joint_shell_class_cdf_1[prec], num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
+ nmv_tr->joint_shell_class_cdf_1[prec], num_mv_class_1 - 1);
+ AVERAGE_CDF(nmv_left->joint_shell_last_two_classes_cdf,
+ nmv_tr->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ AVERAGE_CDF(nmv_left->joint_shell_class_cdf_1[prec],
+ nmv_tr->joint_shell_class_cdf_1[prec], num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
for (int prec = 0; prec < NUM_MV_PRECISIONS; prec++) {
int num_mv_class = get_default_num_shell_class(prec);
- AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
- nmv_tr->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (prec == MV_PRECISION_ONE_EIGHTH_PEL) {
+ AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
+ nmv_tr->joint_shell_class_cdf[prec], num_mv_class - 1);
+ AVERAGE_CDF(nmv_left->joint_shell_last_two_classes_cdf,
+ nmv_tr->joint_shell_last_two_classes_cdf, 2);
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ AVERAGE_CDF(nmv_left->joint_shell_class_cdf[prec],
+ nmv_tr->joint_shell_class_cdf[prec], num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
-#endif
+#endif // CONFIG_REDUCE_SYMBOL_SIZE
AVERAGE_CDF(nmv_left->shell_offset_low_class_cdf,
nmv_tr->shell_offset_low_class_cdf, 2);
AVERAGE_CDF(nmv_left->shell_offset_class2_cdf,
diff --git a/av1/encoder/encodemv.c b/av1/encoder/encodemv.c
index 22e6b7b..309c765 100644
--- a/av1/encoder/encodemv.c
+++ b/av1/encoder/encodemv.c
@@ -365,14 +365,44 @@
num_mv_class_0);
} else {
aom_write_symbol(w, 1, mvctx->joint_shell_set_cdf, 2);
- aom_write_symbol(w, shell_class - num_mv_class_0,
- mvctx->joint_shell_class_cdf_1[pb_mv_precision],
- num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (pb_mv_precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ const int map_shell_class = get_map_shell_class(shell_class);
+ aom_write_symbol(w, map_shell_class - num_mv_class_0,
+ mvctx->joint_shell_class_cdf_1[pb_mv_precision],
+ num_mv_class_1 - 1);
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ aom_write_symbol(w, shell_class == MAX_NUM_SHELL_CLASS - 1,
+ mvctx->joint_shell_last_two_classes_cdf, 2);
+ }
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ aom_write_symbol(w, shell_class - num_mv_class_0,
+ mvctx->joint_shell_class_cdf_1[pb_mv_precision],
+ num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
- aom_write_symbol(w, shell_class,
- mvctx->joint_shell_class_cdf[pb_mv_precision],
- num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (pb_mv_precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ const int map_shell_class = get_map_shell_class(shell_class);
+ aom_write_symbol(w, map_shell_class,
+ mvctx->joint_shell_class_cdf[pb_mv_precision],
+ num_mv_class - 1);
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ aom_write_symbol(w, shell_class == MAX_NUM_SHELL_CLASS - 1,
+ mvctx->joint_shell_last_two_classes_cdf, 2);
+ }
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ aom_write_symbol(w, shell_class,
+ mvctx->joint_shell_class_cdf[pb_mv_precision],
+ num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
assert(shell_class >= 0 && shell_class < num_mv_class);
@@ -474,12 +504,41 @@
num_mv_class_0);
} else {
update_cdf(mvctx->joint_shell_set_cdf, 1, 2);
- update_cdf(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
- shell_class - num_mv_class_0, num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (pb_mv_precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ const int map_shell_class = get_map_shell_class(shell_class);
+ update_cdf(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
+ map_shell_class - num_mv_class_0, num_mv_class_1 - 1);
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ update_cdf(mvctx->joint_shell_last_two_classes_cdf,
+ shell_class == MAX_NUM_SHELL_CLASS - 1, 2);
+ }
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ update_cdf(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
+ shell_class - num_mv_class_0, num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
- update_cdf(mvctx->joint_shell_class_cdf[pb_mv_precision], shell_class,
- num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (pb_mv_precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ const int map_shell_class = get_map_shell_class(shell_class);
+ update_cdf(mvctx->joint_shell_class_cdf[pb_mv_precision], map_shell_class,
+ num_mv_class - 1);
+
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ update_cdf(mvctx->joint_shell_last_two_classes_cdf,
+ shell_class == MAX_NUM_SHELL_CLASS - 1, 2);
+ }
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ update_cdf(mvctx->joint_shell_class_cdf[pb_mv_precision], shell_class,
+ num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
assert(shell_class >= 0 && shell_class < num_mv_class);
@@ -1032,8 +1091,17 @@
int joint_shell_class_cost_0[FIRST_SHELL_CLASS];
int joint_shell_class_cost_1[SECOND_SHELL_CLASS];
#else
+#if CONFIG_MV_RANGE_EXTENSION
+ int joint_shell_class_cost[MAX_NUM_SHELL_CLASS - 1];
+#else
int joint_shell_class_cost[MAX_NUM_SHELL_CLASS];
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
+
+#if CONFIG_MV_RANGE_EXTENSION
+ int joint_shell_last_two_classes_cost[2];
+#endif // CONFIG_MV_RANGE_EXTENSION
+
int shell_offset_low_class_cost[2][2];
#if CONFIG_MVD_CDF_REDUCTION
@@ -1070,6 +1138,13 @@
ctx->joint_shell_class_cdf[precision], NULL);
#endif // CONFIG_REDUCE_SYMBOL_SIZE
+#if CONFIG_MV_RANGE_EXTENSION
+ if (precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ av1_cost_tokens_from_cdf(joint_shell_last_two_classes_cost,
+ ctx->joint_shell_last_two_classes_cdf, NULL);
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
+
for (int i = 0; i < 2; i++) {
av1_cost_tokens_from_cdf(shell_offset_low_class_cost[i],
ctx->shell_offset_low_class_cdf[i], NULL);
@@ -1193,11 +1268,40 @@
shell_cost[shell_index] += joint_shell_class_cost_0[shell_class];
} else {
shell_cost[shell_index] += joint_shell_set_cost[1];
- shell_cost[shell_index] +=
- joint_shell_class_cost_1[shell_class - num_mv_class_0];
+#if CONFIG_MV_RANGE_EXTENSION
+ if (precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ const int map_shell_class = get_map_shell_class(shell_class);
+ shell_cost[shell_index] +=
+ joint_shell_class_cost_1[map_shell_class - num_mv_class_0];
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ const int is_last_class = (shell_class == MAX_NUM_SHELL_CLASS - 1);
+ shell_cost[shell_index] +=
+ joint_shell_last_two_classes_cost[is_last_class];
+ }
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ shell_cost[shell_index] +=
+ joint_shell_class_cost_1[shell_class - num_mv_class_0];
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
- shell_cost[shell_index] += joint_shell_class_cost[shell_class];
+#if CONFIG_MV_RANGE_EXTENSION
+ if (precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ const int map_shell_class = get_map_shell_class(shell_class);
+ shell_cost[shell_index] += joint_shell_class_cost[map_shell_class];
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ const int is_last_class = (shell_class == MAX_NUM_SHELL_CLASS - 1);
+ shell_cost[shell_index] +=
+ joint_shell_last_two_classes_cost[is_last_class];
+ }
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ shell_cost[shell_index] += joint_shell_class_cost[shell_class];
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
assert(shell_class >= 0 && shell_class < num_mv_class);
diff --git a/av1/encoder/encodemv.h b/av1/encoder/encodemv.h
index e6f054a..6fb2381 100644
--- a/av1/encoder/encodemv.h
+++ b/av1/encoder/encodemv.h
@@ -117,7 +117,7 @@
static INLINE MV_CLASS_TYPE av1_get_mv_class(int z, int *offset) {
assert(z >= 0);
const MV_CLASS_TYPE c = (MV_CLASS_TYPE)av1_log_in_base_2(z >> 3);
- assert(c <= MV_CLASS_10);
+ assert(c < MV_CLASSES);
if (offset) *offset = z - av1_mv_class_base(c);
return c;
}
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index a209260..b503f83 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -1790,7 +1790,13 @@
const int max_mv_def = AOMMAX(cm->width, cm->height);
// Default based on max resolution.
- mv_search_params->mv_step_param = av1_init_search_range(max_mv_def);
+ mv_search_params->mv_step_param =
+ av1_init_search_range(max_mv_def
+#if CONFIG_MV_RANGE_EXTENSION
+ ,
+ cpi->oxcf.tool_cfg.enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
+ );
if (cpi->sf.mv_sf.auto_mv_step_size) {
if (frame_is_intra_only(cm)) {
@@ -1804,7 +1810,12 @@
// in the previous frame, capped by the default max_mv_magnitude based
// on resolution.
mv_search_params->mv_step_param = av1_init_search_range(
- AOMMIN(max_mv_def, 2 * mv_search_params->max_mv_magnitude));
+ AOMMIN(max_mv_def, 2 * mv_search_params->max_mv_magnitude)
+#if CONFIG_MV_RANGE_EXTENSION
+ ,
+ cpi->oxcf.tool_cfg.enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
+ );
}
mv_search_params->max_mv_magnitude = -1;
}
@@ -2125,6 +2136,9 @@
// Function pointer to search site config initialization
// of different search method functions.
typedef void (*av1_init_search_site_config)(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
int stride);
av1_init_search_site_config
@@ -2164,13 +2178,24 @@
// Initialization of search_site_cfg for NUM_DISTINCT_SEARCH_METHODS.
for (SEARCH_METHODS i = DIAMOND; i < NUM_DISTINCT_SEARCH_METHODS; i++) {
av1_init_motion_compensation[i](
- &mv_search_params->search_site_cfg[SS_CFG_SRC][i], y_stride);
+ &mv_search_params->search_site_cfg[SS_CFG_SRC][i],
+#if CONFIG_MV_RANGE_EXTENSION
+ cpi->oxcf.tool_cfg.enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ y_stride);
av1_init_motion_compensation[i](
- &mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD][i], y_stride_src);
+ &mv_search_params->search_site_cfg[SS_CFG_LOOKAHEAD][i],
+#if CONFIG_MV_RANGE_EXTENSION
+ cpi->oxcf.tool_cfg.enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ y_stride_src);
}
// First pass search site config initialization.
av1_init_motion_fpf(&mv_search_params->search_site_cfg[SS_CFG_FPF][DIAMOND],
+#if CONFIG_MV_RANGE_EXTENSION
+ cpi->oxcf.tool_cfg.enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
fpf_y_stride);
for (SEARCH_METHODS i = NSTEP; i < NUM_DISTINCT_SEARCH_METHODS; i++) {
memcpy(&mv_search_params->search_site_cfg[SS_CFG_FPF][i],
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 2d48678..115de67 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -905,6 +905,10 @@
// enable MV trajectory tracking
int enable_mv_traj;
#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ // enable a large motion search window
+ int enable_high_motion;
+#endif // CONFIG_MV_RANGE_EXTENSION
// enable block adaptive weighted prediction
int enable_bawp;
// enable compound weighted prediction
@@ -1307,16 +1311,24 @@
unsigned int joint_shell_class_1_cnts[NUM_MV_PRECISIONS]
[CDF_SIZE(SECOND_SHELL_CLASS)];
#else
+#if CONFIG_MV_RANGE_EXTENSION
+ unsigned int joint_shell_class_cnts[NUM_MV_PRECISIONS][CDF_SIZE(
+ MAX_NUM_SHELL_CLASS - 1)]; // placeholder
+#else
unsigned int joint_shell_class_cnts[NUM_MV_PRECISIONS][CDF_SIZE(
MAX_NUM_SHELL_CLASS)]; // placeholder
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
+#if CONFIG_MV_RANGE_EXTENSION
+ unsigned int joint_shell_last_two_classes_cnts[CDF_SIZE(2)]; // placeholder
+#endif // CONFIG_MV_RANGE_EXTENSION
unsigned int shell_offset_low_class_cnts[2][CDF_SIZE(2)]; // placeholder
unsigned int shell_offset_class2_cnts[3][CDF_SIZE(2)]; // // placeholder
unsigned int shell_offset_other_class_cnts[NUM_CTX_CLASS_OFFSETS]
[SHELL_INT_OFFSET_BIT]
[CDF_SIZE(2)]; // placeholder
- unsigned int col_mv_greter_flags_cnts[NUM_CTX_COL_MV_GTX]
- [CDF_SIZE(2)]; // placeholder
+ unsigned int col_mv_greater_flags_cnts[NUM_CTX_COL_MV_GTX]
+ [CDF_SIZE(2)]; // placeholder
unsigned int col_mv_index_cnts[NUM_CTX_COL_MV_INDEX]
[CDF_SIZE(2)]; // placeholder
#else
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index e841958..42cb00a 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -185,11 +185,22 @@
// Refine the motion search range according to the frame dimension
// for first pass test.
-static int get_search_range(const InitialDimensions *initial_dimensions) {
+static int get_search_range(const InitialDimensions *initial_dimensions
+#if CONFIG_MV_RANGE_EXTENSION
+ ,
+ int enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
+) {
int sr = 0;
const int dim = AOMMIN(initial_dimensions->width, initial_dimensions->height);
- while ((dim << sr) < MAX_FULL_PEL_VAL) ++sr;
+#if CONFIG_MV_RANGE_EXTENSION
+ const int max_full_range =
+ enable_high_motion ? MAX_FULL_PEL_VAL : LOW_MOTION_MAX_FULL_PEL_VAL;
+#else
+ const int max_full_range = MAX_FULL_PEL_VAL;
+#endif // CONFIG_MV_RANGE_EXTENSION
+ while ((dim << sr) < max_full_range) ++sr;
return sr;
}
@@ -203,7 +214,12 @@
int tmp_err;
const BLOCK_SIZE bsize = xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART];
const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY;
- const int sr = get_search_range(&cpi->initial_dimensions);
+ const int sr = get_search_range(&cpi->initial_dimensions
+#if CONFIG_MV_RANGE_EXTENSION
+ ,
+ cpi->oxcf.tool_cfg.enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
+ );
const int step_param = 3 + sr;
const search_site_config *first_pass_search_sites =
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c
index d5b3716..a3cbe81 100644
--- a/av1/encoder/mcomp.c
+++ b/av1/encoder/mcomp.c
@@ -446,14 +446,28 @@
}
#endif // !CONFIG_TIP_MV_SIMPLIFICATION
-int av1_init_search_range(int size) {
+int av1_init_search_range(int size
+#if CONFIG_MV_RANGE_EXTENSION
+ ,
+ int enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
+) {
int sr = 0;
// Minimum search size no matter what the passed in value.
size = AOMMAX(16, size);
- while ((size << sr) < MAX_FULL_PEL_VAL) sr++;
+#if CONFIG_MV_RANGE_EXTENSION
+ const int max_full_range =
+ enable_high_motion ? MAX_FULL_PEL_VAL : LOW_MOTION_MAX_FULL_PEL_VAL;
+ const int max_search_steps =
+ enable_high_motion ? MAX_MVSEARCH_STEPS - 2 : MAX_MVSEARCH_STEPS - 4;
+#else
+ const int max_full_range = MAX_FULL_PEL_VAL;
+ const int max_search_steps = MAX_MVSEARCH_STEPS - 2;
+#endif // CONFIG_MV_RANGE_EXTENSION
+ while ((size << sr) < max_full_range) sr++;
- sr = AOMMIN(sr, MAX_MVSEARCH_STEPS - 2);
+ sr = AOMMIN(sr, max_search_steps);
return sr;
}
@@ -957,19 +971,36 @@
// =============================================================================
// Fullpixel Motion Search: Translational
// =============================================================================
+#if CONFIG_MV_RANGE_EXTENSION
+#define MAX_PATTERN_SCALES 13
+#else
#define MAX_PATTERN_SCALES 11
+#endif // CONFIG_MV_RANGE_EXTENSION
#define MAX_PATTERN_CANDIDATES 8 // max number of candidates per scale
#define PATTERN_CANDIDATES_REF 3 // number of refinement candidates
-void av1_init_dsmotion_compensation(search_site_config *cfg, int stride) {
+void av1_init_dsmotion_compensation(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride) {
int num_search_steps = 0;
+#if CONFIG_MV_RANGE_EXTENSION
+ cfg->enable_high_motion = enable_high_motion;
+ int stage_index =
+ enable_high_motion ? MAX_MVSEARCH_STEPS - 1 : MAX_MVSEARCH_STEPS - 3;
+ const int init_radius =
+ enable_high_motion ? MAX_FIRST_STEP : LOW_MOTION_MAX_FIRST_STEP;
+#else
int stage_index = MAX_MVSEARCH_STEPS - 1;
+ const int init_radius = MAX_FIRST_STEP;
+#endif // CONFIG_MV_RANGE_EXTENSION
cfg->site[stage_index][0].mv.col = cfg->site[stage_index][0].mv.row = 0;
cfg->site[stage_index][0].offset = 0;
cfg->stride = stride;
- for (int radius = MAX_FIRST_STEP; radius > 0; radius /= 2) {
+ for (int radius = init_radius; radius > 0; radius /= 2) {
int num_search_pts = 8;
const FULLPEL_MV search_site_mvs[13] = {
@@ -992,15 +1023,28 @@
cfg->num_search_steps = num_search_steps;
}
-void av1_init_motion_fpf(search_site_config *cfg, int stride) {
+void av1_init_motion_fpf(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride) {
int num_search_steps = 0;
+#if CONFIG_MV_RANGE_EXTENSION
+ cfg->enable_high_motion = enable_high_motion;
+ int stage_index =
+ enable_high_motion ? MAX_MVSEARCH_STEPS - 1 : MAX_MVSEARCH_STEPS - 3;
+ const int init_radius =
+ enable_high_motion ? MAX_FIRST_STEP : LOW_MOTION_MAX_FIRST_STEP;
+#else
int stage_index = MAX_MVSEARCH_STEPS - 1;
+ const int init_radius = MAX_FIRST_STEP;
+#endif // CONFIG_MV_RANGE_EXTENSION
cfg->site[stage_index][0].mv.col = cfg->site[stage_index][0].mv.row = 0;
cfg->site[stage_index][0].offset = 0;
cfg->stride = stride;
- for (int radius = MAX_FIRST_STEP; radius > 0; radius /= 2) {
+ for (int radius = init_radius; radius > 0; radius /= 2) {
// Generate offsets for 8 search sites per step.
int tan_radius = AOMMAX((int)(0.41 * radius), 1);
int num_search_pts = 12;
@@ -1037,16 +1081,28 @@
}
// Search site initialization for NSTEP search method.
-void av1_init_motion_compensation_nstep(search_site_config *cfg, int stride) {
+void av1_init_motion_compensation_nstep(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride) {
int num_search_steps = 0;
int stage_index = 0;
cfg->stride = stride;
int radius = 1;
-#if CONFIG_MV_SEARCH_RANGE
- for (stage_index = 0; stage_index < 16; ++stage_index) {
+#if CONFIG_MV_RANGE_EXTENSION
+ cfg->enable_high_motion = enable_high_motion;
+ // 20 corresponds to 17bits mv range for NSTEP
+ const int max_stage_index = enable_high_motion ? 20 : 16;
#else
- for (stage_index = 0; stage_index < 15; ++stage_index) {
+#if CONFIG_MV_SEARCH_RANGE
+ const int max_stage_index = 16;
+#else
+ const int max_stage_index = 15;
#endif // CONFIG_MV_SEARCH_RANGE
+#endif // CONFIG_MV_RANGE_EXTENSION
+
+ for (stage_index = 0; stage_index < max_stage_index; ++stage_index) {
int tan_radius = AOMMAX((int)(0.41 * radius), 1);
int num_search_pts = 12;
if (radius <= 5) {
@@ -1087,12 +1143,19 @@
// Search site initialization for BIGDIA / FAST_BIGDIA / FAST_DIAMOND
// search methods.
-void av1_init_motion_compensation_bigdia(search_site_config *cfg, int stride) {
+void av1_init_motion_compensation_bigdia(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride) {
cfg->stride = stride;
// First scale has 4-closest points, the rest have 8 points in diamond
// shape at increasing scales
static const int bigdia_num_candidates[MAX_PATTERN_SCALES] = {
4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+#if CONFIG_MV_RANGE_EXTENSION
+ 8, 8,
+#endif // CONFIG_MV_RANGE_EXTENSION
};
// BIGDIA search method candidates.
@@ -1122,11 +1185,24 @@
{ 256, 256 }, { 0, 512 }, { -256, 256 }, { -512, 0 } },
{ { -512, -512 }, { 0, -1024 }, { 512, -512 }, { 1024, 0 },
{ 512, 512 }, { 0, 1024 }, { -512, 512 }, { -1024, 0 } },
+#if CONFIG_MV_RANGE_EXTENSION
+ { { -1024, -1024 }, { 0, -2048 }, { 1024, -1024 }, { 2048, 0 },
+ { 1024, 1024 }, { 0, 2048 }, { -1024, 1024 }, { -2048, 0 } },
+ { { -2048, -2048 }, { 0, -4096 }, { 2048, -2048 }, { 4096, 0 },
+ { 2048, 2048 }, { 0, 4096 }, { -2048, 2048 }, { -4096, 0 } },
+#endif // CONFIG_MV_RANGE_EXTENSION
};
/* clang-format on */
int radius = 1;
- for (int i = 0; i < MAX_PATTERN_SCALES; ++i) {
+#if CONFIG_MV_RANGE_EXTENSION
+ cfg->enable_high_motion = enable_high_motion;
+ const int max_search_steps =
+ enable_high_motion ? MAX_PATTERN_SCALES : MAX_PATTERN_SCALES - 2;
+#else
+ const int max_search_steps = MAX_PATTERN_SCALES;
+#endif // CONFIG_MV_RANGE_EXTENSION
+ for (int i = 0; i < max_search_steps; ++i) {
cfg->searches_per_step[i] = bigdia_num_candidates[i];
cfg->radius[i] = radius;
for (int j = 0; j < MAX_PATTERN_CANDIDATES; ++j) {
@@ -1136,15 +1212,22 @@
}
radius *= 2;
}
- cfg->num_search_steps = MAX_PATTERN_SCALES;
+ cfg->num_search_steps = max_search_steps;
}
// Search site initialization for SQUARE search method.
-void av1_init_motion_compensation_square(search_site_config *cfg, int stride) {
+void av1_init_motion_compensation_square(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride) {
cfg->stride = stride;
// All scales have 8 closest points in square shape.
static const int square_num_candidates[MAX_PATTERN_SCALES] = {
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+#if CONFIG_MV_RANGE_EXTENSION
+ 8, 8,
+#endif // CONFIG_MV_RANGE_EXTENSION
};
// Square search method candidates.
@@ -1174,11 +1257,24 @@
{ 512, 512 }, { 0, 512 }, { -512, 512 }, { -512, 0 } },
{ { -1024, -1024 }, { 0, -1024 }, { 1024, -1024 }, { 1024, 0 },
{ 1024, 1024 }, { 0, 1024 }, { -1024, 1024 }, { -1024, 0 } },
+#if CONFIG_MV_RANGE_EXTENSION
+ { { -2048, -2048 }, { 0, -2048 }, { 2048, -2048 }, { 2048, 0 },
+ { 2048, 2048 }, { 0, 2048 }, { -2048, 2048 }, { -2048, 0 } },
+ { { -4096, -4096 }, { 0, -4096 }, { 4096, -4096 }, { 4096, 0 },
+ { 4096, 4096 }, { 0, 4096 }, { -4096, 4096 }, { -4096, 0 } },
+#endif // CONFIG_MV_RANGE_EXTENSION
};
/* clang-format on */
int radius = 1;
- for (int i = 0; i < MAX_PATTERN_SCALES; ++i) {
+#if CONFIG_MV_RANGE_EXTENSION
+ cfg->enable_high_motion = enable_high_motion;
+ const int max_search_steps =
+ enable_high_motion ? MAX_PATTERN_SCALES : MAX_PATTERN_SCALES - 2;
+#else
+ const int max_search_steps = MAX_PATTERN_SCALES;
+#endif // CONFIG_MV_RANGE_EXTENSION
+ for (int i = 0; i < max_search_steps; ++i) {
cfg->searches_per_step[i] = square_num_candidates[i];
cfg->radius[i] = radius;
for (int j = 0; j < MAX_PATTERN_CANDIDATES; ++j) {
@@ -1188,16 +1284,24 @@
}
radius *= 2;
}
- cfg->num_search_steps = MAX_PATTERN_SCALES;
+ cfg->num_search_steps = max_search_steps;
}
// Search site initialization for HEX / FAST_HEX search methods.
-void av1_init_motion_compensation_hex(search_site_config *cfg, int stride) {
+void av1_init_motion_compensation_hex(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride) {
cfg->stride = stride;
// First scale has 8-closest points, the rest have 6 points in hex shape
// at increasing scales.
- static const int hex_num_candidates[MAX_PATTERN_SCALES] = { 8, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6 };
+ static const int hex_num_candidates[MAX_PATTERN_SCALES] = {
+ 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+#if CONFIG_MV_RANGE_EXTENSION
+ 6, 6,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ };
// Note that the largest candidate step at each scale is 2^scale.
/* clang-format off */
static const FULLPEL_MV
@@ -1221,11 +1325,24 @@
{ -256, 512 }, { -512, 0 } },
{ { -512, -1024 }, { 512, -1024 }, { 1024, 0 }, { 512, 1024 },
{ -512, 1024 }, { -1024, 0 } },
+#if CONFIG_MV_RANGE_EXTENSION
+ { { -1024, -2048 }, { 1024, -2048 }, { 2048, 0 }, { 1024, 2048 },
+ { -1024, 2048 }, { -2048, 0 } },
+ { { -2048, -4096 }, { 2048, -4096 }, { 4096, 0 }, { 2048, 4096 },
+ { -2048, 4096 }, { -4096, 0 } },
+#endif // CONFIG_MV_RANGE_EXTENSION
};
/* clang-format on */
int radius = 1;
- for (int i = 0; i < MAX_PATTERN_SCALES; ++i) {
+#if CONFIG_MV_RANGE_EXTENSION
+ cfg->enable_high_motion = enable_high_motion;
+ const int max_search_steps =
+ enable_high_motion ? MAX_PATTERN_SCALES : MAX_PATTERN_SCALES - 2;
+#else
+ const int max_search_steps = MAX_PATTERN_SCALES;
+#endif // CONFIG_MV_RANGE_EXTENSION
+ for (int i = 0; i < max_search_steps; ++i) {
cfg->searches_per_step[i] = hex_num_candidates[i];
cfg->radius[i] = radius;
for (int j = 0; j < hex_num_candidates[i]; ++j) {
@@ -1235,7 +1352,7 @@
}
radius *= 2;
}
- cfg->num_search_steps = MAX_PATTERN_SCALES;
+ cfg->num_search_steps = max_search_steps;
}
// Checks whether the mv is within range of the mv_limits
@@ -1447,8 +1564,8 @@
#if CONFIG_IBC_SR_EXT
if (ms_params->is_intra_mode &&
ms_params->cm->features.allow_local_intrabc) {
- MV sub_mv = { (int16_t)GET_MV_SUBPEL(best_mv.row),
- (int16_t)GET_MV_SUBPEL(best_mv.col) };
+ MV sub_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(best_mv.row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(best_mv.col) };
int flag = av1_is_dv_valid(sub_mv, ms_params->cm, ms_params->xd,
ms_params->mi_row, ms_params->mi_col,
ms_params->bsize, ms_params->mib_size_log2);
@@ -1474,8 +1591,8 @@
#if CONFIG_IBC_SR_EXT
if (ms_params->is_intra_mode &&
ms_params->cm->features.allow_local_intrabc) {
- MV sub_mv = { (int16_t)GET_MV_SUBPEL(this_mv.row),
- (int16_t)GET_MV_SUBPEL(this_mv.col) };
+ MV sub_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(this_mv.row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(this_mv.col) };
int flag = av1_is_dv_valid(
sub_mv, ms_params->cm, ms_params->xd, ms_params->mi_row,
ms_params->mi_col, ms_params->bsize, ms_params->mib_size_log2);
@@ -1506,8 +1623,8 @@
#if CONFIG_IBC_SR_EXT
if (ms_params->is_intra_mode &&
ms_params->cm->features.allow_local_intrabc) {
- MV sub_mv = { (int16_t)GET_MV_SUBPEL(this_mv.row),
- (int16_t)GET_MV_SUBPEL(this_mv.col) };
+ MV sub_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(this_mv.row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(this_mv.col) };
int flag = av1_is_dv_valid(
sub_mv, ms_params->cm, ms_params->xd, ms_params->mi_row,
ms_params->mi_col, ms_params->bsize, ms_params->mib_size_log2);
@@ -1652,7 +1769,10 @@
int search_step, const int do_init_search,
int *cost_list, FULLPEL_MV *best_mv) {
static const int search_steps[MAX_MVSEARCH_STEPS] = {
- 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
+#if CONFIG_MV_RANGE_EXTENSION
+ 12, 11,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,
};
int i, s, t;
@@ -1668,6 +1788,11 @@
int k = -1;
const MV_COST_PARAMS *mv_cost_params = &ms_params->mv_cost_params;
search_step = AOMMIN(search_step, MAX_MVSEARCH_STEPS - 1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (!search_sites->enable_high_motion) {
+ search_step = AOMMAX(search_step, 2);
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
assert(search_step >= 0);
assert(ms_params->mv_cost_params.pb_mv_precision >= MV_PRECISION_ONE_PEL);
@@ -2044,8 +2169,8 @@
#if CONFIG_IBC_SR_EXT
if (ms_params->is_intra_mode && ms_params->cm->features.allow_local_intrabc) {
- MV sub_mv = { (int16_t)GET_MV_SUBPEL(start_mv.row),
- (int16_t)GET_MV_SUBPEL(start_mv.col) };
+ MV sub_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(start_mv.row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(start_mv.col) };
if (av1_is_dv_valid(sub_mv, ms_params->cm, ms_params->xd, ms_params->mi_row,
ms_params->mi_col, ms_params->bsize,
ms_params->mib_size_log2)) {
@@ -2090,9 +2215,10 @@
if (ms_params->is_intra_mode &&
ms_params->cm->features.allow_local_intrabc) {
for (j = 0; j < 4; j++) {
- MV sub_mv = { (int16_t)GET_MV_SUBPEL(best_mv->row + site[1 + j].mv.row),
- (int16_t)GET_MV_SUBPEL(best_mv->col +
- site[1 + j].mv.col) };
+ MV sub_mv = {
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(best_mv->row + site[1 + j].mv.row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(best_mv->col + site[1 + j].mv.col)
+ };
all_in &= av1_is_dv_valid(sub_mv, ms_params->cm, ms_params->xd,
ms_params->mi_row, ms_params->mi_col,
ms_params->bsize, ms_params->mib_size_log2);
@@ -2112,10 +2238,10 @@
for (j = 0; j < 4; j++) {
if (ms_params->is_intra_mode &&
ms_params->cm->features.allow_local_intrabc) {
- MV sub_mv = {
- (int16_t)GET_MV_SUBPEL(best_mv->row + site[idx + j].mv.row),
- (int16_t)GET_MV_SUBPEL(best_mv->col + site[idx + j].mv.col)
- };
+ MV sub_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(
+ best_mv->row + site[idx + j].mv.row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(
+ best_mv->col + site[idx + j].mv.col) };
valid &= av1_is_dv_valid(
sub_mv, ms_params->cm, ms_params->xd, ms_params->mi_row,
ms_params->mi_col, ms_params->bsize, ms_params->mib_size_log2);
@@ -2159,8 +2285,8 @@
#if CONFIG_IBC_SR_EXT
if (ms_params->is_intra_mode &&
ms_params->cm->features.allow_local_intrabc) {
- MV sub_mv = { (int16_t)GET_MV_SUBPEL(this_mv.row),
- (int16_t)GET_MV_SUBPEL(this_mv.col) };
+ MV sub_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(this_mv.row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(this_mv.col) };
int valid = av1_is_dv_valid(
sub_mv, ms_params->cm, ms_params->xd, ms_params->mi_row,
ms_params->mi_col, ms_params->bsize, ms_params->mib_size_log2);
@@ -2294,8 +2420,8 @@
*best_mv = start_mv;
#if CONFIG_IBC_SR_EXT
if (ms_params->is_intra_mode && ms_params->cm->features.allow_local_intrabc) {
- const MV sub_mv = { (int16_t)GET_MV_SUBPEL(start_mv.row),
- (int16_t)GET_MV_SUBPEL(start_mv.col) };
+ const MV sub_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(start_mv.row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(start_mv.col) };
if (av1_is_dv_valid(sub_mv, ms_params->cm, ms_params->xd, ms_params->mi_row,
ms_params->mi_col, ms_params->bsize,
ms_params->mib_size_log2)) {
@@ -2389,8 +2515,8 @@
// stores the best valid mv
if (best_valid_mv.row != best_mv->row ||
best_valid_mv.col != best_mv->col) {
- const MV sub_mv = { (int16_t)GET_MV_SUBPEL(best_mv->row),
- (int16_t)GET_MV_SUBPEL(best_mv->col) };
+ const MV sub_mv = { (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(best_mv->row),
+ (MV_COMP_DATA_TYPE)GET_MV_SUBPEL(best_mv->col) };
if (av1_is_dv_valid(sub_mv, ms_params->cm, ms_params->xd,
ms_params->mi_row, ms_params->mi_col,
ms_params->bsize, ms_params->mib_size_log2)) {
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h
index 4d73baa..cdbfb96 100644
--- a/av1/encoder/mcomp.h
+++ b/av1/encoder/mcomp.h
@@ -25,6 +25,17 @@
// The maximum number of steps in a step search given the largest
// allowed initial step
+#if CONFIG_MV_RANGE_EXTENSION
+#define MAX_MVSEARCH_STEPS 13
+// Enable the use of motion vector in range [-8191, 8191].
+#define MAX_FULL_PEL_VAL ((1 << MV_CLASSES) - 1)
+// Enable the use of motion vector in range [-2047, 2047] for low motion
+#define LOW_MOTION_MAX_FULL_PEL_VAL ((1 << (MV_CLASSES - 2)) - 1)
+// Maximum size of the first step in full pel units
+#define MAX_FIRST_STEP ((1 << MAX_MVSEARCH_STEPS) - 1)
+// Maximum size of the first step in full pel units for low motion
+#define LOW_MOTION_MAX_FIRST_STEP ((1 << (MAX_MVSEARCH_STEPS - 2)) - 1)
+#else
#define MAX_MVSEARCH_STEPS 11
// Max full pel mv specified in the unit of full pixel
#if CONFIG_MV_SEARCH_RANGE
@@ -36,6 +47,7 @@
#endif // CONFIG_MV_SEARCH_RANGE
// Maximum size of the first step in full pel units
#define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS - 1))
+#endif // CONFIG_MV_RANGE_EXTENSION
// Maximum number of neighbors to scan per iteration during
// WARP_CAUSAL refinement
// Note: The elements of warp_search_config.neighbor_mask must be at least
@@ -61,6 +73,9 @@
int searches_per_step[MAX_MVSEARCH_STEPS * 2];
int radius[MAX_MVSEARCH_STEPS * 2];
int stride;
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion;
+#endif // CONFIG_MV_RANGE_EXTENSION
} search_site_config;
typedef struct {
@@ -244,23 +259,46 @@
#if CONFIG_IBC_BV_IMPROVEMENT
const int is_ibc_cost,
#endif
-
const search_site_config search_sites[NUM_DISTINCT_SEARCH_METHODS],
int fine_search_interval);
// Sets up configs for fullpixel diamond search method.
-void av1_init_dsmotion_compensation(search_site_config *cfg, int stride);
+void av1_init_dsmotion_compensation(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride);
// Sets up configs for firstpass motion search.
-void av1_init_motion_fpf(search_site_config *cfg, int stride);
+void av1_init_motion_fpf(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride);
// Sets up configs for all other types of motion search method.
-void av1_init_motion_compensation_nstep(search_site_config *cfg, int stride);
+void av1_init_motion_compensation_nstep(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride);
// Sets up configs for BIGDIA / FAST_DIAMOND / FAST_BIGDIA
// motion search method.
-void av1_init_motion_compensation_bigdia(search_site_config *cfg, int stride);
+void av1_init_motion_compensation_bigdia(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride);
// Sets up configs for HEX or FAST_HEX motion search method.
-void av1_init_motion_compensation_hex(search_site_config *cfg, int stride);
+void av1_init_motion_compensation_hex(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride);
// Sets up configs for SQUARE motion search method.
-void av1_init_motion_compensation_square(search_site_config *cfg, int stride);
+void av1_init_motion_compensation_square(search_site_config *cfg,
+#if CONFIG_MV_RANGE_EXTENSION
+ int enable_high_motion,
+#endif // CONFIG_MV_RANGE_EXTENSION
+ int stride);
// Mv beyond the range do not produce new/different prediction block.
static INLINE void av1_set_mv_search_method(
@@ -355,7 +393,12 @@
void av1_set_tip_mv_search_range(FullMvLimits *mv_limits);
#endif // !CONFIG_TIP_MV_SIMPLIFICATION
-int av1_init_search_range(int size);
+int av1_init_search_range(int size
+#if CONFIG_MV_RANGE_EXTENSION
+ ,
+ int enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
+);
int av1_refining_search_8p_c(const FULLPEL_MOTION_SEARCH_PARAMS *ms_params,
const FULLPEL_MV start_mv, FULLPEL_MV *best_mv);
diff --git a/av1/encoder/motion_search_facade.c b/av1/encoder/motion_search_facade.c
index 4f13af1..c9b762c 100644
--- a/av1/encoder/motion_search_facade.c
+++ b/av1/encoder/motion_search_facade.c
@@ -101,7 +101,12 @@
// max mv magnitude and that based on the best ref mvs of the current
// block for the given reference.
const int ref_frame_idx = COMPACT_INDEX0_NRS(ref);
- step_param = (av1_init_search_range(x->max_mv_context[ref_frame_idx]) +
+ step_param = (av1_init_search_range(x->max_mv_context[ref_frame_idx]
+#if CONFIG_MV_RANGE_EXTENSION
+ ,
+ cpi->oxcf.tool_cfg.enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
+ ) +
mv_search_params->mv_step_param) /
2;
} else {
@@ -1477,10 +1482,17 @@
struct buf_2d backup_yv12;
// ref_mv is used to calculate the cost of the motion vector
const MV ref_mv = kZeroMv;
+#if CONFIG_MV_RANGE_EXTENSION
+ const int max_search_steps = cpi->oxcf.tool_cfg.enable_high_motion
+ ? MAX_MVSEARCH_STEPS - 2
+ : MAX_MVSEARCH_STEPS - 4;
+#else
+ const int max_search_steps = MAX_MVSEARCH_STEPS - 2;
+#endif // CONFIG_MV_RANGE_EXTENSION
const int step_param =
AOMMIN(cpi->mv_search_params.mv_step_param +
cpi->sf.part_sf.simple_motion_search_reduce_search_steps,
- MAX_MVSEARCH_STEPS - 2);
+ max_search_steps);
const search_site_config *src_search_sites =
cpi->mv_search_params.search_site_cfg[SS_CFG_SRC];
int cost_list[5];
@@ -1638,10 +1650,17 @@
struct buf_2d backup_yv12;
// ref_mv is used to calculate the cost of the motion vector
const MV ref_mv = kZeroMv;
+#if CONFIG_MV_RANGE_EXTENSION
+ const int max_search_steps = cpi->oxcf.tool_cfg.enable_high_motion
+ ? MAX_MVSEARCH_STEPS - 2
+ : MAX_MVSEARCH_STEPS - 4;
+#else
+ const int max_search_steps = MAX_MVSEARCH_STEPS - 2;
+#endif // CONFIG_MV_RANGE_EXTENSION
const int step_param =
AOMMIN(cpi->mv_search_params.mv_step_param +
cpi->sf.part_sf.simple_motion_search_reduce_search_steps,
- MAX_MVSEARCH_STEPS - 2);
+ max_search_steps);
const search_site_config *src_search_sites =
cpi->mv_search_params.search_site_cfg[SS_CFG_SRC];
int cost_list[5];
diff --git a/av1/encoder/mv_prec.c b/av1/encoder/mv_prec.c
index 982cdc6..5c21368 100644
--- a/av1/encoder/mv_prec.c
+++ b/av1/encoder/mv_prec.c
@@ -458,18 +458,55 @@
num_mv_class_0);
} else {
total_rate += get_symbol_cost(mvctx->joint_shell_set_cdf, 1);
- total_rate +=
- get_symbol_cost(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
- shell_class - num_mv_class_0);
update_cdf(mvctx->joint_shell_set_cdf, 1, 2);
- update_cdf(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
- shell_class - num_mv_class_0, num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (pb_mv_precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ const int map_shell_class = get_map_shell_class(shell_class);
+ total_rate +=
+ get_symbol_cost(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
+ map_shell_class - num_mv_class_0);
+ update_cdf(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
+ map_shell_class - num_mv_class_0, num_mv_class_1 - 1);
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ total_rate += get_symbol_cost(mvctx->joint_shell_last_two_classes_cdf,
+ shell_class == MAX_NUM_SHELL_CLASS - 1);
+ update_cdf(mvctx->joint_shell_last_two_classes_cdf,
+ shell_class == MAX_NUM_SHELL_CLASS - 1, 2);
+ }
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ total_rate +=
+ get_symbol_cost(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
+ shell_class - num_mv_class_0);
+ update_cdf(mvctx->joint_shell_class_cdf_1[pb_mv_precision],
+ shell_class - num_mv_class_0, num_mv_class_1);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
}
#else
- total_rate += get_symbol_cost(mvctx->joint_shell_class_cdf[pb_mv_precision],
- shell_class);
- update_cdf(mvctx->joint_shell_class_cdf[pb_mv_precision], shell_class,
- num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ if (pb_mv_precision == MV_PRECISION_ONE_EIGHTH_PEL) {
+ const int map_shell_class = get_map_shell_class(shell_class);
+ total_rate += get_symbol_cost(mvctx->joint_shell_class_cdf[pb_mv_precision],
+ map_shell_class);
+ update_cdf(mvctx->joint_shell_class_cdf[pb_mv_precision], map_shell_class,
+ num_mv_class - 1);
+ if (shell_class >= MAX_NUM_SHELL_CLASS - 2) {
+ total_rate += get_symbol_cost(mvctx->joint_shell_last_two_classes_cdf,
+ shell_class == MAX_NUM_SHELL_CLASS - 1);
+ update_cdf(mvctx->joint_shell_last_two_classes_cdf,
+ shell_class == MAX_NUM_SHELL_CLASS - 1, 2);
+ }
+ } else {
+#endif // CONFIG_MV_RANGE_EXTENSION
+ total_rate += get_symbol_cost(mvctx->joint_shell_class_cdf[pb_mv_precision],
+ shell_class);
+ update_cdf(mvctx->joint_shell_class_cdf[pb_mv_precision], shell_class,
+ num_mv_class);
+#if CONFIG_MV_RANGE_EXTENSION
+ }
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
assert(shell_class >= 0 && shell_class < num_mv_class);
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index b44e2b4..bf476ce 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -235,7 +235,12 @@
const search_site_config *search_site_cfg =
cpi->mv_search_params.search_site_cfg[SS_CFG_LOOKAHEAD];
const int step_param = av1_init_search_range(
- AOMMAX(frame_to_filter->y_crop_width, frame_to_filter->y_crop_height));
+ AOMMAX(frame_to_filter->y_crop_width, frame_to_filter->y_crop_height)
+#if CONFIG_MV_RANGE_EXTENSION
+ ,
+ cpi->oxcf.tool_cfg.enable_high_motion
+#endif // CONFIG_MV_RANGE_EXTENSION
+ );
const SUBPEL_SEARCH_TYPE subpel_search_type = USE_8_TAPS;
const int force_integer_mv = cpi->common.features.cur_frame_force_integer_mv;
const MV_COST_TYPE mv_cost_type =
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 24339b4..0a59e13 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -226,7 +226,14 @@
xd->mi[0]->use_amvd = 0;
step_param = tpl_sf->reduce_first_step_size;
- step_param = AOMMIN(step_param, MAX_MVSEARCH_STEPS - 2);
+#if CONFIG_MV_RANGE_EXTENSION
+ const int max_search_steps = cpi->oxcf.tool_cfg.enable_high_motion
+ ? MAX_MVSEARCH_STEPS - 2
+ : MAX_MVSEARCH_STEPS - 4;
+#else
+ const int max_search_steps = MAX_MVSEARCH_STEPS - 2;
+#endif // CONFIG_MV_RANGE_EXTENSION
+ step_param = AOMMIN(step_param, max_search_steps);
const search_site_config *search_site_cfg =
cpi->mv_search_params.search_site_cfg[SS_CFG_SRC];
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index ebaacaf..ef9d1af 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -378,6 +378,9 @@
set_aom_config_var(CONFIG_CTX_MODELS_LINE_BUFFER_REDUCTION 1
"Enable to reduce context model line buffer size")
+set_aom_config_var(CONFIG_MV_RANGE_EXTENSION 1
+ "Enable to extend the range of MV")
+
# This is an encode-only change.
set_aom_config_var(CONFIG_MV_SEARCH_RANGE 1
"Enable a sufficient MV search range.")
diff --git a/common/args.c b/common/args.c
index 62cb59b..7205301 100644
--- a/common/args.c
+++ b/common/args.c
@@ -90,6 +90,12 @@
GET_PARAMS(enable_extended_sdp);
GET_PARAMS(enable_mrls);
GET_PARAMS(enable_tip);
+#if CONFIG_TMVP_SIMPLIFICATIONS_F085
+ GET_PARAMS(enable_mv_traj);
+#endif // CONFIG_TMVP_SIMPLIFICATIONS_F085
+#if CONFIG_MV_RANGE_EXTENSION
+ GET_PARAMS(enable_high_motion);
+#endif // CONFIG_MV_RANGE_EXTENSION
GET_PARAMS(enable_bawp);
GET_PARAMS(enable_cwp);
#if CONFIG_D071_IMP_MSK_BLD
diff --git a/tools/aom_entropy_optimizer.c b/tools/aom_entropy_optimizer.c
index 9c0e0c3..a2c0361 100644
--- a/tools/aom_entropy_optimizer.c
+++ b/tools/aom_entropy_optimizer.c
@@ -719,6 +719,15 @@
"[NUM_MV_PRECISIONS][CDF_SIZE(SECOND_SHELL_CLASS)]",
0, &total_count, 0, mem_wanted, "Inter");
#else
+#if CONFIG_MV_RANGE_EXTENSION
+ cts_each_dim[0] = ibc == 0 ? NUM_MV_PRECISIONS : 1;
+ cts_each_dim[1] = MAX_NUM_SHELL_CLASS - 1;
+ optimize_cdf_table(&nmvc_cnts->joint_shell_class_cnts[0][0], probsfile, 2,
+ cts_each_dim,
+ "static aom_cdf_prob joint_shell_class_cdf_placeholder"
+ "[NUM_MV_PRECISIONS][CDF_SIZE(MAX_NUM_SHELL_CLASS - 1)]",
+ 0, &total_count, 0, mem_wanted, "Inter");
+#else
cts_each_dim[0] = ibc == 0 ? NUM_MV_PRECISIONS : 1;
cts_each_dim[1] = MAX_NUM_SHELL_CLASS;
optimize_cdf_table(&nmvc_cnts->joint_shell_class_cnts[0][0], probsfile, 2,
@@ -726,8 +735,19 @@
"static aom_cdf_prob joint_shell_class_cdf_placeholder"
"[NUM_MV_PRECISIONS][CDF_SIZE(MAX_NUM_SHELL_CLASS)]",
0, &total_count, 0, mem_wanted, "Inter");
+#endif // CONFIG_MV_RANGE_EXTENSION
#endif // CONFIG_REDUCE_SYMBOL_SIZE
+#if CONFIG_MV_RANGE_EXTENSION
+ cts_each_dim[0] = 2;
+ optimize_cdf_table(
+ &nmvc_cnts->joint_shell_last_two_classes_cnts[0], probsfile, 1,
+ cts_each_dim,
+ "static aom_cdf_prob joint_shell_last_two_classes_cdf_placeholder"
+ "[CDF_SIZE(2)]",
+ 0, &total_count, 0, mem_wanted, "Inter");
+#endif // CONFIG_MV_RANGE_EXTENSION
+
cts_each_dim[0] = 2;
cts_each_dim[1] = 2;
optimize_cdf_table(
@@ -758,11 +778,11 @@
#endif // !CONFIG_CTX_MV_SHELL_OFFSET_OTHER
cts_each_dim[0] = NUM_CTX_COL_MV_GTX;
cts_each_dim[1] = 2;
- optimize_cdf_table(&nmvc_cnts->col_mv_greter_flags_cnts[0][0], probsfile, 2,
- cts_each_dim,
- "static aom_cdf_prob col_mv_greter_flags_cdf_placeholder"
- "[NUM_CTX_COL_MV_GTX][CDF_SIZE(2)]",
- 0, &total_count, 0, mem_wanted, "Inter");
+ optimize_cdf_table(
+ &nmvc_cnts->col_mv_greater_flags_cnts[0][0], probsfile, 2, cts_each_dim,
+ "static aom_cdf_prob col_mv_greater_flags_cdf_placeholder"
+ "[NUM_CTX_COL_MV_GTX][CDF_SIZE(2)]",
+ 0, &total_count, 0, mem_wanted, "Inter");
cts_each_dim[0] = NUM_CTX_COL_MV_INDEX;
cts_each_dim[1] = 2;