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