<div dir="ltr">From 0a3736655de21539cd7c302af18a46ec05c41b43 Mon Sep 17 00:00:00 2001<br>From: AnusuyaKumarasamy <<a href="mailto:anusuya.kumarasamy@multicorewareinc.com">anusuya.kumarasamy@multicorewareinc.com</a>><br>Date: Thu, 24 Oct 2024 12:57:53 +0530<br>Subject: [PATCH 03/10] Make use of halfpel & quarterpel resolution reference<br> frame from lookahead for mcstf<br><br>---<br> source/common/temporalfilter.cpp | 62 ++++++++++++++++----------------<br> source/common/temporalfilter.h   |  7 ++--<br> source/encoder/encoder.cpp       | 21 +++--------<br> 3 files changed, 40 insertions(+), 50 deletions(-)<br><br>diff --git a/source/common/temporalfilter.cpp b/source/common/temporalfilter.cpp<br>index 235379b63..7c1be767e 100644<br>--- a/source/common/temporalfilter.cpp<br>+++ b/source/common/temporalfilter.cpp<br>@@ -194,7 +194,7 @@ fail:<br> int TemporalFilter::motionErrorLumaSAD(<br>     pixel* src,<br>     int stride,<br>-    PicYuv *buffer,<br>+    pixel* buf,<br>     int x,<br>     int y,<br>     int dx,<br>@@ -205,8 +205,8 @@ int TemporalFilter::motionErrorLumaSAD(<br> <br>     pixel* origOrigin = src;<br>     intptr_t origStride = stride;<br>-    pixel *buffOrigin = buffer->m_picOrg[0];<br>-    intptr_t buffStride = buffer->m_stride;<br>+    pixel *buffOrigin = buf;<br>+    intptr_t buffStride = stride;<br>     int error = 0;// dx * 10 + dy * 10;<br>     if (((dx | dy) & 0xF) == 0)<br>     {<br>@@ -299,7 +299,7 @@ int TemporalFilter::motionErrorLumaSAD(<br> int TemporalFilter::motionErrorLumaSSD(<br>     pixel* src,<br>     int stride,<br>-    PicYuv *buffer,<br>+    pixel* buf,<br>     int x,<br>     int y,<br>     int dx,<br>@@ -310,8 +310,8 @@ int TemporalFilter::motionErrorLumaSSD(<br> <br>     pixel* origOrigin = src;<br>     intptr_t origStride = stride;<br>-    pixel *buffOrigin = buffer->m_picOrg[0];<br>-    intptr_t buffStride = buffer->m_stride;<br>+    pixel *buffOrigin = buf;<br>+    intptr_t buffStride = stride;<br>     int error = 0;// dx * 10 + dy * 10;<br>     if (((dx | dy) & 0xF) == 0)<br>     {<br>@@ -648,7 +648,7 @@ void TemporalFilter::bilateralFilter(Frame* frame,<br>     }<br> }<br> <br>-void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src,int stride, int height, int width, PicYuv *buffer, int blockSize,<br>+void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src,int stride, int height, int width, pixel* buf, int blockSize,<br>     MV *previous, uint32_t prevMvStride, int factor)<br> {<br> <br>@@ -694,9 +694,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src<br>                             MV old = previous[mvIdx];<br> <br>                             if (m_useSADinME)<br>-                                error = motionErrorLumaSAD(src, stride, buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);<br>+                                error = motionErrorLumaSAD(src, stride, buf, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);<br>                             else<br>-                                error = motionErrorLumaSSD(src, stride, buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);<br>+                                error = motionErrorLumaSSD(src, stride, buf, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);<br> <br>                             if (error < leastError)<br>                             {<br>@@ -708,9 +708,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src<br>                 }<br> <br>                 if (m_useSADinME)<br>-                    error = motionErrorLumaSAD(src, stride, buffer, blockX, blockY, 0, 0, blockSize, leastError);<br>+                    error = motionErrorLumaSAD(src, stride, buf, blockX, blockY, 0, 0, blockSize, leastError);<br>                 else<br>-                    error = motionErrorLumaSSD(src, stride, buffer, blockX, blockY, 0, 0, blockSize, leastError);<br>+                    error = motionErrorLumaSSD(src, stride, buf, blockX, blockY, 0, 0, blockSize, leastError);<br> <br>                 if (error < leastError)<br>                 {<br>@@ -726,9 +726,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src<br>                 for (int x2 = prevBest.x / m_motionVectorFactor - range; x2 <= prevBest.x / m_motionVectorFactor + range; x2++)<br>                 {<br>                     if (m_useSADinME)<br>-                        error = motionErrorLumaSAD(src, stride, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);<br>+                        error = motionErrorLumaSAD(src, stride, buf, blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);<br>                     else<br>-                        error = motionErrorLumaSSD(src, stride, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);<br>+                        error = motionErrorLumaSSD(src, stride, buf, blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);<br>                     if (error < leastError)<br>                     {<br>                         best.set(x2 * m_motionVectorFactor, y2 * m_motionVectorFactor);<br>@@ -743,9 +743,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src<br>                 MV aboveMV = mvs[idx];<br> <br>                 if (m_useSADinME)<br>-                    error = motionErrorLumaSAD(src, stride, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);<br>+                    error = motionErrorLumaSAD(src, stride, buf, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);<br>                 else<br>-                    error = motionErrorLumaSSD(src, stride, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);<br>+                    error = motionErrorLumaSSD(src, stride, buf, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);<br> <br>                 if (error < leastError)<br>                 {<br>@@ -760,9 +760,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src<br>                 MV leftMV = mvs[idx];<br> <br>                 if (m_useSADinME)<br>-                    error = motionErrorLumaSAD(src, stride, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);<br>+                    error = motionErrorLumaSAD(src, stride, buf, blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);<br>                 else<br>-                    error = motionErrorLumaSSD(src, stride, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);<br>+                    error = motionErrorLumaSSD(src, stride, buf, blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);<br> <br>                 if (error < leastError)<br>                 {<br>@@ -848,9 +848,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, P<br>                             MV old = previous[mvIdx];<br> <br>                             if (m_useSADinME)<br>-                                error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);<br>+                                error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);<br>                             else<br>-                                error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);<br>+                                error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);<br> <br>                             if (error < leastError)<br>                             {<br>@@ -862,9 +862,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, P<br>                 }<br> <br>                 if (m_useSADinME)<br>-                    error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, 0, 0, blockSize, leastError);<br>+                    error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, 0, 0, blockSize, leastError);<br>                 else<br>-                    error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, 0, 0, blockSize, leastError);<br>+                    error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, 0, 0, blockSize, leastError);<br> <br>                 if (error < leastError)<br>                 {<br>@@ -880,9 +880,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, P<br>                 for (int x2 = prevBest.x / m_motionVectorFactor - range; x2 <= prevBest.x / m_motionVectorFactor + range; x2++)<br>                 {<br>                     if (m_useSADinME)<br>-                        error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);<br>+                        error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);<br>                     else<br>-                        error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);<br>+                        error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);<br> <br>                     if (error < leastError)<br>                     {<br>@@ -899,9 +899,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, P<br>                 for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x + doubleRange; x2 += 4)<br>                 {<br>                     if (m_useSADinME)<br>-                        error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);<br>+                        error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2, y2, blockSize, leastError);<br>                     else<br>-                        error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);<br>+                        error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2, y2, blockSize, leastError);<br> <br>                     if (error < leastError)<br>                     {<br>@@ -918,9 +918,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, P<br>                 for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x + doubleRange; x2++)<br>                 {<br>                     if (m_useSADinME)<br>-                        error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);<br>+                        error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2, y2, blockSize, leastError);<br>                     else<br>-                        error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);<br>+                        error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2, y2, blockSize, leastError);<br> <br>                     if (error < leastError)<br>                     {<br>@@ -937,9 +937,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, P<br>                 MV aboveMV = mvs[idx];<br> <br>                 if (m_useSADinME)<br>-                    error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);<br>+                    error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);<br>                 else<br>-                    error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);<br>+                    error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);<br> <br>                 if (error < leastError)<br>                 {<br>@@ -954,9 +954,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, P<br>                 MV leftMV = mvs[idx];<br> <br>                 if (m_useSADinME)<br>-                    error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);<br>+                    error = motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);<br>                 else<br>-                    error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);<br>+                    error = motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0], blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);<br> <br>                 if (error < leastError)<br>                 {<br>diff --git a/source/common/temporalfilter.h b/source/common/temporalfilter.h<br>index ae60c77f8..9fe51da8c 100644<br>--- a/source/common/temporalfilter.h<br>+++ b/source/common/temporalfilter.h<br>@@ -104,6 +104,7 @@ namespace X265_NS {<br>         uint32_t   mvsStride2;<br>         int*       error;<br>         int*       noise;<br>+        int        poc;<br> <br>         int16_t    origOffset;<br>         bool       isFilteredFrame;<br>@@ -152,7 +153,7 @@ namespace X265_NS {<br> <br>         void bilateralFilter(Frame* frame, TemporalFilterRefPicInfo* mctfRefList, double overallStrength);<br> <br>-        void motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src, int stride, int height, int width, PicYuv *buffer, int bs,<br>+        void motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src, int stride, int height, int width, pixel* buf, int bs,<br>             MV *previous = 0, uint32_t prevmvStride = 0, int factor = 1);<br> <br>         void motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, PicYuv *orig, PicYuv *buffer, int blockSize,<br>@@ -160,7 +161,7 @@ namespace X265_NS {<br> <br>         int motionErrorLumaSSD(pixel* src,<br>             int stride,<br>-            PicYuv *buffer,<br>+            pixel* buf,<br>             int x,<br>             int y,<br>             int dx,<br>@@ -170,7 +171,7 @@ namespace X265_NS {<br> <br>         int motionErrorLumaSAD(pixel* src,<br>             int stride,<br>-            PicYuv *buffer,<br>+            pixel* buf,<br>             int x,<br>             int y,<br>             int dx,<br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index 58818379a..0a0c09307 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -1408,6 +1408,7 @@ bool Encoder::isFilterThisframe(uint8_t sliceTypeConfig, int curSliceType)<br> inline int enqueueRefFrame(FrameEncoder* curframeEncoder, Frame* iterFrame, Frame* curFrame, bool isPreFiltered, int16_t i)<br> {<br>     TemporalFilterRefPicInfo* dest = &curframeEncoder->m_mcstfRefList[curFrame->m_mcstf->m_numRef];<br>+    dest->poc = iterFrame->m_poc;<br>     dest->picBuffer = iterFrame->m_fencPic;<br>     dest->picBufferSubSampled2 = iterFrame->m_fencPicSubsampled2;<br>     dest->picBufferSubSampled4 = iterFrame->m_fencPicSubsampled4;<br>@@ -2510,23 +2511,11 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)<br>                 for (uint8_t i = 1; i <= frameEnc[0]->m_mcstf->m_numRef; i++)<br>                 {<br>                     TemporalFilterRefPicInfo *ref = &curEncoder->m_mcstfRefList[i - 1];<br>-                    if (!*ref->isSubsampled)<br>-                    {<br>-                        primitives.frameSubSampleLuma((const pixel *)ref->picBuffer->m_picOrg[0], ref->picBufferSubSampled2->m_picOrg[0], ref->picBuffer->m_stride, ref->picBufferSubSampled2->m_stride, ref->picBufferSubSampled2->m_picWidth, ref->picBufferSubSampled2->m_picHeight);<br>-                        extendPicBorder(ref->picBufferSubSampled2->m_picOrg[0], ref->picBufferSubSampled2->m_stride, ref->picBufferSubSampled2->m_picWidth, ref->picBufferSubSampled2->m_picHeight, ref->picBufferSubSampled2->m_lumaMarginX, ref->picBufferSubSampled2->m_lumaMarginY);<br>-                        primitives.frameSubSampleLuma((const pixel *)ref->picBufferSubSampled2->m_picOrg[0],ref->picBufferSubSampled4->m_picOrg[0], ref->picBufferSubSampled2->m_stride, ref->picBufferSubSampled4->m_stride, ref->picBufferSubSampled4->m_picWidth, ref->picBufferSubSampled4->m_picHeight);<br>-                        extendPicBorder(ref->picBufferSubSampled4->m_picOrg[0], ref->picBufferSubSampled4->m_stride, ref->picBufferSubSampled4->m_picWidth, ref->picBufferSubSampled4->m_picHeight, ref->picBufferSubSampled4->m_lumaMarginX, ref->picBufferSubSampled4->m_lumaMarginY);<br>-                        *ref->isSubsampled = true;<br>-                    }<br>-                }<br>-<br>-                for (uint8_t i = 1; i <= frameEnc[0]->m_mcstf->m_numRef; i++)<br>-                {<br>-                    TemporalFilterRefPicInfo *ref = &curEncoder->m_mcstfRefList[i - 1];<br>+                    Frame* curFrame = m_origPicBuffer->m_mcstfPicList.getPOCMCSTF(ref->poc);<br> <br>-                    curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs0, ref->mvsStride0, frameEnc[0]->m_lowres.lowerResPlane[0], (frameEnc[0]->m_lowres.lumaStride / 2), frameEnc[0]->m_fencPicSubsampled4->m_picHeight, frameEnc[0]->m_fencPicSubsampled4->m_picWidth, ref->picBufferSubSampled4, 16);<br>-                    curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs1, ref->mvsStride1, frameEnc[0]->m_lowres.lowresPlane[0], frameEnc[0]->m_lowres.lumaStride, frameEnc[0]->m_fencPicSubsampled2->m_picHeight, frameEnc[0]->m_fencPicSubsampled2->m_picWidth, ref->picBufferSubSampled2, 16, ref->mvs0, ref->mvsStride0, 2);<br>-                    curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs2, ref->mvsStride2, frameEnc[0]->m_fencPic->m_picOrg[0], frameEnc[0]->m_fencPic->m_stride, frameEnc[0]->m_fencPic->m_picHeight, frameEnc[0]->m_fencPic->m_picWidth, ref->picBuffer, 16, ref->mvs1, ref->mvsStride1, 2);<br>+                    curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs0, ref->mvsStride0, frameEnc[0]->m_lowres.lowerResPlane[0], (frameEnc[0]->m_lowres.lumaStride / 2), frameEnc[0]->m_fencPicSubsampled4->m_picHeight, frameEnc[0]->m_fencPicSubsampled4->m_picWidth, curFrame->m_lowres.lowerResPlane[0], 16);<br>+                    curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs1, ref->mvsStride1, frameEnc[0]->m_lowres.lowresPlane[0], frameEnc[0]->m_lowres.lumaStride, frameEnc[0]->m_fencPicSubsampled2->m_picHeight, frameEnc[0]->m_fencPicSubsampled2->m_picWidth, curFrame->m_lowres.lowresPlane[0], 16, ref->mvs0, ref->mvsStride0, 2);<br>+                    curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs2, ref->mvsStride2, frameEnc[0]->m_fencPic->m_picOrg[0], frameEnc[0]->m_fencPic->m_stride, frameEnc[0]->m_fencPic->m_picHeight, frameEnc[0]->m_fencPic->m_picWidth, ref->picBuffer->m_picOrg[0], 16, ref->mvs1, ref->mvsStride1, 2);<br>                     curEncoder->m_frameEncTF->motionEstimationLumaDoubleRes(ref->mvs, ref->mvsStride, frameEnc[0]->m_fencPic, ref->picBuffer, 8, ref->mvs2, ref->mvsStride2, 1, ref->error);<br>                 }<br> <br>-- <br>2.36.0.windows.1<br><br></div>