[x265] [PATCH 4 of 4] cli: add cli options analysis-mode and analysis-file

sagar at multicorewareinc.com sagar at multicorewareinc.com
Thu Sep 11 15:55:18 CEST 2014


# 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;
+            }
+        }
+    }
+
     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 };
 
 /* x265 input parameters
  *


More information about the x265-devel mailing list