<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>