[x265] [PATCH] encoder:auto-padding to min CU size and set conformance window

Gopu Govindaswamy gopu at multicorewareinc.com
Mon Oct 21 10:42:21 CEST 2013


# HG changeset patch
# User Gopu Govindaswamy <gopu at multicorewareinc.com>
# Date 1382344931 -19800
# Node ID 7171863830432dbdbfaab8e9803a7526c3500088
# Parent  ff8860e0b3082cbb1848e0f5c89e73dc1d7aa87e
encoder:auto-padding to min CU size and set conformance window

diff -r ff8860e0b308 -r 717186383043 source/Lib/TLibCommon/TComPicYuv.cpp
--- a/source/Lib/TLibCommon/TComPicYuv.cpp	Mon Oct 21 13:16:44 2013 +0530
+++ b/source/Lib/TLibCommon/TComPicYuv.cpp	Mon Oct 21 14:12:11 2013 +0530
@@ -357,7 +357,7 @@
  * Upscale pixels from 8bits to 16 bits when required, but do not modify pixels.
  * This new routine is GPL
  */
-void TComPicYuv::copyFromPicture(const x265_picture_t& pic)
+void TComPicYuv::copyFromPicture(const x265_picture_t& pic, int *pad)
 {
     Pel *Y = getLumaAddr();
     Pel *U = getCbAddr();
@@ -367,15 +367,22 @@
     uint8_t *u = (uint8_t*)pic.planes[1];
     uint8_t *v = (uint8_t*)pic.planes[2];
 
+    int padx = pad[0];
+    int pady = pad[1];
+
 #if HIGH_BIT_DEPTH
     if (sizeof(Pel) * 8 > pic.bitDepth)
     {
         assert(pic.bitDepth == 8);
 
+        /* width and height - without padsize */
+        int width = m_picWidth - padx;
+        int height = m_picHeight - pady;
+
         // Manually copy pixels to up-size them
-        for (int r = 0; r < m_picHeight; r++)
+        for (int r = 0; r < height; r++)
         {
-            for (int c = 0; c < m_picWidth; c++)
+            for (int c = 0; c < width; c++)
             {
                 Y[c] = (Pel)y[c];
             }
@@ -384,9 +391,9 @@
             y += pic.stride[0];
         }
 
-        for (int r = 0; r < m_picHeight >> 1; r++)
+        for (int r = 0; r < height >> 1; r++)
         {
-            for (int c = 0; c < m_picWidth >> 1; c++)
+            for (int c = 0; c < width >> 1; c++)
             {
                 U[c] = (Pel)u[c];
                 V[c] = (Pel)v[c];
@@ -397,30 +404,105 @@
             u += pic.stride[1];
             v += pic.stride[2];
         }
+
+        /* Extend the right if width is not multiple of minimum CU size */
+        Y = getLumaAddr();
+        U = getCbAddr();
+        V = getCrAddr();
+
+        if (padx)
+        {
+            for (int r = 0; r < height; r++)
+            {
+                for (int x = 0; x < padx; x++)
+                    Y[width + x] = Y[width - 1];
+                Y += getStride();
+            }
+
+            for (int r = 0; r < height >> 1; r++)
+            {
+                for (int x = 0; x < padx >> 1; x++)
+                {
+                    U[(width >> 1) + x] = U[(width >> 1) - 1];
+                    V[(width >> 1) + x] = V[(width >> 1) - 1];
+                }
+                U += getCStride();
+                V += getCStride();
+            }
+        }
+
+        /* extend the top if height is not multiple of the minimum CU size */
+        if (pady)
+        {
+            Y = getLumaAddr();
+            U = getCbAddr();
+            V = getCrAddr();
+
+            for (uint32_t i = 0; i < pady; i++)
+                memcpy(Y - (i + 1) * getStride(), Y, getStride() * sizeof(Pel));
+
+            for (uint32_t y = 0; y < pady; y++)
+            {
+                memcpy(U - (y + 1) * getCStride(), U, getCStride() * sizeof(Pel));
+                memcpy(V - (y + 1) * getCStride(), V, getCStride() * sizeof(Pel));
+            }
+        }
     }
     else
 #endif // if HIGH_BIT_DEPTH
     {
-        int width = m_picWidth * (pic.bitDepth > 8 ? 2 : 1);
+
+        /* width and height - without padsize */
+        int width = (m_picWidth * (pic.bitDepth > 8 ? 2 : 1)) - padx;
+        int height = m_picHeight - pady;
 
         // copy pixels by row into encoder's buffer
-        for (int r = 0; r < m_picHeight; r++)
+        for (int r = 0; r < height; r++)
         {
             memcpy(Y, y, width);
 
+            /* extend the right if width is not multiple of the minimum CU size */
+            if (padx)
+                ::memset(Y + width, Y[width - 1], padx);
+
             Y += getStride();
             y += pic.stride[0];
+
         }
 
-        for (int r = 0; r < m_picHeight >> 1; r++)
+        for (int r = 0; r < height >> 1; r++)
         {
             memcpy(U, u, width >> 1);
             memcpy(V, v, width >> 1);
 
+            /* extend the right if width is not multiple of the minimum CU size */
+            if (padx)
+            {
+                ::memset(U + (width >> 1), U[(width >> 1) - 1], padx >> 1);
+                ::memset(V + (width >> 1), V[(width >> 1) - 1], padx >> 1);
+            }
+
             U += getCStride();
             V += getCStride();
             u += pic.stride[1];
             v += pic.stride[2];
         }
+
+        /* extend the top if height is not multiple of the minimum CU size */
+        if (pady)
+        {
+            Y = getLumaAddr();
+            U = getCbAddr();
+            V = getCrAddr();
+
+            for (uint32_t i = 0; i < pady; i++)
+                memcpy(Y - (i + 1) * getStride(), Y, getStride() * sizeof(pixel));
+
+            for (uint32_t y = 0; y < pady; y++)
+            {
+                memcpy(U - (y + 1) * getCStride(), U, getCStride() * sizeof(pixel));
+                memcpy(V - (y + 1) * getCStride(), V, getCStride() * sizeof(pixel));
+            }
+        }
     }
 }
diff -r ff8860e0b308 -r 717186383043 source/Lib/TLibCommon/TComPicYuv.h
--- a/source/Lib/TLibCommon/TComPicYuv.h	Mon Oct 21 13:16:44 2013 +0530
+++ b/source/Lib/TLibCommon/TComPicYuv.h	Mon Oct 21 14:12:11 2013 +0530
@@ -178,7 +178,7 @@
     void  copyToPicLuma(TComPicYuv* destYuv);
     void  copyToPicCb(TComPicYuv* destYuv);
     void  copyToPicCr(TComPicYuv* destYuv);
-    void  copyFromPicture(const x265_picture_t&);
+    void  copyFromPicture(const x265_picture_t&, int *pad);
 
     MotionReference* generateMotionReference(wpScalingParam *w);
 
diff -r ff8860e0b308 -r 717186383043 source/Lib/TLibCommon/TComSlice.h
--- a/source/Lib/TLibCommon/TComSlice.h	Mon Oct 21 13:16:44 2013 +0530
+++ b/source/Lib/TLibCommon/TComSlice.h	Mon Oct 21 14:12:11 2013 +0530
@@ -558,7 +558,7 @@
 
 class Window
 {
-private:
+public:
 
     bool          m_enabledFlag;
     int           m_winLeftOffset;
@@ -566,8 +566,6 @@
     int           m_winTopOffset;
     int           m_winBottomOffset;
 
-public:
-
     Window()
         : m_enabledFlag(false)
         , m_winLeftOffset(0)
diff -r ff8860e0b308 -r 717186383043 source/common/common.cpp
--- a/source/common/common.cpp	Mon Oct 21 13:16:44 2013 +0530
+++ b/source/common/common.cpp	Mon Oct 21 14:12:11 2013 +0530
@@ -250,10 +250,6 @@
           "Minimum partition width size should be larger than or equal to 8");
     CHECK(param->maxCUSize < 16,
           "Maximum partition width size should be larger than or equal to 16");
-    CHECK((param->sourceWidth  % (param->maxCUSize >> (maxCUDepth - 1))) != 0,
-          "Resulting coded frame width must be a multiple of the minimum CU size");
-    CHECK((param->sourceHeight % (param->maxCUSize >> (maxCUDepth - 1))) != 0,
-          "Resulting coded frame height must be a multiple of the minimum CU size");
 
     CHECK((1u << tuQTMaxLog2Size) > param->maxCUSize,
           "QuadtreeTULog2MaxSize must be log2(maxCUSize) or smaller.");
diff -r ff8860e0b308 -r 717186383043 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Mon Oct 21 13:16:44 2013 +0530
+++ b/source/encoder/encoder.cpp	Mon Oct 21 14:12:11 2013 +0530
@@ -180,7 +180,7 @@
 
         /* Copy input picture into a TComPic, send to lookahead */
         pic->getSlice()->setPOC(++m_pocLast);
-        pic->getPicYuvOrg()->copyFromPicture(*pic_in);
+        pic->getPicYuvOrg()->copyFromPicture(*pic_in, m_pad);
         pic->m_userData = pic_in->userData;
         pic->m_pts = pic_in->pts;
 
@@ -972,9 +972,36 @@
     m_maxCuDQPDepth = 0;
     m_maxNumOffsetsPerPic = 2048;
     m_log2ParallelMergeLevelMinus2 = 0;
-    m_conformanceWindow.setWindow(0, 0, 0, 0);
-    int nullpad[2] = { 0, 0 };
-    setPad(nullpad);
+    m_pad[0] = m_pad[1] = 0;
+
+    //======== set pad size if width is not multiple of the minimum CU size =========
+    uint32_t maxCUDepth = (uint32_t)g_convertToBit[_param->maxCUSize];
+    uint32_t minCUDepth = (_param->maxCUSize >> (maxCUDepth - 1));
+    if ((_param->sourceWidth % minCUDepth) != 0)
+    {
+        uint32_t padsize = 0;
+        uint32_t rem = _param->sourceWidth % (_param->maxCUSize >> (maxCUDepth - 1));
+        padsize = (_param->maxCUSize >> (maxCUDepth - 1)) - rem;
+        _param->sourceWidth += padsize;
+        m_pad[0] = padsize; //pad width
+    }
+
+    //======== set pad size if height is not multiple of the minimum CU size =========
+    if ((_param->sourceHeight % minCUDepth) != 0)
+    {
+        uint32_t padsize = 0;
+        uint32_t rem = _param->sourceHeight % (_param->maxCUSize >> (maxCUDepth - 1));
+        padsize = (_param->maxCUSize >> (maxCUDepth - 1)) - rem;
+        _param->sourceHeight += padsize;
+        m_pad[1] = padsize; //pad height
+    }
+
+    //======== set the confirmation window ========================================
+    m_conformanceWindow.m_enabledFlag = true;
+    m_conformanceWindow.m_winRightOffset = m_pad[0];
+    m_conformanceWindow.m_winTopOffset = m_pad[1];
+    m_conformanceWindow.m_winBottomOffset = 0;
+    m_conformanceWindow.m_winLeftOffset = 0;
 
     m_progressiveSourceFlag = true;
     m_interlacedSourceFlag = false;


More information about the x265-devel mailing list