[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