[x265] [PATCH 3/14] Added functions related to mcstf feature

Snehaa Giridharan snehaa at multicorewareinc.com
Wed Oct 19 07:29:25 UTC 2022


>From 7c777cce9b374a31c999c960f1e794616987cb8f Mon Sep 17 00:00:00 2001
From: ashok2022 <ashok at multicorewareinc.com>
Date: Wed, 21 Sep 2022 17:48:38 +0530
Subject: [PATCH] Added functions related to mcstf feature

---
 source/common/common.h    |   2 +
 source/common/frame.cpp   |  64 ++++++++++++++++++++++++
 source/common/frame.h     |  12 +++++
 source/common/mv.h        |   2 +
 source/common/piclist.cpp | 101 ++++++++++++++++++++++++++++++++++++++
 source/common/piclist.h   |   7 +++
 source/common/picyuv.cpp  |  52 ++++++++++++++++++++
 source/common/picyuv.h    |   2 +
 source/common/slice.h     |   1 +
 9 files changed, 243 insertions(+)

diff --git a/source/common/common.h b/source/common/common.h
index a245c7dae..982b03d89 100644
--- a/source/common/common.h
+++ b/source/common/common.h
@@ -342,6 +342,8 @@ typedef int16_t  coeff_t;      // transform coefficient
 #define MAX_NUM_DYN_REFINE          (NUM_CU_DEPTH *
X265_REFINE_INTER_LEVELS)
 #define X265_BYTE 8

+#define MAX_MCTF_TEMPORAL_WINDOW_LENGTH 8
+
 namespace X265_NS {

 enum { SAO_NUM_OFFSET = 4 };
diff --git a/source/common/frame.cpp b/source/common/frame.cpp
index 255882a9d..0ce301bfa 100644
--- a/source/common/frame.cpp
+++ b/source/common/frame.cpp
@@ -64,12 +64,38 @@ Frame::Frame()
     m_edgeBitPlane = NULL;
     m_edgeBitPic = NULL;
     m_isInsideWindow = 0;
+
+    // mcstf
+    m_isSubSampled = NULL;
+    m_mcstf = NULL;
+    m_refPicCnt[0] = 0;
+    m_refPicCnt[1] = 0;
+    m_nextMCSTF = NULL;
+    m_prevMCSTF = NULL;
+
 }

 bool Frame::create(x265_param *param, float* quantOffsets)
 {
     m_fencPic = new PicYuv;
     m_param = param;
+
+    if (m_param->bEnableGopBasedTemporalFilter)
+    {
+        m_mcstf = new TemporalFilter;
+        m_mcstf->init(param);
+
+        m_fencPicSubsampled2 = new PicYuv;
+        m_fencPicSubsampled4 = new PicYuv;
+
+        if (!m_fencPicSubsampled2->createScaledPicYUV(param, 2))
+            return false;
+        if (!m_fencPicSubsampled4->createScaledPicYUV(param, 4))
+            return false;
+
+        CHECKED_MALLOC_ZERO(m_isSubSampled, int, 1);
+    }
+
     CHECKED_MALLOC_ZERO(m_rcData, RcStats, 1);

     if (param->bCTUInfo)
@@ -151,6 +177,24 @@ fail:
     return false;
 }

+bool Frame::createSubSample()
+{
+
+    //m_param = param;
+
+    m_fencPicSubsampled2 = new PicYuv;
+    m_fencPicSubsampled4 = new PicYuv;
+
+    if (!m_fencPicSubsampled2->createScaledPicYUV(m_param, 2))
+        return false;
+    if (!m_fencPicSubsampled4->createScaledPicYUV(m_param, 4))
+        return false;
+    CHECKED_MALLOC_ZERO(m_isSubSampled, int, 1);
+    return true;
+fail:
+    return false;
+}
+
 bool Frame::allocEncodeData(x265_param *param, const SPS& sps)
 {
     m_encData = new FrameData;
@@ -207,6 +251,26 @@ void Frame::destroy()
         m_fencPic = NULL;
     }

+    if (m_param->bEnableGopBasedTemporalFilter)
+    {
+
+        if (m_fencPicSubsampled2)
+        {
+            m_fencPicSubsampled2->destroy();
+            delete m_fencPicSubsampled2;
+            m_fencPicSubsampled2 = NULL;
+        }
+
+        if (m_fencPicSubsampled4)
+        {
+            m_fencPicSubsampled4->destroy();
+            delete m_fencPicSubsampled4;
+            m_fencPicSubsampled4 = NULL;
+        }
+        delete m_mcstf;
+        X265_FREE(m_isSubSampled);
+    }
+
     if (m_reconPic)
     {
         m_reconPic->destroy();
diff --git a/source/common/frame.h b/source/common/frame.h
index ac1185e81..b1dd00e21 100644
--- a/source/common/frame.h
+++ b/source/common/frame.h
@@ -28,6 +28,7 @@
 #include "common.h"
 #include "lowres.h"
 #include "threading.h"
+#include "temporalfilter.h"

 namespace X265_NS {
 // private namespace
@@ -84,6 +85,9 @@ public:

     /* Data associated with x265_picture */
     PicYuv*                m_fencPic;
+    PicYuv*                m_fencPicSubsampled2;
+    PicYuv*                m_fencPicSubsampled4;
+
     int                    m_poc;
     int                    m_encodeOrder;
     int64_t                m_pts;                // user provided
presentation time stamp
@@ -133,6 +137,13 @@ public:
     bool                   m_classifyFrame;
     int                    m_fieldNum;

+    /*MCSTF*/
+    TemporalFilter*        m_mcstf;
+    int                    m_refPicCnt[2];
+    Frame*                 m_nextMCSTF;           // PicList doubly linked
list pointers
+    Frame*                 m_prevMCSTF;
+    int*                   m_isSubSampled;
+
     /* aq-mode 4 : Gaussian, edge and theta frames for edge information */
     pixel*                 m_edgePic;
     pixel*                 m_gaussianPic;
@@ -147,6 +158,7 @@ public:
     Frame();

     bool create(x265_param *param, float* quantOffsets);
+    bool createSubSample();
     bool allocEncodeData(x265_param *param, const SPS& sps);
     void reinit(const SPS& sps);
     void destroy();
diff --git a/source/common/mv.h b/source/common/mv.h
index 191090cb9..5a8872cdd 100644
--- a/source/common/mv.h
+++ b/source/common/mv.h
@@ -105,6 +105,8 @@ public:
     {
         return x >= _min.x && x <= _max.x && y >= _min.y && y <= _max.y;
     }
+
+    void set(int32_t _x, int32_t _y) { x = _x; y = _y; }
 };
 }

diff --git a/source/common/piclist.cpp b/source/common/piclist.cpp
index 91929f101..275617f6f 100644
--- a/source/common/piclist.cpp
+++ b/source/common/piclist.cpp
@@ -45,6 +45,25 @@ void PicList::pushFront(Frame& curFrame)
     m_count++;
 }

+void PicList::pushFrontMCSTF(Frame& curFrame)
+{
+    X265_CHECK(!curFrame.m_nextMCSTF && !curFrame.m_nextMCSTF, "piclist:
picture already in OPB list\n"); // ensure frame is not in a list
+    curFrame.m_nextMCSTF = m_start;
+    curFrame.m_prevMCSTF = NULL;
+
+    if (m_count)
+    {
+        m_start->m_prevMCSTF = &curFrame;
+        m_start = &curFrame;
+    }
+    else
+    {
+        m_start = m_end = &curFrame;
+    }
+    m_count++;
+
+}
+
 void PicList::pushBack(Frame& curFrame)
 {
     X265_CHECK(!curFrame.m_next && !curFrame.m_prev, "piclist: picture
already in list\n"); // ensure frame is not in a list
@@ -63,6 +82,24 @@ void PicList::pushBack(Frame& curFrame)
     m_count++;
 }

+void PicList::pushBackMCSTF(Frame& curFrame)
+{
+    X265_CHECK(!curFrame.m_nextMCSTF && !curFrame.m_prevMCSTF, "piclist:
picture already in OPB list\n"); // ensure frame is not in a list
+    curFrame.m_nextMCSTF = NULL;
+    curFrame.m_prevMCSTF = m_end;
+
+    if (m_count)
+    {
+        m_end->m_nextMCSTF = &curFrame;
+        m_end = &curFrame;
+    }
+    else
+    {
+        m_start = m_end = &curFrame;
+    }
+    m_count++;
+}
+
 Frame *PicList::popFront()
 {
     if (m_start)
@@ -94,6 +131,14 @@ Frame* PicList::getPOC(int poc)
     return curFrame;
 }

+Frame* PicList::getPOCMCSTF(int poc)
+{
+    Frame *curFrame = m_start;
+    while (curFrame && curFrame->m_poc != poc)
+        curFrame = curFrame->m_nextMCSTF;
+    return curFrame;
+}
+
 Frame *PicList::popBack()
 {
     if (m_end)
@@ -117,6 +162,29 @@ Frame *PicList::popBack()
         return NULL;
 }

+Frame *PicList::popBackMCSTF()
+{
+    if (m_end)
+    {
+        Frame* temp = m_end;
+        m_count--;
+
+        if (m_count)
+        {
+            m_end = m_end->m_prevMCSTF;
+            m_end->m_nextMCSTF = NULL;
+        }
+        else
+        {
+            m_start = m_end = NULL;
+        }
+        temp->m_nextMCSTF = temp->m_prevMCSTF = NULL;
+        return temp;
+    }
+    else
+        return NULL;
+}
+
 Frame* PicList::getCurFrame(void)
 {
     Frame *curFrame = m_start;
@@ -158,3 +226,36 @@ void PicList::remove(Frame& curFrame)

     curFrame.m_next = curFrame.m_prev = NULL;
 }
+
+void PicList::removeMCSTF(Frame& curFrame)
+{
+#if _DEBUG
+    Frame *tmp = m_start;
+    while (tmp && tmp != &curFrame)
+    {
+        tmp = tmp->m_nextMCSTF;
+    }
+
+    X265_CHECK(tmp == &curFrame, "framelist: pic being removed was not in
list\n"); // verify pic is in this list
+#endif
+
+    m_count--;
+    if (m_count)
+    {
+        if (m_start == &curFrame)
+            m_start = curFrame.m_nextMCSTF;
+        if (m_end == &curFrame)
+            m_end = curFrame.m_prevMCSTF;
+
+        if (curFrame.m_nextMCSTF)
+            curFrame.m_nextMCSTF->m_prevMCSTF = curFrame.m_prevMCSTF;
+        if (curFrame.m_prevMCSTF)
+            curFrame.m_prevMCSTF->m_nextMCSTF = curFrame.m_nextMCSTF;
+    }
+    else
+    {
+        m_start = m_end = NULL;
+    }
+
+    curFrame.m_nextMCSTF = curFrame.m_prevMCSTF = NULL;
+}
diff --git a/source/common/piclist.h b/source/common/piclist.h
index e1d6e714a..45023c93b 100644
--- a/source/common/piclist.h
+++ b/source/common/piclist.h
@@ -49,24 +49,31 @@ public:

     /** Push picture to end of the list */
     void pushBack(Frame& pic);
+    void pushBackMCSTF(Frame& pic);

     /** Push picture to beginning of the list */
     void pushFront(Frame& pic);
+    void pushFrontMCSTF(Frame& pic);

     /** Pop picture from end of the list */
     Frame* popBack();
+    Frame* popBackMCSTF();

     /** Pop picture from beginning of the list */
     Frame* popFront();

     /** Find frame with specified POC */
     Frame* getPOC(int poc);
+    /* Find next MCSTF frame with specified POC */
+    Frame* getPOCMCSTF(int poc);

     /** Get the current Frame from the list **/
     Frame* getCurFrame(void);

     /** Remove picture from list */
     void remove(Frame& pic);
+    /* Remove MCSTF picture from list */
+    void removeMCSTF(Frame& pic);

     Frame* first()        { return m_start;   }

diff --git a/source/common/picyuv.cpp b/source/common/picyuv.cpp
index e65dbdd46..2855356b5 100644
--- a/source/common/picyuv.cpp
+++ b/source/common/picyuv.cpp
@@ -125,6 +125,58 @@ fail:
     return false;
 }

+/*Copy pixels from the picture buffer of a frame to picture buffer of
another frame*/
+void PicYuv::copyFromFrame(PicYuv* source)
+{
+    uint32_t numCuInHeight = (m_picHeight + m_param->maxCUSize - 1) /
m_param->maxCUSize;
+
+    int maxHeight = numCuInHeight * m_param->maxCUSize;
+    memcpy(m_picBuf[0], source->m_picBuf[0], sizeof(pixel)* m_stride *
(maxHeight + (m_lumaMarginY * 2)));
+    m_picOrg[0] = m_picBuf[0] + m_lumaMarginY * m_stride + m_lumaMarginX;
+
+    if (m_picCsp != X265_CSP_I400)
+    {
+        memcpy(m_picBuf[1], source->m_picBuf[1], sizeof(pixel)* m_strideC
* ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
+        memcpy(m_picBuf[2], source->m_picBuf[2], sizeof(pixel)* m_strideC
* ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
+
+        m_picOrg[1] = m_picBuf[1] + m_chromaMarginY * m_strideC +
m_chromaMarginX;
+        m_picOrg[2] = m_picBuf[2] + m_chromaMarginY * m_strideC +
m_chromaMarginX;
+    }
+    else
+    {
+        m_picBuf[1] = m_picBuf[2] = NULL;
+        m_picOrg[1] = m_picOrg[2] = NULL;
+    }
+}
+
+bool PicYuv::createScaledPicYUV(x265_param* param, uint8_t scaleFactor)
+{
+    m_param = param;
+    m_picWidth = m_param->sourceWidth / scaleFactor;
+    m_picHeight = m_param->sourceHeight / scaleFactor;
+
+    m_picCsp = m_param->internalCsp;
+    m_hChromaShift = CHROMA_H_SHIFT(m_picCsp);
+    m_vChromaShift = CHROMA_V_SHIFT(m_picCsp);
+
+    uint32_t numCuInWidth = (m_picWidth + param->maxCUSize - 1) /
param->maxCUSize;
+    uint32_t numCuInHeight = (m_picHeight + param->maxCUSize - 1) /
param->maxCUSize;
+
+    m_lumaMarginX = 32; // search margin for L0 and L1 ME in horizontal
direction
+    m_lumaMarginY = 32; // search margin for L0 and L1 ME in vertical
direction
+    m_stride = (numCuInWidth * param->maxCUSize) + (m_lumaMarginX << 1);
+
+    int maxHeight = numCuInHeight * param->maxCUSize;
+    CHECKED_MALLOC_ZERO(m_picBuf[0], pixel, m_stride * (maxHeight +
(m_lumaMarginY * 2)));
+    m_picOrg[0] = m_picBuf[0] + m_lumaMarginY * m_stride + m_lumaMarginX;
+    m_picBuf[1] = m_picBuf[2] = NULL;
+    m_picOrg[1] = m_picOrg[2] = NULL;
+    return true;
+
+fail:
+    return false;
+}
+
 int PicYuv::getLumaBufLen(uint32_t picWidth, uint32_t picHeight, uint32_t
picCsp)
 {
     m_picWidth = picWidth;
diff --git a/source/common/picyuv.h b/source/common/picyuv.h
index 0b53d354d..ba448567a 100644
--- a/source/common/picyuv.h
+++ b/source/common/picyuv.h
@@ -78,11 +78,13 @@ public:
     PicYuv();

     bool  create(x265_param* param, bool picAlloc = true, pixel *pixelbuf
= NULL);
+    bool  createScaledPicYUV(x265_param* param, uint8_t scaleFactor);
     bool  createOffsets(const SPS& sps);
     void  destroy();
     int   getLumaBufLen(uint32_t picWidth, uint32_t picHeight, uint32_t
picCsp);

     void  copyFromPicture(const x265_picture&, const x265_param& param,
int padx, int pady);
+    void  copyFromFrame(PicYuv* source);

     intptr_t getChromaAddrOffset(uint32_t ctuAddr, uint32_t absPartIdx)
const { return m_cuOffsetC[ctuAddr] + m_buOffsetC[absPartIdx]; }

diff --git a/source/common/slice.h b/source/common/slice.h
index 9a48d39c6..c5327c198 100644
--- a/source/common/slice.h
+++ b/source/common/slice.h
@@ -363,6 +363,7 @@ public:
     int         m_iNumRPSInSPS;
     const x265_param *m_param;
     int         m_fieldNum;
+    Frame*      m_mcstfRefFrameList[2][MAX_MCTF_TEMPORAL_WINDOW_LENGTH];

     Slice()
     {
-- 
2.34.1.windows.1

*Thanks and Regards,*





*Snehaa.GVideo Codec Engineer,Media & AI analytics
<https://multicorewareinc.com/>*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20221019/151f7de6/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mcstf_patch_03.diff
Type: application/octet-stream
Size: 13201 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20221019/151f7de6/attachment-0001.obj>


More information about the x265-devel mailing list