[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