<div dir="ltr"><div dir="ltr"><div>From 38b58fad3d88b09647ebcd41649cb3791ed6bcda Mon Sep 17 00:00:00 2001</div><div>From: ashok2022 <<a href="mailto:ashok@multicorewareinc.com">ashok@multicorewareinc.com</a>></div><div>Date: Thu, 29 Sep 2022 12:46:06 +0530</div><div>Subject: [PATCH] Made separate functions for low res and full res planes</div><div><br></div><div>---</div><div> source/common/temporalfilter.cpp | 169 ++++++++++++++++++++++++++-----</div><div> source/common/temporalfilter.h   |   5 +-</div><div> source/encoder/encoder.cpp       |   2 +-</div><div> 3 files changed, 150 insertions(+), 26 deletions(-)</div><div><br></div><div>diff --git a/source/common/temporalfilter.cpp b/source/common/temporalfilter.cpp</div><div>index b286fc235..1d7e670e1 100644</div><div>--- a/source/common/temporalfilter.cpp</div><div>+++ b/source/common/temporalfilter.cpp</div><div>@@ -746,10 +746,10 @@ void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, PicYuv *or</div><div> </div><div> /*New Version: motionEstimationLuma*/</div><div> void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, PicYuv *orig, PicYuv *buffer, int blockSize,</div><div>-    MV *previous, uint32_t prevMvStride, int factor, bool doubleRes, int* minError)</div><div>+    MV *previous, uint32_t prevMvStride, int factor)</div><div> {</div><div> </div><div>-    int range = doubleRes ? 0 : 5;</div><div>+    int range = 5;</div><div> </div><div> </div><div>     const int stepSize = blockSize;</div><div>@@ -817,39 +817,161 @@ void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, PicYuv *or</div><div>                 }</div><div>             }</div><div> </div><div>-            if (doubleRes)</div><div>-            { // merge into one loop, probably with precision array (here [12, 3] or maybe [4, 1]) with setable number of iterations</div><div>-                prevBest = best;</div><div>-                int doubleRange = 3 * 4;</div><div>-                for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y + doubleRange; y2 += 4)</div><div>+            if (blockY > 0)</div><div>+            {</div><div>+                MV aboveMV = mvs[(blockX / stepSize, (blockY - stepSize) / stepSize)];</div><div>+                int error = motionErrorLuma(orig, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);</div><div>+                if (error < leastError)</div><div>                 {</div><div>-                    for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x + doubleRange; x2 += 4)</div><div>+                    best.set(aboveMV.x, aboveMV.y);</div><div>+                    leastError = error;</div><div>+                }</div><div>+            }</div><div>+            if (blockX > 0)</div><div>+            {</div><div>+                MV leftMV = mvs[((blockX - stepSize) / stepSize, blockY / stepSize)];</div><div>+                int error = motionErrorLuma(orig, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);</div><div>+                if (error < leastError)</div><div>+                {</div><div>+                    best.set(leftMV.x, leftMV.y);</div><div>+                    leastError = error;</div><div>+                }</div><div>+            }</div><div>+</div><div>+            // calculate average</div><div>+            double avg = 0.0;</div><div>+            for (int x1 = 0; x1 < blockSize; x1++)</div><div>+            {</div><div>+                for (int y1 = 0; y1 < blockSize; y1++)</div><div>+                {</div><div>+                    avg = avg + *(orig->m_picOrg[0] + (blockX + x1 + orig->m_stride * (blockY + y1)));</div><div>+                }</div><div>+            }</div><div>+            avg = avg / (blockSize * blockSize);</div><div>+</div><div>+            // calculate variance</div><div>+            double variance = 0;</div><div>+            for (int x1 = 0; x1 < blockSize; x1++)</div><div>+            {</div><div>+                for (int y1 = 0; y1 < blockSize; y1++)</div><div>+                {</div><div>+                    int pix = *(orig->m_picOrg[0] + (blockX + x1 + orig->m_stride * (blockY + y1)));</div><div>+                    variance = variance + (pix - avg) * (pix - avg);</div><div>+                }</div><div>+            }</div><div>+</div><div>+            leastError = (int)(20 * ((leastError + 5.0) / (variance + 5.0)) + (leastError / (blockSize * blockSize)) / 50);</div><div>+</div><div>+            int mvIdx = (blockY / stepSize) * mvStride + (blockX / stepSize);</div><div>+            mvs[mvIdx] = best;</div><div>+        }</div><div>+    }</div><div>+}</div><div>+</div><div>+</div><div>+void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, PicYuv *orig, PicYuv *buffer, int blockSize,</div><div>+    MV *previous, uint32_t prevMvStride, int factor, int* minError)</div><div>+{</div><div>+</div><div>+    int range = 0;</div><div>+</div><div>+</div><div>+    const int stepSize = blockSize;</div><div>+</div><div>+    const int origWidth = orig->m_picWidth;</div><div>+    const int origHeight = orig->m_picHeight;</div><div>+</div><div>+</div><div>+    for (int blockY = 0; blockY + blockSize <= origHeight; blockY += stepSize)</div><div>+    {</div><div>+        for (int blockX = 0; blockX + blockSize <= origWidth; blockX += stepSize)</div><div>+        {</div><div>+            MV best(0, 0);</div><div>+            int leastError = INT_MAX;</div><div>+</div><div>+            if (previous == NULL)</div><div>+            {</div><div>+                range = 8;</div><div>+            }</div><div>+            else</div><div>+            {</div><div>+</div><div>+                for (int py = -1; py <= 1; py++)</div><div>+                {</div><div>+                    int testy = blockY / (2 * blockSize) + py;</div><div>+</div><div>+                    for (int px = -1; px <= 1; px++)</div><div>                     {</div><div>-                        int error = motionErrorLuma(orig, buffer, blockX, blockY, x2, y2, blockSize, leastError);</div><div>-                        if (error < leastError)</div><div>+</div><div>+                        int testx = blockX / (2 * blockSize) + px;</div><div>+                        if ((testx >= 0) && (testx < origWidth / (2 * blockSize)) && (testy >= 0) && (testy < origHeight / (2 * blockSize)))</div><div>                         {</div><div>-                            best.set(x2, y2);</div><div>-                            leastError = error;</div><div>+                            int mvIdx = testy * prevMvStride + testx;</div><div>+                            MV old = previous[mvIdx];</div><div>+                            int error = motionErrorLuma(orig, buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);</div><div>+                            if (error < leastError)</div><div>+                            {</div><div>+                                best.set(old.x * factor, old.y * factor);</div><div>+                                leastError = error;</div><div>+                            }</div><div>                         }</div><div>                     }</div><div>                 }</div><div> </div><div>-                prevBest = best;</div><div>-                doubleRange = 3;</div><div>-                for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y + doubleRange; y2++)</div><div>+                int error = motionErrorLuma(orig, buffer, blockX, blockY, 0, 0, blockSize, leastError);</div><div>+                if (error < leastError)</div><div>                 {</div><div>-                    for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x + doubleRange; x2++)</div><div>+                    best.set(0, 0);</div><div>+                    leastError = error;</div><div>+                }</div><div>+</div><div>+            }</div><div>+</div><div>+            MV prevBest = best;</div><div>+            for (int y2 = prevBest.y / s_motionVectorFactor - range; y2 <= prevBest.y / s_motionVectorFactor + range; y2++)</div><div>+            {</div><div>+                for (int x2 = prevBest.x / s_motionVectorFactor - range; x2 <= prevBest.x / s_motionVectorFactor + range; x2++)</div><div>+                {</div><div>+                    int error = motionErrorLuma(orig, buffer, blockX, blockY, x2 * s_motionVectorFactor, y2 * s_motionVectorFactor, blockSize, leastError);</div><div>+                    if (error < leastError)</div><div>                     {</div><div>-                        int error = motionErrorLuma(orig, buffer, blockX, blockY, x2, y2, blockSize, leastError);</div><div>-                        if (error < leastError)</div><div>-                        {</div><div>-                            best.set(x2, y2);</div><div>-                            leastError = error;</div><div>-                        }</div><div>+                        best.set(x2 * s_motionVectorFactor, y2 * s_motionVectorFactor);</div><div>+                        leastError = error;</div><div>                     }</div><div>                 }</div><div>             }</div><div> </div><div>+            prevBest = best;</div><div>+            int doubleRange = 3 * 4;</div><div>+            for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y + doubleRange; y2 += 4)</div><div>+            {</div><div>+                for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x + doubleRange; x2 += 4)</div><div>+                {</div><div>+                    int error = motionErrorLuma(orig, buffer, blockX, blockY, x2, y2, blockSize, leastError);</div><div>+                    if (error < leastError)</div><div>+                    {</div><div>+                        best.set(x2, y2);</div><div>+                        leastError = error;</div><div>+                    }</div><div>+                }</div><div>+            }</div><div>+</div><div>+            prevBest = best;</div><div>+            doubleRange = 3;</div><div>+            for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y + doubleRange; y2++)</div><div>+            {</div><div>+                for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x + doubleRange; x2++)</div><div>+                {</div><div>+                    int error = motionErrorLuma(orig, buffer, blockX, blockY, x2, y2, blockSize, leastError);</div><div>+                    if (error < leastError)</div><div>+                    {</div><div>+                        best.set(x2, y2);</div><div>+                        leastError = error;</div><div>+                    }</div><div>+                }</div><div>+            }</div><div>+</div><div>+</div><div>             if (blockY > 0)</div><div>             {</div><div>                 MV aboveMV = mvs[(blockX / stepSize, (blockY - stepSize) / stepSize)];</div><div>@@ -897,8 +1019,7 @@ void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride, PicYuv *or</div><div> </div><div>             int mvIdx = (blockY / stepSize) * mvStride + (blockX / stepSize);</div><div>             mvs[mvIdx] = best;</div><div>-            if (doubleRes)</div><div>-                minError[mvIdx] = leastError;</div><div>+            minError[mvIdx] = leastError;</div><div>         }</div><div>     }</div><div> }</div><div>diff --git a/source/common/temporalfilter.h b/source/common/temporalfilter.h</div><div>index 14d59c396..003630994 100644</div><div>--- a/source/common/temporalfilter.h</div><div>+++ b/source/common/temporalfilter.h</div><div>@@ -161,7 +161,10 @@ public:</div><div>     void bilateralFilter(Frame* frame, MCTFReferencePicInfo* mctfRefList, double overallStrength);</div><div> </div><div>     void motionEstimationLuma(MV *mvs, uint32_t mvStride, PicYuv *orig, PicYuv *buffer, int bs,</div><div>-        MV *previous = 0, uint32_t prevmvStride = 0, int factor = 1, bool doubleRes = false, int *minError = 0);</div><div>+        MV *previous = 0, uint32_t prevmvStride = 0, int factor = 1);</div><div>+</div><div>+    void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride, PicYuv *orig, PicYuv *buffer, int blockSize,</div><div>+        MV *previous, uint32_t prevMvStride, int factor, int* minError);</div><div> </div><div>     int motionErrorLuma(PicYuv *orig,</div><div>         PicYuv *buffer,</div><div>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp</div><div>index 790503d80..53094cdf1 100644</div><div>--- a/source/encoder/encoder.cpp</div><div>+++ b/source/encoder/encoder.cpp</div><div>@@ -2726,7 +2726,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)</div><div>                     curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs0, ref->mvsStride0, frameEnc->m_fencPicSubsampled4, ref->picBufferSubSampled4, 16);</div><div>                     curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs1, ref->mvsStride1, frameEnc->m_fencPicSubsampled2, ref->picBufferSubSampled2, 16, ref->mvs0, ref->mvsStride0, 2);</div><div>                     curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs2, ref->mvsStride2, frameEnc->m_fencPic, ref->picBuffer, 16, ref->mvs1, ref->mvsStride1, 2);</div><div>-                    curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs,  ref->mvsStride, frameEnc->m_fencPic, ref->picBuffer, 8, ref->mvs2, ref->mvsStride2, 1, true, ref->error);</div><div>+                    curEncoder->m_frameEncTF->motionEstimationLumaDoubleRes(ref->mvs,  ref->mvsStride, frameEnc->m_fencPic, ref->picBuffer, 8, ref->mvs2, ref->mvsStride2, 1, ref->error);</div><div>                 }</div><div> </div><div>                 for (int i = 0; i < frameEnc->m_mcstf->m_numRef; i++)</div><div>-- </div><div>2.34.1.windows.1</div><div><br></div><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><i><font face="georgia, serif">Thanks and Regards,</font></i></div><div><i><font face="georgia, serif"><b>Snehaa.G</b><br>Video Codec Engineer,<br>Media & AI analytics<br><a href="https://multicorewareinc.com/" target="_blank"><img src="https://ci3.googleusercontent.com/mail-sig/AIorK4yEumXeQ2mgcFAR2us9INa7z3rCbl8ordut3fbdeIbuPv0n3EA75Or1rHs0neGaI0WM8mFPz1g"></a><br><span></span><span></span><br></font></i></div></div></div></div></div></div>