[x265] [PATCH] Fix for recon high bit depth when recon is y4m

Karam Singh karam.singh at multicorewareinc.com
Thu Mar 28 08:20:40 UTC 2024


Patch pushed to master branch.

Karam Singh
Senior Software (Video Codec) Engineer
MulticoreWare, India


On Sun, Mar 17, 2024 at 12:04 PM Karam Singh <
karam.singh at multicorewareinc.com> wrote:

> 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/20240328/fba3e9ff/attachment-0001.htm>


More information about the x265-devel mailing list