[x265] [PATCH 1 of 4] reference: cache MotionReference instances in each FrameEncoder

Steve Borho steve at borho.org
Thu Oct 24 07:01:41 CEST 2013


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1382589451 18000
#      Wed Oct 23 23:37:31 2013 -0500
# Node ID db5d34950f77f8af13ef3edcc2185d1aa6e95201
# Parent  0cb0692d6c69dbf6c5b49c51f6f528e29674baa9
reference: cache MotionReference instances in each FrameEncoder

This prevents these structures from being allocated over and over for each frame
The source files were moved into the encoder folder where they've belonged but
couldn't live in the past because TComPicYuv needed to know their contents.

diff -r 0cb0692d6c69 -r db5d34950f77 source/Lib/TLibCommon/TComPicYuv.cpp
--- a/source/Lib/TLibCommon/TComPicYuv.cpp	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/Lib/TLibCommon/TComPicYuv.cpp	Wed Oct 23 23:37:31 2013 -0500
@@ -58,12 +58,11 @@
     m_picOrgY = NULL;  // m_apiPicBufY + m_iMarginLuma*getStride() + m_iMarginLuma
     m_picOrgU = NULL;
     m_picOrgV = NULL;
-
-    m_refList = NULL;
 }
 
 TComPicYuv::~TComPicYuv()
-{}
+{
+}
 
 void TComPicYuv::create(int picWidth, int picHeight, UInt maxCUWidth, UInt maxCUHeight, UInt maxCUDepth)
 {
@@ -133,23 +132,6 @@
     delete[] m_cuOffsetC;
     delete[] m_buOffsetY;
     delete[] m_buOffsetC;
-
-    while (m_refList)
-    {
-        MotionReference *mref = m_refList->m_next;
-        delete m_refList;
-        m_refList = mref;
-    }
-}
-
-void  TComPicYuv::clearReferences()
-{
-    while (m_refList)
-    {
-        MotionReference *mref = m_refList->m_next;
-        delete m_refList;
-        m_refList = mref;
-    }
 }
 
 void TComPicYuv::createLuma(int picWidth, int picHeight, UInt maxCUWidth, UInt maxCUHeight, UInt maxCUDepth)
@@ -234,31 +216,6 @@
     ::memcpy(destPicYuv->getBufV(), m_picBufV, sizeof(Pel) * ((m_picWidth >> 1) + (m_chromaMarginX << 1)) * ((m_picHeight >> 1) + (m_chromaMarginY << 1)));
 }
 
-MotionReference* TComPicYuv::generateMotionReference(wpScalingParam *w)
-{
-    /* HPEL generation requires luma integer plane to already be extended */
-    // NOTE: We extend border every CURow, so I remove code here
-
-    MotionReference *mref;
-
-    for (mref = m_refList; mref != NULL; mref = mref->m_next)
-    {
-        if (w)
-        {
-            if (mref->matchesWeight(*w))
-                return mref;
-        }
-        else if (mref->isWeighted == false)
-            return mref;
-    }
-
-    mref = new MotionReference();
-    mref->init(this, w);
-    mref->m_next = m_refList;
-    m_refList = mref;
-    return mref;
-}
-
 void TComPicYuv::xExtendPicCompBorder(Pel* recon, int stride, int width, int height, int iMarginX, int iMarginY)
 {
     int x, y;
diff -r 0cb0692d6c69 -r db5d34950f77 source/Lib/TLibCommon/TComPicYuv.h
--- a/source/Lib/TLibCommon/TComPicYuv.h	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/Lib/TLibCommon/TComPicYuv.h	Wed Oct 23 23:37:31 2013 -0500
@@ -41,8 +41,7 @@
 #include "CommonDef.h"
 #include "TComRom.h"
 
-#include "x265.h"
-#include "reference.h"
+struct x265_picture_t;
 
 namespace x265 {
 // private namespace
@@ -59,7 +58,7 @@
 /// picture YUV buffer class
 class TComPicYuv
 {
-private:
+public:
 
     // ------------------------------------------------------------------------------------------------
     //  YUV buffer
@@ -73,10 +72,6 @@
     Pel*  m_picOrgU;
     Pel*  m_picOrgV;
 
-    // Pre-interpolated reference pictures for each QPEL offset, may be more than
-    // one if weighted references are in use
-    MotionReference *m_refList;
-
     // ------------------------------------------------------------------------------------------------
     //  Parameter for general YUV buffer usage
     // ------------------------------------------------------------------------------------------------
@@ -97,8 +92,6 @@
     int   m_stride;
     int   m_strideC;
 
-public:
-
     int   m_numCuInWidth;
     int   m_numCuInHeight;
 
@@ -106,6 +99,7 @@
     virtual ~TComPicYuv();
 
     void xExtendPicCompBorder(Pel* recon, int stride, int width, int height, int marginX, int marginY);
+
     // ------------------------------------------------------------------------------------------------
     //  Memory management
     // ------------------------------------------------------------------------------------------------
@@ -116,8 +110,6 @@
     void  createLuma(int picWidth, int picHeight, UInt maxCUWidth, UInt maxCUHeight, UInt maxCUDepth);
     void  destroyLuma();
 
-    void  clearReferences();
-
     // ------------------------------------------------------------------------------------------------
     //  Get information of picture
     // ------------------------------------------------------------------------------------------------
@@ -180,12 +172,8 @@
     void  copyToPicCr(TComPicYuv* destYuv);
     void  copyFromPicture(const x265_picture_t&, int *pad);
 
-    MotionReference* generateMotionReference(wpScalingParam *w);
-
     //  Dump picture
     void  dump(char* pFileName, bool bAdd = false);
-
-    friend class MotionReference;
 }; // END CLASS DEFINITION TComPicYuv
 
 void calcChecksum(TComPicYuv & pic, UChar digest[3][16]);
diff -r 0cb0692d6c69 -r db5d34950f77 source/Lib/TLibCommon/TComPrediction.cpp
--- a/source/Lib/TLibCommon/TComPrediction.cpp	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/Lib/TLibCommon/TComPrediction.cpp	Wed Oct 23 23:37:31 2013 -0500
@@ -342,7 +342,7 @@
     cu->clipMv(mv);
 
     if (bLuma)
-        xPredInterLumaBlk(cu, cu->getSlice()->m_mref[picList][refIdx], partAddr, &mv, width, height, outPredYuv);
+        xPredInterLumaBlk(cu, cu->getSlice()->getRefPic(picList, refIdx)->getPicYuvRec(), partAddr, &mv, width, height, outPredYuv);
 
     if (bChroma)
         xPredInterChromaBlk(cu, cu->getSlice()->getRefPic(picList, refIdx)->getPicYuvRec(), partAddr, &mv, width, height, outPredYuv);
@@ -469,15 +469,14 @@
  * \param height   Height of block
  * \param dstPic   Pointer to destination picture
  */
-void TComPrediction::xPredInterLumaBlk(TComDataCU *cu, MotionReference *ref, UInt partAddr, MV *mv, int width, int height, TComYuv *dstPic)
+void TComPrediction::xPredInterLumaBlk(TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, MV *mv, int width, int height, TComYuv *dstPic)
 {
     int dstStride = dstPic->getStride();
     Pel *dst      = dstPic->getLumaAddr(partAddr);
 
-    TComPicYuv* pic = ref->m_reconPic;
-    int srcStride = ref->lumaStride;
-    int refOffset = (mv->x >> 2) + (mv->y >> 2) * srcStride;
-    Pel* src = pic->getLumaAddr(cu->getAddr(), cu->getZorderIdxInCU() + partAddr) + refOffset;
+    int srcStride = refPic->getStride();
+    int srcOffset = (mv->x >> 2) + (mv->y >> 2) * srcStride;
+    Pel* src = refPic->getLumaAddr(cu->getAddr(), cu->getZorderIdxInCU() + partAddr) + srcOffset;
 
     int xFrac = mv->x & 0x3;
     int yFrac = mv->y & 0x3;
diff -r 0cb0692d6c69 -r db5d34950f77 source/Lib/TLibCommon/TComPrediction.h
--- a/source/Lib/TLibCommon/TComPrediction.h	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/Lib/TLibCommon/TComPrediction.h	Wed Oct 23 23:37:31 2013 -0500
@@ -45,11 +45,12 @@
 #include "TComTrQuant.h"
 #include "TComWeightPrediction.h"
 #include "TShortYUV.h"
-#include "reference.h"
 
 namespace x265 {
 // private namespace
 
+struct ReferencePlanes;
+
 //! \ingroup TLibCommon
 //! \{
 
@@ -85,7 +86,7 @@
     // motion compensation functions
     void xPredInterUni(TComDataCU* cu, UInt partAddr, int width, int height, RefPicList picList, TComYuv* outPredYuv, bool bLuma = true, bool bChroma = true);
     void xPredInterUni(TComDataCU* cu, UInt partAddr, int width, int height, RefPicList picList, TShortYUV* outPredYuv, bool bLuma = true, bool bChroma = true);
-    void xPredInterLumaBlk(TComDataCU *cu, MotionReference *refPic, UInt partAddr, MV *mv, int width, int height, TComYuv *dstPic);
+    void xPredInterLumaBlk(TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, MV *mv, int width, int height, TComYuv *dstPic);
     void xPredInterLumaBlk(TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, MV *mv, int width, int height, TShortYUV *dstPic);
     void xPredInterChromaBlk(TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, MV *mv, int width, int height, TComYuv *dstPic);
     void xPredInterChromaBlk(TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, MV *mv, int width, int height, TShortYUV *dstPic);
diff -r 0cb0692d6c69 -r db5d34950f77 source/Lib/TLibCommon/TComSlice.h
--- a/source/Lib/TLibCommon/TComSlice.h	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/Lib/TLibCommon/TComSlice.h	Wed Oct 23 23:37:31 2013 -0500
@@ -41,7 +41,6 @@
 #include "CommonDef.h"
 #include "TComRom.h"
 #include "x265.h"  // NAL type enums
-#include "reference.h"
 #include "piclist.h"
 
 #include <cstring>
@@ -55,6 +54,8 @@
 
 class TComPic;
 class TComTrQuant;
+class MotionReference;
+
 // ====================================================================================================================
 // Constants
 // ====================================================================================================================
@@ -1375,7 +1376,6 @@
 
 public:
 
-    MotionReference * m_mref[2][MAX_NUM_REF + 1];
     wpScalingParam  m_weightPredTable[2][MAX_NUM_REF][3]; // [REF_PIC_LIST_0 or REF_PIC_LIST_1][refIdx][0:Y, 1:U, 2:V]
 
     /* SSIM values per frame */
diff -r 0cb0692d6c69 -r db5d34950f77 source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp	Wed Oct 23 23:37:31 2013 -0500
@@ -2283,7 +2283,7 @@
 
                     MV mvmin, mvmax;
                     xSetSearchRange(cu, mvp, merange, mvmin, mvmax);
-                    int satdCost = m_me.motionEstimate(cu->getSlice()->m_mref[picList][idx],
+                    int satdCost = m_me.motionEstimate(m_mref[picList][idx],
                                                        mvmin, mvmax, mvp, 3, m_mvPredictors, merange, outmv);
 
                     /* Get total cost of partition, but only include MV bit cost once */
@@ -2327,8 +2327,8 @@
                 ::memcpy(mvpIdxBi, mvpIdx, sizeof(mvpIdx));
 
                 // Generate reference subpels
-                xPredInterLumaBlk(cu, cu->getSlice()->m_mref[0][refIdx[0]], partAddr, &mv[0], roiWidth, roiHeight, &m_predYuv[0]);
-                xPredInterLumaBlk(cu, cu->getSlice()->m_mref[1][refIdx[1]], partAddr, &mv[1], roiWidth, roiHeight, &m_predYuv[1]);
+                xPredInterLumaBlk(cu, cu->getSlice()->getRefPic(REF_PIC_LIST_0, refIdx[0])->getPicYuvRec(), partAddr, &mv[0], roiWidth, roiHeight, &m_predYuv[0]);
+                xPredInterLumaBlk(cu, cu->getSlice()->getRefPic(REF_PIC_LIST_1, refIdx[1])->getPicYuvRec(), partAddr, &mv[1], roiWidth, roiHeight, &m_predYuv[1]);
 
                 pixel *ref0 = m_predYuv[0].getLumaAddr(partAddr);
                 pixel *ref1 = m_predYuv[1].getLumaAddr(partAddr);
@@ -2344,9 +2344,9 @@
 
                 if (mv[0].notZero() || mv[1].notZero())
                 {
-                    ref0 = cu->getSlice()->m_mref[0][refIdx[0]]->fpelPlane + (pu - fenc->getLumaAddr());  //MV(0,0) of ref0
-                    ref1 = cu->getSlice()->m_mref[1][refIdx[1]]->fpelPlane + (pu - fenc->getLumaAddr());  //MV(0,0) of ref1
-                    intptr_t refStride = cu->getSlice()->m_mref[0][refIdx[0]]->lumaStride;
+                    ref0 = m_mref[0][refIdx[0]]->fpelPlane + (pu - fenc->getLumaAddr());  //MV(0,0) of ref0
+                    ref1 = m_mref[1][refIdx[1]]->fpelPlane + (pu - fenc->getLumaAddr());  //MV(0,0) of ref1
+                    intptr_t refStride = m_mref[0][refIdx[0]]->lumaStride;
 
                     primitives.pixelavg_pp[partEnum](avg, roiWidth, ref0, refStride, ref1, refStride, 32);
                     satdCost = primitives.satd[partEnum](pu, fenc->getStride(), avg, roiWidth);
@@ -2725,8 +2725,7 @@
     cu->clipMv(mvCand);
 
     // prediction pattern
-    MotionReference* ref = cu->getSlice()->m_mref[picList][refIdx];
-    xPredInterLumaBlk(cu, ref, partAddr, &mvCand, sizex, sizey, templateCand);
+    xPredInterLumaBlk(cu, cu->getSlice()->getRefPic(picList, refIdx)->getPicYuvRec(), partAddr, &mvCand, sizex, sizey, templateCand);
 
     // calc distortion
     UInt cost = m_me.bufSAD(templateCand->getLumaAddr(partAddr), templateCand->getStride());
diff -r 0cb0692d6c69 -r db5d34950f77 source/Lib/TLibEncoder/TEncSearch.h
--- a/source/Lib/TLibEncoder/TEncSearch.h	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/Lib/TLibEncoder/TEncSearch.h	Wed Oct 23 23:37:31 2013 -0500
@@ -70,7 +70,8 @@
 {
 public:
 
-    MotionEstimate  m_me;
+    MotionEstimate   m_me;
+    MotionReference* m_mref[2][MAX_NUM_REF + 1];
 
 protected:
 
diff -r 0cb0692d6c69 -r db5d34950f77 source/common/CMakeLists.txt
--- a/source/common/CMakeLists.txt	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/common/CMakeLists.txt	Wed Oct 23 23:37:31 2013 -0500
@@ -226,7 +226,6 @@
     wavefront.h wavefront.cpp
     md5.cpp md5.h
     TShortYUV.cpp TShortYUV.h mv.h
-    reference.cpp reference.h
     common.cpp common.h
     lowres.cpp lowres.h
     piclist.cpp piclist.h)
diff -r 0cb0692d6c69 -r db5d34950f77 source/common/lowres.h
--- a/source/common/lowres.h	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/common/lowres.h	Wed Oct 23 23:37:31 2013 -0500
@@ -24,9 +24,8 @@
 #ifndef X265_LOWRES_H
 #define X265_LOWRES_H
 
-#include "TLibCommon/TComPicYuv.h"
+#include "primitives.h"
 #include "common.h"
-#include "reference.h"
 #include "mv.h"
 
 namespace x265 {
diff -r 0cb0692d6c69 -r db5d34950f77 source/common/mv.h
--- a/source/common/mv.h	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/common/mv.h	Wed Oct 23 23:37:31 2013 -0500
@@ -24,6 +24,7 @@
 #ifndef X265_MV_H
 #define X265_MV_H
 
+#include "primitives.h"
 #include <stdint.h>
 
 namespace x265 {
@@ -98,6 +99,23 @@
         return x >= _min.x && x <= _max.x && y >= _min.y && y <= _max.y;
     }
 };
+
+struct ReferencePlanes
+{
+    ReferencePlanes() : isWeighted(false), isLowres(false) {}
+
+    pixel* fpelPlane;
+    pixel* lowresPlane[4];
+    pixel* unweightedFPelPlane;
+
+    bool isWeighted;
+    bool isLowres;
+    int  lumaStride;
+    int  weight;
+    int  offset;
+    int  shift;
+    int  round;
+};
 }
 
 #endif // ifndef X265_MV_H
diff -r 0cb0692d6c69 -r db5d34950f77 source/common/reference.cpp
--- a/source/common/reference.cpp	Wed Oct 23 20:09:33 2013 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*****************************************************************************
- * Copyright (C) 2013 x265 project
- *
- * Authors: Steve Borho <steve at borho.org>
- *          Deepthi Devaki <deepthidevaki at multicorewareinc.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
- *
- * This program is also available under a commercial proprietary license.
- * For more information, contact us at licensing at multicorewareinc.com.
- *****************************************************************************/
-
-#include "TLibCommon/TypeDef.h"
-#include "TLibCommon/TComPicYuv.h"
-#include "TLibCommon/TComPic.h"
-#include "TLibCommon/TComSlice.h"
-#include "primitives.h"
-#include "reference.h"
-
-using namespace x265;
-
-void ReferencePlanes::setWeight(const wpScalingParam& w)
-{
-    weight = w.inputWeight;
-    offset = w.inputOffset * (1 << (X265_DEPTH - 8));
-    shift  = w.log2WeightDenom;
-    round  = (w.log2WeightDenom >= 1) ? (1 << (w.log2WeightDenom - 1)) : (0);
-    isWeighted = true;
-}
-
-bool ReferencePlanes::matchesWeight(const wpScalingParam& w)
-{
-    if (!isWeighted)
-        return false;
-
-    if ((weight == w.inputWeight) && (shift == (int)w.log2WeightDenom) &&
-        (offset == w.inputOffset * (1 << (X265_DEPTH - 8))))
-        return true;
-
-    return false;
-}
-
-MotionReference::MotionReference()
-{}
-
-int MotionReference::init(TComPicYuv* pic, wpScalingParam *w)
-{
-    m_reconPic = pic;
-    unweightedFPelPlane = pic->getLumaAddr();
-    lumaStride = pic->getStride();
-    m_startPad = pic->m_lumaMarginY * lumaStride + pic->m_lumaMarginX;
-    m_next = NULL;
-    isWeighted = false;
-    m_numWeightedRows = 0;
-
-    if (w)
-    {
-        int width = pic->getWidth();
-        int height = pic->getHeight();
-        size_t padwidth = width + pic->m_lumaMarginX * 2;
-        size_t padheight = height + pic->m_lumaMarginY * 2;
-        setWeight(*w);
-        fpelPlane = (pixel*)X265_MALLOC(pixel,  padwidth * padheight);
-        if (fpelPlane) fpelPlane += m_startPad;
-        else return -1;
-    }
-    else
-    {
-        /* directly reference the pre-extended integer pel plane */
-        fpelPlane = pic->m_picBufY + m_startPad;
-    }
-    return 0;
-}
-
-MotionReference::~MotionReference()
-{
-    if (isWeighted && fpelPlane)
-        X265_FREE(fpelPlane - m_startPad);
-}
-
-void MotionReference::applyWeight(int rows, int numRows)
-{
-    rows = X265_MIN(rows, numRows);
-    if (m_numWeightedRows >= rows)
-        return;
-    int marginX = m_reconPic->m_lumaMarginX;
-    int marginY = m_reconPic->m_lumaMarginY;
-    pixel* src = (pixel*)m_reconPic->getLumaAddr() + (m_numWeightedRows * (int)g_maxCUHeight * lumaStride);
-    pixel* dst = fpelPlane + ((m_numWeightedRows * (int)g_maxCUHeight) * lumaStride);
-    int width = m_reconPic->getWidth();
-    int height = ((rows - m_numWeightedRows) * g_maxCUHeight);
-    if (rows == numRows)
-        height = ((m_reconPic->getHeight() % g_maxCUHeight) ? (m_reconPic->getHeight() % g_maxCUHeight) : g_maxCUHeight);
-    size_t dstStride = lumaStride;
-
-    // Computing weighted CU rows
-    int shiftNum = IF_INTERNAL_PREC - X265_DEPTH;
-    int local_shift = shift + shiftNum;
-    int local_round = local_shift ? (1 << (local_shift - 1)) : 0;
-    primitives.weightpUniPixel(src, dst, lumaStride, dstStride, width, height, weight, local_round, local_shift, offset);
-
-    // Extending Left & Right
-    primitives.extendRowBorder(dst, dstStride, width, height, marginX);
-
-    // Extending Above
-    if (m_numWeightedRows == 0)
-    {
-        pixel *pixY = fpelPlane - marginX;
-        for (int y = 0; y < marginY; y++)
-        {
-            memcpy(pixY - (y + 1) * dstStride, pixY, dstStride * sizeof(pixel));
-        }
-    }
-
-    // Extending Bottom
-    if (rows == numRows)
-    {
-        pixel *pixY = fpelPlane - marginX + (m_reconPic->getHeight() - 1) * dstStride;
-        for (int y = 0; y < marginY; y++)
-        {
-            memcpy(pixY + (y + 1) * dstStride, pixY, dstStride * sizeof(pixel));
-        }
-    }
-    m_numWeightedRows = rows;
-}
diff -r 0cb0692d6c69 -r db5d34950f77 source/common/reference.h
--- a/source/common/reference.h	Wed Oct 23 20:09:33 2013 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*****************************************************************************
- * Copyright (C) 2013 x265 project
- *
- * Authors: Steve Borho <steve at borho.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
- *
- * This program is also available under a commercial proprietary license.
- * For more information, contact us at licensing at multicorewareinc.com.
- *****************************************************************************/
-
-#ifndef X265_REFERENCE_H
-#define X265_REFERENCE_H
-
-#include "primitives.h"
-
-namespace x265 {
-// private x265 namespace
-
-class TComPicYuv;
-class TComPic;
-struct WpScalingParam;
-typedef WpScalingParam wpScalingParam;
-
-struct ReferencePlanes
-{
-    ReferencePlanes() : isWeighted(false), isLowres(false) {}
-
-    void setWeight(const wpScalingParam&);
-    bool matchesWeight(const wpScalingParam&);
-
-    pixel* fpelPlane;
-    pixel* lowresPlane[4];
-    pixel* unweightedFPelPlane;
-
-    bool isWeighted;
-    bool isLowres;
-    int  lumaStride;
-    int  weight;
-    int  offset;
-    int  shift;
-    int  round;
-};
-
-class MotionReference : public ReferencePlanes
-{
-public:
-
-    MotionReference();
-    ~MotionReference();
-    int  init(TComPicYuv*, wpScalingParam* w = NULL);
-    void applyWeight(int rows, int numRows);
-
-    MotionReference *m_next;
-    TComPicYuv      *m_reconPic;
-    int              m_numWeightedRows;
-
-protected:
-
-    intptr_t         m_startPad;
-
-    MotionReference& operator =(const MotionReference&);
-};
-}
-
-#endif // ifndef X265_REFERENCE_H
diff -r 0cb0692d6c69 -r db5d34950f77 source/encoder/CMakeLists.txt
--- a/source/encoder/CMakeLists.txt	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/encoder/CMakeLists.txt	Wed Oct 23 23:37:31 2013 -0500
@@ -64,4 +64,5 @@
     dpb.cpp dpb.h
     ratecontrol.cpp ratecontrol.h
     compress.cpp
+    reference.cpp reference.h
     encoder.cpp encoder.h)
diff -r 0cb0692d6c69 -r db5d34950f77 source/encoder/dpb.cpp
--- a/source/encoder/dpb.cpp	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/encoder/dpb.cpp	Wed Oct 23 23:37:31 2013 -0500
@@ -52,7 +52,6 @@
         iterPic = iterPic->m_next;
         if (pic->getSlice()->isReferenced() == false && pic->m_countRefEncoders == 0)
         {
-            pic->getPicYuvRec()->clearReferences();
             pic->m_reconRowCount = 0;
 
             // iterator is invalidated by remove, restart scan
diff -r 0cb0692d6c69 -r db5d34950f77 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/encoder/frameencoder.cpp	Wed Oct 23 23:37:31 2013 -0500
@@ -111,6 +111,9 @@
     for (int i = 0; i < m_numRows; ++i)
     {
         m_rows[i].create(top);
+        for (int list = 0; list <= 1; list++)
+            for (int ref = 0; ref <= MAX_NUM_REF; ref++)
+                m_rows[i].m_search.m_mref[list][ref] = &m_mref[list][ref];
     }
 
     // NOTE: 2 times of numRows because both Encoder and Filter in same queue
@@ -119,7 +122,7 @@
         assert(!"Unable to initialize job queue.");
         m_pool = NULL;
     }
-
+    
     m_frameFilter.init(top, numRows, getRDGoOnSbacCoder(0));
 
     // initialize SPS
@@ -427,7 +430,7 @@
             TComPicYuv *recon = slice->getRefPic(list, ref)->getPicYuvRec();
             if ((slice->isInterP() && slice->getPPS()->getUseWP()))
                 w = slice->m_weightPredTable[list][ref];
-            slice->m_mref[list][ref] = recon->generateMotionReference(w);
+            m_mref[l][ref].init(recon, w);
         }
     }
 
@@ -922,7 +925,7 @@
 
                     if (slice->getPPS()->getUseWP() && (slice->getSliceType() == P_SLICE))
                     {
-                        slice->m_mref[list][ref]->applyWeight(row + refLagRows, m_numRows);
+                        m_mref[list][ref].applyWeight(row + refLagRows, m_numRows);
                     }
                 }
             }
@@ -959,7 +962,7 @@
 
                         if (slice->getPPS()->getUseWP() && (slice->getSliceType() == P_SLICE))
                         {
-                            slice->m_mref[list][ref]->applyWeight(i + refLagRows, m_numRows);
+                            m_mref[list][ref].applyWeight(i + refLagRows, m_numRows);
                         }
                     }
                 }
diff -r 0cb0692d6c69 -r db5d34950f77 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h	Wed Oct 23 20:09:33 2013 +0800
+++ b/source/encoder/frameencoder.h	Wed Oct 23 23:37:31 2013 -0500
@@ -41,6 +41,7 @@
 #include "framefilter.h"
 #include "cturow.h"
 #include "ratecontrol.h"
+#include "reference.h"
 
 namespace x265 {
 // private x265 namespace
@@ -168,6 +169,7 @@
     Encoder*                 m_top;
     TEncCfg*                 m_cfg;
 
+    MotionReference          m_mref[2][MAX_NUM_REF + 1];
     WeightPredAnalysis       m_wp;
     TEncSbac                 m_sbacCoder;
     TEncBinCABAC             m_binCoderCABAC;
diff -r 0cb0692d6c69 -r db5d34950f77 source/encoder/reference.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/encoder/reference.cpp	Wed Oct 23 23:37:31 2013 -0500
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * Copyright (C) 2013 x265 project
+ *
+ * Authors: Steve Borho <steve at borho.org>
+ *          Deepthi Devaki <deepthidevaki at multicorewareinc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
+ *
+ * This program is also available under a commercial proprietary license.
+ * For more information, contact us at licensing at multicorewareinc.com.
+ *****************************************************************************/
+
+#include "TLibCommon/TypeDef.h"
+#include "TLibCommon/TComPicYuv.h"
+#include "TLibCommon/TComSlice.h"
+#include "primitives.h"
+#include "reference.h"
+#include "common.h"
+
+using namespace x265;
+
+MotionReference::MotionReference()
+{
+}
+
+int MotionReference::init(TComPicYuv* pic, wpScalingParam *w)
+{
+    m_reconPic = pic;
+    unweightedFPelPlane = pic->getLumaAddr();
+    lumaStride = pic->getStride();
+    m_startPad = pic->m_lumaMarginY * lumaStride + pic->m_lumaMarginX;
+    m_numWeightedRows = 0;
+    isWeighted = false;
+
+    if (w)
+    {
+        isWeighted = true;
+        if (!m_weightBuffer)
+        {
+            int width = pic->getWidth();
+            int height = pic->getHeight();
+            size_t padwidth = width + pic->m_lumaMarginX * 2;
+            size_t padheight = height + pic->m_lumaMarginY * 2;
+            m_weightBuffer = (pixel*)X265_MALLOC(pixel,  padwidth * padheight);
+            if (!m_weightBuffer)
+                return -1;
+        }
+
+        weight = w->inputWeight;
+        offset = w->inputOffset * (1 << (X265_DEPTH - 8));
+        shift  = w->log2WeightDenom;
+        round  = (w->log2WeightDenom >= 1) ? (1 << (w->log2WeightDenom - 1)) : (0);
+
+        /* use our buffer which will have weighted pixels written to it */
+        fpelPlane = m_weightBuffer + m_startPad;
+    }
+    else
+    {
+        /* directly reference the pre-extended integer pel plane */
+        fpelPlane = pic->m_picBufY + m_startPad;
+    }
+    return 0;
+}
+
+MotionReference::~MotionReference()
+{
+    X265_FREE(m_weightBuffer);
+}
+
+void MotionReference::applyWeight(int rows, int numRows)
+{
+    rows = X265_MIN(rows, numRows);
+    if (m_numWeightedRows >= rows)
+        return;
+    int marginX = m_reconPic->m_lumaMarginX;
+    int marginY = m_reconPic->m_lumaMarginY;
+    pixel* src = (pixel*)m_reconPic->getLumaAddr() + (m_numWeightedRows * (int)g_maxCUHeight * lumaStride);
+    pixel* dst = fpelPlane + ((m_numWeightedRows * (int)g_maxCUHeight) * lumaStride);
+    int width = m_reconPic->getWidth();
+    int height = ((rows - m_numWeightedRows) * g_maxCUHeight);
+    if (rows == numRows)
+        height = ((m_reconPic->getHeight() % g_maxCUHeight) ? (m_reconPic->getHeight() % g_maxCUHeight) : g_maxCUHeight);
+    size_t dstStride = lumaStride;
+
+    // Computing weighted CU rows
+    int shiftNum = IF_INTERNAL_PREC - X265_DEPTH;
+    int local_shift = shift + shiftNum;
+    int local_round = local_shift ? (1 << (local_shift - 1)) : 0;
+    primitives.weightpUniPixel(src, dst, lumaStride, dstStride, width, height, weight, local_round, local_shift, offset);
+
+    // Extending Left & Right
+    primitives.extendRowBorder(dst, dstStride, width, height, marginX);
+
+    // Extending Above
+    if (m_numWeightedRows == 0)
+    {
+        pixel *pixY = fpelPlane - marginX;
+        for (int y = 0; y < marginY; y++)
+        {
+            memcpy(pixY - (y + 1) * dstStride, pixY, dstStride * sizeof(pixel));
+        }
+    }
+
+    // Extending Bottom
+    if (rows == numRows)
+    {
+        pixel *pixY = fpelPlane - marginX + (m_reconPic->getHeight() - 1) * dstStride;
+        for (int y = 0; y < marginY; y++)
+        {
+            memcpy(pixY + (y + 1) * dstStride, pixY, dstStride * sizeof(pixel));
+        }
+    }
+    m_numWeightedRows = rows;
+}
diff -r 0cb0692d6c69 -r db5d34950f77 source/encoder/reference.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/encoder/reference.h	Wed Oct 23 23:37:31 2013 -0500
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ * Copyright (C) 2013 x265 project
+ *
+ * Authors: Steve Borho <steve at borho.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
+ *
+ * This program is also available under a commercial proprietary license.
+ * For more information, contact us at licensing at multicorewareinc.com.
+ *****************************************************************************/
+
+#ifndef X265_REFERENCE_H
+#define X265_REFERENCE_H
+
+#include "primitives.h"
+#include "mv.h"
+
+namespace x265 {
+// private x265 namespace
+
+class TComPicYuv;
+struct WpScalingParam;
+typedef WpScalingParam wpScalingParam;
+
+class MotionReference : public ReferencePlanes
+{
+public:
+
+    MotionReference();
+    ~MotionReference();
+    int  init(TComPicYuv*, wpScalingParam* w = NULL);
+    void applyWeight(int rows, int numRows);
+
+    TComPicYuv      *m_reconPic;
+    pixel           *m_weightBuffer;
+    int              m_numWeightedRows;
+
+protected:
+
+    intptr_t         m_startPad;
+
+    MotionReference& operator =(const MotionReference&);
+};
+}
+
+#endif // ifndef X265_REFERENCE_H


More information about the x265-devel mailing list