[x265] [PATCH 3 of 4] cli: allow -P/--profile to influence requested API bit-depth
Steve Borho
steve at borho.org
Tue Apr 28 22:40:00 CEST 2015
# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1430249504 18000
# Tue Apr 28 14:31:44 2015 -0500
# Node ID 41f1bb787a740001e6605eeee0eb26645bd2b256
# Parent 2184362dd1cb6c13adf6c6ff93db2ea2f22645f0
cli: allow -P/--profile to influence requested API bit-depth
This allows our x265 CLI to be linked (statically or dynamically) to a build of
libx265 with one bit-depth, and then use another shared libx265 of another
bit-depth to perform the actual encode.
The bulk of the changes in this commit were necessary to move x265_api_get()
in between the initial argument parsing and x265_param_default_preset()
diff -r 2184362dd1cb -r 41f1bb787a74 source/x265.cpp
--- a/source/x265.cpp Tue Apr 28 14:18:13 2015 -0500
+++ b/source/x265.cpp Tue Apr 28 14:31:44 2015 -0500
@@ -75,14 +75,18 @@
OutputFile* output;
FILE* qpfile;
const char* reconPlayCmd;
- bool bProgress;
- bool bForceY4m;
- bool bDither;
+ const x265_api* api;
+
+ bool bProgress;
+ bool bForceY4m;
+ bool bDither;
+
uint32_t seek; // number of frames to skip from the beginning
uint32_t framesToBeEncoded; // number of frames to encode
+
uint64_t totalbytes;
- int64_t startTime;
- int64_t prevUpdateTime;
+ int64_t startTime;
+ int64_t prevUpdateTime;
/* in microseconds */
static const int UPDATE_INTERVAL = 250000;
@@ -92,6 +96,9 @@
input = NULL;
recon = NULL;
output = NULL;
+ qpfile = NULL;
+ reconPlayCmd = NULL;
+ api = NULL;
framesToBeEncoded = seek = 0;
totalbytes = 0;
bProgress = true;
@@ -99,13 +106,12 @@
startTime = x265_mdate();
prevUpdateTime = 0;
bDither = false;
- qpfile = NULL;
- reconPlayCmd = NULL;
}
+ x265_param* parse(int argc, char** argv);
+
void destroy();
- void printStatus(uint32_t frameNum, x265_param *param);
- bool parse(int argc, char **argv, x265_param* param);
+ void printStatus(uint32_t frameNum, x265_param* param);
bool parseQPFile(x265_picture &pic_org);
bool validateFanout(x265_param*);
};
@@ -153,9 +159,10 @@
prevUpdateTime = time;
}
-bool CLIOptions::parse(int argc, char **argv, x265_param* param)
+x265_param* CLIOptions::parse(int argc, char **argv)
{
- bool bError = 0;
+ bool bError = false;
+ bool bShowHelp = false;
int help = 0;
int inputBitDepth = 8;
int reconFileBitDepth = 0;
@@ -169,7 +176,7 @@
if (argc <= 1)
{
x265_log(NULL, X265_LOG_ERROR, "No input file. Run x265 --help for a list of options.\n");
- return true;
+ return NULL;
}
/* Presets are applied before all other options. */
@@ -180,18 +187,40 @@
break;
if (c == 'p')
preset = optarg;
- if (c == 't')
+ else if (c == 't')
tune = optarg;
+ else if (c == 'P')
+ profile = optarg;
else if (c == '?')
- showHelp(param);
+ bShowHelp = true;
}
- if (x265_param_default_preset(param, preset, tune) < 0)
+ api = NULL;
+ if (profile)
+ {
+ /* Try to respect the user's wishes, as specified by --profile */
+ if (!strcmp(profile, "main") || !strcmp(profile, "mainstillpicture") || !strcmp(profile, "msp") || !strcmp(profile, "main444-8"))
+ api = x265_api_get(8);
+ else if (!strcmp(profile, "main10") || !strcmp(profile, "main422-10") || !strcmp(profile, "main444-10"))
+ api = x265_api_get(10);
+ }
+ if (!api)
+ api = x265_api_get(X265_DEPTH); /* prefer what the cli was compiled against */
+ if (!api)
+ api = x265_api_get(0); /* prefer what we link against */
+
+ x265_param* param = api->param_alloc();
+
+ if (api->param_default_preset(param, preset, tune) < 0)
{
x265_log(NULL, X265_LOG_ERROR, "preset or tune unrecognized\n");
- return true;
+ api->param_free(param);
+ return NULL;
}
+ if (bShowHelp)
+ showHelp(param);
+
for (optind = 0;; )
{
int long_options_index = -1;
@@ -227,13 +256,15 @@
/* getopt_long might have already printed an error message */
if (c != 63)
x265_log(NULL, X265_LOG_WARNING, "internal error: short option '%c' has no long option\n", c);
- return true;
+ api->param_free(param);
+ return NULL;
}
}
if (long_options_index < 0)
{
x265_log(NULL, X265_LOG_WARNING, "short option '%c' unrecognized\n", c);
- return true;
+ api->param_free(param);
+ return NULL;
}
#define OPT(longname) \
else if (!strcmp(long_options[long_options_index].name, longname))
@@ -252,7 +283,7 @@
OPT("dither") this->bDither = true;
OPT("recon-depth") reconFileBitDepth = (uint32_t)x265_atoi(optarg, bError);
OPT("y4m") this->bForceY4m = true;
- OPT("profile") profile = optarg; /* handled last */
+ OPT("profile") /* handled above (and below) */;
OPT("preset") /* handled above */;
OPT("tune") /* handled above */;
OPT("recon-y4m-exec") reconPlayCmd = optarg;
@@ -262,17 +293,19 @@
if (!this->qpfile)
{
x265_log(param, X265_LOG_ERROR, "%s qpfile not found or error in opening qp file\n", optarg);
- return false;
+ api->param_free(param);
+ return NULL;
}
}
else
- bError |= !!x265_param_parse(param, long_options[long_options_index].name, optarg);
+ bError |= !!api->param_parse(param, long_options[long_options_index].name, optarg);
if (bError)
{
const char *name = long_options_index > 0 ? long_options[long_options_index].name : argv[optind - 2];
x265_log(NULL, X265_LOG_ERROR, "invalid argument: %s = %s\n", name, optarg);
- return true;
+ api->param_free(param);
+ return NULL;
}
#undef OPT
}
@@ -285,7 +318,8 @@
if (optind < argc)
{
x265_log(param, X265_LOG_WARNING, "extra unused command arguments given <%s>\n", argv[optind]);
- return true;
+ api->param_free(param);
+ return NULL;
}
if (argc <= 1 || help)
@@ -294,13 +328,15 @@
if (inputfn == NULL || outputfn == NULL)
{
x265_log(param, X265_LOG_ERROR, "input or output file not specified, try -V for help\n");
- return true;
+ api->param_free(param);
+ return NULL;
}
- if (param->internalBitDepth != x265_max_bit_depth)
+ if (param->internalBitDepth != api->max_bit_depth)
{
- x265_log(param, X265_LOG_ERROR, "Only bit depths of %d are supported in this build\n", x265_max_bit_depth);
- return true;
+ x265_log(param, X265_LOG_ERROR, "Only bit depths of %d are supported in this build\n", api->max_bit_depth);
+ api->param_free(param);
+ return NULL;
}
InputFileInfo info;
@@ -321,13 +357,15 @@
if (!this->input || this->input->isFail())
{
x265_log(param, X265_LOG_ERROR, "unable to open input file <%s>\n", inputfn);
- return true;
+ api->param_free(param);
+ return NULL;
}
if (info.depth < 8 || info.depth > 16)
{
x265_log(param, X265_LOG_ERROR, "Input bit depth (%d) must be between 8 and 16\n", inputBitDepth);
- return true;
+ api->param_free(param);
+ return NULL;
}
/* Unconditionally accept height/width/csp from file info */
@@ -351,8 +389,11 @@
info.timebaseNum = param->fpsDenom;
info.timebaseDenom = param->fpsNum;
- if (x265_param_apply_profile(param, profile))
- return true;
+ if (api->param_apply_profile(param, profile))
+ {
+ api->param_free(param);
+ return NULL;
+ }
if (param->logLevel >= X265_LOG_INFO)
{
@@ -398,10 +439,11 @@
if (this->output->isFail())
{
x265_log(param, X265_LOG_ERROR, "failed to open output file <%s> for writing\n", outputfn);
- return true;
+ api->param_free(param);
+ return NULL;
}
general_log(param, this->output->getName(), X265_LOG_INFO, "output file: %s\n", outputfn);
- return false;
+ return param;
}
bool CLIOptions::parseQPFile(x265_picture &pic_org)
@@ -458,21 +500,18 @@
GetConsoleTitle(orgConsoleTitle, CONSOLE_TITLE_SIZE);
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED);
- const x265_api* api = x265_api_get(X265_DEPTH); /* prefer what the cli was compiled against */
- if (!api)
- api = x265_api_get(0);
-
ReconPlay* reconPlay = NULL;
- x265_param* param = api->param_alloc();
CLIOptions cliopt;
- if (cliopt.parse(argc, argv, param))
+ x265_param* param = cliopt.parse(argc, argv);
+ if (!param)
{
cliopt.destroy();
- api->param_free(param);
exit(1);
}
+ const x265_api* api = cliopt.api;
+
/* This allow muxers to modify bitstream format */
cliopt.output->setParam(param);
More information about the x265-devel
mailing list