<div dir="ltr">Pushed <br clear="all"><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div>Thanks,</div><div dir="ltr"><span></span><span></span>Kalyan Goswami, PhD</div><div dir="ltr"><span style="font-size:12.8px">Video Architect @ MulticoreWare</span></div><div dir="ltr"><div><a href="http://www.multicorewareinc.com/" target="_blank">http:</a><a href="http://www.multicorewareinc.com/" style="font-size:12.8px" target="_blank">//www.multicorewareinc.com</a></div><div><span style="font-size:12.8px">+91 9884989331</span><br></div><div></div></div></div></div></div></div></div></div></div></div></div></div></div><br></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Dec 20, 2018 at 4:33 PM <<a href="mailto:bhavna@multicorewareinc.com">bhavna@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"># HG changeset patch<br>
# User Bhavna Hariharan <<a href="mailto:bhavna@multicorewareinc.com" target="_blank">bhavna@multicorewareinc.com</a>><br>
# Date 1544769275 -19800<br>
#      Fri Dec 14 12:04:35 2018 +0530<br>
# Node ID 592b83c9068d7f402c85394fcf113b767b58f08d<br>
# Parent  1f44f1f1623d677c80469e713ed642f6673af91d<br>
zone: add support to parse zone files<br>
<br>
diff -r 1f44f1f1623d -r 592b83c9068d doc/reST/cli.rst<br>
--- a/doc/reST/cli.rst  Mon Dec 17 16:49:08 2018 +0530<br>
+++ b/doc/reST/cli.rst  Fri Dec 14 12:04:35 2018 +0530<br>
@@ -1826,6 +1826,20 @@<br>
<br>
        If zones overlap, whichever comes later in the list takes precedence.<br>
        Default none<br>
+       <br>
+       <br>
+.. option:: --zonefile <filename><br>
+<br>
+       Specify a text file which contains the boundaries of the zones where <br>
+       each of zones are configurable. The format of each line is:<br>
+<br>
+       <frame number> <options to be configured><br>
+<br>
+       The frame number indicates the beginning of a zone. The options <br>
+       following this is applied until another zone begins. The reconfigurable <br>
+       options can be spcified as --<feature name> <feature value><br>
+       <br>
+       **CLI ONLY**<br>
<br>
 Quantization Options<br>
 ====================<br>
diff -r 1f44f1f1623d -r 592b83c9068d source/common/param.cpp<br>
--- a/source/common/param.cpp   Mon Dec 17 16:49:08 2018 +0530<br>
+++ b/source/common/param.cpp   Fri Dec 14 12:04:35 2018 +0530<br>
@@ -244,6 +244,7 @@<br>
     param->rc.complexityBlur = 20;<br>
     param->rc.qblur = 0.5;<br>
     param->rc.zoneCount = 0;<br>
+    param->rc.zonefileCount = 0;<br>
     param->rc.zones = NULL;<br>
     param->rc.bEnableSlowFirstPass = 1;<br>
     param->rc.bStrictCbr = 0;<br>
@@ -564,6 +565,104 @@<br>
<br>
     return x265_atoi(arg, bError);<br>
 }<br>
+/* internal versions of string-to-int with additional error checking */<br>
+#undef atoi<br>
+#undef atof<br>
+#define atoi(str) x265_atoi(str, bError)<br>
+#define atof(str) x265_atof(str, bError)<br>
+#define atobool(str) (x265_atobool(str, bError))<br>
+<br>
+int x265_zone_param_parse(x265_param* p, const char* name, const char* value)<br>
+{<br>
+    bool bError = false;<br>
+    char nameBuf[64];<br>
+<br>
+    if (!name)<br>
+        return X265_PARAM_BAD_NAME;<br>
+<br>
+    // skip -- prefix if provided<br>
+    if (name[0] == '-' && name[1] == '-')<br>
+        name += 2;<br>
+<br>
+    // s/_/-/g<br>
+    if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))<br>
+    {<br>
+        char *c;<br>
+        strcpy(nameBuf, name);<br>
+        while ((c = strchr(nameBuf, '_')) != 0)<br>
+            *c = '-';<br>
+<br>
+        name = nameBuf;<br>
+    }<br>
+<br>
+    if (!strncmp(name, "no-", 3))<br>
+    {<br>
+        name += 3;<br>
+        value = !value || x265_atobool(value, bError) ? "false" : "true";<br>
+    }<br>
+    else if (!strncmp(name, "no", 2))<br>
+    {<br>
+        name += 2;<br>
+        value = !value || x265_atobool(value, bError) ? "false" : "true";<br>
+    }<br>
+    else if (!value)<br>
+        value = "true";<br>
+    else if (value[0] == '=')<br>
+        value++;<br>
+<br>
+#define OPT(STR) else if (!strcmp(name, STR))<br>
+#define OPT2(STR1, STR2) else if (!strcmp(name, STR1) || !strcmp(name, STR2))<br>
+<br>
+    if (0);<br>
+    OPT("ref") p->maxNumReferences = atoi(value);<br>
+    OPT("fast-intra") p->bEnableFastIntra = atobool(value);<br>
+    OPT("early-skip") p->bEnableEarlySkip = atobool(value);<br>
+    OPT("rskip") p->bEnableRecursionSkip = atobool(value);<br>
+    OPT("me")p->searchMethod = parseName(value, x265_motion_est_names, bError);<br>
+    OPT("subme") p->subpelRefine = atoi(value);<br>
+    OPT("merange") p->searchRange = atoi(value);<br>
+    OPT("rect") p->bEnableRectInter = atobool(value);<br>
+    OPT("amp") p->bEnableAMP = atobool(value);<br>
+    OPT("max-merge") p->maxNumMergeCand = (uint32_t)atoi(value);<br>
+    OPT("rd") p->rdLevel = atoi(value);<br>
+    OPT2("rdoq", "rdoq-level")<br>
+    {<br>
+        int bval = atobool(value);<br>
+        if (bError || bval)<br>
+        {<br>
+            bError = false;<br>
+            p->rdoqLevel = atoi(value);<br>
+        }<br>
+        else<br>
+            p->rdoqLevel = 0;<br>
+    }<br>
+    OPT("b-intra") p->bIntraInBFrames = atobool(value);<br>
+    OPT("scaling-list") p->scalingLists = strdup(value);<br>
+    OPT("aq-mode") p->rc.aqMode = atoi(value);<br>
+    OPT("aq-strength") p->rc.aqStrength = atof(value);<br>
+    OPT("nr-intra") p->noiseReductionIntra = atoi(value);<br>
+    OPT("nr-inter") p->noiseReductionInter = atoi(value);<br>
+    OPT("limit-modes") p->limitModes = atobool(value);<br>
+    OPT("splitrd-skip") p->bEnableSplitRdSkip = atobool(value);<br>
+    OPT("cu-lossless") p->bCULossless = atobool(value);<br>
+    OPT("rd-refine") p->bEnableRdRefine = atobool(value);<br>
+    OPT("limit-tu") p->limitTU = atoi(value);<br>
+    OPT("tskip") p->bEnableTransformSkip = atobool(value);<br>
+    OPT("tskip-fast") p->bEnableTSkipFast = atobool(value);<br>
+    OPT("rdpenalty") p->rdPenalty = atoi(value);<br>
+    OPT("dynamic-rd") p->dynamicRd = atof(value);<br>
+    else<br>
+        return X265_PARAM_BAD_NAME;<br>
+<br>
+#undef OPT<br>
+#undef OPT2<br>
+<br>
+    return bError ? X265_PARAM_BAD_VALUE : 0;<br>
+}<br>
+<br>
+#undef atobool<br>
+#undef atoi<br>
+#undef atof<br>
<br>
 /* internal versions of string-to-int with additional error checking */<br>
 #undef atoi<br>
diff -r 1f44f1f1623d -r 592b83c9068d source/common/param.h<br>
--- a/source/common/param.h     Mon Dec 17 16:49:08 2018 +0530<br>
+++ b/source/common/param.h     Fri Dec 14 12:04:35 2018 +0530<br>
@@ -51,6 +51,7 @@<br>
 int x265_param_default_preset(x265_param *, const char *preset, const char *tune);<br>
 int x265_param_apply_profile(x265_param *, const char *profile);<br>
 int x265_param_parse(x265_param *p, const char *name, const char *value);<br>
+int x265_zone_param_parse(x265_param* p, const char* name, const char* value);<br>
 #define PARAM_NS X265_NS<br>
 #endif<br>
 }<br>
diff -r 1f44f1f1623d -r 592b83c9068d source/encoder/api.cpp<br>
--- a/source/encoder/api.cpp    Mon Dec 17 16:49:08 2018 +0530<br>
+++ b/source/encoder/api.cpp    Fri Dec 14 12:04:35 2018 +0530<br>
@@ -674,9 +674,9 @@<br>
 #if ENABLE_LIBVMAF<br>
     &x265_calculate_vmafscore,<br>
     &x265_calculate_vmaf_framelevelscore,<br>
-    &x265_vmaf_encoder_log<br>
+    &x265_vmaf_encoder_log,<br>
 #endif<br>
-<br>
+    &PARAM_NS::x265_zone_param_parse<br>
 };<br>
<br>
 typedef const x265_api* (*api_get_func)(int bitDepth);<br>
diff -r 1f44f1f1623d -r 592b83c9068d source/x265.cpp<br>
--- a/source/x265.cpp   Mon Dec 17 16:49:08 2018 +0530<br>
+++ b/source/x265.cpp   Fri Dec 14 12:04:35 2018 +0530<br>
@@ -74,6 +74,7 @@<br>
     ReconFile* recon;<br>
     OutputFile* output;<br>
     FILE*       qpfile;<br>
+    FILE*       zoneFile;<br>
     FILE*    dolbyVisionRpu;    /* File containing Dolby Vision BL RPU metadata */<br>
     const char* reconPlayCmd;<br>
     const x265_api* api;<br>
@@ -97,6 +98,7 @@<br>
         recon = NULL;<br>
         output = NULL;<br>
         qpfile = NULL;<br>
+        zoneFile = NULL;<br>
         dolbyVisionRpu = NULL;<br>
         reconPlayCmd = NULL;<br>
         api = NULL;<br>
@@ -114,7 +116,9 @@<br>
     void destroy();<br>
     void printStatus(uint32_t frameNum);<br>
     bool parse(int argc, char **argv);<br>
+    bool parseZoneParam(int argc, char **argv, x265_param* globalParam, int zonefileCount);<br>
     bool parseQPFile(x265_picture &pic_org);<br>
+    bool parseZoneFile();<br>
 };<br>
<br>
 void CLIOptions::destroy()<br>
@@ -128,6 +132,9 @@<br>
     if (qpfile)<br>
         fclose(qpfile);<br>
     qpfile = NULL;<br>
+    if (zoneFile)<br>
+        fclose(zoneFile);<br>
+    zoneFile = NULL;<br>
     if (dolbyVisionRpu)<br>
         fclose(dolbyVisionRpu);<br>
     dolbyVisionRpu = NULL;<br>
@@ -163,6 +170,110 @@<br>
     prevUpdateTime = time;<br>
 }<br>
<br>
+bool CLIOptions::parseZoneParam(int argc, char **argv, x265_param* globalParam, int zonefileCount)<br>
+{<br>
+    bool bError = false;<br>
+    int bShowHelp = false;<br>
+    int outputBitDepth = 0;<br>
+    const char *profile = NULL;<br>
+<br>
+    /* Presets are applied before all other options. */<br>
+    for (optind = 0;;)<br>
+    {<br>
+        int c = getopt_long(argc, argv, short_options, long_options, NULL);<br>
+        if (c == -1)<br>
+            break;<br>
+        else if (c == 'D')<br>
+            outputBitDepth = atoi(optarg);<br>
+        else if (c == 'P')<br>
+            profile = optarg;<br>
+        else if (c == '?')<br>
+            bShowHelp = true;<br>
+    }<br>
+<br>
+    if (!outputBitDepth && profile)<br>
+    {<br>
+        /* try to derive the output bit depth from the requested profile */<br>
+        if (strstr(profile, "10"))<br>
+            outputBitDepth = 10;<br>
+        else if (strstr(profile, "12"))<br>
+            outputBitDepth = 12;<br>
+        else<br>
+            outputBitDepth = 8;<br>
+    }<br>
+<br>
+    api = x265_api_get(outputBitDepth);<br>
+    if (!api)<br>
+    {<br>
+        x265_log(NULL, X265_LOG_WARNING, "falling back to default bit-depth\n");<br>
+        api = x265_api_get(0);<br>
+    }<br>
+<br>
+    if (bShowHelp)<br>
+    {<br>
+        printVersion(globalParam, api);<br>
+        showHelp(globalParam);<br>
+    }<br>
+<br>
+    globalParam->rc.zones[zonefileCount].zoneParam = api->param_alloc();<br>
+    if (!globalParam->rc.zones[zonefileCount].zoneParam)<br>
+    {<br>
+        x265_log(NULL, X265_LOG_ERROR, "param alloc failed\n");<br>
+        return true;<br>
+    }<br>
+<br>
+    memcpy(globalParam->rc.zones[zonefileCount].zoneParam, globalParam, sizeof(x265_param));<br>
+<br>
+    for (optind = 0;;)<br>
+    {<br>
+        int long_options_index = -1;<br>
+        int c = getopt_long(argc, argv, short_options, long_options, &long_options_index);<br>
+        if (c == -1)<br>
+            break;<br>
+<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>
+<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>
+                return true;<br>
+            }<br>
+        }<br>
+        if (long_options_index < 0)<br>
+        {<br>
+            x265_log(NULL, X265_LOG_WARNING, "short option '%c' unrecognized\n", c);<br>
+            return true;<br>
+        }<br>
+<br>
+        bError |= !!api->zone_param_parse(globalParam->rc.zones[zonefileCount].zoneParam, long_options[long_options_index].name, optarg);<br>
+<br>
+        if (bError)<br>
+        {<br>
+            const char *name = long_options_index > 0 ? long_options[long_options_index].name : argv[optind - 2];<br>
+            x265_log(NULL, X265_LOG_ERROR, "invalid argument: %s = %s\n", name, optarg);<br>
+            return true;<br>
+        }<br>
+    }<br>
+<br>
+    if (optind < argc)<br>
+    {<br>
+        x265_log(param, X265_LOG_WARNING, "extra unused command arguments given <%s>\n", argv[optind]);<br>
+        return true;<br>
+    }<br>
+    return false;<br>
+}<br>
+<br>
 bool CLIOptions::parse(int argc, char **argv)<br>
 {<br>
     bool bError = false;<br>
@@ -327,6 +438,12 @@<br>
                     return true;<br>
                 }<br>
             }<br>
+            OPT("zonefile")<br>
+            {<br>
+                this->zoneFile = x265_fopen(optarg, "rb");<br>
+                if (!this->zoneFile)<br>
+                    x265_log_file(param, X265_LOG_ERROR, "%s zone file not found or error in opening zone file\n", optarg);<br>
+            }<br>
             OPT("fullhelp")<br>
             {<br>
                 param->logLevel = X265_LOG_FULL;<br>
@@ -535,6 +652,59 @@<br>
     return 1;<br>
 }<br>
<br>
+bool CLIOptions::parseZoneFile()<br>
+{<br>
+    char line[256];<br>
+    char* argLine;<br>
+    param->rc.zonefileCount = 0;<br>
+<br>
+    while (fgets(line, sizeof(line), zoneFile))<br>
+    {<br>
+        if (!((*line == '#') || (strcmp(line, "\r\n") == 0)))<br>
+            param->rc.zonefileCount++;<br>
+    }<br>
+<br>
+    rewind(zoneFile);<br>
+    param->rc.zones = X265_MALLOC(x265_zone, param->rc.zonefileCount);<br>
+    for (int i = 0; i < param->rc.zonefileCount; i++)<br>
+    {<br>
+        while (fgets(line, sizeof(line), zoneFile))<br>
+        {<br>
+            if (*line == '#' || (strcmp(line, "\r\n") == 0))<br>
+                continue;<br>
+            param->rc.zones[i].zoneParam = X265_MALLOC(x265_param, 1);<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>
+            start++;<br>
+            param->rc.zones[i].startFrame = atoi(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>
+            }<br>
+            args[argCount] = '\0';<br>
+            CLIOptions cliopt;<br>
+            if (cliopt.parseZoneParam(argCount, args,param, i))<br>
+            {<br>
+                cliopt.destroy();<br>
+                if (cliopt.api)<br>
+                    cliopt.api->param_free(cliopt.param);<br>
+                exit(1);<br>
+            }<br>
+            break;<br>
+        }<br>
+    }<br>
+    return 1;<br>
+}<br>
+<br>
 #ifdef _WIN32<br>
 /* Copy of x264 code, which allows for Unicode characters in the command line.<br>
  * Retrieve command line arguments as UTF-8. */<br>
@@ -667,6 +837,16 @@<br>
     if (cliopt.reconPlayCmd)<br>
         reconPlay = new ReconPlay(cliopt.reconPlayCmd, *param);<br>
<br>
+    if (cliopt.zoneFile)<br>
+    {<br>
+        if (!cliopt.parseZoneFile())<br>
+        {<br>
+            x265_log(NULL, X265_LOG_ERROR, "Unable to parse zonefile\n");<br>
+            fclose(cliopt.zoneFile);<br>
+            cliopt.zoneFile = NULL;<br>
+        }<br>
+    }<br>
+<br>
     /* note: we could try to acquire a different libx265 API here based on<br>
      * the profile found during option parsing, but it must be done before<br>
      * opening an encoder */<br>
diff -r 1f44f1f1623d -r 592b83c9068d source/x265.h<br>
--- a/source/x265.h     Mon Dec 17 16:49:08 2018 +0530<br>
+++ b/source/x265.h     Fri Dec 14 12:04:35 2018 +0530<br>
@@ -659,6 +659,8 @@<br>
 static const char * const x265_interlace_names[] = { "prog", "tff", "bff", 0 };<br>
 static const char * const x265_analysis_names[] = { "off", "save", "load", 0 };<br>
<br>
+struct x265_zone;<br>
+struct x265_param;<br>
 /* Zones: override ratecontrol for specific sections of the video.<br>
  * If zones overlap, whichever comes later in the list takes precedence. */<br>
 typedef struct x265_zone<br>
@@ -667,6 +669,7 @@<br>
     int   bForceQp;             /* whether to use qp vs bitrate factor */<br>
     int   qp;<br>
     float bitrateFactor;<br>
+    x265_param* zoneParam;<br>
 } x265_zone;<br>
<br>
 /* data to calculate aggregate VMAF score */<br>
@@ -1395,6 +1398,9 @@<br>
         int        zoneCount;<br>
         x265_zone* zones;<br>
<br>
+        /* number of zones in zone-file*/<br>
+        int        zonefileCount;<br>
+<br>
         /* specify a text file which contains MAX_MAX_QP + 1 floating point<br>
          * values to be copied into x265_lambda_tab and a second set of<br>
          * MAX_MAX_QP + 1 floating point values for x265_lambda2_tab. All values<br>
@@ -1773,6 +1779,8 @@<br>
 #define X265_PARAM_BAD_VALUE (-2)<br>
 int x265_param_parse(x265_param *p, const char *name, const char *value);<br>
<br>
+int x265_zone_param_parse(x265_param* p, const char* name, const char* value);<br>
+<br>
 static const char * const x265_profile_names[] = {<br>
     /* HEVC v1 */<br>
     "main", "main10", "mainstillpicture", /* alias */ "msp",<br>
@@ -2066,6 +2074,7 @@<br>
     double        (*calculate_vmaf_framelevelscore)(x265_vmaf_framedata *);<br>
     void          (*vmaf_encoder_log)(x265_encoder*, int, char**, x265_param *, x265_vmaf_data *);<br>
 #endif<br>
+    int           (*zone_param_parse)(x265_param*, const char*, const char*);<br>
     /* add new pointers to the end, or increment X265_MAJOR_VERSION */<br>
 } x265_api;<br>
<br>
diff -r 1f44f1f1623d -r 592b83c9068d source/x265cli.h<br>
--- a/source/x265cli.h  Mon Dec 17 16:49:08 2018 +0530<br>
+++ b/source/x265cli.h  Fri Dec 14 12:04:35 2018 +0530<br>
@@ -242,6 +242,7 @@<br>
     { "no-info",              no_argument, NULL, 0 },<br>
     { "zones",          required_argument, NULL, 0 },<br>
     { "qpfile",         required_argument, NULL, 0 },<br>
+    { "zonefile",       required_argument, NULL, 0 },<br>
     { "lambda-file",    required_argument, NULL, 0 },<br>
     { "b-intra",              no_argument, NULL, 0 },<br>
     { "no-b-intra",           no_argument, NULL, 0 },<br>
@@ -541,6 +542,7 @@<br>
     H1("                                   where <option> is either\n");<br>
     H1("                                       q=<integer> (force QP)\n");<br>
     H1("                                   or  b=<float> (bitrate multiplier)\n");<br>
+    H0("   --zonefile <filename>         Zone file containing the zone boundaries and the parameters to be reconfigured.\n");<br>
     H1("   --lambda-file <string>        Specify a file containing replacement values for the lambda tables\n");<br>
     H1("                                 MAX_MAX_QP+1 floats for lambda table, then again for lambda2 table\n");<br>
     H1("                                 Blank lines and lines starting with hash(#) are ignored\n");<br>
_______________________________________________<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>