[x265] [PATCH 2 of 3] main10: allow pixel sizes of 10 and 12 for HIGH_BIT_DEPTH builds

Steve Borho steve at borho.org
Tue Nov 5 22:41:34 CET 2013


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1383684853 21600
#      Tue Nov 05 14:54:13 2013 -0600
# Node ID 695e69ec99dbd4894b5703847496d367bf6d17ef
# Parent  4c81c660b25131fb6c2eb25148c5a4137276ff06
main10: allow pixel sizes of 10 and 12 for HIGH_BIT_DEPTH builds

Removes param.internalBitDepth and uses inputBitDepth to mean both the size of
input pixels and internal pixels (x265 will do no color space conversions)

diff -r 4c81c660b251 -r 695e69ec99db source/common/common.cpp
--- a/source/common/common.cpp	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/common/common.cpp	Tue Nov 05 14:54:13 2013 -0600
@@ -141,9 +141,8 @@
     param->logLevel = X265_LOG_INFO;
     param->bEnableWavefront = 1;
     param->frameNumThreads = 1;
-
-    param->internalBitDepth = 8;
-
+    param->inputBitDepth = 8;
+    
     /* CU definitions */
     param->maxCUSize = 64;
     param->tuQTMaxInterDepth = 3;
@@ -206,7 +205,8 @@
 void x265_picture_init(x265_param *param, x265_picture *pic)
 {
     memset(pic, 0, sizeof(x265_picture));
-    pic->bitDepth = param->internalBitDepth;
+    /* This is the encoder internal bit depth */
+    pic->bitDepth = param->inputBitDepth;
 }
 
 extern "C"
@@ -219,7 +219,7 @@
     else if (!strcmp(profile, "main10"))
     {
 #if HIGH_BIT_DEPTH
-        param->internalBitDepth = 10;
+        param->inputBitDepth = 10;
 #else
         x265_log(param, X265_LOG_WARNING, "not compiled for 16bpp. Falling back to main profile.\n");
         return -1;
@@ -427,9 +427,10 @@
     uint32_t tuQTMaxLog2Size = maxCUDepth + 2 - 1;
     uint32_t tuQTMinLog2Size = 2; //log2(4)
 
-    CHECK(param->internalBitDepth > x265_max_bit_depth,
-          "InternalBitDepth must be <= x265_max_bit_depth");
-    CHECK(param->rc.qp < -6 * (param->internalBitDepth - 8) || param->rc.qp > 51,
+    CHECK(param->inputBitDepth > x265_max_bit_depth,
+          "inputBitDepth must be <= x265_max_bit_depth");
+
+    CHECK(param->rc.qp < -6 * (param->inputBitDepth - 8) || param->rc.qp > 51,
           "QP exceeds supported range (-QpBDOffsety to 51)");
     CHECK(param->frameRate <= 0,
           "Frame rate must be more than 1");
@@ -517,9 +518,9 @@
             x265_log(param, X265_LOG_ERROR, "maxCUSize must be the same for all encoders in a single process");
             return -1;
         }
-        if (param->internalBitDepth != g_bitDepth)
+        if (param->inputBitDepth != g_bitDepth)
         {
-            x265_log(param, X265_LOG_ERROR, "internalBitDepth must be the same for all encoders in a single process");
+            x265_log(param, X265_LOG_ERROR, "inputBitDepth must be the same for all encoders in a single process");
             return -1;
         }
     }
@@ -528,7 +529,7 @@
         // set max CU width & height
         g_maxCUWidth  = param->maxCUSize;
         g_maxCUHeight = param->maxCUSize;
-        g_bitDepth = param->internalBitDepth;
+        g_bitDepth = param->inputBitDepth;
 
         // compute actual CU depth with respect to config depth and max transform size
         g_addCUDepth = 0;
@@ -557,7 +558,7 @@
     if (param->logLevel < X265_LOG_INFO)
         return;
 #if HIGH_BIT_DEPTH
-    x265_log(param, X265_LOG_INFO, "Internal bit depth           : %d\n", param->internalBitDepth);
+    x265_log(param, X265_LOG_INFO, "Input bit depth              : %d\n", param->inputBitDepth);
 #endif
     x265_log(param, X265_LOG_INFO, "CU size                      : %d\n", param->maxCUSize);
     x265_log(param, X265_LOG_INFO, "Max RQT depth inter / intra  : %d / %d\n", param->tuQTMaxInterDepth, param->tuQTMaxIntraDepth);
diff -r 4c81c660b251 -r 695e69ec99db source/common/version.cpp
--- a/source/common/version.cpp	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/common/version.cpp	Tue Nov 05 14:54:13 2013 -0600
@@ -75,7 +75,7 @@
 
 #if HIGH_BIT_DEPTH
 #define BITDEPTH "16bpp"
-const int x265_max_bit_depth = 8; // 12;
+const int x265_max_bit_depth = 12;
 #else
 #define BITDEPTH "8bpp"
 const int x265_max_bit_depth = 8;
diff -r 4c81c660b251 -r 695e69ec99db source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/encoder/encoder.cpp	Tue Nov 05 14:54:13 2013 -0600
@@ -1003,7 +1003,7 @@
         break;
     }
 
-    if (_param->internalBitDepth == 10)
+    if (_param->inputBitDepth > 8)
         m_profile = Profile::MAIN10;
     else if (_param->keyframeMax == 1)
         m_profile = Profile::MAINSTILLPICTURE;
diff -r 4c81c660b251 -r 695e69ec99db source/input/input.cpp
--- a/source/input/input.cpp	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/input/input.cpp	Tue Nov 05 14:54:13 2013 -0600
@@ -28,12 +28,12 @@
 
 using namespace x265;
 
-Input* Input::open(const char *filename, bool bForceY4m)
+Input* Input::open(const char *filename, uint32_t inputBitDepth, bool bForceY4m)
 {
     const char * s = strrchr(filename, '.');
 
     if (bForceY4m || (s && !strcmp(s, ".y4m")))
-        return new Y4MInput(filename);
+        return new Y4MInput(filename, inputBitDepth);
     else
-        return new YUVInput(filename);
+        return new YUVInput(filename, inputBitDepth);
 }
diff -r 4c81c660b251 -r 695e69ec99db source/input/input.h
--- a/source/input/input.h	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/input/input.h	Tue Nov 05 14:54:13 2013 -0600
@@ -47,7 +47,7 @@
 
     Input()           {}
 
-    static Input* open(const char *filename, bool bForceY4m);
+    static Input* open(const char *filename, uint32_t inputBitDepth, bool bForceY4m);
 
     virtual void setDimensions(int width, int height) = 0;
 
diff -r 4c81c660b251 -r 695e69ec99db source/input/y4m.cpp
--- a/source/input/y4m.cpp	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/input/y4m.cpp	Tue Nov 05 14:54:13 2013 -0600
@@ -39,7 +39,7 @@
 using namespace x265;
 using namespace std;
 
-Y4MInput::Y4MInput(const char *filename)
+Y4MInput::Y4MInput(const char *filename, uint32_t /*inputBitDepth*/)
 {
 
 #if defined ENABLE_THREAD
diff -r 4c81c660b251 -r 695e69ec99db source/input/y4m.h
--- a/source/input/y4m.h	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/input/y4m.h	Tue Nov 05 14:54:13 2013 -0600
@@ -74,7 +74,7 @@
 
 public:
 
-    Y4MInput(const char *filename);
+    Y4MInput(const char *filename, uint32_t inputBitDepth);
 
     virtual ~Y4MInput();
 
diff -r 4c81c660b251 -r 695e69ec99db source/input/yuv.cpp
--- a/source/input/yuv.cpp	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/input/yuv.cpp	Tue Nov 05 14:54:13 2013 -0600
@@ -39,7 +39,7 @@
 using namespace x265;
 using namespace std;
 
-YUVInput::YUVInput(const char *filename)
+YUVInput::YUVInput(const char *filename, uint32_t inputBitDepth)
 {
 #if defined ENABLE_THREAD
     for (int i = 0; i < QUEUE_SIZE; i++)
@@ -50,7 +50,7 @@
     buf = NULL;
 #endif
     width = height = 0;
-    depth = 8;
+    depth = inputBitDepth;
     threadActive = false;
     if (!strcmp(filename, "-"))
     {
diff -r 4c81c660b251 -r 695e69ec99db source/input/yuv.h
--- a/source/input/yuv.h	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/input/yuv.h	Tue Nov 05 14:54:13 2013 -0600
@@ -75,7 +75,7 @@
 
 public:
 
-    YUVInput(const char *filename);
+    YUVInput(const char *filename, uint32_t inputBitDepth);
 
     virtual ~YUVInput();
 
diff -r 4c81c660b251 -r 695e69ec99db source/output/y4m.cpp
--- a/source/output/y4m.cpp	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/output/y4m.cpp	Tue Nov 05 14:54:13 2013 -0600
@@ -22,6 +22,7 @@
  *****************************************************************************/
 
 #include "PPA/ppa.h"
+#include "common.h"
 #include "output.h"
 #include "y4m.h"
 
@@ -56,13 +57,18 @@
 
     if (pic.bitDepth > 8)
     {
-        // encoder gave us short pixels, downscale, then write
+        if (pic.poc == 0)
+        {
+            x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting reconstructed pixels to 8 bits\n");
+        }
+        // encoder gave us short pixels, downshift, then write
         uint16_t *Y = (uint16_t*)pic.planes[0];
+        int shift = pic.bitDepth - 8;
         for (int i = 0; i < height; i++)
         {
             for (int j = 0; j < width; j++)
             {
-                buf[j] = (char)Y[j];
+                buf[j] = (char)(Y[j] >> shift);
             }
 
             ofs.write(buf, width);
@@ -73,7 +79,7 @@
         {
             for (int j = 0; j < width >> 1; j++)
             {
-                buf[j] = (char)U[j];
+                buf[j] = (char)(U[j] >> shift);
             }
 
             ofs.write(buf, width >> 1);
@@ -84,7 +90,7 @@
         {
             for (int j = 0; j < width >> 1; j++)
             {
-                buf[j] = (char)V[j];
+                buf[j] = (char)(V[j] >> shift);
             }
 
             ofs.write(buf, width >> 1);
diff -r 4c81c660b251 -r 695e69ec99db source/x265.cpp
--- a/source/x265.cpp	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/x265.cpp	Tue Nov 05 14:54:13 2013 -0600
@@ -252,7 +252,6 @@
 {
     x265_param_default(param);
     printVersion(param);
-    uint32_t inputBitDepth = 8, outputBitDepth = param->internalBitDepth;
 
 #define H0 printf
 #define OPT(value) (value ? "enabled" : "disabled")
@@ -274,7 +273,7 @@
     H0("-o/--output                      Bitstream output file name\n");
     H0("\nInput Options:\n");
     H0("   --input                       Raw YUV or Y4M input file name\n");
-    H0("   --input-depth                 Bit-depth of input file (YUV only) Default %d\n", inputBitDepth);
+    H0("   --input-depth                 Bit-depth of input file (YUV only) Default %d\n", param->inputBitDepth);
     H0("   --input-res                   Source picture size [w x h], auto-detected if Y4M\n");
     H0("   --fps                         Source frame rate, auto-detected if Y4M\n");
     H0("   --frame-skip                  Number of frames to skip at start of input file\n");
@@ -328,7 +327,7 @@
     H0("   --[no-]psnr                   Enable reporting PSNR metric scores. Default %s\n", OPT(param->bEnablePsnr));
     H0("\nReconstructed video options (debugging):\n");
     H0("-r/--recon                       Reconstructed image YUV or Y4M output file name\n");
-    H0("   --recon-depth                 Bit-depth of output file. Default %d\n", outputBitDepth);
+    H0("   --recon-depth                 Bit-depth of output file. Default %d\n", param->reconFileBitDepth);
     H0("\nSEI options:\n");
     H0("   --hash                        Decoded Picture Hash SEI 0: disabled, 1: MD5, 2: CRC, 3: Checksum. Default %d\n", param->decodedPictureHashSEI);
 #undef OPT
@@ -341,8 +340,6 @@
     int berror = 0;
     int help = 0;
     int cpuid = 0;
-    uint32_t inputBitDepth = 8;
-    uint32_t outputBitDepth = 8;
     const char *inputfn = NULL;
     const char *reconfn = NULL;
     const char *bitstreamfn = NULL;
@@ -424,8 +421,8 @@
             OPT("output") bitstreamfn = optarg;
             OPT("input") inputfn = optarg;
             OPT("recon") reconfn = optarg;
-            OPT("input-depth") inputBitDepth = (uint32_t)atoi(optarg);
-            OPT("recon-depth") outputBitDepth = (uint32_t)atoi(optarg);
+            OPT("input-depth") param->inputBitDepth = (uint32_t)atoi(optarg);
+            OPT("recon-depth") param->reconFileBitDepth = (uint32_t)atoi(optarg);
             OPT("input-res") inputRes = optarg;
             OPT("y4m") bForceY4m = true;
         else
@@ -459,7 +456,7 @@
         x265_log(param, X265_LOG_ERROR, "input or output file not specified, try -V for help\n");
         return true;
     }
-    this->input = Input::open(inputfn, bForceY4m);
+    this->input = Input::open(inputfn, param->inputBitDepth, bForceY4m);
     if (!this->input || this->input->isFail())
     {
         x265_log(param, X265_LOG_ERROR, "unable to open input file <%s>\n", inputfn);
@@ -471,13 +468,12 @@
         param->sourceWidth = this->input->getWidth();
         param->sourceHeight = this->input->getHeight();
         param->frameRate = (int)this->input->getRate();
-        inputBitDepth = 8;
     }
     else if (inputRes)
     {
         sscanf(inputRes, "%dx%d", &param->sourceWidth, &param->sourceHeight);
         this->input->setDimensions(param->sourceWidth, param->sourceHeight);
-        this->input->setBitDepth(inputBitDepth);
+        this->input->setBitDepth(param->inputBitDepth);
     }
     else if (param->sourceHeight <= 0 || param->sourceWidth <= 0 || param->frameRate <= 0)
     {
@@ -487,12 +483,22 @@
     else
     {
         this->input->setDimensions(param->sourceWidth, param->sourceHeight);
-        this->input->setBitDepth(inputBitDepth);
+        this->input->setBitDepth(param->inputBitDepth);
     }
 
-    /* rules for input, output and internal bitdepths as per help text */
-    if (!param->internalBitDepth) { param->internalBitDepth = inputBitDepth; }
-    if (!outputBitDepth) { outputBitDepth = param->internalBitDepth; }
+    if (param->reconFileBitDepth > 0)
+    {
+        if (param->reconFileBitDepth != param->inputBitDepth)
+        {
+            x265_log(param, X265_LOG_ERROR, "Bit depth of the recon file should be the same as input bit depth\n");
+            /* TODO: Support recon files with bitdepth > input bit depth??*/
+            return true;
+        }
+    }
+    else
+    {
+        param->reconFileBitDepth = param->inputBitDepth;
+    }
 
     int guess = this->input->guessFrameCount();
     if (this->frameSkip)
@@ -521,7 +527,7 @@
 
     if (reconfn)
     {
-        this->recon = Output::open(reconfn, param->sourceWidth, param->sourceHeight, outputBitDepth, param->frameRate);
+        this->recon = Output::open(reconfn, param->sourceWidth, param->sourceHeight, param->reconFileBitDepth, param->frameRate);
         if (this->recon->isFail())
         {
             x265_log(param, X265_LOG_WARNING, "unable to write reconstruction file\n");
@@ -530,10 +536,16 @@
         }
     }
 
-#if !HIGH_BIT_DEPTH
-    if (inputBitDepth != 8 || outputBitDepth != 8 || param->internalBitDepth != 8)
+#if HIGH_BIT_DEPTH
+    if (param->inputBitDepth != 12 && param->inputBitDepth != 10 && param->inputBitDepth != 8)
     {
-        x265_log(NULL, X265_LOG_ERROR, "not compiled for bit depths greater than 8\n");
+        x265_log(param, X265_LOG_ERROR, "Only bit depths of 8, 10, or 12 are supported\n");
+        return true;
+    }
+#else
+    if (param->inputBitDepth != 8)
+    {
+        x265_log(param, X265_LOG_ERROR, "not compiled for bit depths greater than 8\n");
         return true;
     }
 #endif
diff -r 4c81c660b251 -r 695e69ec99db source/x265.h
--- a/source/x265.h	Tue Nov 05 14:42:46 2013 -0600
+++ b/source/x265.h	Tue Nov 05 14:54:13 2013 -0600
@@ -250,10 +250,10 @@
     int       bEnableWavefront;                ///< enable wavefront parallel processing
     int       poolNumThreads;                  ///< number of threads to allocate for thread pool
     int       frameNumThreads;                 ///< number of concurrently encoded frames
+    const char *csvfn;                         ///< csv log filename. logLevel >= 3 is frame logging, else one line per run
 
-    int       internalBitDepth;                ///< bit-depth at which the encoder operates
-
-    const char *csvfn;                         ///< csv log filename. logLevel >= 3 is frame logging, else one line per run
+    int       inputBitDepth;
+    int       reconFileBitDepth;
 
     // source specification
     int       frameRate;                       ///< source frame-rate in Hz


More information about the x265-devel mailing list