[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", ¶m->sourceWidth, ¶m->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