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;