[x265] [PATCH 2 of 2] abr-ladder: Parse config file and launch ABR tiers
Aruna Matheswaran
aruna at multicorewareinc.com
Tue Mar 31 15:53:53 CEST 2020
Pushed the patch set to default.
On Tue, Mar 31, 2020 at 6:22 PM Aruna Matheswaran <
aruna at multicorewareinc.com> wrote:
> # HG changeset patch
> # User Aruna Matheswaran <aruna at multicorewareinc.com>
> # Date 1585653210 -19800
> # Tue Mar 31 16:43:30 2020 +0530
> # Node ID d78121f6445e01f55c2ac7728bdb12c8850fa2f9
> # Parent 3eccfeafc04000b68c25ab52c43741a1acac21c8
> abr-ladder: Parse config file and launch ABR tiers
>
> diff -r 3eccfeafc040 -r d78121f6445e doc/reST/cli.rst
> --- a/doc/reST/cli.rst Wed Feb 26 16:37:13 2020 +0530
> +++ b/doc/reST/cli.rst Tue Mar 31 16:43:30 2020 +0530
> @@ -2520,6 +2520,28 @@
> --recon-y4m-exec "ffplay -i pipe:0 -autoexit"
>
> **CLI ONLY**
> +
> +ABR-ladder Options
> +==================
> +
> +.. option:: --abr-ladder <filename>
> +
> + File containing the encoder configurations to generate ABR ladder.
> + The format of each line is:
> +
> + **<encID:reuse-level:refID> <CLI>**
> +
> + where, encID indicates the unique name given to the encode, refID
> indicates
> + the name of the encode from which analysis info has to be re-used
> ( set to 'nil'
> + if analysis reuse isn't preferred ), and reuse-level indicates the
> level ( :option:`--analysis-load-reuse-level`)
> + at which analysis info has to be reused.
> +
> + A sample config file is available in `the downloads page <
> https://bitbucket.org/multicoreware/x265/downloads/Sample_ABR_ladder_config
> >`_
> +
> + Default: Disabled ( Conventional single encode generation ).
> Experimental feature.
> +
> + **CLI ONLY**
> +
>
> SVT-HEVC Encoder Options
> ========================
> diff -r 3eccfeafc040 -r d78121f6445e source/x265.cpp
> --- a/source/x265.cpp Wed Feb 26 16:37:13 2020 +0530
> +++ b/source/x265.cpp Tue Mar 31 16:43:30 2020 +0530
> @@ -27,6 +27,7 @@
>
> #include "x265.h"
> #include "x265cli.h"
> +#include "abrEncApp.h"
>
> #include "input/input.h"
> #include "output/output.h"
> @@ -49,12 +50,13 @@
>
> using namespace X265_NS;
>
> +#ifdef _WIN32
> +#define strdup _strdup
> +#endif
> +
> /* Ctrl-C handler */
> static volatile sig_atomic_t b_ctrl_c /* = 0 */;
> -static void sigint_handler(int)
> -{
> - b_ctrl_c = 1;
> -}
> +
> #define START_CODE 0x00000001
> #define START_CODE_BYTES 4
>
> @@ -91,59 +93,178 @@
> }
> #endif
>
> -/* Parse the RPU file and extract the RPU corresponding to the current
> picture
> - * and fill the rpu field of the input picture */
> -static int rpuParser(x265_picture * pic, FILE * ptr)
> -{
> - uint8_t byteVal;
> - uint32_t code = 0;
> - int bytesRead = 0;
> - pic->rpu.payloadSize = 0;
> +/* Checks for abr-ladder config file in the command line.
> + * Returns true if abr-config file is present. Returns
> + * false otherwise */
>
> - if (!pic->pts)
> - {
> - while (bytesRead++ < 4 && fread(&byteVal, sizeof(uint8_t), 1,
> ptr))
> - code = (code << 8) | byteVal;
> -
> - if (code != START_CODE)
> - {
> - x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU
> startcode in POC %d\n", pic->pts);
> - return 1;
> - }
> - }
> -
> - bytesRead = 0;
> - while (fread(&byteVal, sizeof(uint8_t), 1, ptr))
> +static bool IsAbrLadder(int argc, char **argv, FILE **abrConfig)
> +{
> + for (optind = 0;;)
> {
> - code = (code << 8) | byteVal;
> - if (bytesRead++ < 3)
> - continue;
> - if (bytesRead >= 1024)
> + int long_options_index = -1;
> + int c = getopt_long(argc, argv, short_options, long_options,
> &long_options_index);
> + if (c == -1)
> + break;
> + if (long_options_index < 0 && c > 0)
> {
> - x265_log(NULL, X265_LOG_ERROR, "Invalid Dolby Vision RPU size
> in POC %d\n", pic->pts);
> - return 1;
> + 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);
> + return false;
> + }
> }
> -
> - if (code != START_CODE)
> - pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8))
> & 0xFF;
> - else
> - return 0;
> + if (long_options_index < 0)
> + {
> + x265_log(NULL, X265_LOG_WARNING, "short option '%c'
> unrecognized\n", c);
> + return false;
> + }
> + if (!strcmp(long_options[long_options_index].name, "abr-ladder"))
> + {
> + *abrConfig = x265_fopen(optarg, "rb");
> + if (!abrConfig)
> + x265_log_file(NULL, X265_LOG_ERROR, "%s abr-ladder config
> file not found or error in opening zone file\n", optarg);
> + return true;
> + }
> }
> + return false;
> +}
>
> - int ShiftBytes = START_CODE_BYTES - (bytesRead -
> pic->rpu.payloadSize);
> - int bytesLeft = bytesRead - pic->rpu.payloadSize;
> - code = (code << ShiftBytes * 8);
> - for (int i = 0; i < bytesLeft; i++)
> +static uint8_t getNumAbrEncodes(FILE* abrConfig)
> +{
> + char line[1024];
> + uint8_t numEncodes = 0;
> +
> + while (fgets(line, sizeof(line), abrConfig))
> {
> - pic->rpu.payload[pic->rpu.payloadSize++] = (code >> (3 * 8)) &
> 0xFF;
> - code = (code << 8);
> + if (strcmp(line, "\n") == 0)
> + continue;
> + else if (!(*line == '#'))
> + numEncodes++;
> }
> - if (!pic->rpu.payloadSize)
> - x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU not found for
> POC %d\n", pic->pts);
> - return 0;
> + rewind(abrConfig);
> + return numEncodes;
> }
>
> +#define X265_HEAD_ENTRIES 3
>
> +static bool parseAbrConfig(FILE* abrConfig, CLIOptions cliopt[])
> +{
> + char line[1024];
> + char* argLine;
> + uint32_t numEncodes = 0;
> +
> + while (fgets(line, sizeof(line), abrConfig))
> + {
> + if (!((*line == '#') || (strcmp(line, "\r\n") == 0)))
> + numEncodes++;
> + }
> + rewind(abrConfig);
> +
> + for (uint32_t i = 0; i < numEncodes; i++)
> + {
> + while (fgets(line, sizeof(line), abrConfig))
> + {
> + if (*line == '#' || (strcmp(line, "\r\n") == 0))
> + continue;
> + int index = (int)strcspn(line, "\r\n");
> + line[index] = '\0';
> + argLine = line;
> + char* start = strchr(argLine, ' ');
> + while (isspace((unsigned char)*start)) start++;
> + int argCount = 0;
> + char **args = (char**)malloc(256 * sizeof(char *));
> + // Adding a dummy string to avoid file parsing error
> + args[argCount++] = (char *)"x265";
> +
> + /* Parse CLI header to identify the ID of the load encode and
> the reuse level */
> + char *header = strtok(argLine, "[]");
> + uint32_t idCount = 0;
> + char *id = strtok(header, ":");
> + char *head[X265_HEAD_ENTRIES];
> + cliopt[i].encId = i;
> +
> + while (id && (idCount <= X265_HEAD_ENTRIES))
> + {
> + head[idCount] = id;
> + id = strtok(NULL, ":");
> + idCount++;
> + }
> + if (idCount != X265_HEAD_ENTRIES)
> + {
> + x265_log(NULL, X265_LOG_ERROR, "Incorrect number of
> arguments in ABR CLI header at line %d\n", i);
> + return false;
> + }
> + else
> + {
> + cliopt[i].encName = strdup(head[0]);
> + cliopt[i].loadLevel = atoi(head[1]);
> + cliopt[i].reuseName = strdup(head[2]);
> + }
> +
> + char* token = strtok(start, " ");
> + while (token)
> + {
> + args[argCount++] = token;
> + token = strtok(NULL, " ");
> + }
> + args[argCount] = NULL;
> + if (cliopt[i].parse(argCount, args))
> + {
> + cliopt[i].destroy();
> + if (cliopt[i].api)
> + cliopt[i].api->param_free(cliopt[i].param);
> + exit(1);
> + }
> + break;
> + }
> + }
> + return true;
> +}
> +
> +static bool setRefContext(CLIOptions cliopt[], uint32_t numEncodes)
> +{
> + bool hasRef = false;
> + bool isRefFound = false;
> +
> + /* Identify reference encode IDs and set save/load reuse levels */
> + for (uint32_t curEnc = 0; curEnc < numEncodes; curEnc++)
> + {
> + isRefFound = false;
> + hasRef = !strcmp(cliopt[curEnc].reuseName, "nil") ? false : true;
> + if (hasRef)
> + {
> + for (uint32_t refEnc = 0; refEnc < numEncodes; refEnc++)
> + {
> + if (!strcmp(cliopt[curEnc].reuseName,
> cliopt[refEnc].encName))
> + {
> + cliopt[curEnc].refId = refEnc;
> + cliopt[refEnc].numRefs++;
> + cliopt[refEnc].saveLevel =
> X265_MAX(cliopt[refEnc].saveLevel, cliopt[curEnc].loadLevel);
> + isRefFound = true;
> + break;
> + }
> + }
> + if (!isRefFound)
> + {
> + x265_log(NULL, X265_LOG_ERROR, "Reference encode (%s) not
> found for %s\n", cliopt[curEnc].reuseName,
> + cliopt[curEnc].encName);
> + return false;
> + }
> + }
> + }
> + return true;
> +}
> /* CLI return codes:
> *
> * 0 - encode successful
> @@ -168,354 +289,42 @@
> get_argv_utf8(&argc, &argv);
> #endif
>
> - ReconPlay* reconPlay = NULL;
> - CLIOptions cliopt;
> + uint8_t numEncodes = 1;
> + FILE *abrConfig = NULL;
> + bool isAbrLadder = IsAbrLadder(argc, argv, &abrConfig);
> +
> + if (isAbrLadder)
> + numEncodes = getNumAbrEncodes(abrConfig);
> +
> + CLIOptions* cliopt = new CLIOptions[numEncodes];
>
> - if (cliopt.parse(argc, argv))
> + if (isAbrLadder)
> {
> - cliopt.destroy();
> - if (cliopt.api)
> - cliopt.api->param_free(cliopt.param);
> + if(!parseAbrConfig(abrConfig, cliopt))
> + exit(1);
> + if(!setRefContext(cliopt, numEncodes))
> + exit(1);
> + }
> + else if(cliopt[0].parse(argc, argv))
> + {
> + cliopt[0].destroy();
> + if (cliopt[0].api)
> + cliopt[0].api->param_free(cliopt[0].param);
> exit(1);
> }
>
> - x265_param* param = cliopt.param;
> - const x265_api* api = cliopt.api;
> -#if ENABLE_LIBVMAF
> - x265_vmaf_data* vmafdata = cliopt.vmafData;
> -#endif
> - /* This allows muxers to modify bitstream format */
> - cliopt.output->setParam(param);
> -
> - if (cliopt.reconPlayCmd)
> - reconPlay = new ReconPlay(cliopt.reconPlayCmd, *param);
> -
> - if (cliopt.zoneFile)
> - {
> - if (!cliopt.parseZoneFile())
> - {
> - x265_log(NULL, X265_LOG_ERROR, "Unable to parse zonefile\n");
> - fclose(cliopt.zoneFile);
> - cliopt.zoneFile = NULL;
> - }
> - }
> -
> - /* note: we could try to acquire a different libx265 API here based on
> - * the profile found during option parsing, but it must be done before
> - * opening an encoder */
> -
> - x265_encoder *encoder = api->encoder_open(param);
> - if (!encoder)
> - {
> - x265_log(param, X265_LOG_ERROR, "failed to open encoder\n");
> - cliopt.destroy();
> - api->param_free(param);
> - api->cleanup();
> - exit(2);
> - }
> -
> - /* get the encoder parameters post-initialization */
> - api->encoder_parameters(encoder, param);
> -
> - /* Control-C handler */
> - if (signal(SIGINT, sigint_handler) == SIG_ERR)
> - x265_log(param, X265_LOG_ERROR, "Unable to register CTRL+C
> handler: %s\n", strerror(errno));
> + int ret = 0;
>
> - x265_picture pic_orig, pic_out;
> - x265_picture *pic_in = &pic_orig;
> - /* Allocate recon picture if analysis save/load is enabled */
> - std::priority_queue<int64_t>* pts_queue = cliopt.output->needPTS() ?
> new std::priority_queue<int64_t>() : NULL;
> - x265_picture *pic_recon = (cliopt.recon || param->analysisSave ||
> param->analysisLoad || pts_queue || reconPlay || param->csvLogLevel) ?
> &pic_out : NULL;
> - uint32_t inFrameCount = 0;
> - uint32_t outFrameCount = 0;
> - x265_nal *p_nal;
> - x265_stats stats;
> - uint32_t nal;
> - int16_t *errorBuf = NULL;
> - bool bDolbyVisionRPU = false;
> - uint8_t *rpuPayload = NULL;
> - int ret = 0;
> - int inputPicNum = 1;
> - x265_picture picField1, picField2;
> -
> - if (!param->bRepeatHeaders && !param->bEnableSvtHevc)
> + AbrEncoder* abrEnc = new AbrEncoder(cliopt, numEncodes, ret);
> + int threadsActive = abrEnc->m_numActiveEncodes.get();
> + while (threadsActive)
> {
> - if (api->encoder_headers(encoder, &p_nal, &nal) < 0)
> - {
> - x265_log(param, X265_LOG_ERROR, "Failure generating stream
> headers\n");
> - ret = 3;
> - goto fail;
> - }
> - else
> - cliopt.totalbytes += cliopt.output->writeHeaders(p_nal, nal);
> - }
> -
> - if (param->bField && param->interlaceMode)
> - {
> - api->picture_init(param, &picField1);
> - api->picture_init(param, &picField2);
> - // return back the original height of input
> - param->sourceHeight *= 2;
> - api->picture_init(param, pic_in);
> - }
> - else
> - api->picture_init(param, pic_in);
> -
> - if (param->dolbyProfile && cliopt.dolbyVisionRpu)
> - {
> - rpuPayload = X265_MALLOC(uint8_t, 1024);
> - pic_in->rpu.payload = rpuPayload;
> - if (pic_in->rpu.payload)
> - bDolbyVisionRPU = true;
> - }
> -
> - if (cliopt.bDither)
> - {
> - errorBuf = X265_MALLOC(int16_t, param->sourceWidth + 1);
> - if (errorBuf)
> - memset(errorBuf, 0, (param->sourceWidth + 1) *
> sizeof(int16_t));
> - else
> - cliopt.bDither = false;
> + threadsActive =
> abrEnc->m_numActiveEncodes.waitForChange(threadsActive);
> }
>
> - // main encoder loop
> - while (pic_in && !b_ctrl_c)
> - {
> - pic_orig.poc = (param->bField && param->interlaceMode) ?
> inFrameCount * 2 : inFrameCount;
> - if (cliopt.qpfile)
> - {
> - if (!cliopt.parseQPFile(pic_orig))
> - {
> - x265_log(NULL, X265_LOG_ERROR, "can't parse qpfile for
> frame %d\n", pic_in->poc);
> - fclose(cliopt.qpfile);
> - cliopt.qpfile = NULL;
> - }
> - }
> -
> - if (cliopt.framesToBeEncoded && inFrameCount >=
> cliopt.framesToBeEncoded)
> - pic_in = NULL;
> - else if (cliopt.input->readPicture(pic_orig))
> - inFrameCount++;
> - else
> - pic_in = NULL;
> -
> - if (pic_in)
> - {
> - if (pic_in->bitDepth > param->internalBitDepth &&
> cliopt.bDither)
> - {
> - x265_dither_image(pic_in, cliopt.input->getWidth(),
> cliopt.input->getHeight(), errorBuf, param->internalBitDepth);
> - pic_in->bitDepth = param->internalBitDepth;
> - }
> - /* Overwrite PTS */
> - pic_in->pts = pic_in->poc;
> -
> - // convert to field
> - if (param->bField && param->interlaceMode)
> - {
> - int height = pic_in->height >> 1;
> -
> - int static bCreated = 0;
> - if (bCreated == 0)
> - {
> - bCreated = 1;
> - inputPicNum = 2;
> - picField1.fieldNum = 1;
> - picField2.fieldNum = 2;
> -
> - picField1.bitDepth = picField2.bitDepth =
> pic_in->bitDepth;
> - picField1.colorSpace = picField2.colorSpace =
> pic_in->colorSpace;
> - picField1.height = picField2.height = pic_in->height
> >> 1;
> - picField1.framesize = picField2.framesize =
> pic_in->framesize >> 1;
> -
> - size_t fieldFrameSize = (size_t)pic_in->framesize >>
> 1;
> - char* field1Buf = X265_MALLOC(char, fieldFrameSize);
> - char* field2Buf = X265_MALLOC(char, fieldFrameSize);
> -
> - int stride = picField1.stride[0] =
> picField2.stride[0] = pic_in->stride[0];
> - uint64_t framesize = stride * (height >>
> x265_cli_csps[pic_in->colorSpace].height[0]);
> - picField1.planes[0] = field1Buf;
> - picField2.planes[0] = field2Buf;
> - for (int i = 1; i <
> x265_cli_csps[pic_in->colorSpace].planes; i++)
> - {
> - picField1.planes[i] = field1Buf + framesize;
> - picField2.planes[i] = field2Buf + framesize;
> -
> - stride = picField1.stride[i] =
> picField2.stride[i] = pic_in->stride[i];
> - framesize += (stride * (height >>
> x265_cli_csps[pic_in->colorSpace].height[i]));
> - }
> - assert(framesize == picField1.framesize);
> - }
> -
> - picField1.pts = picField1.poc = pic_in->poc;
> - picField2.pts = picField2.poc = pic_in->poc + 1;
> -
> - picField1.userSEI = picField2.userSEI = pic_in->userSEI;
> -
> - //if (pic_in->userData)
> - //{
> - // // Have to handle userData here
> - //}
> -
> - if (pic_in->framesize)
> - {
> - for (int i = 0; i <
> x265_cli_csps[pic_in->colorSpace].planes; i++)
> - {
> - char* srcP1 = (char*)pic_in->planes[i];
> - char* srcP2 = (char*)pic_in->planes[i] +
> pic_in->stride[i];
> - char* p1 = (char*)picField1.planes[i];
> - char* p2 = (char*)picField2.planes[i];
> -
> - int stride = picField1.stride[i];
> -
> - for (int y = 0; y < (height >>
> x265_cli_csps[pic_in->colorSpace].height[i]); y++)
> - {
> - memcpy(p1, srcP1, stride);
> - memcpy(p2, srcP2, stride);
> - srcP1 += 2*stride;
> - srcP2 += 2*stride;
> - p1 += stride;
> - p2 += stride;
> - }
> - }
> - }
> - }
> -
> - if (bDolbyVisionRPU)
> - {
> - if (param->bField && param->interlaceMode)
> - {
> - if (rpuParser(&picField1, cliopt.dolbyVisionRpu) > 0)
> - goto fail;
> - if (rpuParser(&picField2, cliopt.dolbyVisionRpu) > 0)
> - goto fail;
> - }
> - else
> - {
> - if (rpuParser(pic_in, cliopt.dolbyVisionRpu) > 0)
> - goto fail;
> - }
> - }
> - }
> -
> - for (int inputNum = 0; inputNum < inputPicNum; inputNum++)
> - {
> - x265_picture *picInput = NULL;
> - if (inputPicNum == 2)
> - picInput = pic_in ? (inputNum ? &picField2 : &picField1)
> : NULL;
> - else
> - picInput = pic_in;
> -
> - int numEncoded = api->encoder_encode( encoder, &p_nal, &nal,
> picInput, pic_recon );
> - if( numEncoded < 0 )
> - {
> - b_ctrl_c = 1;
> - ret = 4;
> - break;
> - }
> -
> - if (reconPlay && numEncoded)
> - reconPlay->writePicture(*pic_recon);
> -
> - outFrameCount += numEncoded;
> -
> - if (numEncoded && pic_recon && cliopt.recon)
> - cliopt.recon->writePicture(pic_out);
> - if (nal)
> - {
> - cliopt.totalbytes += cliopt.output->writeFrame(p_nal,
> nal, pic_out);
> - if (pts_queue)
> - {
> - pts_queue->push(-pic_out.pts);
> - if (pts_queue->size() > 2)
> - pts_queue->pop();
> - }
> - }
> - cliopt.printStatus( outFrameCount );
> - }
> - }
> -
> - /* Flush the encoder */
> - while (!b_ctrl_c)
> - {
> - int numEncoded = api->encoder_encode(encoder, &p_nal, &nal, NULL,
> pic_recon);
> - if (numEncoded < 0)
> - {
> - ret = 4;
> - break;
> - }
> -
> - if (reconPlay && numEncoded)
> - reconPlay->writePicture(*pic_recon);
> -
> - outFrameCount += numEncoded;
> - if (numEncoded && pic_recon && cliopt.recon)
> - cliopt.recon->writePicture(pic_out);
> - if (nal)
> - {
> - cliopt.totalbytes += cliopt.output->writeFrame(p_nal, nal,
> pic_out);
> - if (pts_queue)
> - {
> - pts_queue->push(-pic_out.pts);
> - if (pts_queue->size() > 2)
> - pts_queue->pop();
> - }
> - }
> -
> - cliopt.printStatus(outFrameCount);
> -
> - if (!numEncoded)
> - break;
> - }
> -
> - if (bDolbyVisionRPU)
> - {
> - if(fgetc(cliopt.dolbyVisionRpu) != EOF)
> - x265_log(NULL, X265_LOG_WARNING, "Dolby Vision RPU count is
> greater than frame count\n");
> - x265_log(NULL, X265_LOG_INFO, "VES muxing with Dolby Vision RPU
> file successful\n");
> - }
> -
> - /* clear progress report */
> - if (cliopt.bProgress)
> - fprintf(stderr, "%*s\r", 80, " ");
> -
> -fail:
> -
> - delete reconPlay;
> -
> - api->encoder_get_stats(encoder, &stats, sizeof(stats));
> - if (param->csvfn && !b_ctrl_c)
> -#if ENABLE_LIBVMAF
> - api->vmaf_encoder_log(encoder, argc, argv, param, vmafdata);
> -#else
> - api->encoder_log(encoder, argc, argv);
> -#endif
> - api->encoder_close(encoder);
> -
> - int64_t second_largest_pts = 0;
> - int64_t largest_pts = 0;
> - if (pts_queue && pts_queue->size() >= 2)
> - {
> - second_largest_pts = -pts_queue->top();
> - pts_queue->pop();
> - largest_pts = -pts_queue->top();
> - pts_queue->pop();
> - delete pts_queue;
> - pts_queue = NULL;
> - }
> - cliopt.output->closeFile(largest_pts, second_largest_pts);
> -
> - if (b_ctrl_c)
> - general_log(param, NULL, X265_LOG_INFO, "aborted at input frame
> %d, output frame %d\n",
> - cliopt.seek + inFrameCount,
> stats.encodedPictureCount);
> -
> - api->cleanup(); /* Free library singletons */
> -
> - cliopt.destroy();
> -
> - api->param_free(param);
> -
> - X265_FREE(errorBuf);
> - X265_FREE(rpuPayload);
> + abrEnc->destroy();
> + for (uint8_t idx = 0; idx < numEncodes; idx++)
> + cliopt[idx].destroy();
>
> SetConsoleTitle(orgConsoleTitle);
> SetThreadExecutionState(ES_CONTINUOUS);
> diff -r 3eccfeafc040 -r d78121f6445e source/x265cli.cpp
> --- a/source/x265cli.cpp Wed Feb 26 16:37:13 2020 +0530
> +++ b/source/x265cli.cpp Tue Mar 31 16:43:30 2020 +0530
> @@ -348,6 +348,8 @@
> H0(" --svt-pred-struct Select pred structure for
> SVT HEVC encoder; Accepts inputs in the range 0-2 \n");
> H0(" --[no-]svt-fps-in-vps Enable VPS timing info for
> SVT HEVC encoder \n");
> #endif
> + H0(" ABR-ladder settings\n");
> + H0(" --abr-ladder <file> File containing config
> settings required for the generation of ABR-ladder\n");
> H1("\nExecutable return codes:\n");
> H1(" 0 - encode successful\n");
> H1(" 1 - unable to parse command line\n");
> diff -r 3eccfeafc040 -r d78121f6445e source/x265cli.h
> --- a/source/x265cli.h Wed Feb 26 16:37:13 2020 +0530
> +++ b/source/x265cli.h Tue Mar 31 16:43:30 2020 +0530
> @@ -372,6 +372,7 @@
> { "cll", no_argument, NULL, 0 },
> { "no-cll", no_argument, NULL, 0 },
> { "hme-range", required_argument, NULL, 0 },
> + { "abr-ladder", required_argument, NULL, 0 },
> { 0, 0, 0, 0 },
> { 0, 0, 0, 0 },
> { 0, 0, 0, 0 },
> @@ -399,6 +400,18 @@
> uint64_t totalbytes;
> int64_t startTime;
> int64_t prevUpdateTime;
> +
> + /* ABR ladder settings */
> + bool enableScaler;
> + char* encName;
> + char* reuseName;
> + uint32_t encId;
> + int refId;
> + uint32_t loadLevel;
> + uint32_t saveLevel;
> + uint32_t numRefs;
> +
> +
> /* in microseconds */
> static const int UPDATE_INTERVAL = 250000;
> CLIOptions()
> @@ -420,6 +433,12 @@
> startTime = x265_mdate();
> prevUpdateTime = 0;
> bDither = false;
> + enableScaler = false;
> + encId = 0;
> + refId = -1;
> + loadLevel = 0;
> + saveLevel = 0;
> + numRefs = 0;
> }
>
> void destroy();
>
--
Regards,
*Aruna Matheswaran,*
Video Codec Engineer,
Media & AI analytics BU,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20200331/d8fa1b15/attachment-0001.html>
More information about the x265-devel
mailing list