[x265] [PATCH MV-HEVC 01/10] Add compile time configuration and support for parsing multiview config file
Karam Singh
karam.singh at multicorewareinc.com
Wed Aug 7 08:51:42 UTC 2024
All the patches of MV-HEVC are pushed to the master branch.
*__________________________*
*Karam Singh*
*Ph.D. IIT Guwahati*
Senior Software (Video Coding) Engineer
Mobile: +91 8011279030
Block 9A, 6th floor, DLF Cyber City
Manapakkam, Chennai 600 089
On Tue, Aug 6, 2024 at 4:12 PM Anusuya Kumarasamy <
anusuya.kumarasamy at multicorewareinc.com> wrote:
> From dba87b3da6bea98ce677bc7be006b928c9d7f8d0 Mon Sep 17 00:00:00 2001
> From: Kirithika <kirithika at multicorewareinc.com>
> Date: Wed, 10 Jul 2024 16:06:01 +0530
> Subject: [PATCH] Add compile time configuration and support for parsing
> multiview config file
>
> ---
> doc/reST/cli.rst | 30 +++++++
> source/CMakeLists.txt | 7 +-
> source/common/param.cpp | 21 +++++
> source/x265.h | 9 ++
> source/x265cli.cpp | 176 ++++++++++++++++++++++++++++++++++++++--
> source/x265cli.h | 13 +++
> 6 files changed, 249 insertions(+), 7 deletions(-)
>
> diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst
> index 4d5ac1a15..298ee334a 100755
> --- a/doc/reST/cli.rst
> +++ b/doc/reST/cli.rst
> @@ -2893,4 +2893,34 @@ Alpha Encode Options
>
> **CLI_ONLY**
>
> +Multiview Encode Options
> +===================
> +
> + Enable multiview encoding support in x265.This option can be enabled
> + only when ENABLE_MULTIVIEW is set during the make of x265.
> +
> +.. option:: --num-views <integer>
> + Specify the number of views in the multiview input video.
> +
> +.. option:: --format <integer>
> + Specify the format of the input video
> + 0 : Two separate input videos
> + 1 : One input video with both views in left and right format
> + 2 : One input video with both views in top and bottom format
> +
> +.. option:: --multiview-config <filename>
> + File containing the configurations to enable multiview encoding.
> +
> + Sample config file::
> +
> + --num-views 2
> + --format 0
> + --input multiview-input-01.yuv
> + --input multiview-input-02.yuv
> +
> + Other input parameters such as input-csp/input-depth/input-res/fps must
> be configured through
> + normal CLI and is expected to be same for all views
> +
> +**CLI_ONLY**
> +
> .. vim: noet
> diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
> index 2dcac3dc6..f25bc8b84 100755
> --- a/source/CMakeLists.txt
> +++ b/source/CMakeLists.txt
> @@ -31,7 +31,7 @@ option(NATIVE_BUILD "Target the build CPU" OFF)
> option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
> mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
> # X265_BUILD must be incremented each time the public API is changed
> -set(X265_BUILD 210)
> +set(X265_BUILD 211)
> configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
> "${PROJECT_BINARY_DIR}/x265.def")
> configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
> @@ -600,6 +600,11 @@ if(ENABLE_ALPHA)
> add_definitions(-DENABLE_ALPHA)
> endif()
>
> +option(ENABLE_MULTIVIEW "Enable Multi-view encoding in HEVC" OFF)
> +if(ENABLE_MULTIVIEW)
> + add_definitions(-DENABLE_MULTIVIEW)
> +endif()
> +
> add_subdirectory(encoder)
> add_subdirectory(common)
>
> diff --git a/source/common/param.cpp b/source/common/param.cpp
> index dec6ff6c9..c2efb11cf 100755
> --- a/source/common/param.cpp
> +++ b/source/common/param.cpp
> @@ -403,6 +403,9 @@ void x265_param_default(x265_param* param)
> /* Film grain characteristics model filename */
> param->filmGrain = NULL;
> param->bEnableSBRC = 0;
> +
> + /* Multi-View Encoding*/
> + param->numViews = 1;
> }
>
> int x265_param_default_preset(x265_param* param, const char* preset,
> const char* tune)
> @@ -1457,6 +1460,12 @@ int x265_param_parse(x265_param* p, const char*
> name, const char* value)
> p->numScalableLayers = 2;
> }
> }
> +#endif
> +#if ENABLE_MULTIVIEW
> + OPT("num-views")
> + {
> + p->numViews = atoi(value);
> + }
> #endif
> else
> return X265_PARAM_BAD_NAME;
> @@ -1935,6 +1944,9 @@ int x265_check_params(x265_param* param)
> CHECK((param->internalCsp != X265_CSP_I420), "Alpha encode
> supported only with i420a colorspace");
> CHECK((param->rc.rateControlMode != X265_RC_CQP), "Alpha encode
> supported only with CQP mode");
> }
> +#endif
> +#if ENABLE_MULTIVIEW
> + CHECK((param->numViews > 2), "Multi-View Encoding currently support
> only 2 views");
> #endif
> return check_failed;
> }
> @@ -2103,6 +2115,9 @@ void x265_print_params(x265_param* param)
> #if ENABLE_ALPHA
> TOOLOPT(param->numScalableLayers > 1, "alpha");
> #endif
> +#if ENABLE_MULTIVIEW
> + TOOLOPT(param->numViews > 1, "multi-view");
> +#endif
> #if ENABLE_HDR10_PLUS
> TOOLOPT(param->toneMapFile != NULL, "dhdr10-info");
> #endif
> @@ -2369,6 +2384,9 @@ char *x265_param2string(x265_param* p, int padx, int
> pady)
> BOOL(p->bEnableTemporalFilter, "mcstf");
> #if ENABLE_ALPHA
> BOOL(p->bEnableAlpha, "alpha");
> +#endif
> +#if ENABLE_MULTIVIEW
> + s += sprintf(s, " num-views=%d", p->numViews);
> #endif
> BOOL(p->bEnableSBRC, "sbrc");
> #undef BOOL
> @@ -2895,6 +2913,9 @@ void x265_copy_params(x265_param* dst, x265_param*
> src)
> dst->bEnableAlpha = src->bEnableAlpha;
> dst->numScalableLayers = src->numScalableLayers;
> #endif
> +#if ENABLE_MULTIVIEW
> + dst->numViews = src->numViews;
> +#endif
>
> if (src->videoSignalTypePreset) dst->videoSignalTypePreset =
> strdup(src->videoSignalTypePreset);
> else dst->videoSignalTypePreset = NULL;
> diff --git a/source/x265.h b/source/x265.h
> index 084f7cd64..baf18e4fc 100644
> --- a/source/x265.h
> +++ b/source/x265.h
> @@ -626,6 +626,12 @@ typedef enum
> #define X265_MAX_GOP_LENGTH 16
> #define MAX_T_LAYERS 7
>
> +#if ENABLE_MULTIVIEW
> +#define MAX_VIEWS 2
> +#else
> +#define MAX_VIEWS 1
> +#endif
> +
> #if ENABLE_ALPHA
> #define MAX_SCALABLE_LAYERS 2
> #define MAX_VPS_NUM_SCALABILITY_TYPES 16
> @@ -2284,6 +2290,9 @@ typedef struct x265_param
> /*Alpha channel encoding*/
> int bEnableAlpha;
> int numScalableLayers;
> +
> + /*Multi View Encoding*/
> + int numViews;
> } x265_param;
>
> /* x265_param_alloc:
> diff --git a/source/x265cli.cpp b/source/x265cli.cpp
> index 1ba0a5877..86e1d9bd8 100755
> --- a/source/x265cli.cpp
> +++ b/source/x265cli.cpp
> @@ -377,6 +377,10 @@ namespace X265_NS {
> #if ENABLE_ALPHA
> H0(" --alpha Enable alpha channel
> support. Default %d\n", param->bEnableAlpha);
> #endif
> +#if ENABLE_MULTIVIEW
> + H0(" --num-views Number of Views for
> Multiview Encoding. Default %d\n", param->numViews);
> + H0(" --multiview-config Configuration file for
> Multiview Encoding\n");
> +#endif
> #ifdef SVT_HEVC
> H0(" --[no]svt Enable SVT HEVC encoder
> %s\n", OPT(param->bEnableSvtHevc));
> H0(" --[no-]svt-hme Enable Hierarchial motion
> estimation(HME) in SVT HEVC encoder \n");
> @@ -583,7 +587,11 @@ namespace X265_NS {
> int inputBitDepth = 8;
> int outputBitDepth = 0;
> int reconFileBitDepth = 0;
> - const char *inputfn = NULL;
> + char* inputfn[MAX_VIEWS] = { NULL };
> + for (int view = 0; view < MAX_VIEWS; view++)
> + {
> + inputfn[view] = X265_MALLOC(char, sizeof(char) * 1024);
> + }
> const char* reconfn[MAX_SCALABLE_LAYERS] = { NULL };
> const char *outputfn = NULL;
> const char *preset = NULL;
> @@ -723,7 +731,7 @@ namespace X265_NS {
> OPT("frames") this->framesToBeEncoded =
> (uint32_t)x265_atoi(optarg, bError);
> OPT("no-progress") this->bProgress = false;
> OPT("output") outputfn = optarg;
> - OPT("input") inputfn = optarg;
> + OPT("input") inputfn[0] = optarg;
> OPT("recon") reconfn[0] = optarg;
> OPT("input-depth") inputBitDepth =
> (uint32_t)x265_atoi(optarg, bError);
> OPT("dither") this->bDither = true;
> @@ -756,6 +764,14 @@ namespace X265_NS {
> if (!this->scenecutAwareQpConfig)
> x265_log_file(param, X265_LOG_ERROR, "%s scenecut
> aware qp config file not found or error in opening config file\n", optarg);
> }
> +#if ENABLE_MULTIVIEW
> + OPT("multiview-config")
> + {
> + this->multiViewConfig = x265_fopen(optarg, "rb");
> + if (!this->multiViewConfig)
> + x265_log_file(param, X265_LOG_ERROR, "%s
> Multiview config file not found or error in opening config file\n", optarg);
> + }
> +#endif
> OPT("zonefile")
> {
> this->zoneFile = x265_fopen(optarg, "rb");
> @@ -782,8 +798,10 @@ namespace X265_NS {
> }
> }
>
> - if (optind < argc && !inputfn)
> - inputfn = argv[optind++];
> +#if !ENABLE_MULTIVIEW
> + if (optind < argc && !inputfn[0])
> + inputfn[0] = argv[optind++];
> +#endif
> if (optind < argc && !outputfn)
> outputfn = argv[optind++];
> if (optind < argc)
> @@ -799,7 +817,18 @@ namespace X265_NS {
> showHelp(param);
> }
>
> - if (!inputfn || !outputfn)
> +#if ENABLE_MULTIVIEW
> + if (this->multiViewConfig)
> + {
> + if (!this->parseMultiViewConfig(inputfn))
> + {
> + x265_log(NULL, X265_LOG_ERROR, "Unable to parse multiview
> config file \n");
> + fclose(this->multiViewConfig);
> + this->multiViewConfig = NULL;
> + }
> + }
> +#endif
> + if (!inputfn[0] || !outputfn)
> {
> x265_log(param, X265_LOG_ERROR, "input or output file not
> specified, try --help for help\n");
> return true;
> @@ -824,7 +853,7 @@ namespace X265_NS {
> #endif
>
> InputFileInfo info;
> - info.filename = inputfn;
> + info.filename = inputfn[0];
> info.depth = inputBitDepth;
> info.csp = param->internalCsp;
> info.width = param->sourceWidth;
> @@ -1250,6 +1279,141 @@ namespace X265_NS {
> return false;
> }
>
> +#if ENABLE_MULTIVIEW
> + bool CLIOptions::parseMultiViewConfig(char** fn)
> + {
> + char line[256];
> + char* argLine;
> + rewind(multiViewConfig);
> + int linenum = 0;
> + int numInput = 0;
> + while (fgets(line, sizeof(line), multiViewConfig))
> + {
> + if (*line == '#' || (strcmp(line, "\r\n") == 0))
> + continue;
> + int index = (int)strcspn(line, "\r\n");
> + line[index] = '\0';
> + argLine = line;
> + while (isspace((unsigned char)*argLine)) argLine++;
> + char* start = strchr(argLine, '-');
> + int argCount = 0;
> + char** args = (char**)malloc(256 * sizeof(char*));
> + //Adding a dummy string to avoid file parsing error
> + args[argCount++] = (char*)"x265";
> + char* token = strtok(start, " ");
> + while (token)
> + {
> + args[argCount++] = token;
> + token = strtok(NULL, " ");
> + while (token && strchr(token, '"'))
> + {
> + token = strchr(token, '"');
> + token = strtok(token, "\"");
> + }
> + }
> + args[argCount] = NULL;
> + bool bError = false;
> + bool bInvalid = false;
> + for (optind = 0;;)
> + {
> + int long_options_index = -1;
> + int c = getopt_long(argCount, args, short_options,
> long_options, &long_options_index);
> + if (c == -1)
> + break;
> + if (long_options_index < 0 && c > 0)
> + {
> + for (size_t i = 0; i < sizeof(long_options) /
> sizeof(long_options[0]); i++)
> + {
> + if (long_options[i].val == c)
> + {
> + long_options_index = (int)i;
> + break;
> + }
> + }
> + if (long_options_index < 0)
> + {
> + /* 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);
> + bInvalid = true;
> + break;
> + }
> + }
> + if (long_options_index < 0)
> + {
> + x265_log(NULL, X265_LOG_WARNING, "short option '%c'
> unrecognized\n", c);
> + bInvalid = true;
> + break;
> + }
> + char nameBuf[64];
> + const char* name = long_options[long_options_index].name;
> + if (!name)
> + bError = true;
> + else
> + {
> + // skip -- prefix if provided
> + if (name[0] == '-' && name[1] == '-')
> + name += 2;
> + // s/_/-/g
> + if (strlen(name) + 1 < sizeof(nameBuf) &&
> strchr(name, '_'))
> + {
> + char* ch;
> + strcpy(nameBuf, name);
> + while ((ch = strchr(nameBuf, '_')) != 0)
> + *ch = '-';
> + name = nameBuf;
> + }
> + if (!optarg)
> + optarg = "true";
> + else if (optarg[0] == '=')
> + optarg++;
> +#define OPT(STR) else if (!strcmp(name, STR))
> + if (0);
> + OPT("num-views") param->numViews = x265_atoi(optarg,
> bError);
> + if (param->numViews > 1)
> + {
> + if (0);
> + OPT("input")
> + {
> + strcpy(fn[numInput++], optarg);
> + }
> +
> + }
> +#undef OPT
> + }
> + if (bError)
> + {
> + const char* optname = long_options_index > 0 ?
> long_options[long_options_index].name : args[optind - 2];
> + x265_log(NULL, X265_LOG_ERROR, "invalid argument: %s
> = %s\n", optname, optarg);
> + bInvalid = true;
> + break;
> + }
> + }
> + if (optind < argCount)
> + {
> + x265_log(param, X265_LOG_WARNING, "extra unused command
> arguments given <%s>\n", args[optind]);
> + bInvalid = true;
> + }
> + if (bInvalid)
> + {
> + if (api)
> + api->param_free(param);
> + exit(1);
> + }
> + linenum++;
> + }
> + if (numInput != param->numViews)
> + {
> + x265_log(NULL, X265_LOG_WARNING, "Input file missing for
> given number of views<%d>\n", param->numViews);
> + if (api)
> + api->param_free(param);
> + exit(1);
> + }
> + return 1;
> + }
> +
> +#endif
> +
> #ifdef __cplusplus
> }
> #endif
> \ No newline at end of file
> diff --git a/source/x265cli.h b/source/x265cli.h
> index 7abf91eb8..0fdad9cf3 100644
> --- a/source/x265cli.h
> +++ b/source/x265cli.h
> @@ -361,6 +361,10 @@ static const struct option long_options[] =
> #if ENABLE_ALPHA
> { "alpha", no_argument, NULL, 0 },
> #endif
> +#if ENABLE_MULTIVIEW
> + { "num-views", required_argument, NULL, 0 },
> + { "multiview-config", required_argument, NULL, 0 },
> +#endif
> #ifdef SVT_HEVC
> { "svt", no_argument, NULL, 0 },
> { "no-svt", no_argument, NULL, 0 },
> @@ -403,6 +407,9 @@ static const struct option long_options[] =
> FILE* zoneFile;
> FILE* dolbyVisionRpu; /* File containing Dolby Vision BL
> RPU metadata */
> FILE* scenecutAwareQpConfig; /* File containing scenecut aware
> frame quantization related CLI options */
> +#if ENABLE_MULTIVIEW
> + FILE* multiViewConfig; /* File containing multi-view related CLI
> options */
> +#endif
> const char* reconPlayCmd;
> const x265_api* api;
> x265_param* param;
> @@ -442,6 +449,9 @@ static const struct option long_options[] =
> zoneFile = NULL;
> dolbyVisionRpu = NULL;
> scenecutAwareQpConfig = NULL;
> +#if ENABLE_MULTIVIEW
> + multiViewConfig = NULL;
> +#endif
> reconPlayCmd = NULL;
> api = NULL;
> param = NULL;
> @@ -474,6 +484,9 @@ static const struct option long_options[] =
> int rpuParser(x265_picture * pic);
> bool parseScenecutAwareQpConfig();
> bool parseScenecutAwareQpParam(int argc, char **argv, x265_param*
> globalParam);
> +#if ENABLE_MULTIVIEW
> + bool parseMultiViewConfig(char** fn);
> +#endif
> };
> #ifdef __cplusplus
> }
> --
> 2.36.0.windows.1
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240807/7c785580/attachment-0001.htm>
More information about the x265-devel
mailing list