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 < [email protected]> wrote: > From dc11768f77e035bc8df5e991374321fc63f99cd4 Mon Sep 17 00:00:00 2001 > From: Karam Singh <[email protected]> > 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 >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
