From 26105adff31020d537ebd4c70fda594fb2a1731c Mon Sep 17 00:00:00 2001 From: DTL2020 <68707763+DTL2020@users.noreply.github.com> Date: Tue, 7 Mar 2023 22:30:08 +0300 Subject: [PATCH 1/2] Fix for unbiased integer division error --- Sources/MDegrainN.cpp | 6 ++++-- Sources/MVDegrain3.cpp | 4 +++- Sources/PlaneOfBlocks.h | 17 +++++++++++------ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/Sources/MDegrainN.cpp b/Sources/MDegrainN.cpp index 79771a28..0e27da6d 100644 --- a/Sources/MDegrainN.cpp +++ b/Sources/MDegrainN.cpp @@ -1948,8 +1948,10 @@ void MDegrainN::use_block_uv( if (usable_flag) { const FakeBlockData &block = c_info._clip_sptr->GetBlock(0, i); - const int blx = block.GetX() * nPel + block.GetMV().x; - const int bly = block.GetY() * nPel + block.GetMV().y; + int blx = block.GetX() * nPel + block.GetMV().x; + int bly = block.GetY() * nPel + block.GetMV().y; + if (nLogxRatioUV_super == 1) blx++; // add bias for integer division for 4:2:x formats + if (nLogyRatioUV_super == 1) bly++; // add bias for integer division for 4:2:x formats p = plane_ptr->GetPointer(blx >> nLogxRatioUV_super, bly >> nLogyRatioUV_super); np = plane_ptr->GetPitch(); const sad_t block_sad = block.GetSAD(); // SAD of MV Block. Scaled to MVClip's bits_per_pixel; diff --git a/Sources/MVDegrain3.cpp b/Sources/MVDegrain3.cpp index 241f6bbe..03a4b6b3 100644 --- a/Sources/MVDegrain3.cpp +++ b/Sources/MVDegrain3.cpp @@ -1544,7 +1544,9 @@ MV_FORCEINLINE void MVDegrainX::use_block_uv(const BYTE * &p, int &np, int &WRef { const FakeBlockData &block = mvclip.GetBlock(0, i); int blx = block.GetX() * nPel + block.GetMV().x; - int bly = block.GetY() * nPel + block.GetMV().y; + int bly = block.GetY() * nPel + block.GetMV().y; + if (nLogxRatioUV_super == 1) blx++; // add bias for integer division for 4:2:x formats + if (nLogyRatioUV_super == 1) bly++; // add bias for integer division for 4:2:x formats p = pPlane->GetPointer(blx >> nLogxRatioUV_super, bly >> nLogyRatioUV_super); // pixelsize - aware np = pPlane->GetPitch(); sad_t blockSAD = block.GetSAD(); // SAD of MV Block. Scaled to MVClip's bits_per_pixel; diff --git a/Sources/PlaneOfBlocks.h b/Sources/PlaneOfBlocks.h index 4b14f87e..ee843a48 100644 --- a/Sources/PlaneOfBlocks.h +++ b/Sources/PlaneOfBlocks.h @@ -409,18 +409,23 @@ class PlaneOfBlocks MV_FORCEINLINE const uint8_t* GetRefBlockU(WorkingArea& workarea, int nVx, int nVy) { + int nVx1 = (nLogxRatioUV == 1) ? nVx + 1 : nVx; + int nVy1 = (nLogxRatioUV == 1) ? nVy + 1 : nVy; return - (nPel == 2) ? pRefFrame->GetPlane(UPLANE)->GetAbsolutePointerPel <1>((workarea.x[1] << 1) + (nVx >> nLogxRatioUV), (workarea.y[1] << 1) + (nVy >> nLogyRatioUV)) : - (nPel == 1) ? pRefFrame->GetPlane(UPLANE)->GetAbsolutePointerPel <0>((workarea.x[1]) + (nVx >> nLogxRatioUV), (workarea.y[1]) + (nVy >> nLogyRatioUV)) : - pRefFrame->GetPlane(UPLANE)->GetAbsolutePointerPel <2>((workarea.x[1] << 2) + (nVx >> nLogxRatioUV), (workarea.y[1] << 2) + (nVy >> nLogyRatioUV)); + (nPel == 2) ? pRefFrame->GetPlane(UPLANE)->GetAbsolutePointerPel <1>((workarea.x[1] << 1) + (nVx1 >> nLogxRatioUV), (workarea.y[1] << 1) + (nVy1 >> nLogyRatioUV)) : + (nPel == 1) ? pRefFrame->GetPlane(UPLANE)->GetAbsolutePointerPel <0>((workarea.x[1]) + (nVx1 >> nLogxRatioUV), (workarea.y[1]) + (nVy1 >> nLogyRatioUV)) : + pRefFrame->GetPlane(UPLANE)->GetAbsolutePointerPel <2>((workarea.x[1] << 2) + (nVx1 >> nLogxRatioUV), (workarea.y[1] << 2) + (nVy1 >> nLogyRatioUV)); + } MV_FORCEINLINE const uint8_t* GetRefBlockV(WorkingArea& workarea, int nVx, int nVy) { + int nVx1 = (nLogxRatioUV == 1) ? nVx + 1 : nVx; + int nVy1 = (nLogxRatioUV == 1) ? nVy + 1 : nVy; return - (nPel == 2) ? pRefFrame->GetPlane(VPLANE)->GetAbsolutePointerPel <1>((workarea.x[2] << 1) + (nVx >> nLogxRatioUV), (workarea.y[2] << 1) + (nVy >> nLogyRatioUV)) : - (nPel == 1) ? pRefFrame->GetPlane(VPLANE)->GetAbsolutePointerPel <0>((workarea.x[2]) + (nVx >> nLogxRatioUV), (workarea.y[2]) + (nVy >> nLogyRatioUV)) : - pRefFrame->GetPlane(VPLANE)->GetAbsolutePointerPel <2>((workarea.x[2] << 2) + (nVx >> nLogxRatioUV), (workarea.y[2] << 2) + (nVy >> nLogyRatioUV)); + (nPel == 2) ? pRefFrame->GetPlane(VPLANE)->GetAbsolutePointerPel <1>((workarea.x[2] << 1) + (nVx1 >> nLogxRatioUV), (workarea.y[2] << 1) + (nVy1 >> nLogyRatioUV)) : + (nPel == 1) ? pRefFrame->GetPlane(VPLANE)->GetAbsolutePointerPel <0>((workarea.x[2]) + (nVx1 >> nLogxRatioUV), (workarea.y[2]) + (nVy1 >> nLogyRatioUV)) : + pRefFrame->GetPlane(VPLANE)->GetAbsolutePointerPel <2>((workarea.x[2] << 2) + (nVx1 >> nLogxRatioUV), (workarea.y[2] << 2) + (nVy1 >> nLogyRatioUV)); } MV_FORCEINLINE const uint8_t* GetSrcBlock(int nX, int nY) From fa9eb74afb28a8d9ca48ba2ec48befd608bab0e5 Mon Sep 17 00:00:00 2001 From: DTL2020 <68707763+DTL2020@users.noreply.github.com> Date: Wed, 8 Mar 2023 13:05:22 +0300 Subject: [PATCH 2/2] Fixed bug in PlanesOfBlocks.h and added fix for subsampled chroma shift in MCompensate (for QTGMC and other MC denoise scripts). --- Sources/MVCompensate.cpp | 92 ++++++++++++++++++++++++++-------------- Sources/PlaneOfBlocks.h | 4 +- 2 files changed, 63 insertions(+), 33 deletions(-) diff --git a/Sources/MVCompensate.cpp b/Sources/MVCompensate.cpp index 017befce..085b6a92 100644 --- a/Sources/MVCompensate.cpp +++ b/Sources/MVCompensate.cpp @@ -678,12 +678,14 @@ void MVCompensate::compensate_slice_normal(Slicer::TaskData &td) BLITLUMA( pDstCur[0] + xx, nDstPitches[0], pPlanes[0]->GetPointer(blx, bly), pPlanes[0]->GetPitch() - ); + ); for (int i = 1; i < planecount; i++) { if (pPlanes[i]) - { + { + int blx_uv = (nLogxRatioUVs[i] == 1) ? blx + 1 : blx; // add bias for integer division for 4:2:x formats + int bly_uv = (nLogyRatioUVs[i] == 1) ? bly + 1 : bly; // add bias for integer division for 4:2:x formats BLITCHROMA(pDstCur[i] + (xx >> nLogxRatioUVs[i]), nDstPitches[i], - pPlanes[i]->GetPointer(blx >> nLogxRatioUVs[i], bly >> nLogyRatioUVs[i]), pPlanes[i]->GetPitch() + pPlanes[i]->GetPointer(blx_uv >> nLogxRatioUVs[i], bly_uv >> nLogyRatioUVs[i]), pPlanes[i]->GetPitch() ); } } @@ -698,11 +700,15 @@ void MVCompensate::compensate_slice_normal(Slicer::TaskData &td) pSrcPlanes[0]->GetPointer(blxsrc, blysrc), pSrcPlanes[0]->GetPitch() ); for (int i = 1; i < planecount; i++) { - if (pSrcPlanes[i]) + if (pSrcPlanes[i]) + { + int blxsrc_uv = (nLogxRatioUVs[i] == 1) ? blxsrc + 1 : blxsrc; // add bias for integer division for 4:2:x formats + int blysrc_uv = (nLogyRatioUVs[i] == 1) ? blysrc + 1 : blysrc; // add bias for integer division for 4:2:x formats BLITCHROMA( pDstCur[i] + (xx >> nLogxRatioUVs[i]), nDstPitches[i], - pSrcPlanes[i]->GetPointer(blxsrc >> nLogxRatioUVs[i], blysrc >> nLogyRatioUVs[i]), pSrcPlanes[i]->GetPitch() - ); + pSrcPlanes[i]->GetPointer(blxsrc_uv >> nLogxRatioUVs[i], blysrc_uv >> nLogyRatioUVs[i]), pSrcPlanes[i]->GetPitch() + ); + } } } @@ -831,12 +837,16 @@ void MVCompensate::compensate_slice_overlap(int y_beg, int y_end) winOver, nBlkSizeX ); for (int i = 1; i < planecount; i++) { - if (pPlanes[i]) + if (pPlanes[i]) + { + int blx_uv = (nLogxRatioUVs[i] == 1) ? blx + 1 : blx; // add bias for integer division for 4:2:x formats + int bly_uv = (nLogyRatioUVs[i] == 1) ? bly + 1 : bly; // add bias for integer division for 4:2:x formats OVERSCHROMA( - (uint16_t *)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], - pPlanes[i]->GetPointer(blx >> nLogxRatioUVs[i], bly >> nLogyRatioUVs[i]), pPlanes[i]->GetPitch(), + (uint16_t*)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], + pPlanes[i]->GetPointer(blx_uv >> nLogxRatioUVs[i], bly_uv >> nLogyRatioUVs[i]), pPlanes[i]->GetPitch(), winOverUV, nBlkSizeX >> nLogxRatioUVs[i] - ); + ); + } } } else if (pixelsize_super == 2) { @@ -848,12 +858,16 @@ void MVCompensate::compensate_slice_overlap(int y_beg, int y_end) ); // chroma uv for (int i = 1; i < planecount; i++) { - if (pPlanes[i]) + if (pPlanes[i]) + { + int blx_uv = (nLogxRatioUVs[i] == 1) ? blx + 1 : blx; // add bias for integer division for 4:2:x formats + int bly_uv = (nLogyRatioUVs[i] == 1) ? bly + 1 : bly; // add bias for integer division for 4:2:x formats OVERSCHROMA16( - (uint16_t *)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], - pPlanes[i]->GetPointer(blx >> nLogxRatioUVs[i], bly >> nLogyRatioUVs[i]), pPlanes[i]->GetPitch(), + (uint16_t*)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], + pPlanes[i]->GetPointer(blx_uv >> nLogxRatioUVs[i], bly_uv >> nLogyRatioUVs[i]), pPlanes[i]->GetPitch(), winOverUV, nBlkSizeX >> nLogxRatioUVs[i] - ); + ); + } } } else { // pixelsize_super == 4 @@ -865,12 +879,16 @@ void MVCompensate::compensate_slice_overlap(int y_beg, int y_end) ); // chroma uv for (int i = 1; i < planecount; i++) { - if (pPlanes[i]) + if (pPlanes[i]) + { + int blx_uv = (nLogxRatioUVs[i] == 1) ? blx + 1 : blx; // add bias for integer division for 4:2:x formats + int bly_uv = (nLogyRatioUVs[i] == 1) ? bly + 1 : bly; // add bias for integer division for 4:2:x formats OVERSCHROMA32( - (uint16_t *)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], - pPlanes[i]->GetPointer(blx >> nLogxRatioUVs[i], bly >> nLogyRatioUVs[i]), pPlanes[i]->GetPitch(), + (uint16_t*)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], + pPlanes[i]->GetPointer(blx_uv >> nLogxRatioUVs[i], bly_uv >> nLogyRatioUVs[i]), pPlanes[i]->GetPitch(), winOverUV, nBlkSizeX >> nLogxRatioUVs[i] - ); + ); + } } } } @@ -889,12 +907,16 @@ void MVCompensate::compensate_slice_overlap(int y_beg, int y_end) ); // chroma uv for (int i = 1; i < planecount; i++) { - if (pSrcPlanes[i]) + if (pSrcPlanes[i]) + { + int blxsrc_uv = (nLogxRatioUVs[i] == 1) ? blxsrc + 1 : blxsrc; // add bias for integer division for 4:2:x formats + int blysrc_uv = (nLogyRatioUVs[i] == 1) ? blysrc + 1 : blysrc; // add bias for integer division for 4:2:x formats OVERSCHROMA( - (uint16_t *)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], - pSrcPlanes[i]->GetPointer(blxsrc >> nLogxRatioUVs[i], blysrc >> nLogyRatioUVs[i]), pSrcPlanes[i]->GetPitch(), + (uint16_t*)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], + pSrcPlanes[i]->GetPointer(blxsrc_uv >> nLogxRatioUVs[i], blysrc_uv >> nLogyRatioUVs[i]), pSrcPlanes[i]->GetPitch(), winOverUV, nBlkSizeX >> nLogxRatioUVs[i] - ); + ); + } } } else if (pixelsize_super == 2){ @@ -906,12 +928,16 @@ void MVCompensate::compensate_slice_overlap(int y_beg, int y_end) ); // chroma uv for (int i = 1; i < planecount; i++) { - if (pSrcPlanes[i]) + if (pSrcPlanes[i]) + { + int blxsrc_uv = (nLogxRatioUVs[i] == 1) ? blxsrc + 1 : blxsrc; // add bias for integer division for 4:2:x formats + int blysrc_uv = (nLogyRatioUVs[i] == 1) ? blysrc + 1 : blysrc; // add bias for integer division for 4:2:x formats OVERSCHROMA16( - (uint16_t *)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], - pSrcPlanes[i]->GetPointer(blxsrc >> nLogxRatioUVs[i], blysrc >> nLogyRatioUVs[i]), pSrcPlanes[i]->GetPitch(), + (uint16_t*)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], + pSrcPlanes[i]->GetPointer(blxsrc_uv >> nLogxRatioUVs[i], blysrc_uv >> nLogyRatioUVs[i]), pSrcPlanes[i]->GetPitch(), winOverUV, nBlkSizeX >> nLogxRatioUVs[i] - ); + ); + } } } else { // if (pixelsize_super == 4) @@ -922,12 +948,16 @@ void MVCompensate::compensate_slice_overlap(int y_beg, int y_end) ); // chroma uv for (int i = 1; i < planecount; i++) { - if (pSrcPlanes[i]) + if (pSrcPlanes[i]) + { + int blxsrc_uv = (nLogxRatioUVs[i] == 1) ? blxsrc + 1 : blxsrc; // add bias for integer division for 4:2:x formats + int blysrc_uv = (nLogyRatioUVs[i] == 1) ? blysrc + 1 : blysrc; // add bias for integer division for 4:2:x formats OVERSCHROMA32( - (uint16_t *)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], - pSrcPlanes[i]->GetPointer(blxsrc >> nLogxRatioUVs[i], blysrc >> nLogyRatioUVs[i]), pSrcPlanes[i]->GetPitch(), - winOverUV, nBlkSizeX >> nLogxRatioUVs[i] - ); + (uint16_t*)(pDstShorts[i] + (xx >> nLogxRatioUVs[i])), dstShortPitches[i], + pSrcPlanes[i]->GetPointer(blxsrc_uv >> nLogxRatioUVs[i], blysrc_uv >> nLogyRatioUVs[i]), pSrcPlanes[i]->GetPitch(), + winOverUV, nBlkSizeX >> nLogxRatioUVs[i] + ); + } } } } diff --git a/Sources/PlaneOfBlocks.h b/Sources/PlaneOfBlocks.h index ee843a48..0d4ac982 100644 --- a/Sources/PlaneOfBlocks.h +++ b/Sources/PlaneOfBlocks.h @@ -410,7 +410,7 @@ class PlaneOfBlocks MV_FORCEINLINE const uint8_t* GetRefBlockU(WorkingArea& workarea, int nVx, int nVy) { int nVx1 = (nLogxRatioUV == 1) ? nVx + 1 : nVx; - int nVy1 = (nLogxRatioUV == 1) ? nVy + 1 : nVy; + int nVy1 = (nLogyRatioUV == 1) ? nVy + 1 : nVy; return (nPel == 2) ? pRefFrame->GetPlane(UPLANE)->GetAbsolutePointerPel <1>((workarea.x[1] << 1) + (nVx1 >> nLogxRatioUV), (workarea.y[1] << 1) + (nVy1 >> nLogyRatioUV)) : (nPel == 1) ? pRefFrame->GetPlane(UPLANE)->GetAbsolutePointerPel <0>((workarea.x[1]) + (nVx1 >> nLogxRatioUV), (workarea.y[1]) + (nVy1 >> nLogyRatioUV)) : @@ -421,7 +421,7 @@ class PlaneOfBlocks MV_FORCEINLINE const uint8_t* GetRefBlockV(WorkingArea& workarea, int nVx, int nVy) { int nVx1 = (nLogxRatioUV == 1) ? nVx + 1 : nVx; - int nVy1 = (nLogxRatioUV == 1) ? nVy + 1 : nVy; + int nVy1 = (nLogyRatioUV == 1) ? nVy + 1 : nVy; return (nPel == 2) ? pRefFrame->GetPlane(VPLANE)->GetAbsolutePointerPel <1>((workarea.x[2] << 1) + (nVx1 >> nLogxRatioUV), (workarea.y[2] << 1) + (nVy1 >> nLogyRatioUV)) : (nPel == 1) ? pRefFrame->GetPlane(VPLANE)->GetAbsolutePointerPel <0>((workarea.x[2]) + (nVx1 >> nLogxRatioUV), (workarea.y[2]) + (nVy1 >> nLogyRatioUV)) :