<div dir="ltr">Patch pushed to master branch.<font color="#888888"><br class="gmail-Apple-interchange-newline"></font><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><br></div><div>Karam Singh</div>Senior Software (Video Codec) Engineer<div>MulticoreWare, India</div></div></div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Mar 17, 2024 at 12:04 PM Karam Singh <<a href="mailto:karam.singh@multicorewareinc.com">karam.singh@multicorewareinc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">From dc11768f77e035bc8df5e991374321fc63f99cd4 Mon Sep 17 00:00:00 2001<br>From: Karam Singh <<a href="mailto:karam.singh@multicorewareinc.com" target="_blank">karam.singh@multicorewareinc.com</a>><br>Date: Wed, 13 Mar 2024 16:03:58 +0530<br>Subject: [PATCH] Fix for recon high bit depth when recon is .y4m<br><br>---<br> source/output/output.cpp | 2 +-<br> source/output/y4m.cpp | 107 ++++++++++++++++++++++++++-------------<br> source/output/y4m.h | 4 +-<br> 3 files changed, 76 insertions(+), 37 deletions(-)<br><br>diff --git a/source/output/output.cpp b/source/output/output.cpp<br>index c2327b672..7a5151987 100644<br>--- a/source/output/output.cpp<br>+++ b/source/output/output.cpp<br>@@ -35,7 +35,7 @@ ReconFile* ReconFile::open(const char *fname, int width, int height, uint32_t bi<br> const char * s = strrchr(fname, '.');<br> <br> if (s && !strcmp(s, ".y4m"))<br>- return new Y4MOutput(fname, width, height, fpsNum, fpsDenom, csp, sourceBitDepth);<br>+ return new Y4MOutput(fname, width, height, bitdepth, fpsNum, fpsDenom, csp, sourceBitDepth);<br> else<br> return new YUVOutput(fname, width, height, bitdepth, csp, sourceBitDepth);<br> }<br>diff --git a/source/output/y4m.cpp b/source/output/y4m.cpp<br>index 0ebd91c41..91b410f57 100644<br>--- a/source/output/y4m.cpp<br>+++ b/source/output/y4m.cpp<br>@@ -28,9 +28,10 @@<br> using namespace X265_NS;<br> using namespace std;<br> <br>-Y4MOutput::Y4MOutput(const char *filename, int w, int h, uint32_t fpsNum, uint32_t fpsDenom, int csp, int inputdepth)<br>+Y4MOutput::Y4MOutput(const char* filename, int w, int h, uint32_t bitdepth, uint32_t fpsNum, uint32_t fpsDenom, int csp, int inputdepth)<br> : width(w)<br> , height(h)<br>+ , bitDepth(bitdepth)<br> , colorSpace(csp)<br> , frameSize(0)<br> , inputDepth(inputdepth)<br>@@ -42,7 +43,13 @@ Y4MOutput::Y4MOutput(const char *filename, int w, int h, uint32_t fpsNum, uint32<br> <br> if (ofs)<br> {<br>- ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "\n";<br>+ if (bitDepth == 10)<br>+ ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "p10" << " XYSCSS = " << cf << "P10" << "\n";<br>+ else if (bitDepth == 12)<br>+ ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "p12" << " XYSCSS = " << cf << "P12" << "\n";<br>+ else<br>+ ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "\n";<br>+<br> header = ofs.tellp();<br> }<br> <br>@@ -59,50 +66,80 @@ Y4MOutput::~Y4MOutput()<br> bool Y4MOutput::writePicture(const x265_picture& pic)<br> {<br> std::ofstream::pos_type outPicPos = header;<br>- outPicPos += (uint64_t)pic.poc * (6 + frameSize);<br>+ if (pic.bitDepth > 8)<br>+ outPicPos += (uint64_t)(pic.poc * (6 + frameSize * 2));<br>+ else<br>+ outPicPos += (uint64_t)pic.poc * (6 + frameSize);<br> ofs.seekp(outPicPos);<br> ofs << "FRAME\n";<br> <br>-#if HIGH_BIT_DEPTH<br>- if (pic.bitDepth > 8 && pic.poc == 0)<br>- x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting reconstructed pixels to 8 bits\n");<br>-#else<br>- if (pic.bitDepth > 8 && pic.poc == 0)<br>- x265_log(NULL, X265_LOG_WARNING, "y4m: forcing reconstructed pixels to 8 bits\n");<br>-#endif<br>+ if (inputDepth > 8)<br>+ {<br>+ if (pic.bitDepth == 8 && pic.poc == 0)<br>+ x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting reconstructed pixels to 8 bits\n");<br>+ }<br> <br> X265_CHECK(pic.colorSpace == colorSpace, "invalid chroma subsampling\n");<br> <br>- if (inputDepth > 8)<br>+ if (inputDepth > 8)//if HIGH_BIT_DEPTH<br> {<br>- // encoder gave us short pixels, downshift, then write<br>- X265_CHECK(pic.bitDepth > 8, "invalid bit depth\n");<br>- int shift = pic.bitDepth - 8;<br>- for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)<br>- {<br>- uint16_t *src = (uint16_t*)pic.planes[i];<br>- for (int h = 0; h < height >> x265_cli_csps[colorSpace].height[i]; h++)<br>- {<br>- for (int w = 0; w < width >> x265_cli_csps[colorSpace].width[i]; w++)<br>- buf[w] = (char)(src[w] >> shift);<br>+ if (pic.bitDepth == 8)<br>+ {<br>+ // encoder gave us short pixels, downshift, then write<br>+ X265_CHECK(pic.bitDepth == 8, "invalid bit depth\n");<br>+ int shift = pic.bitDepth - 8;<br>+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)<br>+ {<br>+ char *src = (char*)pic.planes[i];<br>+ for (int h = 0; h < height >> x265_cli_csps[colorSpace].height[i]; h++)<br>+ {<br>+ for (int w = 0; w < width >> x265_cli_csps[colorSpace].width[i]; w++)<br>+ buf[w] = (char)(src[w] >> shift);<br> <br>- ofs.write(buf, width >> x265_cli_csps[colorSpace].width[i]);<br>- src += pic.stride[i] / sizeof(*src);<br>- }<br>- } <br>+ ofs.write(buf, width >> x265_cli_csps[colorSpace].width[i]);<br>+ src += pic.stride[i] / sizeof(*src);<br>+ }<br>+ }<br>+ }<br>+ else<br>+ {<br>+ X265_CHECK(pic.bitDepth > 8, "invalid bit depth\n");<br>+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)<br>+ {<br>+ uint16_t *src = (uint16_t*)pic.planes[i];<br>+ for (int h = 0; h < (height * 1) >> x265_cli_csps[colorSpace].height[i]; h++)<br>+ {<br>+ ofs.write((const char*)src, (width * 2) >> x265_cli_csps[colorSpace].width[i]);<br>+ src += pic.stride[i] / sizeof(*src);<br>+ }<br>+ }<br>+ }<br>+ }<br>+ else if (inputDepth == 8 && pic.bitDepth > 8)<br>+ {<br>+ X265_CHECK(pic.bitDepth > 8, "invalid bit depth\n");<br>+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)<br>+ {<br>+ uint16_t* src = (uint16_t*)pic.planes[i];<br>+ for (int h = 0; h < (height * 1) >> x265_cli_csps[colorSpace].height[i]; h++)<br>+ {<br>+ ofs.write((const char*)src, (width * 2) >> x265_cli_csps[colorSpace].width[i]);<br>+ src += pic.stride[i] / sizeof(*src);<br>+ }<br>+ }<br> }<br> else<br> {<br>- X265_CHECK(pic.bitDepth == 8, "invalid bit depth\n");<br>- for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)<br>- {<br>- char *src = (char*)pic.planes[i];<br>- for (int h = 0; h < height >> x265_cli_csps[colorSpace].height[i]; h++)<br>- {<br>- ofs.write(src, width >> x265_cli_csps[colorSpace].width[i]);<br>- src += pic.stride[i] / sizeof(*src);<br>- }<br>- }<br>+ X265_CHECK(pic.bitDepth == 8, "invalid bit depth\n");<br>+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)<br>+ {<br>+ char *src = (char*)pic.planes[i];<br>+ for (int h = 0; h < height >> x265_cli_csps[colorSpace].height[i]; h++)<br>+ {<br>+ ofs.write(src, width >> x265_cli_csps[colorSpace].width[i]);<br>+ src += pic.stride[i] / sizeof(*src);<br>+ }<br>+ }<br> }<br> <br> return true;<br>diff --git a/source/output/y4m.h b/source/output/y4m.h<br>index f00175bd8..5aaf05994 100644<br>--- a/source/output/y4m.h<br>+++ b/source/output/y4m.h<br>@@ -38,6 +38,8 @@ protected:<br> <br> int height;<br> <br>+ uint32_t bitDepth;<br>+<br> int colorSpace;<br> <br> uint32_t frameSize;<br>@@ -54,7 +56,7 @@ protected:<br> <br> public:<br> <br>- Y4MOutput(const char *filename, int width, int height, uint32_t fpsNum, uint32_t fpsDenom, int csp, int inputDepth);<br>+ Y4MOutput(const char *filename, int width, int height, uint32_t bitdepth, uint32_t fpsNum, uint32_t fpsDenom, int csp, int inputDepth);<br> <br> virtual ~Y4MOutput();<br> <br>-- <br>2.36.0.windows.1<br><br><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><br></div><div><br></div><div><br></div><div>Karam Singh</div>Senior Software (Video Codec) Engineer<div>MulticoreWare, India</div></div></div></div></div>
</blockquote></div>