<div dir="ltr"><div dir="ltr"><div>From c2b49f57dce86763f2d03e7444d3cda5260d9703 Mon Sep 17 00:00:00 2001</div><div>From: ashok2022 <<a href="mailto:ashok@multicorewareinc.com">ashok@multicorewareinc.com</a>></div><div>Date: Wed, 21 Sep 2022 17:19:14 +0530</div><div>Subject: [PATCH] Modify CmakeLists.txt to add temporalfilter.cpp and</div><div> temporalfilter.h file</div><div><br></div><div>---</div><div> source/common/CMakeLists.txt     |   3 +-</div><div> source/common/temporalfilter.cpp | 960 +++++++++++++++++++++++++++++++</div><div> source/common/temporalfilter.h   | 181 ++++++</div><div> 3 files changed, 1143 insertions(+), 1 deletion(-)</div><div> create mode 100644 source/common/temporalfilter.cpp</div><div> create mode 100644 source/common/temporalfilter.h</div><div><br></div><div>diff --git a/source/common/CMakeLists.txt b/source/common/CMakeLists.txt</div><div>index 0db9d297f..7dce52015 100644</div><div>--- a/source/common/CMakeLists.txt</div><div>+++ b/source/common/CMakeLists.txt</div><div>@@ -173,4 +173,5 @@ add_library(common OBJECT</div><div>     quant.cpp quant.h contexts.h</div><div>     deblock.cpp deblock.h</div><div>     scaler.cpp scaler.h</div><div>-    ringmem.cpp ringmem.h)</div><div>+    ringmem.cpp ringmem.h</div><div>+    temporalfilter.cpp temporalfilter.h)</div><div>diff --git a/source/common/temporalfilter.cpp b/source/common/temporalfilter.cpp</div><div>new file mode 100644</div><div>index 000000000..b286fc235</div><div>--- /dev/null</div><div>+++ b/source/common/temporalfilter.cpp</div><div>@@ -0,0 +1,960 @@</div><div>+/*****************************************************************************</div><div>+* Copyright (C) 2013-2021 MulticoreWare, Inc</div><div>+*</div><div>+* This program is free software; you can redistribute it and/or modify</div><div>+* it under the terms of the GNU General Public License as published by</div><div>+* the Free Software Foundation; either version 2 of the License, or</div><div>+* (at your option) any later version.</div><div>+*</div><div>+* This program is distributed in the hope that it will be useful,</div><div>+* but WITHOUT ANY WARRANTY; without even the implied warranty of</div><div>+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</div><div>+* GNU General Public License for more details.</div><div>+*</div><div>+* You should have received a copy of the GNU General Public License</div><div>+* along with this program; if not, write to the Free Software</div><div>+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.</div><div>+*</div><div>+* This program is also available under a commercial proprietary license.</div><div>+* For more information, contact us at license @ <a href="http://x265.com">x265.com</a>.</div><div>+*****************************************************************************/</div><div>+</div><div>+#include "temporalfilter.h"</div><div>+</div><div>+#include "frame.h"</div><div>+#include "slice.h"</div><div>+#include "framedata.h"</div><div>+#include "analysis.h"</div><div>+</div><div>+using namespace X265_NS;</div><div>+</div><div>+void OrigPicBuffer::addPicture(Frame* inFrame)</div><div>+{</div><div>+    m_mcstfPicList.pushFrontMCSTF(*inFrame);</div><div>+}</div><div>+</div><div>+void OrigPicBuffer::addEncPicture(Frame* inFrame)</div><div>+{</div><div>+    m_mcstfOrigPicFreeList.pushFrontMCSTF(*inFrame);</div><div>+}</div><div>+</div><div>+void OrigPicBuffer::addEncPictureToPicList(Frame* inFrame)</div><div>+{</div><div>+    m_mcstfOrigPicList.pushFrontMCSTF(*inFrame);</div><div>+}</div><div>+</div><div>+OrigPicBuffer::~OrigPicBuffer()</div><div>+{</div><div>+    while (!m_mcstfOrigPicList.empty())</div><div>+    {</div><div>+        Frame* curFrame = m_mcstfOrigPicList.popBackMCSTF();</div><div>+        curFrame->destroy();</div><div>+        delete curFrame;</div><div>+    }</div><div>+</div><div>+    while (!m_mcstfOrigPicFreeList.empty())</div><div>+    {</div><div>+        Frame* curFrame = m_mcstfOrigPicFreeList.popBackMCSTF();</div><div>+        curFrame->destroy();</div><div>+        delete curFrame;</div><div>+    }</div><div>+}</div><div>+</div><div>+void OrigPicBuffer::setOrigPicList(Frame* inFrame, int frameCnt)</div><div>+{</div><div>+    Slice* slice = inFrame->m_encData->m_slice;</div><div>+    uint8_t j = 0;</div><div>+    for (int iterPOC = (inFrame->m_poc - inFrame->m_mcstf->s_range);</div><div>+        iterPOC <= (inFrame->m_poc + inFrame->m_mcstf->s_range); iterPOC++)</div><div>+    {</div><div>+        if (iterPOC != inFrame->m_poc)</div><div>+        {</div><div>+            if (iterPOC < 0)</div><div>+                continue;</div><div>+            if (iterPOC >= frameCnt)</div><div>+                break;</div><div>+</div><div>+            Frame *iterFrame = m_mcstfPicList.getPOCMCSTF(iterPOC);</div><div>+            X265_CHECK(iterFrame, "Reference frame not found in OPB");</div><div>+            if (iterFrame != NULL)</div><div>+            {</div><div>+                slice->m_mcstfRefFrameList[1][j] = iterFrame;</div><div>+                iterFrame->m_refPicCnt[1]--;</div><div>+            }</div><div>+</div><div>+            iterFrame = m_mcstfOrigPicList.getPOCMCSTF(iterPOC);</div><div>+            if (iterFrame != NULL)</div><div>+            {</div><div>+</div><div>+                slice->m_mcstfRefFrameList[1][j] = iterFrame;</div><div>+</div><div>+                iterFrame->m_refPicCnt[1]--;</div><div>+                Frame *cFrame = m_mcstfOrigPicList.getPOCMCSTF(inFrame->m_poc);</div><div>+                X265_CHECK(cFrame, "Reference frame not found in encoded OPB");</div><div>+                cFrame->m_refPicCnt[1]--;</div><div>+            }</div><div>+            j++;</div><div>+        }</div><div>+    }</div><div>+}</div><div>+</div><div>+void OrigPicBuffer::recycleOrigPicList()</div><div>+{</div><div>+    Frame *iterFrame = m_mcstfPicList.first();</div><div>+</div><div>+    while (iterFrame)</div><div>+    {</div><div>+        Frame *curFrame = iterFrame;</div><div>+        iterFrame = iterFrame->m_nextMCSTF;</div><div>+        if (!curFrame->m_refPicCnt[1])</div><div>+        {</div><div>+            m_mcstfPicList.removeMCSTF(*curFrame);</div><div>+            iterFrame = m_mcstfPicList.first();</div><div>+        }</div><div>+    }</div><div>+</div><div>+    iterFrame = m_mcstfOrigPicList.first();</div><div>+</div><div>+    while (iterFrame)</div><div>+    {</div><div>+        Frame *curFrame = iterFrame;</div><div>+        iterFrame = iterFrame->m_nextMCSTF;</div><div>+        if (!curFrame->m_refPicCnt[1])</div><div>+        {</div><div>+            m_mcstfOrigPicList.removeMCSTF(*curFrame);</div><div>+            *curFrame->m_isSubSampled = false;</div><div>+            m_mcstfOrigPicFreeList.pushFrontMCSTF(*curFrame);</div><div>+            iterFrame = m_mcstfOrigPicList.first();</div><div>+        }</div><div>+    }</div><div>+}</div><div>+</div><div>+void OrigPicBuffer::addPictureToFreelist(Frame* inFrame)</div><div>+{</div><div>+    m_mcstfOrigPicFreeList.pushBack(*inFrame);</div><div>+}</div><div>+</div><div>+TemporalFilter::TemporalFilter() {</div><div>+    m_FrameSkip = 0;</div><div>+    m_sourceWidth = 0;</div><div>+    m_sourceHeight = 0,</div><div>+    m_QP = 0;</div><div>+    m_GOPSize = 0;</div><div>+    m_framesToBeEncoded = 0;</div><div>+    m_sliceTypeConfig = 3;</div><div>+    m_numRef = 0;</div><div>+</div><div>+    s_range = 2;</div><div>+    s_chromaFactor = 0.55;</div><div>+    s_sigmaMultiplier = 9.0;</div><div>+    s_sigmaZeroPoint = 10.0;</div><div>+    s_motionVectorFactor = 16;</div><div>+    s_padding = 128;</div><div>+}</div><div>+</div><div>+void TemporalFilter::init(const x265_param* param)</div><div>+{</div><div>+    m_param = param;</div><div>+    m_bitDepth = param->internalBitDepth;</div><div>+    m_sourceWidth = param->sourceWidth;</div><div>+    m_sourceHeight = param->sourceHeight;</div><div>+    m_internalCsp = param->internalCsp;</div><div>+    m_numComponents = (m_internalCsp != X265_CSP_I400) ? MAX_NUM_COMPONENT : 1;</div><div>+}</div><div>+</div><div>+int TemporalFilter::createRefPicInfo(MCTFReferencePicInfo* refFrame, x265_param* param)</div><div>+{</div><div>+    CHECKED_MALLOC_ZERO(refFrame->mvs, MV, sizeof(MV)* ((m_sourceWidth ) / 4) * ((m_sourceHeight ) / 4));</div><div>+    refFrame->mvsStride = m_sourceWidth / 4;</div><div>+    CHECKED_MALLOC_ZERO(refFrame->mvs0, MV, sizeof(MV)* ((m_sourceWidth ) / 16) * ((m_sourceHeight ) / 16));</div><div>+    refFrame->mvsStride0 = m_sourceWidth / 16;</div><div>+    CHECKED_MALLOC_ZERO(refFrame->mvs1, MV, sizeof(MV)* ((m_sourceWidth ) / 16) * ((m_sourceHeight ) / 16));</div><div>+    refFrame->mvsStride1 = m_sourceWidth / 16;</div><div>+    CHECKED_MALLOC_ZERO(refFrame->mvs2, MV, sizeof(MV)* ((m_sourceWidth ) / 16)*((m_sourceHeight ) / 16));</div><div>+    refFrame->mvsStride2 = m_sourceWidth / 16;</div><div>+</div><div>+    CHECKED_MALLOC_ZERO(refFrame->noise, int, sizeof(int) * ((m_sourceWidth) / 4) * ((m_sourceHeight) / 4));</div><div>+    CHECKED_MALLOC_ZERO(refFrame->error, int, sizeof(int) * ((m_sourceWidth) / 4) * ((m_sourceHeight) / 4));</div><div>+</div><div>+    refFrame->slicetype = X265_TYPE_AUTO;</div><div>+</div><div>+    refFrame->compensatedPic = new PicYuv;</div><div>+    refFrame->compensatedPic->create(param, true);</div><div>+</div><div>+    return 1;</div><div>+fail:</div><div>+    return 0;</div><div>+}</div><div>+</div><div>+int TemporalFilter::motionErrorLuma(</div><div>+    PicYuv *orig,</div><div>+    PicYuv *buffer,</div><div>+    int x,</div><div>+    int y,</div><div>+    int dx,</div><div>+    int dy,</div><div>+    int bs,</div><div>+    int besterror)</div><div>+{</div><div>+</div><div>+    pixel* origOrigin = orig->m_picOrg[0];</div><div>+    intptr_t origStride = orig->m_stride;</div><div>+    pixel *buffOrigin = buffer->m_picOrg[0];</div><div>+    intptr_t buffStride = buffer->m_stride;</div><div>+    int error = 0;// dx * 10 + dy * 10;</div><div>+    if (((dx | dy) & 0xF) == 0)</div><div>+    {</div><div>+        dx /= s_motionVectorFactor;</div><div>+        dy /= s_motionVectorFactor;</div><div>+        for (int y1 = 0; y1 < bs; y1++)</div><div>+        {</div><div>+            const pixel* origRowStart = origOrigin + (y + y1)*origStride + x;</div><div>+            const pixel* bufferRowStart = buffOrigin + (y + y1 + dy)*buffStride + (x + dx);</div><div>+            for (int x1 = 0; x1 < bs; x1 += 2)</div><div>+            {</div><div>+                int diff = origRowStart[x1] - bufferRowStart[x1];</div><div>+                error += diff * diff;</div><div>+                diff = origRowStart[x1 + 1] - bufferRowStart[x1 + 1];</div><div>+                error += diff * diff;</div><div>+            }</div><div>+            if (error > besterror)</div><div>+            {</div><div>+                return error;</div><div>+            }</div><div>+        }</div><div>+    }</div><div>+    else</div><div>+    {</div><div>+        const int *xFilter = s_interpolationFilter[dx & 0xF];</div><div>+        const int *yFilter = s_interpolationFilter[dy & 0xF];</div><div>+        int tempArray[64 + 8][64];</div><div>+</div><div>+        int iSum, iBase;</div><div>+        for (int y1 = 1; y1 < bs + 7; y1++)</div><div>+        {</div><div>+            const int yOffset = y + y1 + (dy >> 4) - 3;</div><div>+            const pixel *sourceRow = buffOrigin + (yOffset)*buffStride + 0;</div><div>+            for (int x1 = 0; x1 < bs; x1++)</div><div>+            {</div><div>+                iSum = 0;</div><div>+                iBase = x + x1 + (dx >> 4) - 3;</div><div>+                const pixel *rowStart = sourceRow + iBase;</div><div>+</div><div>+                iSum += xFilter[1] * rowStart[1];</div><div>+                iSum += xFilter[2] * rowStart[2];</div><div>+                iSum += xFilter[3] * rowStart[3];</div><div>+                iSum += xFilter[4] * rowStart[4];</div><div>+                iSum += xFilter[5] * rowStart[5];</div><div>+                iSum += xFilter[6] * rowStart[6];</div><div>+</div><div>+                tempArray[y1][x1] = iSum;</div><div>+            }</div><div>+        }</div><div>+</div><div>+        const pixel maxSampleValue = (1 << m_bitDepth) - 1;</div><div>+        for (int y1 = 0; y1 < bs; y1++)</div><div>+        {</div><div>+            const pixel *origRow = origOrigin + (y + y1)*origStride + 0;</div><div>+            for (int x1 = 0; x1 < bs; x1++)</div><div>+            {</div><div>+                iSum = 0;</div><div>+                iSum += yFilter[1] * tempArray[y1 + 1][x1];</div><div>+                iSum += yFilter[2] * tempArray[y1 + 2][x1];</div><div>+                iSum += yFilter[3] * tempArray[y1 + 3][x1];</div><div>+                iSum += yFilter[4] * tempArray[y1 + 4][x1];</div><div>+                iSum += yFilter[5] * tempArray[y1 + 5][x1];</div><div>+                iSum += yFilter[6] * tempArray[y1 + 6][x1];</div><div>+</div><div>+                iSum = (iSum + (1 << 11)) >> 12;</div><div>+                iSum = iSum < 0 ? 0 : (iSum > maxSampleValue ? maxSampleValue : iSum);</div><div>+</div><div>+                error += (iSum - origRow[x + x1]) * (iSum - origRow[x + x1]);</div><div>+            }</div><div>+            if (error > besterror)</div><div>+            {</div><div>+                return error;</div><div>+            }</div><div>+        }</div><div>+    }</div><div>+    return error;</div><div>+}</div><div>+</div><div>+void TemporalFilter::applyMotion(MV *mvs, uint32_t mvsStride, PicYuv *input, PicYuv *output)</div><div>+{</div><div>+    static const int lumaBlockSize = 8;</div><div>+    int srcStride = 0;</div><div>+    int dstStride = 0;</div><div>+    int csx = 0, csy = 0;</div><div>+    for (int c = 0; c < m_numComponents; c++)</div><div>+    {</div><div>+        const pixel maxValue = (1 << X265_DEPTH) - 1;</div><div>+</div><div>+        const pixel *pSrcImage = input->m_picOrg[c];</div><div>+        pixel *pDstImage = output->m_picOrg[c];</div><div>+</div><div>+        if (c == 0)</div><div>+        {</div><div>+            srcStride = (int)input->m_stride;</div><div>+            dstStride = (int)output->m_stride;</div><div>+        }</div><div>+        else</div><div>+        {</div><div>+            srcStride = (int)input->m_strideC;</div><div>+            dstStride = (int)output->m_strideC;</div><div>+            csx = CHROMA_H_SHIFT(m_internalCsp);</div><div>+            csy = CHROMA_V_SHIFT(m_internalCsp);</div><div>+        }</div><div>+        const int blockSizeX = lumaBlockSize >> csx;</div><div>+        const int blockSizeY = lumaBlockSize >> csy;</div><div>+        const int height = input->m_picHeight >> csy;</div><div>+        const int width = input->m_picWidth >> csx;</div><div>+</div><div>+        for (int y = 0, blockNumY = 0; y + blockSizeY <= height; y += blockSizeY, blockNumY++)</div><div>+        {</div><div>+            for (int x = 0, blockNumX = 0; x + blockSizeX <= width; x += blockSizeX, blockNumX++)</div><div>+            {</div><div>+                int mvIdx = blockNumY * mvsStride + blockNumX;</div><div>+                const MV &mv = mvs[mvIdx];</div><div>+                const int dx = mv.x >> csx;</div><div>+                const int dy = mv.y >> csy;</div><div>+                const int xInt = mv.x >> (4 + csx);</div><div>+                const int yInt = mv.y >> (4 + csy);</div><div>+</div><div>+                const int *xFilter = s_interpolationFilter[dx & 0xf];</div><div>+                const int *yFilter = s_interpolationFilter[dy & 0xf]; // will add 6 bit.</div><div>+                const int numFilterTaps = 7;</div><div>+                const int centreTapOffset = 3;</div><div>+</div><div>+                int tempArray[lumaBlockSize + numFilterTaps][lumaBlockSize];</div><div>+</div><div>+                for (int by = 1; by < blockSizeY + numFilterTaps; by++)</div><div>+                {</div><div>+                    const int yOffset = y + by + yInt - centreTapOffset;</div><div>+                    const pixel *sourceRow = pSrcImage + yOffset * srcStride;</div><div>+                    for (int bx = 0; bx < blockSizeX; bx++)</div><div>+                    {</div><div>+                        int iBase = x + bx + xInt - centreTapOffset;</div><div>+                        const pixel *rowStart = sourceRow + iBase;</div><div>+</div><div>+                        int iSum = 0;</div><div>+                        iSum += xFilter[1] * rowStart[1];</div><div>+                        iSum += xFilter[2] * rowStart[2];</div><div>+                        iSum += xFilter[3] * rowStart[3];</div><div>+                        iSum += xFilter[4] * rowStart[4];</div><div>+                        iSum += xFilter[5] * rowStart[5];</div><div>+                        iSum += xFilter[6] * rowStart[6];</div><div>+</div><div>+                        tempArray[by][bx] = iSum;</div><div>+                    }</div><div>+                }</div><div>+</div><div>+                pixel *pDstRow = pDstImage + y * dstStride;</div><div>+                for (int by = 0; by < blockSizeY; by++, pDstRow += dstStride)</div><div>+                {</div><div>+                    pixel *pDstPel = pDstRow + x;</div><div>+                    for (int bx = 0; bx < blockSizeX; bx++, pDstPel++)</div><div>+                    {</div><div>+                        int iSum = 0;</div><div>+</div><div>+                        iSum += yFilter[1] * tempArray[by + 1][bx];</div><div>+                        iSum += yFilter[2] * tempArray[by + 2][bx];</div><div>+                        iSum += yFilter[3] * tempArray[by + 3][bx];</div><div>+                        iSum += yFilter[4] * tempArray[by + 4][bx];</div><div>+                        iSum += yFilter[5] * tempArray[by + 5][bx];</div><div>+                        iSum += yFilter[6] * tempArray[by + 6][bx];</div><div>+</div><div>+                        iSum = (iSum + (1 << 11)) >> 12;</div><div>+                        iSum = iSum < 0 ? 0 : (iSum > maxValue ? maxValue : iSum);</div><div>+                        *pDstPel = (pixel)iSum;</div><div>+                    }</div><div>+                }</div><div>+            }</div><div>+        }</div><div>+    }</div><div>+}</div><div>+</div><div>+#if 0</div><div>+/*</div><div>+* Old Version: bilateralFilter</div><div>+*/</div><div>+void TemporalFilter::bilateralFilter(Frame* frame,</div><div>+    MCTFReferencePicInfo* m_mctfRefList,</div><div>+    double overallStrength)</div><div>+{</div><div>+</div><div>+    const int numRefs = frame->m_mcstf->m_numRef;</div><div>+</div><div>+    for (int i = 0; i < numRefs; i++)</div><div>+    {</div><div>+        MCTFReferencePicInfo *ref = &m_mctfRefList[i];</div><div>+        applyMotion(m_mctfRefList[i].mvs, m_mctfRefList[i].mvsStride, m_mctfRefList[i].picBuffer, ref->compensatedPic);</div><div>+    }</div><div>+</div><div>+    int refStrengthRow = 2;</div><div>+    if (numRefs == s_range * 2)</div><div>+    {</div><div>+        refStrengthRow = 0;</div><div>+    }</div><div>+    else if (numRefs == s_range)</div><div>+    {</div><div>+        refStrengthRow = 1;</div><div>+    }</div><div>+</div><div>+    const double lumaSigmaSq = (m_QP - s_sigmaZeroPoint) * (m_QP - s_sigmaZeroPoint) * s_sigmaMultiplier;</div><div>+    const double chromaSigmaSq = 30 * 30;</div><div>+</div><div>+    PicYuv* orgPic = frame->m_fencPic;</div><div>+</div><div>+    for (int c = 0; c < m_numComponents; c++)</div><div>+    {</div><div>+        int height, width;</div><div>+        pixel *srcPelRow = NULL;</div><div>+        intptr_t srcStride, correctedPicsStride = 0;</div><div>+</div><div>+        if (c == 0)</div><div>+        {</div><div>+            height = orgPic->m_picHeight;</div><div>+            width = orgPic->m_picWidth;</div><div>+            srcPelRow = orgPic->m_picOrg[c];</div><div>+            srcStride = orgPic->m_stride;</div><div>+        }</div><div>+        else</div><div>+        {</div><div>+            int csx = CHROMA_H_SHIFT(m_internalCsp);</div><div>+            int csy = CHROMA_V_SHIFT(m_internalCsp);</div><div>+</div><div>+            height = orgPic->m_picHeight >> csy;</div><div>+            width = orgPic->m_picWidth >> csx;</div><div>+            srcPelRow = orgPic->m_picOrg[c];</div><div>+            srcStride = (int)orgPic->m_strideC;</div><div>+        }</div><div>+</div><div>+        const double sigmaSq = (!c) ? lumaSigmaSq : chromaSigmaSq;</div><div>+        const double weightScaling = overallStrength * ((!c) ? 0.4 : s_chromaFactor);</div><div>+</div><div>+        const pixel maxSampleValue = (1 << m_bitDepth) - 1;</div><div>+        const double bitDepthDiffWeighting = 1024.0 / (maxSampleValue + 1);</div><div>+</div><div>+        for (int y = 0; y < height; y++, srcPelRow += srcStride/*, dstPelRow += dstStride*/)</div><div>+        {</div><div>+            pixel *srcPel = srcPelRow;</div><div>+</div><div>+            for (int x = 0; x < width; x++, srcPel++)</div><div>+            {</div><div>+                const int orgVal = (int)*srcPel;</div><div>+                double temporalWeightSum = 1.0;</div><div>+                double newVal = (double)orgVal;</div><div>+</div><div>+                for (int i = 0; i < numRefs; i++)</div><div>+                {</div><div>+                    MCTFReferencePicInfo *refPicInfo = &m_mctfRefList[i];</div><div>+</div><div>+                    if (c == 0)</div><div>+                        correctedPicsStride = refPicInfo->compensatedPic->m_stride;</div><div>+                    else</div><div>+                        correctedPicsStride = refPicInfo->compensatedPic->m_strideC;</div><div>+</div><div>+                    const pixel *pCorrectedPelPtr = refPicInfo->compensatedPic->m_picOrg[c] + (y * correctedPicsStride + x);</div><div>+                    const int refVal = (int)*pCorrectedPelPtr;</div><div>+                    double diff = (double)(refVal - orgVal);</div><div>+                    diff *= bitDepthDiffWeighting;</div><div>+                    double diffSq = diff * diff;</div><div>+</div><div>+                    const int index = X265_MIN(1, std::abs(refPicInfo->origOffset) - 1);</div><div>+                    const double weight = weightScaling * s_refStrengths[refStrengthRow][index] * exp(-diffSq / (2 * sigmaSq));</div><div>+</div><div>+                    newVal += weight * refVal;</div><div>+                    temporalWeightSum += weight;</div><div>+                }</div><div>+                newVal /= temporalWeightSum;</div><div>+                pixel sampleVal = (pixel)round(newVal);</div><div>+                sampleVal = (sampleVal < 0 ? 0 : (sampleVal > maxSampleValue ? maxSampleValue : sampleVal));</div><div>+                //*dstPel = sampleVal;</div><div>+                *srcPel = sampleVal;</div><div>+            }</div><div>+        }</div><div>+    }</div><div>+}</div><div>+</div><div>+#else</div><div>+</div><div>+/*</div><div>+* New Version: bilateralFilter</div><div>+*/</div><div>+void TemporalFilter::bilateralFilter(Frame* frame,</div><div>+    MCTFReferencePicInfo* m_mctfRefList,</div><div>+    double overallStrength)</div><div>+{</div><div>+</div><div>+    const int numRefs = frame->m_mcstf->m_numRef;</div><div>+</div><div>+    for (int i = 0; i < numRefs; i++)</div><div>+    {</div><div>+        MCTFReferencePicInfo *ref = &m_mctfRefList[i];</div><div>+        applyMotion(m_mctfRefList[i].mvs, m_mctfRefList[i].mvsStride, m_mctfRefList[i].picBuffer, ref->compensatedPic);</div><div>+    }</div><div>+</div><div>+    int refStrengthRow = 2;</div><div>+    if (numRefs == s_range * 2)</div><div>+    {</div><div>+        refStrengthRow = 0;</div><div>+    }</div><div>+    else if (numRefs == s_range)</div><div>+    {</div><div>+        refStrengthRow = 1;</div><div>+    }</div><div>+</div><div>+    const double lumaSigmaSq = (m_QP - s_sigmaZeroPoint) * (m_QP - s_sigmaZeroPoint) * s_sigmaMultiplier;</div><div>+    const double chromaSigmaSq = 30 * 30;</div><div>+</div><div>+    PicYuv* orgPic = frame->m_fencPic;</div><div>+</div><div>+    for (int c = 0; c < m_numComponents; c++)</div><div>+    {</div><div>+        int height, width;</div><div>+        pixel *srcPelRow = NULL;</div><div>+        intptr_t srcStride, correctedPicsStride = 0;</div><div>+</div><div>+        if (c == 0)</div><div>+        {</div><div>+            height = orgPic->m_picHeight;</div><div>+            width = orgPic->m_picWidth;</div><div>+            srcPelRow = orgPic->m_picOrg[c];</div><div>+            srcStride = orgPic->m_stride;</div><div>+        }</div><div>+        else</div><div>+        {</div><div>+            int csx = CHROMA_H_SHIFT(m_internalCsp);</div><div>+            int csy = CHROMA_V_SHIFT(m_internalCsp);</div><div>+</div><div>+            height = orgPic->m_picHeight >> csy;</div><div>+            width = orgPic->m_picWidth >> csx;</div><div>+            srcPelRow = orgPic->m_picOrg[c];</div><div>+            srcStride = (int)orgPic->m_strideC;</div><div>+        }</div><div>+</div><div>+        const double sigmaSq = (!c)  ? lumaSigmaSq : chromaSigmaSq;</div><div>+        const double weightScaling = overallStrength * ( (!c) ? 0.4 : s_chromaFactor);</div><div>+</div><div>+        const pixel maxSampleValue = (1 << m_bitDepth) - 1;</div><div>+        const double bitDepthDiffWeighting = 1024.0 / (maxSampleValue + 1);</div><div>+</div><div>+        const int blkSize = (!c) ? 8 : 4;</div><div>+</div><div>+        for (int y = 0; y < height; y++, srcPelRow += srcStride)</div><div>+        {</div><div>+            pixel *srcPel = srcPelRow;</div><div>+</div><div>+            for (int x = 0; x < width; x++, srcPel++)</div><div>+            {</div><div>+                const int orgVal = (int)*srcPel;</div><div>+                double temporalWeightSum = 1.0;</div><div>+                double newVal = (double)orgVal;</div><div>+</div><div>+                if ((y % blkSize == 0) && (x % blkSize == 0))</div><div>+                {</div><div>+                    for (int i = 0; i < numRefs; i++)</div><div>+                    {</div><div>+                        MCTFReferencePicInfo *refPicInfo = &m_mctfRefList[i];</div><div>+</div><div>+                        if (!c)</div><div>+                            correctedPicsStride = refPicInfo->compensatedPic->m_stride;</div><div>+                        else</div><div>+                            correctedPicsStride = refPicInfo->compensatedPic->m_strideC;</div><div>+</div><div>+                        double variance = 0, diffsum = 0;</div><div>+                        for (int y1 = 0; y1 < blkSize - 1; y1++)</div><div>+                        {</div><div>+                            for (int x1 = 0; x1 < blkSize - 1; x1++)</div><div>+                            {</div><div>+                                int pix = *(srcPel + x1);</div><div>+                                int pixR = *(srcPel + x1 + 1);</div><div>+                                int pixD = *(srcPel + x1 + srcStride);</div><div>+</div><div>+                                int ref = *(refPicInfo->compensatedPic->m_picOrg[c] + ((y + y1) * correctedPicsStride + x + x1));</div><div>+                                int refR = *(refPicInfo->compensatedPic->m_picOrg[c] + ((y + y1) * correctedPicsStride + x + x1 + 1));</div><div>+                                int refD = *(refPicInfo->compensatedPic->m_picOrg[c] + ((y + y1 + 1) * correctedPicsStride + x + x1));</div><div>+</div><div>+                                int diff = pix - ref;</div><div>+                                int diffR = pixR - refR;</div><div>+                                int diffD = pixD - refD;</div><div>+</div><div>+                                variance += diff * diff;</div><div>+                                diffsum += (diffR - diff) * (diffR - diff);</div><div>+                                diffsum += (diffD - diff) * (diffD - diff);</div><div>+                            }</div><div>+                        }</div><div>+</div><div>+                        refPicInfo->noise[(y / blkSize) * refPicInfo->mvsStride + (x / blkSize)] = (int)round((300 * variance + 50) / (10 * diffsum + 50));</div><div>+                    }</div><div>+                }</div><div>+</div><div>+                double minError = 9999999;</div><div>+                for (int i = 0; i < numRefs; i++)</div><div>+                {</div><div>+                    MCTFReferencePicInfo *refPicInfo = &m_mctfRefList[i];</div><div>+                    minError = X265_MIN(minError, (double)refPicInfo->error[(y / blkSize) * refPicInfo->mvsStride + (x / blkSize)]);</div><div>+                }</div><div>+</div><div>+                for (int i = 0; i < numRefs; i++)</div><div>+                {</div><div>+                    MCTFReferencePicInfo *refPicInfo = &m_mctfRefList[i];</div><div>+</div><div>+                    const int error = refPicInfo->error[(y / blkSize) * refPicInfo->mvsStride + (x / blkSize)];</div><div>+                    const int noise = refPicInfo->noise[(y / blkSize) * refPicInfo->mvsStride + (x / blkSize)];</div><div>+</div><div>+                    const pixel *pCorrectedPelPtr = refPicInfo->compensatedPic->m_picOrg[c] + (y * correctedPicsStride + x);</div><div>+                    const int refVal = (int)*pCorrectedPelPtr;</div><div>+                    double diff = (double)(refVal - orgVal);</div><div>+                    diff *= bitDepthDiffWeighting;</div><div>+                    double diffSq = diff * diff;</div><div>+</div><div>+                    const int index = X265_MIN(3, std::abs(refPicInfo->origOffset) - 1);</div><div>+                    double ww = 1, sw = 1;</div><div>+                    ww *= (noise < 25) ? 1 : 1.2;</div><div>+                    sw *= (noise < 25) ? 1.3 : 0.8;</div><div>+                    ww *= (error < 50) ? 1.2 : ((error > 100) ? 0.8 : 1);</div><div>+                    sw *= (error < 50) ? 1.3 : 1;</div><div>+                    ww *= ((minError + 1) / (error + 1));</div><div>+                    const double weight = weightScaling * s_refStrengths[refStrengthRow][index] * ww * exp(-diffSq / (2 * sw * sigmaSq));</div><div>+</div><div>+                    newVal += weight * refVal;</div><div>+                    temporalWeightSum += weight;</div><div>+                }</div><div>+                newVal /= temporalWeightSum;</div><div>+                pixel sampleVal = (pixel)round(newVal);</div><div>+                sampleVal = (sampleVal < 0 ? 0 : (sampleVal > maxSampleValue ? maxSampleValue : sampleVal));</div><div>+                //*dstPel = sampleVal;</div><div>+                *srcPel = sampleVal;</div><div>+            }</div><div>+        }</div><div>+    }</div><div>+}</div><div>+#endif</div><div>+</div><div>+#if 0</div><div>+/*Old Version: motionEstimationLuma*/</div><div>+</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>+{</div><div>+</div><div>+    int range = 5;</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 = -2; py <= 2; py++)</div><div>+                {</div><div>+                    int testy = blockY / (2 * blockSize) + py;</div><div>+</div><div>+                    for (int px = -2; px <= 2; px++)</div><div>+                    {</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>+                            int mvIdx = testy * prevMvStride + testx;</div><div>+                            MV old = previous[mvIdx];</div><div>+</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>+            }</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/*best.error*/);</div><div>+                    if (error < leastError)</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>+            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>+                {</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>+            int mvIdx = (blockY / stepSize) * mvStride + (blockX / stepSize);</div><div>+            mvs[mvIdx] = best;</div><div>+            if (doubleRes)</div><div>+                minError[mvIdx] = leastError;</div><div>+        }</div><div>+    }</div><div>+}</div><div>+</div><div>+#else</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>+{</div><div>+</div><div>+    int range = doubleRes ? 0 : 5;</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>+</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>+                            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>+                int error = motionErrorLuma(orig, buffer, blockX, blockY, 0, 0, blockSize, leastError);</div><div>+                if (error < leastError)</div><div>+                {</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>+                        best.set(x2 * s_motionVectorFactor, y2 * s_motionVectorFactor);</div><div>+                        leastError = error;</div><div>+                    }</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>+                {</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>+                int error = motionErrorLuma(orig, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);</div><div>+                if (error < leastError)</div><div>+                {</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>+            if (doubleRes)</div><div>+                minError[mvIdx] = leastError;</div><div>+        }</div><div>+    }</div><div>+}</div><div>+#endif</div><div>+</div><div>+void TemporalFilter::subsampleLuma(PicYuv *input, PicYuv *output, int factor)</div><div>+{</div><div>+</div><div>+    int newWidth = output->m_picWidth;</div><div>+    int newHeight = output->m_picHeight;</div><div>+</div><div>+    pixel* srcRow = input->m_picOrg[0];</div><div>+    intptr_t srcStride = input->m_stride;</div><div>+</div><div>+    pixel *dstRow = output->m_picOrg[0];</div><div>+    intptr_t dstStride = output->m_stride;</div><div>+</div><div>+    for (int y = 0; y < newHeight; y++, srcRow += factor * srcStride, dstRow += dstStride)</div><div>+    {</div><div>+        pixel *inRow = srcRow;</div><div>+        pixel *inRowBelow = srcRow + srcStride;</div><div>+        pixel *target = dstRow;</div><div>+</div><div>+        for (int x = 0; x < newWidth; x++)</div><div>+        {</div><div>+            target[x] = (inRow[0] + inRowBelow[0] + inRow[1] + inRowBelow[1] + 2) >> 2;</div><div>+            inRow += 2;</div><div>+            inRowBelow += 2;</div><div>+        }</div><div>+    }</div><div>+</div><div>+    // output.extendPicBorder();</div><div>+    extendPicBorder(output->m_picOrg[0], output->m_stride, output->m_picWidth, output->m_picHeight, output->m_lumaMarginX, output->m_lumaMarginY);</div><div>+}</div><div>+</div><div>+void TemporalFilter::destroyRefPicInfo(MCTFReferencePicInfo* curFrame)</div><div>+{</div><div>+    if (curFrame)</div><div>+    {</div><div>+        if (curFrame->compensatedPic)</div><div>+        {</div><div>+            curFrame->compensatedPic->destroy();</div><div>+            delete curFrame->compensatedPic;</div><div>+        }</div><div>+</div><div>+        if (curFrame->mvs)</div><div>+            X265_FREE(curFrame->mvs);</div><div>+        if (curFrame->mvs0)</div><div>+            X265_FREE(curFrame->mvs0);</div><div>+        if (curFrame->mvs1)</div><div>+            X265_FREE(curFrame->mvs1);</div><div>+        if (curFrame->mvs2)</div><div>+            X265_FREE(curFrame->mvs2);</div><div>+        if (curFrame->noise)</div><div>+            X265_FREE(curFrame->noise);</div><div>+        if (curFrame->error)</div><div>+            X265_FREE(curFrame->error);</div><div>+    }</div><div>+}</div><div>diff --git a/source/common/temporalfilter.h b/source/common/temporalfilter.h</div><div>new file mode 100644</div><div>index 000000000..14d59c396</div><div>--- /dev/null</div><div>+++ b/source/common/temporalfilter.h</div><div>@@ -0,0 +1,181 @@</div><div>+/*****************************************************************************</div><div>+* Copyright (C) 2013-2021 MulticoreWare, Inc</div><div>+*</div><div>+* This program is free software; you can redistribute it and/or modify</div><div>+* it under the terms of the GNU General Public License as published by</div><div>+* the Free Software Foundation; either version 2 of the License, or</div><div>+* (at your option) any later version.</div><div>+*</div><div>+* This program is distributed in the hope that it will be useful,</div><div>+* but WITHOUT ANY WARRANTY; without even the implied warranty of</div><div>+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</div><div>+* GNU General Public License for more details.</div><div>+*</div><div>+* You should have received a copy of the GNU General Public License</div><div>+* along with this program; if not, write to the Free Software</div><div>+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.</div><div>+*</div><div>+* This program is also available under a commercial proprietary license.</div><div>+* For more information, contact us at license @ <a href="http://x265.com">x265.com</a>.</div><div>+*****************************************************************************/</div><div>+</div><div>+#ifndef X265_TEMPORAL_FILTER</div><div>+#define X265_TEMPORAL_FILTER</div><div>+</div><div>+#include "x265.h"</div><div>+#include "picyuv.h"</div><div>+#include "mv.h"</div><div>+#include <vector></div><div>+#include <deque></div><div>+#include "piclist.h"</div><div>+#include "yuv.h"</div><div>+</div><div>+using namespace X265_NS;</div><div>+</div><div>+#define BILTERAL_FILTER_NEW_VERSION 1</div><div>+</div><div>+const int s_interpolationFilter[16][8] =</div><div>+{</div><div>+    {   0,   0,   0,  64,   0,   0,   0,   0 },   //0</div><div>+    {   0,   1,  -3,  64,   4,  -2,   0,   0 },   //1 -->--></div><div>+    {   0,   1,  -6,  62,   9,  -3,   1,   0 },   //2 --></div><div>+    {   0,   2,  -8,  60,  14,  -5,   1,   0 },   //3 -->--></div><div>+    {   0,   2,  -9,  57,  19,  -7,   2,   0 },   //4</div><div>+    {   0,   3, -10,  53,  24,  -8,   2,   0 },   //5 -->--></div><div>+    {   0,   3, -11,  50,  29,  -9,   2,   0 },   //6 --></div><div>+    {   0,   3, -11,  44,  35, -10,   3,   0 },   //7 -->--></div><div>+    {   0,   1,  -7,  38,  38,  -7,   1,   0 },   //8</div><div>+    {   0,   3, -10,  35,  44, -11,   3,   0 },   //9 -->--></div><div>+    {   0,   2,  -9,  29,  50, -11,   3,   0 },   //10--></div><div>+    {   0,   2,  -8,  24,  53, -10,   3,   0 },   //11-->--></div><div>+    {   0,   2,  -7,  19,  57,  -9,   2,   0 },   //12</div><div>+    {   0,   1,  -5,  14,  60,  -8,   2,   0 },   //13-->--></div><div>+    {   0,   1,  -3,   9,  62,  -6,   1,   0 },   //14--></div><div>+    {   0,   0,  -2,   4,  64,  -3,   1,   0 }    //15-->--></div><div>+};</div><div>+</div><div>+#if BILTERAL_FILTER_NEW_VERSION</div><div>+const double s_refStrengths[3][4] =</div><div>+{ // abs(POC offset)</div><div>+  //  1,    2     3     4</div><div>+  {0.85, 0.57, 0.41, 0.33},  // m_range * 2</div><div>+  {1.13, 0.97, 0.81, 0.57},  // m_range</div><div>+  {0.30, 0.30, 0.30, 0.30}   // otherwise</div><div>+};</div><div>+#else</div><div>+const double s_refStrengths[2][2] =</div><div>+{ // abs(POC offset)</div><div>+  //  1,    2</div><div>+  {0.85, 0.60},  // w future refs</div><div>+  {1.20, 1.00},  // w/o future refs</div><div>+};</div><div>+#endif</div><div>+</div><div>+class OrigPicBuffer</div><div>+{</div><div>+public:</div><div>+    PicList    m_mcstfPicList;</div><div>+    PicList    m_mcstfOrigPicFreeList;</div><div>+    PicList    m_mcstfOrigPicList;</div><div>+</div><div>+    ~OrigPicBuffer();</div><div>+    void addPicture(Frame*);</div><div>+    void addEncPicture(Frame*);</div><div>+    void setOrigPicList(Frame*, int);</div><div>+    void recycleOrigPicList();</div><div>+    void addPictureToFreelist(Frame*);</div><div>+    void addEncPictureToPicList(Frame*);</div><div>+};</div><div>+</div><div>+struct TemporalFilterRefPicInfo</div><div>+{</div><div>+    PicYuv*    picBuffer;</div><div>+    MV*        mvs;</div><div>+    int        origOffset;</div><div>+};</div><div>+</div><div>+struct MCTFReferencePicInfo</div><div>+{</div><div>+    PicYuv*    picBuffer;</div><div>+    PicYuv*    picBufferSubSampled2;</div><div>+    PicYuv*    picBufferSubSampled4;</div><div>+    MV*        mvs;</div><div>+    MV*        mvs0;</div><div>+    MV*        mvs1;</div><div>+    MV*        mvs2;</div><div>+    uint32_t mvsStride;</div><div>+    uint32_t mvsStride0;</div><div>+    uint32_t mvsStride1;</div><div>+    uint32_t mvsStride2;</div><div>+    int*     error;</div><div>+    int*     noise;</div><div>+</div><div>+    int16_t    origOffset;</div><div>+    bool       isFilteredFrame;</div><div>+    PicYuv*       compensatedPic;</div><div>+</div><div>+    int*       isSubsampled;</div><div>+</div><div>+    int        slicetype;</div><div>+};</div><div>+</div><div>+class TemporalFilter</div><div>+{</div><div>+public:</div><div>+    TemporalFilter();</div><div>+    ~TemporalFilter() {}</div><div>+</div><div>+    void init(const x265_param* param);</div><div>+</div><div>+//private:</div><div>+    // Private static member variables</div><div>+    const x265_param *m_param;</div><div>+    int32_t  m_bitDepth;</div><div>+    int s_range;</div><div>+    uint8_t m_numRef;</div><div>+    double s_chromaFactor;</div><div>+    double s_sigmaMultiplier;</div><div>+    double s_sigmaZeroPoint;</div><div>+    int s_motionVectorFactor;</div><div>+    int s_padding;</div><div>+</div><div>+    // Private member variables</div><div>+    int m_FrameSkip;</div><div>+    int m_sourceWidth;</div><div>+    int m_sourceHeight;</div><div>+    int m_QP;</div><div>+    int m_GOPSize;</div><div>+</div><div>+    int m_aiPad[2];</div><div>+    int m_framesToBeEncoded;</div><div>+    bool m_bClipInputVideoToRec709Range;</div><div>+    bool m_gopBasedTemporalFilterFutureReference;</div><div>+    int m_internalCsp;</div><div>+    int m_numComponents;</div><div>+    uint8_t m_sliceTypeConfig;</div><div>+</div><div>+    void subsampleLuma(PicYuv *input, PicYuv *output, int factor = 2);</div><div>+</div><div>+    int createRefPicInfo(MCTFReferencePicInfo* refFrame, x265_param* param);</div><div>+</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>+</div><div>+    int motionErrorLuma(PicYuv *orig,</div><div>+        PicYuv *buffer,</div><div>+        int x,</div><div>+        int y,</div><div>+        int dx,</div><div>+        int dy,</div><div>+        int bs,</div><div>+        int besterror = 8 * 8 * 1024 * 1024);</div><div>+</div><div>+    void destroyRefPicInfo(MCTFReferencePicInfo* curFrame);</div><div>+</div><div>+    void applyMotion(MV *mvs, uint32_t mvsStride, PicYuv *input, PicYuv *output);</div><div>+</div><div>+};</div><div>+</div><div>+#endif</div><div>-- </div><div>2.37.2.windows.2</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>