[x265] [PATCH] Fix for recon high bit depth when recon is y4m
Karam Singh
karam.singh at multicorewareinc.com
Sun Mar 17 06:34:03 UTC 2024
>From dc11768f77e035bc8df5e991374321fc63f99cd4 Mon Sep 17 00:00:00 2001
From: Karam Singh <karam.singh at multicorewareinc.com>
Date: Wed, 13 Mar 2024 16:03:58 +0530
Subject: [PATCH] Fix for recon high bit depth when recon is .y4m
---
source/output/output.cpp | 2 +-
source/output/y4m.cpp | 107 ++++++++++++++++++++++++++-------------
source/output/y4m.h | 4 +-
3 files changed, 76 insertions(+), 37 deletions(-)
diff --git a/source/output/output.cpp b/source/output/output.cpp
index c2327b672..7a5151987 100644
--- a/source/output/output.cpp
+++ b/source/output/output.cpp
@@ -35,7 +35,7 @@ ReconFile* ReconFile::open(const char *fname, int width,
int height, uint32_t bi
const char * s = strrchr(fname, '.');
if (s && !strcmp(s, ".y4m"))
- return new Y4MOutput(fname, width, height, fpsNum, fpsDenom, csp,
sourceBitDepth);
+ return new Y4MOutput(fname, width, height, bitdepth, fpsNum,
fpsDenom, csp, sourceBitDepth);
else
return new YUVOutput(fname, width, height, bitdepth, csp,
sourceBitDepth);
}
diff --git a/source/output/y4m.cpp b/source/output/y4m.cpp
index 0ebd91c41..91b410f57 100644
--- a/source/output/y4m.cpp
+++ b/source/output/y4m.cpp
@@ -28,9 +28,10 @@
using namespace X265_NS;
using namespace std;
-Y4MOutput::Y4MOutput(const char *filename, int w, int h, uint32_t fpsNum,
uint32_t fpsDenom, int csp, int inputdepth)
+Y4MOutput::Y4MOutput(const char* filename, int w, int h, uint32_t
bitdepth, uint32_t fpsNum, uint32_t fpsDenom, int csp, int inputdepth)
: width(w)
, height(h)
+ , bitDepth(bitdepth)
, colorSpace(csp)
, frameSize(0)
, inputDepth(inputdepth)
@@ -42,7 +43,13 @@ Y4MOutput::Y4MOutput(const char *filename, int w, int h,
uint32_t fpsNum, uint32
if (ofs)
{
- ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << fpsNum
<< ":" << fpsDenom << " Ip" << " C" << cf << "\n";
+ if (bitDepth == 10)
+ ofs << "YUV4MPEG2 W" << width << " H" << height << " F" <<
fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "p10" << " XYSCSS = "
<< cf << "P10" << "\n";
+ else if (bitDepth == 12)
+ ofs << "YUV4MPEG2 W" << width << " H" << height << " F" <<
fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "p12" << " XYSCSS = "
<< cf << "P12" << "\n";
+ else
+ ofs << "YUV4MPEG2 W" << width << " H" << height << " F" <<
fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "\n";
+
header = ofs.tellp();
}
@@ -59,50 +66,80 @@ Y4MOutput::~Y4MOutput()
bool Y4MOutput::writePicture(const x265_picture& pic)
{
std::ofstream::pos_type outPicPos = header;
- outPicPos += (uint64_t)pic.poc * (6 + frameSize);
+ if (pic.bitDepth > 8)
+ outPicPos += (uint64_t)(pic.poc * (6 + frameSize * 2));
+ else
+ outPicPos += (uint64_t)pic.poc * (6 + frameSize);
ofs.seekp(outPicPos);
ofs << "FRAME\n";
-#if HIGH_BIT_DEPTH
- if (pic.bitDepth > 8 && pic.poc == 0)
- x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting reconstructed
pixels to 8 bits\n");
-#else
- if (pic.bitDepth > 8 && pic.poc == 0)
- x265_log(NULL, X265_LOG_WARNING, "y4m: forcing reconstructed
pixels to 8 bits\n");
-#endif
+ if (inputDepth > 8)
+ {
+ if (pic.bitDepth == 8 && pic.poc == 0)
+ x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting
reconstructed pixels to 8 bits\n");
+ }
X265_CHECK(pic.colorSpace == colorSpace, "invalid chroma
subsampling\n");
- if (inputDepth > 8)
+ if (inputDepth > 8)//if HIGH_BIT_DEPTH
{
- // encoder gave us short pixels, downshift, then write
- X265_CHECK(pic.bitDepth > 8, "invalid bit depth\n");
- int shift = pic.bitDepth - 8;
- for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
- {
- uint16_t *src = (uint16_t*)pic.planes[i];
- for (int h = 0; h < height >> x265_cli_csps[colorSpace].height[i]; h++)
- {
- for (int w = 0; w < width >> x265_cli_csps[colorSpace].width[i]; w++)
- buf[w] = (char)(src[w] >> shift);
+ if (pic.bitDepth == 8)
+ {
+ // encoder gave us short pixels, downshift, then write
+ X265_CHECK(pic.bitDepth == 8, "invalid bit depth\n");
+ int shift = pic.bitDepth - 8;
+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
+ {
+ char *src = (char*)pic.planes[i];
+ for (int h = 0; h < height >>
x265_cli_csps[colorSpace].height[i]; h++)
+ {
+ for (int w = 0; w < width >>
x265_cli_csps[colorSpace].width[i]; w++)
+ buf[w] = (char)(src[w] >> shift);
- ofs.write(buf, width >> x265_cli_csps[colorSpace].width[i]);
- src += pic.stride[i] / sizeof(*src);
- }
- }
+ ofs.write(buf, width >>
x265_cli_csps[colorSpace].width[i]);
+ src += pic.stride[i] / sizeof(*src);
+ }
+ }
+ }
+ else
+ {
+ X265_CHECK(pic.bitDepth > 8, "invalid bit depth\n");
+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
+ {
+ uint16_t *src = (uint16_t*)pic.planes[i];
+ for (int h = 0; h < (height * 1) >>
x265_cli_csps[colorSpace].height[i]; h++)
+ {
+ ofs.write((const char*)src, (width * 2) >>
x265_cli_csps[colorSpace].width[i]);
+ src += pic.stride[i] / sizeof(*src);
+ }
+ }
+ }
+ }
+ else if (inputDepth == 8 && pic.bitDepth > 8)
+ {
+ X265_CHECK(pic.bitDepth > 8, "invalid bit depth\n");
+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
+ {
+ uint16_t* src = (uint16_t*)pic.planes[i];
+ for (int h = 0; h < (height * 1) >>
x265_cli_csps[colorSpace].height[i]; h++)
+ {
+ ofs.write((const char*)src, (width * 2) >>
x265_cli_csps[colorSpace].width[i]);
+ src += pic.stride[i] / sizeof(*src);
+ }
+ }
}
else
{
- X265_CHECK(pic.bitDepth == 8, "invalid bit depth\n");
- for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
- {
- char *src = (char*)pic.planes[i];
- for (int h = 0; h < height >> x265_cli_csps[colorSpace].height[i]; h++)
- {
- ofs.write(src, width >> x265_cli_csps[colorSpace].width[i]);
- src += pic.stride[i] / sizeof(*src);
- }
- }
+ X265_CHECK(pic.bitDepth == 8, "invalid bit depth\n");
+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
+ {
+ char *src = (char*)pic.planes[i];
+ for (int h = 0; h < height >>
x265_cli_csps[colorSpace].height[i]; h++)
+ {
+ ofs.write(src, width >>
x265_cli_csps[colorSpace].width[i]);
+ src += pic.stride[i] / sizeof(*src);
+ }
+ }
}
return true;
diff --git a/source/output/y4m.h b/source/output/y4m.h
index f00175bd8..5aaf05994 100644
--- a/source/output/y4m.h
+++ b/source/output/y4m.h
@@ -38,6 +38,8 @@ protected:
int height;
+ uint32_t bitDepth;
+
int colorSpace;
uint32_t frameSize;
@@ -54,7 +56,7 @@ protected:
public:
- Y4MOutput(const char *filename, int width, int height, uint32_t
fpsNum, uint32_t fpsDenom, int csp, int inputDepth);
+ Y4MOutput(const char *filename, int width, int height, uint32_t
bitdepth, uint32_t fpsNum, uint32_t fpsDenom, int csp, int inputDepth);
virtual ~Y4MOutput();
--
2.36.0.windows.1
Karam Singh
Senior Software (Video Codec) Engineer
MulticoreWare, India
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240317/441ae94c/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Fix_for_recon_high_bit_depth_in_y4m_patch.diff
Type: application/octet-stream
Size: 7520 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240317/441ae94c/attachment-0001.obj>
More information about the x265-devel
mailing list