From 8f8e7bb53c55bccb4378c9533988045135198605 Mon Sep 17 00:00:00 2001 From: Eemeli Kallio Date: Tue, 12 Feb 2019 09:21:03 +0200 Subject: [PATCH] Added possibility to reduce number of maximum number of merge candidates. --- build/kvazaar_cli/kvazaar_cli.vcxproj | 10 ++++---- build/kvazaar_lib/kvazaar_lib.vcxproj | 10 ++++---- build/kvazaar_tests/kvazaar_tests.vcxproj | 10 ++++---- src/cfg.c | 4 ++++ src/cli.c | 1 + src/encode_coding_tree.c | 4 ++-- src/encoder_state-bitstream.c | 4 ++-- src/inter.c | 29 +++++++++++++---------- src/kvazaar.h | 3 +++ src/rdo.c | 2 +- 10 files changed, 44 insertions(+), 33 deletions(-) diff --git a/build/kvazaar_cli/kvazaar_cli.vcxproj b/build/kvazaar_cli/kvazaar_cli.vcxproj index 173acd36..c6344f53 100644 --- a/build/kvazaar_cli/kvazaar_cli.vcxproj +++ b/build/kvazaar_cli/kvazaar_cli.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -26,19 +26,19 @@ true - v120 + v140 true - v120 + v140 false - v120 + v140 false - v120 + v140 diff --git a/build/kvazaar_lib/kvazaar_lib.vcxproj b/build/kvazaar_lib/kvazaar_lib.vcxproj index 0f3a0e73..209b071b 100644 --- a/build/kvazaar_lib/kvazaar_lib.vcxproj +++ b/build/kvazaar_lib/kvazaar_lib.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -27,22 +27,22 @@ StaticLibrary true - v120 + v140 StaticLibrary true - v120 + v140 StaticLibrary false - v120 + v140 StaticLibrary false - v120 + v140 diff --git a/build/kvazaar_tests/kvazaar_tests.vcxproj b/build/kvazaar_tests/kvazaar_tests.vcxproj index 9766bc1e..fcd7e6bb 100644 --- a/build/kvazaar_tests/kvazaar_tests.vcxproj +++ b/build/kvazaar_tests/kvazaar_tests.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -26,19 +26,19 @@ true - v120 + v140 true - v120 + v140 false - v120 + v140 false - v120 + v140 diff --git a/src/cfg.c b/src/cfg.c index ba77bbab..40660b7f 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -138,6 +138,8 @@ int kvz_config_init(kvz_config *cfg) cfg->scaling_list = KVZ_SCALING_LIST_OFF; + cfg->max_merge = 5; + return 1; } @@ -1226,6 +1228,8 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value) } else if (OPT("fast-residual-cost")) cfg->fast_residual_cost_limit = atoi(value); + else if (OPT("max-merge")) + cfg->max_merge = atoi(value); else { return 0; } diff --git a/src/cli.c b/src/cli.c index 418caa99..7596b905 100644 --- a/src/cli.c +++ b/src/cli.c @@ -134,6 +134,7 @@ static const struct option long_options[] = { { "open-gop", no_argument, NULL, 0 }, { "no-open-gop", no_argument, NULL, 0 }, { "scaling-list", required_argument, NULL, 0 }, + { "max-merge", required_argument, NULL, 0 }, {0, 0, 0, 0} }; diff --git a/src/encode_coding_tree.c b/src/encode_coding_tree.c index b8c5600b..19f11351 100644 --- a/src/encode_coding_tree.c +++ b/src/encode_coding_tree.c @@ -302,7 +302,7 @@ static void encode_inter_prediction_unit(encoder_state_t * const state, int16_t num_cand = 0; cabac->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model); CABAC_BIN(cabac, cur_cu->merged, "MergeFlag"); - num_cand = MRG_MAX_NUM_CANDS; + num_cand = state->encoder_control->cfg.max_merge; if (cur_cu->merged) { //merge if (num_cand > 1) { int32_t ui; @@ -801,7 +801,7 @@ void kvz_encode_coding_tree(encoder_state_t * const state, CABAC_BIN(cabac, cur_cu->skipped, "SkipFlag"); if (cur_cu->skipped) { - int16_t num_cand = MRG_MAX_NUM_CANDS; + int16_t num_cand = state->encoder_control->cfg.max_merge; if (num_cand > 1) { for (int ui = 0; ui < num_cand - 1; ui++) { int32_t symbol = (ui != cur_cu->merge_idx); diff --git a/src/encoder_state-bitstream.c b/src/encoder_state-bitstream.c index ebd2d2c4..fad2dbf6 100644 --- a/src/encoder_state-bitstream.c +++ b/src/encoder_state-bitstream.c @@ -806,8 +806,8 @@ static void kvz_encoder_state_write_bitstream_slice_header_independent( WRITE_UE(stream, 0, "collocated_ref_idx"); } } - - WRITE_UE(stream, 5-MRG_MAX_NUM_CANDS, "five_minus_max_num_merge_cand"); + uint8_t max_merge_cands = state->encoder_control->cfg.max_merge; + WRITE_UE(stream, 5- max_merge_cands, "five_minus_max_num_merge_cand"); } { diff --git a/src/inter.c b/src/inter.c index 67adddb5..93237ffa 100644 --- a/src/inter.c +++ b/src/inter.c @@ -1280,11 +1280,14 @@ static bool is_duplicate_candidate(const cu_info_t* cu1, const cu_info_t* cu2) static bool add_merge_candidate(const cu_info_t *cand, const cu_info_t *possible_duplicate1, const cu_info_t *possible_duplicate2, - inter_merge_cand_t *merge_cand_out) + inter_merge_cand_t *merge_cand_out, + uint8_t candidates, + uint8_t max_num_cands) { if (!cand || is_duplicate_candidate(cand, possible_duplicate1) || - is_duplicate_candidate(cand, possible_duplicate2)) { + is_duplicate_candidate(cand, possible_duplicate2) || + candidates >= max_num_cands) { return false; } @@ -1322,7 +1325,7 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state, int8_t zero_idx = 0; merge_candidates_t merge_cand = { {0, 0}, {0, 0, 0}, 0, 0 }; - + uint8_t max_num_cands = state->encoder_control->cfg.max_merge; get_spatial_merge_candidates(x, y, width, height, state->tile->frame->width, state->tile->frame->height, @@ -1335,16 +1338,16 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state, if (!use_a1) a[1] = NULL; if (!use_b1) b[1] = NULL; - if (add_merge_candidate(a[1], NULL, NULL, &mv_cand[candidates])) candidates++; - if (add_merge_candidate(b[1], a[1], NULL, &mv_cand[candidates])) candidates++; - if (add_merge_candidate(b[0], b[1], NULL, &mv_cand[candidates])) candidates++; - if (add_merge_candidate(a[0], a[1], NULL, &mv_cand[candidates])) candidates++; + if (add_merge_candidate(a[1], NULL, NULL, &mv_cand[candidates], candidates, max_num_cands)) candidates++; + if (add_merge_candidate(b[1], a[1], NULL, &mv_cand[candidates], candidates, max_num_cands)) candidates++; + if (add_merge_candidate(b[0], b[1], NULL, &mv_cand[candidates], candidates, max_num_cands)) candidates++; + if (add_merge_candidate(a[0], a[1], NULL, &mv_cand[candidates], candidates, max_num_cands)) candidates++; if (candidates < 4 && - add_merge_candidate(b[2], a[1], b[1], &mv_cand[candidates])) candidates++; + add_merge_candidate(b[2], a[1], b[1], &mv_cand[candidates], candidates, max_num_cands)) candidates++; bool can_use_tmvp = state->encoder_control->cfg.tmvp_enable && - candidates < MRG_MAX_NUM_CANDS && + candidates < max_num_cands && state->frame->ref->used_size; if (can_use_tmvp) { @@ -1375,12 +1378,12 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state, if (mv_cand[candidates].dir != 0) candidates++; } - if (candidates < MRG_MAX_NUM_CANDS && state->frame->slicetype == KVZ_SLICE_B) { + if (candidates < max_num_cands && state->frame->slicetype == KVZ_SLICE_B) { #define NUM_PRIORITY_LIST 12; static const uint8_t priorityList0[] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3 }; static const uint8_t priorityList1[] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 }; uint8_t cutoff = candidates; - for (int32_t idx = 0; idx= candidates || j >= candidates) break; @@ -1412,7 +1415,7 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state, int num_ref = state->frame->ref->used_size; - if (candidates < MRG_MAX_NUM_CANDS && state->frame->slicetype == KVZ_SLICE_B) { + if (candidates < max_num_cands && state->frame->slicetype == KVZ_SLICE_B) { int j; int ref_negative = 0; int ref_positive = 0; @@ -1427,7 +1430,7 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state, } // Add (0,0) prediction - while (candidates != MRG_MAX_NUM_CANDS) { + while (candidates != max_num_cands) { mv_cand[candidates].mv[0][0] = 0; mv_cand[candidates].mv[0][1] = 0; mv_cand[candidates].ref[0] = (zero_idx >= num_ref - 1) ? 0 : zero_idx; diff --git a/src/kvazaar.h b/src/kvazaar.h index 7209b636..21c10d53 100644 --- a/src/kvazaar.h +++ b/src/kvazaar.h @@ -384,6 +384,9 @@ typedef struct kvz_config /** \brief Type of scaling lists to use */ int8_t scaling_list; + /** \brief Maximum number of merge cadidates */ + uint8_t max_merge; + } kvz_config; /** diff --git a/src/rdo.c b/src/rdo.c index 1cad8b00..12e9cfd7 100644 --- a/src/rdo.c +++ b/src/rdo.c @@ -974,7 +974,7 @@ uint32_t kvz_calc_mvd_cost_cabac(const encoder_state_t * state, cabac->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model); CABAC_BIN(cabac, merged, "MergeFlag"); - num_cand = MRG_MAX_NUM_CANDS; + num_cand = state->encoder_control->cfg.max_merge; if (merged) { if (num_cand > 1) { int32_t ui;