[x265] [PATCH 4 of 4] cli: add cli options analysis-mode and analysis-file
Steve Borho
steve at borho.org
Thu Sep 11 19:20:16 CEST 2014
On 09/11, sagar at multicorewareinc.com wrote:
> # HG changeset patch
> # User Sagar Kotecha <sagar at multicorewareinc.com>
> # Date 1410443668 -19800
> # Thu Sep 11 19:24:28 2014 +0530
> # Node ID 2429bf7aa08dbcded7979833b7c01614deb076fd
> # Parent 089f8764b2ebe7f6eb5f29133cdc62e799e74587
> cli: add cli options analysis-mode and analysis-file
>
> analysis-mode: save|1 - Dump analysis buffers into file, load|2 - read analysis buffers from the file
> analysis-file: Specify file name used for either dumping or reading analysis data
>
> diff -r 089f8764b2eb -r 2429bf7aa08d doc/reST/cli.rst
> --- a/doc/reST/cli.rst Thu Sep 11 19:23:25 2014 +0530
> +++ b/doc/reST/cli.rst Thu Sep 11 19:24:28 2014 +0530
> @@ -918,6 +918,22 @@
> * :option:`--subme` = MIN(2, :option:`--subme`)
> * :option:`--rd` = MIN(2, :option:`--rd`)
>
> +.. option:: --analysis-mode <string|int>
> +
> + Following analysis information of each frame is dumped into or read from
> + specified analysis file.
> +
> + I frames - split decisions and luma intra directions of all CUs.
> + P/B frames - motion vectors are dumped at each depth for all CUs.
> +
> + **Range of values:** 0|off **(default)**, 1|save: dump the analysis information
> + 2|load: read the analysis infromation
> +
> +.. option:: --analysis-file
> +
> + Specify file name for dumping or reading analysis data based on
> + analysis-mode option.
> +
> Loop filters
> ============
>
> diff -r 089f8764b2eb -r 2429bf7aa08d source/common/common.h
> --- a/source/common/common.h Thu Sep 11 19:23:25 2014 +0530
> +++ b/source/common/common.h Thu Sep 11 19:24:28 2014 +0530
> @@ -63,6 +63,7 @@
> #define ALIGN_VAR_16(T, var) __declspec(align(16)) T var
> #define ALIGN_VAR_32(T, var) __declspec(align(32)) T var
> #define x265_stack_align(func, ...) func(__VA_ARGS__)
> +#define fseeko _fseeki64
>
> #endif // if defined(__GNUC__)
>
> diff -r 089f8764b2eb -r 2429bf7aa08d source/x265.cpp
> --- a/source/x265.cpp Thu Sep 11 19:23:25 2014 +0530
> +++ b/source/x265.cpp Thu Sep 11 19:24:28 2014 +0530
> @@ -202,6 +202,8 @@
> { "pass", required_argument, NULL, 0 },
> { "slow-firstpass", no_argument, NULL, 0 },
> { "no-slow-firstpass", no_argument, NULL, 0 },
> + { "analysis-mode", required_argument, NULL, 0 },
> + { "analysis-file", required_argument, NULL, 0 },
> { 0, 0, 0, 0 }
> };
>
> @@ -224,11 +226,13 @@
> uint32_t seek; // number of frames to skip from the beginning
> uint32_t framesToBeEncoded; // number of frames to encode
> uint64_t totalbytes;
> + size_t analysisRecordSize; // number of bytes read from or dumped into file
>
> int64_t startTime;
> int64_t prevUpdateTime;
> float frameRate;
> FILE* qpfile;
> + FILE* analysisFile;
>
> /* in microseconds */
> static const int UPDATE_INTERVAL = 250000;
> @@ -245,6 +249,8 @@
> prevUpdateTime = 0;
> bDither = false;
> qpfile = NULL;
> + analysisFile = NULL;
> + analysisRecordSize = 0;
> }
>
> void destroy();
> @@ -254,6 +260,8 @@
> void showHelp(x265_param *param);
> bool parse(int argc, char **argv, x265_param* param);
> bool parseQPFile(x265_picture &pic_org);
> + void readAnalysisFile(x265_picture* pic, x265_param*);
> + void writeAnalysisFile(x265_picture* pic, x265_param*);
> };
>
> void CLIOptions::destroy()
> @@ -267,6 +275,9 @@
> if (qpfile)
> fclose(qpfile);
> qpfile = NULL;
> + if (analysisFile)
> + fclose(analysisFile);
> + analysisFile = NULL;
> }
>
> void CLIOptions::writeNALs(const x265_nal* nal, uint32_t nalcount)
> @@ -432,6 +443,8 @@
> " - 2 : Last pass, does not overwrite stats file\n"
> " - 3 : Nth pass, overwrites stats file\n");
> H0(" --[no-]slow-firstpass Enable a slow first pass in a multipass rate control mode. Default %s\n", OPT(param->rc.bEnableSlowFirstPass));
> + H0(" --analysis-mode <string|int> save|1 - Dump analysis info into file, load|2 - Load analysis buffers from the file. Default %d\n", param->analysisMode);
> + H0(" --analysis-file <filename> Specify file name used for either dumping or reading analysis data.\n");
> H0(" --scaling-list <string> Specify a file containing HM style quant scaling lists or 'default' or 'off'. Default: off\n");
> H0(" --lambda-file <string> Specify a file containing replacement values for the lambda tables\n");
> H0(" MAX_MAX_QP+1 floats for lambda table, then again for lambda2 table\n");
> @@ -486,6 +499,7 @@
> const char *preset = NULL;
> const char *tune = NULL;
> const char *profile = NULL;
> + const char *analysisfn = NULL;
>
> if (argc <= 1)
> {
> @@ -578,6 +592,7 @@
> OPT("profile") profile = optarg; /* handled last */
> OPT("preset") /* handled above */;
> OPT("tune") /* handled above */;
> + OPT("analysis-file") analysisfn = optarg;
> OPT("qpfile")
> {
> this->qpfile = fopen(optarg, "rb");
> @@ -725,9 +740,90 @@
> x265_log(NULL, X265_LOG_ERROR, "failed to open bitstream file <%s> for writing\n", bitstreamfn);
> return true;
> }
> +
> + if ((!analysisfn && param->analysisMode) || (analysisfn && !param->analysisMode))
> + {
> + x265_log(NULL, X265_LOG_ERROR, "Specify analysis file name with analysis-mode option\n");
> + return true;
> + }
> + if (analysisfn)
> + {
> + if (param->analysisMode == X265_ANALYSIS_LOAD)
> + {
> + this->analysisFile = fopen(analysisfn, "rb");
> + if (!this->analysisFile)
> + {
> + x265_log(NULL, X265_LOG_ERROR, "failed to open analysis file %s for reading\n", analysisfn);
> + return true;
> + }
> + }
> + else if (param->analysisMode == X265_ANALYSIS_SAVE)
> + {
> + this->analysisFile = fopen(analysisfn, "wb");
> + if (!this->analysisFile)
> + {
> + x265_log(NULL, X265_LOG_ERROR, "failed to open analysis file %s for writing\n", analysisfn);
> + return true;
> + }
> + }
> + }
I've simplified this by giving a default name for the analysis file and
using a single fopen expression.
> return false;
> }
>
> +void CLIOptions::readAnalysisFile(x265_picture* pic, x265_param* p)
> +{
> + int poc, width, height;
> + uint32_t numPart, numCU;
> + fread(&width, sizeof(int), 1, this->analysisFile);
> + fread(&height, sizeof(int), 1, this->analysisFile);
> + fread(&poc, sizeof(int), 1, this->analysisFile);
> + fread(&pic->sliceType, sizeof(int), 1, this->analysisFile);
> + fread(&numCU, sizeof(int), 1, this->analysisFile);
> + fread(&numPart, sizeof(int), 1, this->analysisFile);
> +
> + if (poc != pic->poc || width != p->sourceWidth || height != p->sourceHeight)
> + {
> + x265_log(NULL, X265_LOG_WARNING, "Error in reading intra-inter data.\n");
> + x265_free_analysis_data(pic);
> + return;
> + }
> +
> + fread(pic->analysisData.intraData->depth,
> + sizeof(uint8_t), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
> + fread(pic->analysisData.intraData->modes,
> + sizeof(uint8_t), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
> + fread(pic->analysisData.intraData->partSizes,
> + sizeof(char), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
> + fread(pic->analysisData.intraData->poc,
> + sizeof(int), pic->analysisData.numCUsInFrame, this->analysisFile);
> + fread(pic->analysisData.intraData->cuAddr,
> + sizeof(uint32_t), pic->analysisData.numCUsInFrame, this->analysisFile);
> + fread(pic->analysisData.interData, sizeof(x265_inter_data), pic->analysisData.numCUsInFrame * 85, this->analysisFile);
> +}
> +
> +void CLIOptions::writeAnalysisFile(x265_picture* pic, x265_param *p)
> +{
> + fpos_t seekTo = pic->poc * this->analysisRecordSize;
> + fseeko(this->analysisFile, seekTo, SEEK_SET);
> + fwrite(&p->sourceWidth, sizeof(int), 1, this->analysisFile);
> + fwrite(&p->sourceHeight, sizeof(int), 1, this->analysisFile);
> + fwrite(&pic->poc, sizeof(int), 1, this->analysisFile);
> + fwrite(&pic->sliceType, sizeof(int), 1, this->analysisFile);
> + fwrite(&pic->analysisData.numCUsInFrame, sizeof(int), 1, this->analysisFile);
> + fwrite(&pic->analysisData.numPartitions, sizeof(int), 1, this->analysisFile);
> +
> + fwrite(pic->analysisData.intraData->depth,
> + sizeof(uint8_t), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
> + fwrite(pic->analysisData.intraData->modes,
> + sizeof(uint8_t), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
> + fwrite(pic->analysisData.intraData->partSizes,
> + sizeof(char), pic->analysisData.numPartitions * pic->analysisData.numCUsInFrame, this->analysisFile);
> + fwrite(pic->analysisData.intraData->poc, sizeof(int), pic->analysisData.numCUsInFrame, this->analysisFile);
> + fwrite(pic->analysisData.intraData->cuAddr, sizeof(uint32_t), pic->analysisData.numCUsInFrame, this->analysisFile);
> + fwrite(pic->analysisData.interData, sizeof(x265_inter_data), pic->analysisData.numCUsInFrame * 85, this->analysisFile);
> +}
> +
> bool CLIOptions::parseQPFile(x265_picture &pic_org)
> {
> int32_t num = -1, qp, ret;
> @@ -820,6 +916,20 @@
>
> x265_picture_init(param, pic_in);
>
> + if (param->analysisMode && !pic_recon)
> + {
> + x265_log(NULL, X265_LOG_ERROR, "Must specify recon with analysis-mode option.\n");
> + goto fail;
> + }
> + if (param->analysisMode)
> + {
> + uint32_t numCU = pic_in->analysisData.numCUsInFrame;
> + uint32_t numPart = pic_in->analysisData.numPartitions;
> +
> + cliopt.analysisRecordSize = ((sizeof(int) * 4 + sizeof(uint32_t) * 2) + sizeof(x265_inter_data) * numCU * 85 +
> + sizeof(uint8_t) * 2 * numPart * numCU + sizeof(char) * numPart * numCU + sizeof(int) * numCU + sizeof(uint32_t) * numCU);
> + }
> +
> if (cliopt.bDither)
> {
> errorBuf = X265_MALLOC(int16_t, param->sourceWidth + 1);
> @@ -856,6 +966,14 @@
> pic_in->bitDepth = X265_DEPTH;
> }
>
> + if (param->analysisMode && pic_in)
> + {
> + x265_alloc_analysis_data(pic_in);
> +
> + if (param->analysisMode == X265_ANALYSIS_LOAD)
> + cliopt.readAnalysisFile(pic_in, param);
> + }
> +
> int numEncoded = x265_encoder_encode(encoder, &p_nal, &nal, pic_in, pic_recon);
> if (numEncoded < 0)
> {
> @@ -866,6 +984,12 @@
> if (numEncoded && pic_recon)
> {
> cliopt.recon->writePicture(pic_out);
> + if (param->analysisMode)
> + {
> + if (param->analysisMode == X265_ANALYSIS_SAVE)
> + cliopt.writeAnalysisFile(pic_recon, param);
> + x265_free_analysis_data(pic_recon);
> + }
> }
>
> if (nal)
> @@ -883,6 +1007,12 @@
> if (numEncoded && pic_recon)
> {
> cliopt.recon->writePicture(pic_out);
> + if (param->analysisMode)
> + {
> + if (param->analysisMode == X265_ANALYSIS_SAVE)
> + cliopt.writeAnalysisFile(pic_recon, param);
> + x265_free_analysis_data(pic_recon);
> + }
> }
>
> if (nal)
> diff -r 089f8764b2eb -r 2429bf7aa08d source/x265.h
> --- a/source/x265.h Thu Sep 11 19:23:25 2014 +0530
> +++ b/source/x265.h Thu Sep 11 19:24:28 2014 +0530
> @@ -276,6 +276,11 @@
>
> #define X265_EXTENDED_SAR 255 /* aspect ratio explicitly specified as width:height */
>
> +/* Analysis options */
> +#define X265_ANALYSIS_OFF 0
> +#define X265_ANALYSIS_SAVE 1
> +#define X265_ANALYSIS_LOAD 2
> +
> typedef struct
> {
> int planes;
> @@ -332,6 +337,7 @@
> static const char * const x265_sar_names[] = { "undef", "1:1", "12:11", "10:11", "16:11", "40:33", "24:11", "20:11",
> "32:11", "80:33", "18:11", "15:11", "64:33", "160:99", "4:3", "3:2", "2:1", 0 };
> static const char * const x265_interlace_names[] = { "prog", "tff", "bff", 0 };
> +static const char * const x265_analysis_mode[] = { "off", "save", "load", 0 };
I folded these changes into the first patch, so the comments could
reference X265_ANALYSIS_OFF and friends. and I've made
x265_analysis_mode plural
> /* x265 input parameters
> *
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
--
Steve Borho
More information about the x265-devel
mailing list