[x265] [PATCH 2 of 3 REVIEW] implementation for minimum CU size

Steve Borho steve at borho.org
Mon Feb 16 03:37:33 CET 2015


On 02/13, santhoshini at multicorewareinc.com wrote:
> # HG changeset patch
> # User Santhoshini Sekar<santhoshini at multicorewareinc.com>
> # Date 1423815957 -19800
> #      Fri Feb 13 13:55:57 2015 +0530
> # Node ID 047eba9f4f6208bf2278bd686d2b8e5277f83526
> # Parent  ffb5d5c4dfca93def3bd2fe153070663a63546ea
> implementation for minimum CU size
> 
> diff -r ffb5d5c4dfca -r 047eba9f4f62 source/common/cudata.cpp
> --- a/source/common/cudata.cpp	Fri Feb 13 10:04:50 2015 +0530
> +++ b/source/common/cudata.cpp	Fri Feb 13 13:55:57 2015 +0530
> @@ -2066,14 +2066,14 @@
>  
>  #define CU_SET_FLAG(bitfield, flag, value) (bitfield) = ((bitfield) & (~(flag))) | ((~((value) - 1)) & (flag))
>  
> -void CUData::calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS])
> +void CUData::calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, uint32_t minCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS])
>  {
>      // Initialize the coding blocks inside the CTB
> -    for (uint32_t log2CUSize = g_log2Size[maxCUSize], rangeCUIdx = 0; log2CUSize >= MIN_LOG2_CU_SIZE; log2CUSize--)
> +    for (uint32_t log2CUSize = g_log2Size[maxCUSize], rangeCUIdx = 0; log2CUSize >= g_log2Size[minCUSize]; log2CUSize--)
>      {
>          uint32_t blockSize = 1 << log2CUSize;
>          uint32_t sbWidth   = 1 << (g_log2Size[maxCUSize] - log2CUSize);
> -        int32_t lastLevelFlag = log2CUSize == MIN_LOG2_CU_SIZE;
> +        int32_t lastLevelFlag = log2CUSize == g_log2Size[minCUSize];
>          for (uint32_t sbY = 0; sbY < sbWidth; sbY++)
>          {
>              for (uint32_t sbX = 0; sbX < sbWidth; sbX++)
> diff -r ffb5d5c4dfca -r 047eba9f4f62 source/common/cudata.h
> --- a/source/common/cudata.h	Fri Feb 13 10:04:50 2015 +0530
> +++ b/source/common/cudata.h	Fri Feb 13 13:55:57 2015 +0530
> @@ -158,7 +158,7 @@
>      CUData();
>  
>      void     initialize(const CUDataMemPool& dataPool, uint32_t depth, int csp, int instance);
> -    static void calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS]);
> +    static void calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, uint32_t minCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS]);
>  
>      void     initCTU(const Frame& frame, uint32_t cuAddr, int qp);
>      void     initSubCU(const CUData& ctu, const CUGeom& cuGeom);
> diff -r ffb5d5c4dfca -r 047eba9f4f62 source/common/param.cpp
> --- a/source/common/param.cpp	Fri Feb 13 10:04:50 2015 +0530
> +++ b/source/common/param.cpp	Fri Feb 13 13:55:57 2015 +0530
> @@ -127,6 +127,7 @@
>  
>      /* CU definitions */
>      param->maxCUSize = 64;
> +    param->minCUSize = 8;
>      param->tuQTMaxInterDepth = 1;
>      param->tuQTMaxIntraDepth = 1;
>      param->maxTUSize = 32;
> @@ -978,6 +979,8 @@
>            "x265 was compiled for 8bit encodes, only 8bit internal depth supported");
>  #endif
>  
> +    CHECK(param->minCUSize != 64 && param->minCUSize != 32 && param->minCUSize != 16 && param->minCUSize != 8 || param->minCUSize > param->maxCUSize,
> +          "min ctu size must be 8, 16, 32, or 64 and should be lesser than the max ctu size");

A CTU is a top level CU, and so will always be the largest possible CU.
'min ctu' has no meaning.

>      CHECK(param->rc.qp < -6 * (param->internalBitDepth - 8) || param->rc.qp > QP_MAX_SPEC,
>            "QP exceeds supported range (-QpBDOffsety to 51)");
>      CHECK(param->fpsNum == 0 || param->fpsDenom == 0,
> @@ -1167,13 +1170,14 @@
>      else
>      {
>          uint32_t maxLog2CUSize = (uint32_t)g_log2Size[param->maxCUSize];
> +        uint32_t minLog2CUSize = (uint32_t)g_log2Size[param->minCUSize];
>  
>          // set max CU width & height
>          g_maxCUSize     = param->maxCUSize;
>          g_maxLog2CUSize = maxLog2CUSize;
>  
>          // compute actual CU depth with respect to config depth and max transform size
> -        g_maxCUDepth   = maxLog2CUSize - MIN_LOG2_CU_SIZE;
> +        g_maxCUDepth   = maxLog2CUSize - minLog2CUSize;
>          g_numCUDepth = maxLog2CUSize - LOG2_UNIT_SIZE;
>  
>          // initialize partition order
> @@ -1195,7 +1199,7 @@
>      if (param->interlaceMode)
>          x265_log(param, X265_LOG_INFO, "Interlaced field inputs             : %s\n", x265_interlace_names[param->interlaceMode]);
>  
> -    x265_log(param, X265_LOG_INFO, "Coding QT: max CU size, min CU size : %d / %d\n", param->maxCUSize, 8);
> +    x265_log(param, X265_LOG_INFO, "Coding QT: max CU size, min CU size : %d / %d\n", param->maxCUSize, param->minCUSize);
>  
>      x265_log(param, X265_LOG_INFO, "Residual QT: max TU size, max depth : %d / %d inter / %d intra\n",
>               param->maxTUSize, param->tuQTMaxInterDepth, param->tuQTMaxIntraDepth);
> diff -r ffb5d5c4dfca -r 047eba9f4f62 source/encoder/analysis.cpp
> --- a/source/encoder/analysis.cpp	Fri Feb 13 10:04:50 2015 +0530
> +++ b/source/encoder/analysis.cpp	Fri Feb 13 13:55:57 2015 +0530
> @@ -260,7 +260,7 @@
>          checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL, NULL);
>          checkBestMode(md.pred[PRED_INTRA], depth);
>  
> -        if (depth == g_maxCUDepth)
> +        if (depth == g_maxCUDepth && m_param->minCUSize == 8)

could be simplified as (cuGeom.log2CUSize == 3) (and probably needs the
quadtreeTULog2MinSize check as below)

>          {
>              md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);
>              checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL, NULL);
> @@ -472,7 +472,7 @@
>          {
>          case 0:
>              slave->checkIntra(md.pred[PRED_INTRA], *m_curGeom, SIZE_2Nx2N, NULL, NULL);
> -            if (m_curGeom->depth == g_maxCUDepth && m_curGeom->log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)
> +            if (m_curGeom->depth == g_maxCUDepth && m_param->minCUSize == 8 && m_curGeom->log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)

similarly: (m_curGeom->cuGeom.log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3)

>                  slave->checkIntra(md.pred[PRED_INTRA_NxN], *m_curGeom, SIZE_NxN, NULL, NULL);
>              break;
>  
> @@ -556,7 +556,7 @@
>          if (bTryIntra)
>          {
>              md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
> -            if (depth == g_maxCUDepth && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)
> +            if (depth == g_maxCUDepth && m_param->minCUSize == 8 && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)

ditto for the rest of these

>                  md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);
>          }
>  
> @@ -704,7 +704,7 @@
>              if (bTryIntra)
>              {
>                  checkBestMode(md.pred[PRED_INTRA], depth);
> -                if (depth == g_maxCUDepth && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)
> +                if (depth == g_maxCUDepth && m_param->minCUSize == 8 && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)
>                      checkBestMode(md.pred[PRED_INTRA_NxN], depth);
>              }
>          }
> @@ -1187,7 +1187,7 @@
>                  checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL, NULL);
>                  checkBestMode(md.pred[PRED_INTRA], depth);
>  
> -                if (depth == g_maxCUDepth && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)
> +                if (depth == g_maxCUDepth && m_param->minCUSize == 8 && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)
>                  {
>                      md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);
>                      checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL, NULL);
> diff -r ffb5d5c4dfca -r 047eba9f4f62 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp	Fri Feb 13 10:04:50 2015 +0530
> +++ b/source/encoder/encoder.cpp	Fri Feb 13 13:55:57 2015 +0530
> @@ -954,7 +954,7 @@
>                      finalLog.cuInterDistribution[depth][m] += enclog.cuInterDistribution[depth][m];
>                  }
>  
> -                if (depth == g_maxCUDepth)
> +                if (depth == g_maxCUDepth && m_param->minCUSize == 8)
>                      finalLog.cntIntraNxN += enclog.cntIntraNxN;
>                  if (sliceType != I_SLICE)
>                  {
> @@ -1047,14 +1047,14 @@
>                                 cuIntraDistribution[1], cuIntraDistribution[2]);
>                  if (sliceType != I_SLICE)
>                  {
> -                    if (depth == g_maxCUDepth)
> +                    if (depth == g_maxCUDepth && m_param->minCUSize == 8)
>                          len += sprintf(stats + len, " %dx%d "X265_LL "%%", cuSize / 2, cuSize / 2, cntIntraNxN);
>                  }
>  
>                  len += sprintf(stats + len, ")");
>                  if (sliceType == I_SLICE)
>                  {
> -                    if (depth == g_maxCUDepth)
> +                    if (depth == g_maxCUDepth && m_param->minCUSize == 8)
>                          len += sprintf(stats + len, " %dx%d: "X265_LL "%%", cuSize / 2, cuSize / 2, cntIntraNxN);
>                  }
>              }
> @@ -1695,10 +1695,10 @@
>      m_conformanceWindow.leftOffset = 0;
>  
>      /* set pad size if width is not multiple of the minimum CU size */
> -    if (p->sourceWidth & (MIN_CU_SIZE - 1))
> +    if (p->sourceWidth & (p->minCUSize - 1))
>      {
> -        uint32_t rem = p->sourceWidth & (MIN_CU_SIZE - 1);
> -        uint32_t padsize = MIN_CU_SIZE - rem;
> +        uint32_t rem = p->sourceWidth & (p->minCUSize - 1);
> +        uint32_t padsize = p->minCUSize - rem;
>          p->sourceWidth += padsize;
>  
>          m_conformanceWindow.bEnabled = true;
> @@ -1706,10 +1706,10 @@
>      }
>  
>      /* set pad size if height is not multiple of the minimum CU size */
> -    if (p->sourceHeight & (MIN_CU_SIZE - 1))
> +    if (p->sourceHeight & (p->minCUSize - 1))
>      {
> -        uint32_t rem = p->sourceHeight & (MIN_CU_SIZE - 1);
> -        uint32_t padsize = MIN_CU_SIZE - rem;
> +        uint32_t rem = p->sourceHeight & (p->minCUSize - 1);
> +        uint32_t padsize = p->minCUSize - rem;
>          p->sourceHeight += padsize;
>  
>          m_conformanceWindow.bEnabled = true;
> diff -r ffb5d5c4dfca -r 047eba9f4f62 source/encoder/frameencoder.cpp
> --- a/source/encoder/frameencoder.cpp	Fri Feb 13 10:04:50 2015 +0530
> +++ b/source/encoder/frameencoder.cpp	Fri Feb 13 13:55:57 2015 +0530
> @@ -143,6 +143,7 @@
>  {
>      /* Geoms only vary between CTUs in the presence of picture edges */
>      int maxCUSize = m_param->maxCUSize;
> +    int minCUSize = m_param->minCUSize;
>      int heightRem = m_param->sourceHeight & (maxCUSize - 1);
>      int widthRem = m_param->sourceWidth & (maxCUSize - 1);
>      int allocGeoms = 1; // body
> @@ -157,7 +158,7 @@
>          return false;
>  
>      // body
> -    CUData::calcCTUGeoms(maxCUSize, maxCUSize, maxCUSize, m_cuGeoms);
> +    CUData::calcCTUGeoms(maxCUSize, maxCUSize, maxCUSize, minCUSize, m_cuGeoms);
>      memset(m_ctuGeomMap, 0, sizeof(uint32_t) * m_numRows * m_numCols);
>      if (allocGeoms == 1)
>          return true;
> @@ -166,7 +167,7 @@
>      if (widthRem)
>      {
>          // right
> -        CUData::calcCTUGeoms(widthRem, maxCUSize, maxCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);
> +        CUData::calcCTUGeoms(widthRem, maxCUSize, maxCUSize, minCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);
>          for (uint32_t i = 0; i < m_numRows; i++)
>          {
>              uint32_t ctuAddr = m_numCols * (i + 1) - 1;
> @@ -177,7 +178,7 @@
>      if (heightRem)
>      {
>          // bottom
> -        CUData::calcCTUGeoms(maxCUSize, heightRem, maxCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);
> +        CUData::calcCTUGeoms(maxCUSize, heightRem, maxCUSize, minCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);
>          for (uint32_t i = 0; i < m_numCols; i++)
>          {
>              uint32_t ctuAddr = m_numCols * (m_numRows - 1) + i;
> @@ -188,7 +189,7 @@
>          if (widthRem)
>          {
>              // corner
> -            CUData::calcCTUGeoms(widthRem, heightRem, maxCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);
> +            CUData::calcCTUGeoms(widthRem, heightRem, maxCUSize, minCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);
>  
>              uint32_t ctuAddr = m_numCols * m_numRows - 1;
>              m_ctuGeomMap[ctuAddr] = countGeoms * CUGeom::MAX_GEOMS;
> @@ -1038,7 +1039,7 @@
>              else if (ctu.m_partSize[absPartIdx] != SIZE_2Nx2N)
>              {
>                  /* TODO: log intra modes at absPartIdx +0 to +3 */
> -                X265_CHECK(depth == g_maxCUDepth, "Intra NxN found at improbable depth\n");
> +                X265_CHECK(depth == g_maxCUDepth && m_param->minCUSize == 8, "Intra NxN found at improbable depth\n");
>                  log->cntIntraNxN++;
>                  log->cntIntra[depth]--;
>              }
> @@ -1086,7 +1087,7 @@
>  
>                  if (ctu.m_partSize[absPartIdx] != SIZE_2Nx2N)
>                  {
> -                    X265_CHECK(depth == g_maxCUDepth, "Intra NxN found at improbable depth\n");
> +                    X265_CHECK(depth == g_maxCUDepth && m_param->minCUSize == 8, "Intra NxN found at improbable depth\n");
>                      log->cntIntraNxN++;
>                      /* TODO: log intra modes at absPartIdx +0 to +3 */
>                  }
> diff -r ffb5d5c4dfca -r 047eba9f4f62 source/x265.h
> --- a/source/x265.h	Fri Feb 13 10:04:50 2015 +0530
> +++ b/source/x265.h	Fri Feb 13 13:55:57 2015 +0530
> @@ -598,6 +598,10 @@
>       * by the DCT transforms, at the expense of more computation */
>      uint32_t  maxTUSize;
>  
> +    /* Miniumum CU width and height in pixels.  The size must be 64, 32, 16, or 8.
> +     * default 8 */
> +    uint32_t  minCUSize;
> +

belongs next to maxCUSize

>      /* The additional depth the residual quadtree is allowed to recurse beyond
>       * the coding quadtree, for inter coded blocks. This must be between 1 and
>       * 4. The higher the value the more efficiently the residual can be
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel

-- 
Steve Borho


More information about the x265-devel mailing list