Added possibility to reduce number of maximum number of merge candidates.

This commit is contained in:
Eemeli Kallio 2019-02-12 09:21:03 +02:00
parent a13fc51003
commit 8f8e7bb53c
10 changed files with 44 additions and 33 deletions

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -26,19 +26,19 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -27,22 +27,22 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -26,19 +26,19 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">

View file

@ -138,6 +138,8 @@ int kvz_config_init(kvz_config *cfg)
cfg->scaling_list = KVZ_SCALING_LIST_OFF; cfg->scaling_list = KVZ_SCALING_LIST_OFF;
cfg->max_merge = 5;
return 1; 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")) else if (OPT("fast-residual-cost"))
cfg->fast_residual_cost_limit = atoi(value); cfg->fast_residual_cost_limit = atoi(value);
else if (OPT("max-merge"))
cfg->max_merge = atoi(value);
else { else {
return 0; return 0;
} }

View file

@ -134,6 +134,7 @@ static const struct option long_options[] = {
{ "open-gop", no_argument, NULL, 0 }, { "open-gop", no_argument, NULL, 0 },
{ "no-open-gop", no_argument, NULL, 0 }, { "no-open-gop", no_argument, NULL, 0 },
{ "scaling-list", required_argument, NULL, 0 }, { "scaling-list", required_argument, NULL, 0 },
{ "max-merge", required_argument, NULL, 0 },
{0, 0, 0, 0} {0, 0, 0, 0}
}; };

View file

@ -302,7 +302,7 @@ static void encode_inter_prediction_unit(encoder_state_t * const state,
int16_t num_cand = 0; int16_t num_cand = 0;
cabac->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model); cabac->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model);
CABAC_BIN(cabac, cur_cu->merged, "MergeFlag"); 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 (cur_cu->merged) { //merge
if (num_cand > 1) { if (num_cand > 1) {
int32_t ui; int32_t ui;
@ -801,7 +801,7 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
CABAC_BIN(cabac, cur_cu->skipped, "SkipFlag"); CABAC_BIN(cabac, cur_cu->skipped, "SkipFlag");
if (cur_cu->skipped) { 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) { if (num_cand > 1) {
for (int ui = 0; ui < num_cand - 1; ui++) { for (int ui = 0; ui < num_cand - 1; ui++) {
int32_t symbol = (ui != cur_cu->merge_idx); int32_t symbol = (ui != cur_cu->merge_idx);

View file

@ -806,8 +806,8 @@ static void kvz_encoder_state_write_bitstream_slice_header_independent(
WRITE_UE(stream, 0, "collocated_ref_idx"); WRITE_UE(stream, 0, "collocated_ref_idx");
} }
} }
uint8_t max_merge_cands = state->encoder_control->cfg.max_merge;
WRITE_UE(stream, 5-MRG_MAX_NUM_CANDS, "five_minus_max_num_merge_cand"); WRITE_UE(stream, 5- max_merge_cands, "five_minus_max_num_merge_cand");
} }
{ {

View file

@ -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, static bool add_merge_candidate(const cu_info_t *cand,
const cu_info_t *possible_duplicate1, const cu_info_t *possible_duplicate1,
const cu_info_t *possible_duplicate2, 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 || if (!cand ||
is_duplicate_candidate(cand, possible_duplicate1) || is_duplicate_candidate(cand, possible_duplicate1) ||
is_duplicate_candidate(cand, possible_duplicate2)) { is_duplicate_candidate(cand, possible_duplicate2) ||
candidates >= max_num_cands) {
return false; return false;
} }
@ -1322,7 +1325,7 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
int8_t zero_idx = 0; int8_t zero_idx = 0;
merge_candidates_t merge_cand = { {0, 0}, {0, 0, 0}, 0, 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, get_spatial_merge_candidates(x, y, width, height,
state->tile->frame->width, state->tile->frame->width,
state->tile->frame->height, 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_a1) a[1] = NULL;
if (!use_b1) b[1] = NULL; if (!use_b1) b[1] = NULL;
if (add_merge_candidate(a[1], NULL, 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++; 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++; 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++; if (add_merge_candidate(a[0], a[1], NULL, &mv_cand[candidates], candidates, max_num_cands)) candidates++;
if (candidates < 4 && 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 = bool can_use_tmvp =
state->encoder_control->cfg.tmvp_enable && state->encoder_control->cfg.tmvp_enable &&
candidates < MRG_MAX_NUM_CANDS && candidates < max_num_cands &&
state->frame->ref->used_size; state->frame->ref->used_size;
if (can_use_tmvp) { 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 (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; #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 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 }; static const uint8_t priorityList1[] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2 };
uint8_t cutoff = candidates; uint8_t cutoff = candidates;
for (int32_t idx = 0; idx<cutoff*(cutoff - 1) && candidates != MRG_MAX_NUM_CANDS; idx++) { for (int32_t idx = 0; idx<cutoff*(cutoff - 1) && candidates != max_num_cands; idx++) {
uint8_t i = priorityList0[idx]; uint8_t i = priorityList0[idx];
uint8_t j = priorityList1[idx]; uint8_t j = priorityList1[idx];
if (i >= candidates || j >= candidates) break; if (i >= 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; 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 j;
int ref_negative = 0; int ref_negative = 0;
int ref_positive = 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 // 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][0] = 0;
mv_cand[candidates].mv[0][1] = 0; mv_cand[candidates].mv[0][1] = 0;
mv_cand[candidates].ref[0] = (zero_idx >= num_ref - 1) ? 0 : zero_idx; mv_cand[candidates].ref[0] = (zero_idx >= num_ref - 1) ? 0 : zero_idx;

View file

@ -384,6 +384,9 @@ typedef struct kvz_config
/** \brief Type of scaling lists to use */ /** \brief Type of scaling lists to use */
int8_t scaling_list; int8_t scaling_list;
/** \brief Maximum number of merge cadidates */
uint8_t max_merge;
} kvz_config; } kvz_config;
/** /**

View file

@ -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->cur_ctx = &(cabac->ctx.cu_merge_flag_ext_model);
CABAC_BIN(cabac, merged, "MergeFlag"); CABAC_BIN(cabac, merged, "MergeFlag");
num_cand = MRG_MAX_NUM_CANDS; num_cand = state->encoder_control->cfg.max_merge;
if (merged) { if (merged) {
if (num_cand > 1) { if (num_cand > 1) {
int32_t ui; int32_t ui;