[x265] [PATCH 3 of 4] cli: allow -P/--profile to influence requested API bit-depth
Xinyue Lu
maillist at 7086.in
Wed Apr 29 01:37:24 CEST 2015
How about using --output-depth instead of --profile?
Profile is the "up-limit" of the stream. For example in x264 world,
it's possible that a stream of yuv420p8 avc is marked as High 444
Profile. This may not make much sense in real world encoding though.
So I'd propose the following code logic.
param->output_depth = 0
param->profile = 0
OPT(output-depth)
..param->output_depth = value
OPT(profile)
..param->profile = value
if param->output_depth && !param->profile
..param->profile = param->output_depth.to_profile
else if !param->output_depth && param->profile
..param->output_depth = param->profile.to_depth
else
..param->output_depth = x265_depth
..param->profile = x265_depth.to_profile
end
if param->profile < param->output_depth.to_profile
..alert(Invalid profile)
end
That is, unless user specify both depth and profile, either option
will take effects.
And IMHO --output-depth 10 makes more sense than using --profile
Main10. You'll probably have --output-csp 422/444 soon as well, as
Main422-10 or Main444 is required for i422p8.
On Tue, Apr 28, 2015 at 1:40 PM, Steve Borho <steve at borho.org> wrote:
> # 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);
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
More information about the x265-devel
mailing list