diff --git a/README.md b/README.md index 5c839386..aec115ea 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,10 @@ Video structure: (e.g. lp-g8d4t2, see README) --(no-)open-gop : Use open GOP configuration. [enabled] --cqmfile : Read custom quantization matrices from a file. + --scaling-list : Set scaling list mode. [off]\n" + - off: Disable scaling lists.\n" + - custom: use custom list (with --cqmfile).\n" + - default: Use default lists.\n" --bitrate : Target bitrate [0] - 0: Disable rate control. - N: Target N bits per second. diff --git a/doc/kvazaar.1 b/doc/kvazaar.1 index fbfb1662..19b7adcc 100644 --- a/doc/kvazaar.1 +++ b/doc/kvazaar.1 @@ -127,6 +127,12 @@ Use open GOP configuration. [enabled] \fB\-\-cqmfile Read custom quantization matrices from a file. .TP +\fB\-\-scaling-list +Set scaling list mode. [off] + \- off: Disable scaling lists. + \- custom: use custom list (with \-\-cqmfile). + \- default: Use default lists. +.TP \fB\-\-bitrate Target bitrate [0] \- 0: Disable rate control. diff --git a/src/cfg.c b/src/cfg.c index 234e4a31..ba77bbab 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -136,6 +136,8 @@ int kvz_config_init(kvz_config *cfg) cfg->me_max_steps = (uint32_t)-1; + cfg->scaling_list = KVZ_SCALING_LIST_OFF; + return 1; } @@ -379,6 +381,8 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value) static const char * const sao_names[] = { "off", "edge", "band", "full", NULL }; + static const char * const scaling_list_names[] = { "off", "custom", "default", NULL }; + static const char * const preset_values[11][23*2] = { { "ultrafast", @@ -758,6 +762,13 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value) } FREE_POINTER(cfg->cqmfile); cfg->cqmfile = cqmfile; + cfg->scaling_list = KVZ_SCALING_LIST_CUSTOM; + } + else if OPT("scaling-list") { + int8_t scaling_list = KVZ_SCALING_LIST_OFF; + int result = parse_enum(value, scaling_list_names, &scaling_list); + cfg->scaling_list = scaling_list; + return result; } else if OPT("tiles-width-split") { int retval = parse_tiles_specification(value, &cfg->tiles_width_count, &cfg->tiles_width_split); @@ -1517,6 +1528,11 @@ int kvz_config_validate(const kvz_config *const cfg) error = 1; } + if ((cfg->scaling_list == KVZ_SCALING_LIST_CUSTOM) && !cfg->cqmfile) { + fprintf(stderr, "Input error: --scaling-list=custom does not work without --cqmfile=.\n"); + error = 1; + } + if (validate_hevc_level((kvz_config *const) cfg)) { // a level error found and it's not okay error = 1; diff --git a/src/cli.c b/src/cli.c index 32618aa6..418caa99 100644 --- a/src/cli.c +++ b/src/cli.c @@ -133,6 +133,7 @@ static const struct option long_options[] = { { "set-qp-in-cu", no_argument, NULL, 0 }, { "open-gop", no_argument, NULL, 0 }, { "no-open-gop", no_argument, NULL, 0 }, + { "scaling-list", required_argument, NULL, 0 }, {0, 0, 0, 0} }; @@ -399,6 +400,10 @@ void print_help(void) " (e.g. lp-g8d4t2, see README)\n" " --(no-)open-gop : Use open GOP configuration. [enabled]\n" " --cqmfile : Read custom quantization matrices from a file.\n" + " --scaling-list : Set scaling list mode. [off]\n" + " - off: Disable scaling lists.\n" + " - custom: use custom list (with --cqmfile).\n" + " - default: Use default lists.\n" " --bitrate : Target bitrate [0]\n" " - 0: Disable rate control.\n" " - N: Target N bits per second.\n" diff --git a/src/encoder.c b/src/encoder.c index e8ef68e6..1365200c 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -305,7 +305,7 @@ encoder_control_t* kvz_encoder_control_init(const kvz_config *const cfg) kvz_scalinglist_init(&encoder->scaling_list); // CQM - if (cfg->cqmfile) { + if (cfg->scaling_list == KVZ_SCALING_LIST_CUSTOM && cfg->cqmfile) { FILE* cqmfile = fopen(cfg->cqmfile, "rb"); if (cqmfile) { kvz_scalinglist_parse(&encoder->scaling_list, cqmfile); @@ -314,7 +314,12 @@ encoder_control_t* kvz_encoder_control_init(const kvz_config *const cfg) fprintf(stderr, "Could not open CQM file.\n"); goto init_failed; } + } else if (cfg->scaling_list == KVZ_SCALING_LIST_DEFAULT) { + // Enable scaling lists if default lists are used + encoder->scaling_list.enable = 1; + encoder->scaling_list.use_default_list = 1; } + kvz_scalinglist_process(&encoder->scaling_list, encoder->bitdepth); kvz_encoder_control_input_init(encoder, encoder->cfg.width, encoder->cfg.height); diff --git a/src/encoder_state-bitstream.c b/src/encoder_state-bitstream.c index 6e7aab8d..ebd2d2c4 100644 --- a/src/encoder_state-bitstream.c +++ b/src/encoder_state-bitstream.c @@ -395,8 +395,11 @@ static void encoder_state_write_bitstream_seq_parameter_set(bitstream_t* stream, // scaling list WRITE_U(stream, encoder->scaling_list.enable, 1, "scaling_list_enable_flag"); if (encoder->scaling_list.enable) { - WRITE_U(stream, 1, 1, "sps_scaling_list_data_present_flag"); - encoder_state_write_bitstream_scaling_list(stream, state); + // Signal scaling list data for custom lists + WRITE_U(stream, (encoder->cfg.scaling_list == KVZ_SCALING_LIST_CUSTOM) ? 1 : 0, 1, "sps_scaling_list_data_present_flag"); + if (encoder->cfg.scaling_list == KVZ_SCALING_LIST_CUSTOM) { + encoder_state_write_bitstream_scaling_list(stream, state); + } } WRITE_U(stream, (encoder->cfg.amp_enable ? 1 : 0), 1, "amp_enabled_flag"); diff --git a/src/kvazaar.h b/src/kvazaar.h index 02dedd6b..7209b636 100644 --- a/src/kvazaar.h +++ b/src/kvazaar.h @@ -207,6 +207,12 @@ enum kvz_sao { KVZ_SAO_FULL = 3 }; +enum kvz_scalinglist { + KVZ_SCALING_LIST_OFF = 0, + KVZ_SCALING_LIST_CUSTOM = 1, + KVZ_SCALING_LIST_DEFAULT = 2, +}; + // Map from input format to chroma format. #define KVZ_FORMAT2CSP(format) ((enum kvz_chroma_format)"\0\1\2\3"[format]) @@ -375,6 +381,9 @@ typedef struct kvz_config /** \brief Flag to enable/disable open GOP configuration */ int8_t open_gop; + /** \brief Type of scaling lists to use */ + int8_t scaling_list; + } kvz_config; /** diff --git a/src/scalinglist.c b/src/scalinglist.c index 1dba8bbe..421042a1 100644 --- a/src/scalinglist.c +++ b/src/scalinglist.c @@ -102,6 +102,7 @@ void kvz_scalinglist_init(scaling_list_t * const scaling_list) } scaling_list->enable = 0; + scaling_list->use_default_list = 0; } /** @@ -397,9 +398,9 @@ void kvz_scalinglist_process(scaling_list_t * const scaling_list, uint8_t bitdep for (size = 0; size < SCALING_LIST_SIZE_NUM; size++) { for (list = 0; list < kvz_g_scaling_list_num[size]; list++) { - const int32_t * const list_ptr = scaling_list->enable ? - scaling_list->scaling_list_coeff[size][list] : - kvz_scalinglist_get_default(size, list); + const int32_t * const list_ptr = scaling_list->use_default_list ? + kvz_scalinglist_get_default(size, list) : + scaling_list->scaling_list_coeff[size][list]; for (qp = 0; qp < SCALING_LIST_REM_NUM; qp++) { kvz_scalinglist_set(scaling_list, list_ptr, list, size, qp); diff --git a/src/scalinglist.h b/src/scalinglist.h index c283a8db..c539b3d3 100644 --- a/src/scalinglist.h +++ b/src/scalinglist.h @@ -33,6 +33,7 @@ typedef struct { int8_t enable; + int8_t use_default_list; int32_t scaling_list_dc [SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM]; const int32_t *scaling_list_coeff[SCALING_LIST_SIZE_NUM][SCALING_LIST_NUM]; const int32_t *quant_coeff[4][6][6];