2015-05-13 09:45:11 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
* This file is part of Kvazaar HEVC encoder.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013-2015 Tampere University of Technology and others (see
|
|
|
|
* COPYING file).
|
|
|
|
*
|
|
|
|
* Kvazaar is free software: you can redistribute it and/or modify it under
|
|
|
|
* the terms of the GNU Lesser General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2.1 of the License, or (at your
|
|
|
|
* option) any later version.
|
|
|
|
*
|
|
|
|
* Kvazaar is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
|
|
|
|
* more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with Kvazaar. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* \file
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2015-07-03 12:04:36 +00:00
|
|
|
#include "cli.h"
|
2015-05-13 09:45:11 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
2015-07-03 12:04:36 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <getopt.h>
|
2015-07-29 16:07:27 +00:00
|
|
|
#include <ctype.h>
|
2015-05-13 09:45:11 +00:00
|
|
|
|
2015-07-03 12:04:36 +00:00
|
|
|
static const char short_options[] = "i:o:d:w:h:n:q:p:r:";
|
|
|
|
static const struct option long_options[] = {
|
|
|
|
{ "input", required_argument, NULL, 'i' },
|
|
|
|
{ "output", required_argument, NULL, 'o' },
|
|
|
|
{ "debug", required_argument, NULL, 'd' },
|
|
|
|
{ "width", required_argument, NULL, 'w' },
|
|
|
|
{ "height", required_argument, NULL, 'h' }, // deprecated
|
|
|
|
{ "frames", required_argument, NULL, 'n' }, // deprecated
|
|
|
|
{ "qp", required_argument, NULL, 'q' },
|
|
|
|
{ "period", required_argument, NULL, 'p' },
|
|
|
|
{ "ref", required_argument, NULL, 'r' },
|
|
|
|
{ "vps-period", required_argument, NULL, 0 },
|
|
|
|
{ "input-res", required_argument, NULL, 0 },
|
|
|
|
{ "input-fps", required_argument, NULL, 0 },
|
2015-11-13 12:20:27 +00:00
|
|
|
{ "deblock", required_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "no-deblock", no_argument, NULL, 0 },
|
2017-08-11 10:12:22 +00:00
|
|
|
{ "sao", optional_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "no-sao", no_argument, NULL, 0 },
|
2015-11-03 15:30:16 +00:00
|
|
|
{ "rdoq", no_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "no-rdoq", no_argument, NULL, 0 },
|
2015-11-03 15:30:16 +00:00
|
|
|
{ "signhide", no_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "no-signhide", no_argument, NULL, 0 },
|
2015-12-15 05:57:38 +00:00
|
|
|
{ "smp", no_argument, NULL, 0 },
|
|
|
|
{ "no-smp", no_argument, NULL, 0 },
|
2015-12-01 12:37:58 +00:00
|
|
|
{ "amp", no_argument, NULL, 0 },
|
|
|
|
{ "no-amp", no_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "rd", required_argument, NULL, 0 },
|
|
|
|
{ "full-intra-search", no_argument, NULL, 0 },
|
2015-11-03 15:30:16 +00:00
|
|
|
{ "no-full-intra-search", no_argument, NULL, 0 },
|
|
|
|
{ "transform-skip", no_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "no-transform-skip", no_argument, NULL, 0 },
|
|
|
|
{ "tr-depth-intra", required_argument, NULL, 0 },
|
|
|
|
{ "me", required_argument, NULL, 0 },
|
|
|
|
{ "subme", required_argument, NULL, 0 },
|
2015-08-13 09:53:14 +00:00
|
|
|
{ "source-scan-type", required_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "sar", required_argument, NULL, 0 },
|
|
|
|
{ "overscan", required_argument, NULL, 0 },
|
|
|
|
{ "videoformat", required_argument, NULL, 0 },
|
|
|
|
{ "range", required_argument, NULL, 0 },
|
|
|
|
{ "colorprim", required_argument, NULL, 0 },
|
|
|
|
{ "transfer", required_argument, NULL, 0 },
|
|
|
|
{ "colormatrix", required_argument, NULL, 0 },
|
|
|
|
{ "chromaloc", required_argument, NULL, 0 },
|
|
|
|
{ "aud", no_argument, NULL, 0 },
|
2015-11-03 15:30:16 +00:00
|
|
|
{ "no-aud", no_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "cqmfile", required_argument, NULL, 0 },
|
|
|
|
{ "seek", required_argument, NULL, 0 },
|
2016-03-07 13:54:35 +00:00
|
|
|
{ "tiles", required_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "tiles-width-split", required_argument, NULL, 0 },
|
|
|
|
{ "tiles-height-split", required_argument, NULL, 0 },
|
|
|
|
{ "wpp", no_argument, NULL, 0 },
|
2015-11-03 15:30:16 +00:00
|
|
|
{ "no-wpp", no_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "owf", required_argument, NULL, 0 },
|
2017-01-31 13:44:23 +00:00
|
|
|
{ "slices", required_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "threads", required_argument, NULL, 0 },
|
|
|
|
{ "cpuid", required_argument, NULL, 0 },
|
|
|
|
{ "pu-depth-inter", required_argument, NULL, 0 },
|
|
|
|
{ "pu-depth-intra", required_argument, NULL, 0 },
|
2015-11-03 15:30:16 +00:00
|
|
|
{ "info", no_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "no-info", no_argument, NULL, 0 },
|
|
|
|
{ "gop", required_argument, NULL, 0 },
|
|
|
|
{ "bipred", no_argument, NULL, 0 },
|
2015-11-03 15:30:16 +00:00
|
|
|
{ "no-bipred", no_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{ "bitrate", required_argument, NULL, 0 },
|
2015-11-03 10:04:22 +00:00
|
|
|
{ "preset", required_argument, NULL, 0 },
|
2015-11-05 11:59:30 +00:00
|
|
|
{ "mv-rdo", no_argument, NULL, 0 },
|
|
|
|
{ "no-mv-rdo", no_argument, NULL, 0 },
|
2016-01-21 13:08:34 +00:00
|
|
|
{ "psnr", no_argument, NULL, 0 },
|
|
|
|
{ "no-psnr", no_argument, NULL, 0 },
|
2016-02-04 11:22:17 +00:00
|
|
|
{ "version", no_argument, NULL, 0 },
|
|
|
|
{ "help", no_argument, NULL, 0 },
|
2016-02-18 17:27:14 +00:00
|
|
|
{ "loop-input", no_argument, NULL, 0 },
|
2016-02-24 10:10:51 +00:00
|
|
|
{ "mv-constraint", required_argument, NULL, 0 },
|
2016-03-17 15:00:43 +00:00
|
|
|
{ "hash", required_argument, NULL, 0 },
|
2016-05-10 11:15:41 +00:00
|
|
|
{"cu-split-termination",required_argument, NULL, 0 },
|
2016-06-07 07:55:26 +00:00
|
|
|
{ "crypto", required_argument, NULL, 0 },
|
2017-08-28 15:15:13 +00:00
|
|
|
{ "key", required_argument, NULL, 0 },
|
2016-06-06 12:47:31 +00:00
|
|
|
{ "me-early-termination",required_argument, NULL, 0 },
|
2016-05-26 07:38:45 +00:00
|
|
|
{ "lossless", no_argument, NULL, 0 },
|
|
|
|
{ "no-lossless", no_argument, NULL, 0 },
|
2016-08-10 08:58:15 +00:00
|
|
|
{ "tmvp", no_argument, NULL, 0 },
|
|
|
|
{ "no-tmvp", no_argument, NULL, 0 },
|
2016-08-17 07:07:40 +00:00
|
|
|
{ "rdoq-skip", no_argument, NULL, 0 },
|
2016-09-11 08:40:16 +00:00
|
|
|
{ "no-rdoq-skip", no_argument, NULL, 0 },
|
2016-08-16 16:03:21 +00:00
|
|
|
{ "input-bitdepth", required_argument, NULL, 0 },
|
|
|
|
{ "input-format", required_argument, NULL, 0 },
|
2016-08-03 05:18:56 +00:00
|
|
|
{ "implicit-rdpcm", no_argument, NULL, 0 },
|
|
|
|
{ "no-implicit-rdpcm", no_argument, NULL, 0 },
|
2017-01-16 06:47:21 +00:00
|
|
|
{ "roi", required_argument, NULL, 0 },
|
2017-04-19 12:47:47 +00:00
|
|
|
{ "erp-aqp", no_argument, NULL, 0 },
|
|
|
|
{ "no-erp-aqp", no_argument, NULL, 0 },
|
2017-11-03 11:04:05 +00:00
|
|
|
{ "level", required_argument, NULL, 0 },
|
2015-07-03 12:04:36 +00:00
|
|
|
{0, 0, 0, 0}
|
|
|
|
};
|
|
|
|
|
2015-07-29 16:07:27 +00:00
|
|
|
/**
|
|
|
|
* \brief Try to detect resolution from file name automatically
|
|
|
|
*
|
|
|
|
* \param file_name file name to get dimensions from
|
|
|
|
* \param out_width detected width
|
|
|
|
* \param out_height detected height
|
|
|
|
* \return 1 if the resolution is set, 0 on fail
|
|
|
|
*/
|
|
|
|
static int select_input_res_auto(const char *file_name, int32_t *out_width, int32_t *out_height)
|
|
|
|
{
|
|
|
|
if (!file_name) return 0;
|
|
|
|
|
|
|
|
// Find the last delimiter char ( / or \ ). Hope the other kind is not used in the name.
|
|
|
|
// If delim is not found, set pointer to the beginning.
|
2015-07-31 15:44:36 +00:00
|
|
|
unsigned char* sub_str = (unsigned char*)MAX(strrchr(file_name, '/'), strrchr(file_name, '\\'));
|
|
|
|
if (!sub_str) sub_str = (unsigned char*)file_name;
|
2015-07-29 16:07:27 +00:00
|
|
|
|
|
|
|
int success = 0;
|
|
|
|
// Try if the substring starts with "<int>x<int>" without either of them being 0
|
|
|
|
do {
|
2015-07-31 15:44:36 +00:00
|
|
|
success = (sscanf((char*)sub_str, "%dx%d%*s", out_width, out_height) == 2);
|
2015-07-29 16:07:27 +00:00
|
|
|
success &= (*out_width > 0 && *out_height > 0);
|
|
|
|
// Move to the next char until a digit is found or the string ends
|
|
|
|
do{
|
|
|
|
++sub_str;
|
|
|
|
} while (*sub_str != 0 && !isdigit(*sub_str));
|
|
|
|
// Continue until "<int>x<int>" is found or the string ends
|
|
|
|
} while (*sub_str != 0 && !success);
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2015-07-03 12:04:36 +00:00
|
|
|
/**
|
|
|
|
* \brief Parse command line arguments.
|
|
|
|
* \param argc Number of arguments
|
|
|
|
* \param argv Argument list
|
|
|
|
* \return Pointer to the parsed options, or NULL on failure.
|
|
|
|
*/
|
|
|
|
cmdline_opts_t* cmdline_opts_parse(const kvz_api *const api, int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int ok = 1;
|
|
|
|
cmdline_opts_t *opts = calloc(1, sizeof(cmdline_opts_t));
|
|
|
|
if (!opts) {
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
opts->config = api->config_alloc();
|
|
|
|
if (!opts->config || !api->config_init(opts->config)) {
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse command line options
|
|
|
|
for (optind = 0;;) {
|
|
|
|
int long_options_index = -1;
|
|
|
|
|
|
|
|
int c = getopt_long(argc, argv, short_options, long_options, &long_options_index);
|
|
|
|
if (c == -1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (long_options_index < 0) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; long_options[i].name; i++)
|
|
|
|
if (long_options[i].val == c) {
|
|
|
|
long_options_index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (long_options_index < 0) {
|
|
|
|
// getopt_long already printed an error message
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* name = long_options[long_options_index].name;
|
|
|
|
if (!strcmp(name, "input")) {
|
|
|
|
if (opts->input) {
|
|
|
|
fprintf(stderr, "Input error: More than one input file given.\n");
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
opts->input = strdup(optarg);
|
|
|
|
} else if (!strcmp(name, "output")) {
|
|
|
|
if (opts->output) {
|
|
|
|
fprintf(stderr, "Input error: More than one output file given.\n");
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
opts->output = strdup(optarg);
|
|
|
|
} else if (!strcmp(name, "debug")) {
|
|
|
|
if (opts->debug) {
|
|
|
|
fprintf(stderr, "Input error: More than one debug output file given.\n");
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
opts->debug = strdup(optarg);
|
|
|
|
} else if (!strcmp(name, "seek")) {
|
|
|
|
opts->seek = atoi(optarg);
|
|
|
|
} else if (!strcmp(name, "frames")) {
|
|
|
|
opts->frames = atoi(optarg);
|
2016-02-04 11:22:17 +00:00
|
|
|
} else if (!strcmp(name, "version")) {
|
|
|
|
opts->version = true;
|
|
|
|
goto done;
|
|
|
|
} else if (!strcmp(name, "help")) {
|
|
|
|
opts->help = true;
|
|
|
|
goto done;
|
2016-02-18 17:27:14 +00:00
|
|
|
} else if (!strcmp(name, "loop-input")) {
|
|
|
|
opts->loop_input = true;
|
2017-11-03 11:04:05 +00:00
|
|
|
} else if (!strcmp(name, "level")) {
|
|
|
|
unsigned int num_first, num_second, level = 0;
|
|
|
|
int matched_amount = sscanf(optarg, "%u.%u", &num_first, &num_second);
|
|
|
|
|
|
|
|
if (matched_amount == 2) {
|
|
|
|
// of form x.y
|
|
|
|
level = num_first * 10 + num_second;
|
|
|
|
} else if (matched_amount == 1) {
|
|
|
|
// no dot
|
|
|
|
if (num_first < 10) {
|
|
|
|
// of form x
|
|
|
|
level = num_first * 10;
|
|
|
|
} else {
|
|
|
|
// of form xx
|
|
|
|
level = num_first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if the level has a valid value
|
|
|
|
switch (level)
|
|
|
|
{
|
|
|
|
case 10:
|
|
|
|
case 20: case 21:
|
|
|
|
case 30: case 31:
|
|
|
|
case 40: case 41:
|
|
|
|
case 50: case 51: case 52:
|
|
|
|
case 60: case 61: case 62:
|
|
|
|
// a-ok
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(stderr, "invalid level value: \"%s\"", optarg);
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
// DEBUG
|
|
|
|
fprintf(stderr, "lvl: %u", level);
|
|
|
|
|
|
|
|
opts->level = level;
|
2015-11-09 11:57:28 +00:00
|
|
|
} else if (!api->config_parse(opts->config, name, optarg)) {
|
2015-07-03 12:04:36 +00:00
|
|
|
fprintf(stderr, "invalid argument: %s=%s\n", name, optarg);
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-13 11:55:23 +00:00
|
|
|
// Check for extra arguments.
|
|
|
|
if (argc - optind > 0) {
|
|
|
|
fprintf(stderr, "Input error: Extra argument found: \"%s\"\n", argv[optind]);
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2015-07-03 12:04:36 +00:00
|
|
|
// Check that the required files were defined
|
|
|
|
if (opts->input == NULL || opts->output == NULL) {
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2015-10-15 12:23:40 +00:00
|
|
|
if (opts->config->vps_period < 0) {
|
|
|
|
// Disabling parameter sets is only possible when using Kvazaar as
|
|
|
|
// a library.
|
|
|
|
fprintf(stderr, "Input error: vps_period must be non-negative\n");
|
|
|
|
ok = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2015-07-29 16:07:27 +00:00
|
|
|
// Set resolution automatically if necessary
|
2016-06-20 05:16:58 +00:00
|
|
|
if (opts->config->width == 0 && opts->config->height == 0) {
|
2015-07-29 16:07:27 +00:00
|
|
|
ok = select_input_res_auto(opts->input, &opts->config->width, &opts->config->height);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2015-07-03 12:04:36 +00:00
|
|
|
done:
|
|
|
|
if (!ok) {
|
|
|
|
cmdline_opts_free(api, opts);
|
|
|
|
opts = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return opts;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Deallocate a cmdline_opts_t structure.
|
|
|
|
*/
|
|
|
|
void cmdline_opts_free(const kvz_api *const api, cmdline_opts_t *opts)
|
|
|
|
{
|
|
|
|
if (opts) {
|
|
|
|
FREE_POINTER(opts->input);
|
|
|
|
FREE_POINTER(opts->output);
|
|
|
|
FREE_POINTER(opts->debug);
|
|
|
|
api->config_destroy(opts->config);
|
|
|
|
opts->config = NULL;
|
|
|
|
}
|
|
|
|
FREE_POINTER(opts);
|
|
|
|
}
|
2015-05-14 15:33:57 +00:00
|
|
|
|
2015-05-13 09:45:11 +00:00
|
|
|
|
2016-02-04 11:22:17 +00:00
|
|
|
void print_usage(void)
|
|
|
|
{
|
|
|
|
fprintf(stdout,
|
|
|
|
"Kvazaar usage: -i and --input-res to set input, -o to set output\n"
|
|
|
|
" --help for more information\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-13 09:45:11 +00:00
|
|
|
void print_version(void)
|
|
|
|
{
|
2016-02-04 11:22:17 +00:00
|
|
|
fprintf(stdout,
|
|
|
|
"Kvazaar " VERSION_STRING "\n"
|
|
|
|
"Kvazaar license: LGPL version 2\n");
|
2015-05-13 09:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void print_help(void)
|
|
|
|
{
|
2016-02-04 11:22:17 +00:00
|
|
|
fprintf(stdout,
|
2015-05-13 09:45:11 +00:00
|
|
|
"Usage:\n"
|
|
|
|
"kvazaar -i <input> --input-res <width>x<height> -o <output>\n"
|
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Required:\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" -i, --input : Input file\n"
|
|
|
|
" --input-res <res> : Input resolution [auto]\n"
|
|
|
|
" auto: detect from file name\n"
|
|
|
|
" <int>x<int>: width times height\n"
|
|
|
|
" -o, --output : Output file\n"
|
2016-10-26 23:33:11 +00:00
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Presets:\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" --preset=<preset> : Set options to a preset [medium]\n"
|
|
|
|
" - ultrafast, superfast, veryfast, faster,\n"
|
|
|
|
" fast, medium, slow, slower, veryslow\n"
|
2016-10-26 23:33:11 +00:00
|
|
|
" placebo\n"
|
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Input:\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" -n, --frames <integer> : Number of frames to code [all]\n"
|
|
|
|
" --seek <integer> : First frame to code [0]\n"
|
|
|
|
" --input-fps <num>/<denom> : Framerate of the input video [25.0]\n"
|
|
|
|
" --source-scan-type <string> : Set source scan type [progressive].\n"
|
|
|
|
" - progressive: progressive scan\n"
|
|
|
|
" - tff: top field first\n"
|
|
|
|
" - bff: bottom field first\n"
|
|
|
|
" --input-format : P420 or P400\n"
|
|
|
|
" --input-bitdepth : 8-16\n"
|
|
|
|
" --loop-input : Re-read input file forever\n"
|
2016-10-26 23:33:11 +00:00
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Options:\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" --help : Print this help message and exit\n"
|
|
|
|
" --version : Print version information and exit\n"
|
|
|
|
" --aud : Use access unit delimiters\n"
|
|
|
|
" --debug <string> : Output encoders reconstruction.\n"
|
|
|
|
" --cpuid <integer> : Disable runtime cpu optimizations with value 0.\n"
|
|
|
|
" --hash : Decoded picture hash [checksum]\n"
|
|
|
|
" - none: 0 bytes\n"
|
|
|
|
" - checksum: 18 bytes\n"
|
|
|
|
" - md5: 56 bytes\n"
|
|
|
|
" --no-psnr : Don't calculate PSNR for frames\n"
|
|
|
|
" --no-info : Don't add encoder info SEI.\n"
|
2016-10-26 23:33:11 +00:00
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Video structure:\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" -q, --qp <integer> : Quantization Parameter [32]\n"
|
|
|
|
" -p, --period <integer> : Period of intra pictures [0]\n"
|
|
|
|
" - 0: only first picture is intra\n"
|
|
|
|
" - 1: all pictures are intra\n"
|
|
|
|
" - 2-N: every Nth picture is intra\n"
|
|
|
|
" --vps-period <integer> : Specify how often the video parameter set is\n"
|
|
|
|
" re-sent. [0]\n"
|
|
|
|
" - 0: only send VPS with the first frame\n"
|
|
|
|
" - N: send VPS with every Nth intra frame\n"
|
|
|
|
" -r, --ref <integer> : Reference frames, range 1..15 [3]\n"
|
|
|
|
" --gop <string> : Definition of GOP structure [0]\n"
|
|
|
|
" - 0: disabled\n"
|
|
|
|
" - 8: B-frame pyramid of length 8\n"
|
|
|
|
" - lp-<string>: lp-gop definition\n"
|
|
|
|
" (e.g. lp-g8d4t2, see README)\n"
|
|
|
|
" --cqmfile <string> : Custom Quantization Matrices from a file\n"
|
|
|
|
" --bitrate <integer> : Target bitrate. [0]\n"
|
|
|
|
" - 0: disable rate-control\n"
|
|
|
|
" - N: target N bits per second\n"
|
|
|
|
" --lossless : Use lossless coding\n"
|
|
|
|
" --mv-constraint : Constrain movement vectors\n"
|
|
|
|
" - none: no constraint\n"
|
|
|
|
" - frametile: constrain within the tile\n"
|
|
|
|
" - frametilemargin: constrain even more\n"
|
2017-01-16 06:47:21 +00:00
|
|
|
" --roi <string> : Use a delta QP map for region of interest\n"
|
|
|
|
" Read an array of delta QP values from\n"
|
|
|
|
" a file, where the first two values are the\n"
|
|
|
|
" width and height, followed by width*height\n"
|
|
|
|
" delta QP values in raster order.\n"
|
|
|
|
" The delta QP map can be any size or aspect\n"
|
|
|
|
" ratio, and will be mapped to LCU's.\n"
|
2017-04-19 12:47:47 +00:00
|
|
|
" --(no-)erp-aqp : Use adaptive QP for 360 video with\n"
|
|
|
|
" equirectangular projection\n"
|
2016-10-26 23:33:11 +00:00
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Compression tools:\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" --deblock [<beta:tc>] : Deblocking\n"
|
|
|
|
" - beta: between -6 and 6\n"
|
|
|
|
" - tc: between -6 and 6\n"
|
|
|
|
" --(no-)sao : Sample Adaptive Offset\n"
|
|
|
|
" --(no-)rdoq : Rate-Distortion Optimized Quantization\n"
|
|
|
|
" --(no-)signhide : Sign Hiding\n"
|
|
|
|
" --(no-)smp : Symmetric Motion Partition\n"
|
|
|
|
" --(no-)amp : Asymmetric Motion Partition\n"
|
|
|
|
" --rd <integer> : Intra mode search complexity\n"
|
|
|
|
" - 0: skip intra if inter is good enough\n"
|
|
|
|
" - 1: rough intra mode search with SATD\n"
|
|
|
|
" - 2: refine intra mode search with SSE\n"
|
|
|
|
" --(no-)mv-rdo : Rate-Distortion Optimized motion vector costs\n"
|
|
|
|
" --(no-)full-intra-search\n"
|
|
|
|
" : Try all intra modes during rough search.\n"
|
|
|
|
" --(no-)transform-skip : Transform skip\n"
|
|
|
|
" --me <string> : Integer motion estimation\n"
|
|
|
|
" - hexbs: Hexagon Based Search\n"
|
|
|
|
" - tz: Test Zone Search\n"
|
|
|
|
" - full: Full Search\n"
|
|
|
|
" - full8, full16, full32, full64\n"
|
|
|
|
" --subme <integer> : Set fractional pixel motion estimation level\n"
|
|
|
|
" - 0: only integer motion estimation\n"
|
|
|
|
" - 1: + 1/2-pixel horizontal and vertical\n"
|
|
|
|
" - 2: + 1/2-pixel diagonal\n"
|
|
|
|
" - 3: + 1/4-pixel horizontal and vertical\n"
|
|
|
|
" - 4: + 1/4-pixel diagonal\n"
|
|
|
|
" --pu-depth-inter <int>-<int>\n"
|
|
|
|
" : Range for sizes for inter predictions\n"
|
|
|
|
" - 0, 1, 2, 3: from 64x64 to 8x8\n"
|
|
|
|
" --pu-depth-intra <int>-<int> : Range for sizes for intra predictions\n"
|
|
|
|
" - 0, 1, 2, 3, 4: from 64x64 to 4x4\n"
|
|
|
|
" --(no-)bipred : Bi-prediction\n"
|
|
|
|
" --(no-)cu-split-termination\n"
|
|
|
|
" : CU split search termination condition\n"
|
|
|
|
" - off: Never terminate cu-split search\n"
|
|
|
|
" - zero: Terminate with zero residual\n"
|
|
|
|
" --(no-)me-early-termination : ME early termination condition\n"
|
|
|
|
" - off: Don't terminate early\n"
|
|
|
|
" - on: Terminate early\n"
|
|
|
|
" - sensitive: Terminate even earlier\n"
|
|
|
|
" --(no-)implicit-rdpcm : Implicit residual DPCM\n"
|
|
|
|
" Currently only supported with lossless coding.\n"
|
|
|
|
" --(no-)tmvp : Temporal Motion Vector Prediction\n"
|
|
|
|
" --(no-)rdoq-skip : Skips RDOQ for 4x4 blocks\n"
|
2015-05-13 09:45:11 +00:00
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Parallel processing:\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" --threads <integer> : Number of threads to use [auto]\n"
|
|
|
|
" - 0: process everything with main thread\n"
|
|
|
|
" - N: use N threads for encoding\n"
|
|
|
|
" - auto: select based on number of cores\n"
|
|
|
|
" --owf <integer> : Frame parallelism [auto]\n"
|
|
|
|
" - N: Process N-1 frames at a time\n"
|
|
|
|
" - auto: Select automatically\n"
|
|
|
|
" --(no-)wpp : Wavefront parallel processing [enabled]\n"
|
|
|
|
" Enabling tiles automatically disables WPP.\n"
|
|
|
|
" To enable WPP with tiles, re-enable it after\n"
|
|
|
|
" enabling tiles.\n"
|
|
|
|
" --tiles <int>x<int> : Split picture into width x height uniform tiles.\n"
|
|
|
|
" --tiles-width-split <string>|u<int> :\n"
|
|
|
|
" Specifies a comma separated list of pixel\n"
|
|
|
|
" positions of tiles columns separation coordinates.\n"
|
|
|
|
" Can also be u followed by and a single int n,\n"
|
|
|
|
" in which case it produces columns of uniform width.\n"
|
|
|
|
" --tiles-height-split <string>|u<int> :\n"
|
|
|
|
" Specifies a comma separated list of pixel\n"
|
|
|
|
" positions of tiles rows separation coordinates.\n"
|
|
|
|
" Can also be u followed by and a single int n,\n"
|
|
|
|
" in which case it produces rows of uniform height.\n"
|
2017-01-31 13:44:23 +00:00
|
|
|
" --slices <string> : Control how slices are used\n"
|
|
|
|
" - tiles: put tiles in independent slices\n"
|
|
|
|
" - wpp: put rows in dependent slices\n"
|
|
|
|
" - tiles+wpp: do both\n"
|
2016-10-26 23:33:11 +00:00
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Video Usability Information:\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" --sar <width:height> : Specify Sample Aspect Ratio\n"
|
|
|
|
" --overscan <string> : Specify crop overscan setting [undef]\n"
|
|
|
|
" - undef, show, crop\n"
|
|
|
|
" --videoformat <string> : Specify video format [undef]\n"
|
|
|
|
" - component, pal, ntsc, secam, mac, undef\n"
|
|
|
|
" --range <string> : Specify color range [tv]\n"
|
|
|
|
" - tv, pc\n"
|
|
|
|
" --colorprim <string> : Specify color primaries [undef]\n"
|
|
|
|
" - undef, bt709, bt470m, bt470bg,\n"
|
|
|
|
" smpte170m, smpte240m, film, bt2020\n"
|
|
|
|
" --transfer <string> : Specify transfer characteristics [undef]\n"
|
|
|
|
" - undef, bt709, bt470m, bt470bg,\n"
|
|
|
|
" smpte170m, smpte240m, linear, log100,\n"
|
|
|
|
" log316, iec61966-2-4, bt1361e,\n"
|
|
|
|
" iec61966-2-1, bt2020-10, bt2020-12\n"
|
|
|
|
" --colormatrix <string> : Specify color matrix setting [undef]\n"
|
|
|
|
" - undef, bt709, fcc, bt470bg, smpte170m,\n"
|
|
|
|
" smpte240m, GBR, YCgCo, bt2020nc, bt2020c\n"
|
|
|
|
" --chromaloc <integer> : Specify chroma sample location (0 to 5) [0]\n"
|
2015-05-13 09:45:11 +00:00
|
|
|
"\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
/* Word wrap to this width to stay under 80 characters (including ") ************/
|
2016-10-26 23:33:11 +00:00
|
|
|
"Deprecated parameters: (might be removed at some point)\n"
|
2016-11-04 13:30:58 +00:00
|
|
|
" -w, --width : Use --input-res\n"
|
|
|
|
" -h, --height : Use --input-res\n");
|
2015-05-13 09:45:11 +00:00
|
|
|
}
|
2015-05-14 15:33:57 +00:00
|
|
|
|
|
|
|
|
2015-09-09 07:28:45 +00:00
|
|
|
void print_frame_info(const kvz_frame_info *const info,
|
|
|
|
const double frame_psnr[3],
|
2017-07-19 07:38:37 +00:00
|
|
|
const uint32_t bytes,
|
|
|
|
const bool print_psnr)
|
2015-05-14 15:33:57 +00:00
|
|
|
{
|
2017-07-19 07:38:37 +00:00
|
|
|
fprintf(stderr, "POC %4d QP %2d (%c-frame) %10d bits",
|
2015-09-09 07:28:45 +00:00
|
|
|
info->poc,
|
|
|
|
info->qp,
|
|
|
|
"BPI"[info->slice_type % 3],
|
2017-07-19 07:38:37 +00:00
|
|
|
bytes << 3);
|
|
|
|
if (print_psnr) {
|
|
|
|
fprintf(stderr, " PSNR Y %2.4f U %2.4f V %2.4f",
|
|
|
|
frame_psnr[0], frame_psnr[1], frame_psnr[2]);
|
|
|
|
}
|
2015-05-14 15:33:57 +00:00
|
|
|
|
2015-09-09 07:28:45 +00:00
|
|
|
if (info->slice_type != KVZ_SLICE_I) {
|
2015-09-09 07:01:02 +00:00
|
|
|
// Print reference picture lists
|
2015-05-14 15:33:57 +00:00
|
|
|
fprintf(stderr, " [L0 ");
|
2017-09-25 10:48:56 +00:00
|
|
|
for (int j = 0; j < info->ref_list_len[0]; j++) {
|
2015-09-09 07:28:45 +00:00
|
|
|
fprintf(stderr, "%d ", info->ref_list[0][j]);
|
2015-05-14 15:33:57 +00:00
|
|
|
}
|
|
|
|
fprintf(stderr, "] [L1 ");
|
2015-09-09 07:28:45 +00:00
|
|
|
for (int j = 0; j < info->ref_list_len[1]; j++) {
|
|
|
|
fprintf(stderr, "%d ", info->ref_list[1][j]);
|
2015-05-14 15:33:57 +00:00
|
|
|
}
|
|
|
|
fprintf(stderr, "]");
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|