[x265] [PATCH 4 of 4] cli: add cli options analysis-out and analysis-in

sagar at multicorewareinc.com sagar at multicorewareinc.com
Wed Sep 10 14:49:03 CEST 2014


# HG changeset patch
# User Sagar Kotecha <sagar at multicorewareinc.com>
# Date 1410353329 -19800
#      Wed Sep 10 18:18:49 2014 +0530
# Node ID f313d0bb2c75799cf7d180950fe63b94d59c175b
# Parent  44004db9861ae68799243fd4f2e395c216f2bb36
cli: add cli options analysis-out and analysis-in

analysis-out - dump the intra/inter information into file
analysis-in -  read the intra/inter information from file

diff -r 44004db9861a -r f313d0bb2c75 doc/reST/cli.rst
--- a/doc/reST/cli.rst	Wed Sep 10 17:37:40 2014 +0530
+++ b/doc/reST/cli.rst	Wed Sep 10 18:18:49 2014 +0530
@@ -918,6 +918,17 @@
 	* :option:`--subme` = MIN(2, :option:`--subme`)
 	* :option:`--rd` = MIN(2, :option:`--rd`)
 
+.. option:: --analysis-out, --no-analysis-out
+
+	The analysis information of each frame is dumped into analysis.txt file.
+	I frames   - For each CU split decisions and luma intra directions are dumped.
+	P/B frames - For each CU motion vectors are dumped for every depth.
+	
+.. option:: --analysis-in, --no-analysis-in	
+
+	The analysis information of each frame is read into buffers from analysis.txt file.
+	This information is forced to use for encoding same clip with diffrent bitrate.
+
 Loop filters
 ============
 
diff -r 44004db9861a -r f313d0bb2c75 source/common/param.cpp
--- a/source/common/param.cpp	Wed Sep 10 17:37:40 2014 +0530
+++ b/source/common/param.cpp	Wed Sep 10 18:18:49 2014 +0530
@@ -732,6 +732,8 @@
         p->rc.bStatRead = pass & 2;
     }
     OPT("stats") p->rc.statFileName = strdup(value);
+    OPT("analysis-out") p->bAnalysisDataOut = atobool(value);
+    OPT("analysis-in") p->bAnalysisDataIn = atobool(value);
     else
         return X265_PARAM_BAD_NAME;
 #undef OPT
diff -r 44004db9861a -r f313d0bb2c75 source/x265.cpp
--- a/source/x265.cpp	Wed Sep 10 17:37:40 2014 +0530
+++ b/source/x265.cpp	Wed Sep 10 18:18:49 2014 +0530
@@ -202,6 +202,10 @@
     { "pass",           required_argument, NULL, 0 },
     { "slow-firstpass",       no_argument, NULL, 0 },
     { "no-slow-firstpass",    no_argument, NULL, 0 },
+    { "analysis-out",         no_argument, NULL, 0 },
+    { "analysis-in",          no_argument, NULL, 0 },
+    { "no-analysis-out",      no_argument, NULL, 0 },
+    { "no-analysis-in",       no_argument, NULL, 0 },
     { 0, 0, 0, 0 }
 };
 
@@ -229,6 +233,7 @@
     int64_t prevUpdateTime;
     float   frameRate;
     FILE*   qpfile;
+    FILE*   analysisFile;
 
     /* in microseconds */
     static const int UPDATE_INTERVAL = 250000;
@@ -245,6 +250,7 @@
         prevUpdateTime = 0;
         bDither = false;
         qpfile = NULL;
+        analysisFile = NULL;
     }
 
     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,9 @@
        "                                   - 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-out                Dump analysis info into analysis.txt file.\n");
+    H0("                                 Analysis info can be used to encode for diffrent bitrate. Default %d\n", OPT(param->bAnalysisDataOut));
+    H0("   --analysis-in                 Read analysis info from analysis.txt file. Default %d\n", OPT(param->bAnalysisDataIn));
     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");
@@ -725,9 +739,86 @@
         x265_log(NULL, X265_LOG_ERROR, "failed to open bitstream file <%s> for writing\n", bitstreamfn);
         return true;
     }
+
+    if (param->bAnalysisDataIn)
+    {
+        this->analysisFile = fopen("analysis.txt", "rb");
+        if (!this->analysisFile)
+        {
+            x265_log(NULL, X265_LOG_ERROR, "failed to open analysis file analysis.txt for reading\n");
+            return true;
+        }
+    }
+
+    if (param->bAnalysisDataOut)
+    {
+        this->analysisFile = fopen("analysis.txt", "wb");
+        if (!this->analysisFile)
+        {
+            x265_log(NULL, X265_LOG_ERROR, "failed to open analysis file analysis.txt for writing\n");
+            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)
+{
+    uint32_t numPart = pic->analysisData.numPartitions, numCU = pic->analysisData.numCUsInFrame;
+    uint32_t seekTo = pic->poc * ((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);
+
+    fseek(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 +911,13 @@
 
     x265_picture_init(param, pic_in);
 
+    if ((param->bAnalysisDataOut || param->bAnalysisDataIn) && !pic_recon)
+    {
+        x265_log(NULL, X265_LOG_WARNING, "Must specify recon with analysis-out or analysis-in options, Disabling analysis options\n");
+        param->bAnalysisDataOut = false;
+        param->bAnalysisDataIn = false;
+    }
+
     if (cliopt.bDither)
     {
         errorBuf = X265_MALLOC(int16_t, param->sourceWidth + 1);
@@ -856,6 +954,16 @@
             pic_in->bitDepth = X265_DEPTH;
         }
 
+        if ((param->bAnalysisDataIn || param->bAnalysisDataOut) && pic_in)
+        {
+            x265_alloc_analysis_data(pic_in, param);
+
+            if (param->bAnalysisDataIn)
+                cliopt.readAnalysisFile(pic_in, param);
+        }
+        else if (param->bAnalysisDataOut && pic_in)
+            x265_alloc_analysis_data(pic_in, param);
+
         int numEncoded = x265_encoder_encode(encoder, &p_nal, &nal, pic_in, pic_recon);
         if (numEncoded < 0)
         {
@@ -866,6 +974,12 @@
         if (numEncoded && pic_recon)
         {
             cliopt.recon->writePicture(pic_out);
+            if (param->bAnalysisDataIn || param->bAnalysisDataOut)
+            {
+                if (param->bAnalysisDataOut)
+                    cliopt.writeAnalysisFile(pic_recon, param);
+                x265_free_analysis_data(pic_recon);
+            }
         }
 
         if (nal)
@@ -883,6 +997,12 @@
         if (numEncoded && pic_recon)
         {
             cliopt.recon->writePicture(pic_out);
+            if (param->bAnalysisDataIn || param->bAnalysisDataOut)
+            {
+                if (param->bAnalysisDataOut)
+                    cliopt.writeAnalysisFile(pic_recon, param);
+                x265_free_analysis_data(pic_recon);
+            }
         }
 
         if (nal)


More information about the x265-devel mailing list