<div dir="ltr">I agree. Santhoshini, except for the whitespace fixes and set_globals addition, no changes should be necessary. The max depth is set in SPS already.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 17, 2015 at 11:14 AM, Steve Borho <span dir="ltr"><<a href="mailto:steve@borho.org" target="_blank">steve@borho.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 02/16, <a href="mailto:santhoshini@multicorewareinc.com">santhoshini@multicorewareinc.com</a> wrote:<br>
> # HG changeset patch<br>
> # User Santhoshini Sekar<<a href="mailto:santhoshini@multicorewareinc.com">santhoshini@multicorewareinc.com</a>><br>
> # Date 1424077388 -19800<br>
> #      Mon Feb 16 14:33:08 2015 +0530<br>
> # Node ID 24e3fc60cb4183fff50921a332f0fd0d98cc0f56<br>
> # Parent  59466f1455ce52920eb642cf06db4b4de8d8ff10<br>
> implementation for minimum CU size<br>
><br>
> diff -r 59466f1455ce -r 24e3fc60cb41 source/common/cudata.cpp<br>
> --- a/source/common/cudata.cpp        Mon Feb 16 14:28:19 2015 +0530<br>
> +++ b/source/common/cudata.cpp        Mon Feb 16 14:33:08 2015 +0530<br>
> @@ -2066,14 +2066,14 @@<br>
><br>
>  #define CU_SET_FLAG(bitfield, flag, value) (bitfield) = ((bitfield) & (~(flag))) | ((~((value) - 1)) & (flag))<br>
><br>
> -void CUData::calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS])<br>
> +void CUData::calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, uint32_t minCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS])<br>
>  {<br>
>      // Initialize the coding blocks inside the CTB<br>
> -    for (uint32_t log2CUSize = g_log2Size[maxCUSize], rangeCUIdx = 0; log2CUSize >= MIN_LOG2_CU_SIZE; log2CUSize--)<br>
> +    for (uint32_t log2CUSize = g_log2Size[maxCUSize], rangeCUIdx = 0; log2CUSize >= g_log2Size[minCUSize]; log2CUSize--)<br>
>      {<br>
>          uint32_t blockSize = 1 << log2CUSize;<br>
>          uint32_t sbWidth   = 1 << (g_log2Size[maxCUSize] - log2CUSize);<br>
> -        int32_t lastLevelFlag = log2CUSize == MIN_LOG2_CU_SIZE;<br>
> +        int32_t lastLevelFlag = log2CUSize == g_log2Size[minCUSize];<br>
>          for (uint32_t sbY = 0; sbY < sbWidth; sbY++)<br>
>          {<br>
>              for (uint32_t sbX = 0; sbX < sbWidth; sbX++)<br>
> diff -r 59466f1455ce -r 24e3fc60cb41 source/common/cudata.h<br>
> --- a/source/common/cudata.h  Mon Feb 16 14:28:19 2015 +0530<br>
> +++ b/source/common/cudata.h  Mon Feb 16 14:33:08 2015 +0530<br>
> @@ -158,7 +158,7 @@<br>
>      CUData();<br>
><br>
>      void     initialize(const CUDataMemPool& dataPool, uint32_t depth, int csp, int instance);<br>
> -    static void calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS]);<br>
> +    static void calcCTUGeoms(uint32_t ctuWidth, uint32_t ctuHeight, uint32_t maxCUSize, uint32_t minCUSize, CUGeom cuDataArray[CUGeom::MAX_GEOMS]);<br>
><br>
>      void     initCTU(const Frame& frame, uint32_t cuAddr, int qp);<br>
>      void     initSubCU(const CUData& ctu, const CUGeom& cuGeom);<br>
> diff -r 59466f1455ce -r 24e3fc60cb41 source/common/param.cpp<br>
> --- a/source/common/param.cpp Mon Feb 16 14:28:19 2015 +0530<br>
> +++ b/source/common/param.cpp Mon Feb 16 14:33:08 2015 +0530<br>
> @@ -127,6 +127,7 @@<br>
><br>
>      /* CU definitions */<br>
>      param->maxCUSize = 64;<br>
> +    param->minCUSize = 8;<br>
>      param->tuQTMaxInterDepth = 1;<br>
>      param->tuQTMaxIntraDepth = 1;<br>
>      param->maxTUSize = 32;<br>
> @@ -978,6 +979,8 @@<br>
>            "x265 was compiled for 8bit encodes, only 8bit internal depth supported");<br>
>  #endif<br>
><br>
> +    CHECK(param->minCUSize != 64 && param->minCUSize != 32 && param->minCUSize != 16 && param->minCUSize != 8,<br>
> +          "minimim CU size must be 8, 16, 32, or 64");<br>
>      CHECK(param->rc.qp < -6 * (param->internalBitDepth - 8) || param->rc.qp > QP_MAX_SPEC,<br>
>            "QP exceeds supported range (-QpBDOffsety to 51)");<br>
>      CHECK(param->fpsNum == 0 || param->fpsDenom == 0,<br>
> @@ -1166,14 +1169,20 @@<br>
>      }<br>
>      else<br>
>      {<br>
> +    if (param->minCUSize > param->maxCUSize)<br>
> +    {<br>
> +        x265_log(param, X265_LOG_WARNING, "Min CU size should be less than or equal to max CU size, setting min CU size = %d\n", param->maxCUSize);<br>
> +        param->minCUSize = param->maxCUSize;<br>
> +    }<br>
<br>
</div></div>w/s here is borked<br>
<span class=""><br>
>          uint32_t maxLog2CUSize = (uint32_t)g_log2Size[param->maxCUSize];<br>
> +        uint32_t minLog2CUSize = (uint32_t)g_log2Size[param->minCUSize];<br>
><br>
>          // set max CU width & height<br>
>          g_maxCUSize     = param->maxCUSize;<br>
>          g_maxLog2CUSize = maxLog2CUSize;<br>
><br>
>          // compute actual CU depth with respect to config depth and max transform size<br>
> -        g_maxCUDepth   = maxLog2CUSize - MIN_LOG2_CU_SIZE;<br>
> +        g_maxCUDepth   = maxLog2CUSize - minLog2CUSize;<br>
>          g_unitSizeDepth = maxLog2CUSize - LOG2_UNIT_SIZE;<br>
<br>
</span>If g_maxCUDepth is going to be based on minLog2CUSize, then we must<br>
validate this in x265_set_globals().<br>
<br>
We have a design decision to make here. We could leave g_maxCUDepth<br>
unmodified here and always signal the min CU size as 8x8 but voluntarily<br>
never split 16x16 (or 32x32) CUs. We will have to signal no-splits at<br>
the lowest remaining level since they will not be implied, this is a<br>
compression cost. Or we can signal the intended min CU size and enforce<br>
this same limit for all encodes in the same process: a loss of<br>
flexibility but a slight gain in compression efficiency.<br>
<br>
I'd love to hear dissenting opinions, but based on what I know most<br>
use-cases that use multiple encodes in a single process will use the<br>
same base preset for all of them.  In that case, it is better to err on<br>
the side of compression efficiency.<br>
<div class="HOEnZb"><div class="h5"><br>
>          // initialize partition order<br>
> @@ -1195,7 +1204,7 @@<br>
>      if (param->interlaceMode)<br>
>          x265_log(param, X265_LOG_INFO, "Interlaced field inputs             : %s\n", x265_interlace_names[param->interlaceMode]);<br>
><br>
> -    x265_log(param, X265_LOG_INFO, "Coding QT: max CU size, min CU size : %d / %d\n", param->maxCUSize, 8);<br>
> +    x265_log(param, X265_LOG_INFO, "Coding QT: max CU size, min CU size : %d / %d\n", param->maxCUSize, param->minCUSize);<br>
><br>
>      x265_log(param, X265_LOG_INFO, "Residual QT: max TU size, max depth : %d / %d inter / %d intra\n",<br>
>               param->maxTUSize, param->tuQTMaxInterDepth, param->tuQTMaxIntraDepth);<br>
> diff -r 59466f1455ce -r 24e3fc60cb41 source/encoder/analysis.cpp<br>
> --- a/source/encoder/analysis.cpp     Mon Feb 16 14:28:19 2015 +0530<br>
> +++ b/source/encoder/analysis.cpp     Mon Feb 16 14:33:08 2015 +0530<br>
> @@ -260,7 +260,7 @@<br>
>          checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL, NULL);<br>
>          checkBestMode(md.pred[PRED_INTRA], depth);<br>
><br>
> -        if (depth == g_maxCUDepth)<br>
> +        if (cuGeom.log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3)<br>
>          {<br>
>              md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);<br>
>              checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL, NULL);<br>
> @@ -472,7 +472,7 @@<br>
>          {<br>
>          case 0:<br>
>              slave->checkIntra(md.pred[PRED_INTRA], *m_curGeom, SIZE_2Nx2N, NULL, NULL);<br>
> -            if (m_curGeom->depth == g_maxCUDepth && m_curGeom->log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)<br>
> +            if (m_curGeom->log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3)<br>
>                  slave->checkIntra(md.pred[PRED_INTRA_NxN], *m_curGeom, SIZE_NxN, NULL, NULL);<br>
>              break;<br>
><br>
> @@ -556,7 +556,7 @@<br>
>          if (bTryIntra)<br>
>          {<br>
>              md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);<br>
> -            if (depth == g_maxCUDepth && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)<br>
> +            if (cuGeom.log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3)<br>
>                  md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);<br>
>          }<br>
><br>
> @@ -704,7 +704,7 @@<br>
>              if (bTryIntra)<br>
>              {<br>
>                  checkBestMode(md.pred[PRED_INTRA], depth);<br>
> -                if (depth == g_maxCUDepth && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)<br>
> +                if (cuGeom.log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3)<br>
>                      checkBestMode(md.pred[PRED_INTRA_NxN], depth);<br>
>              }<br>
>          }<br>
> @@ -1187,7 +1187,7 @@<br>
>                  checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL, NULL);<br>
>                  checkBestMode(md.pred[PRED_INTRA], depth);<br>
><br>
> -                if (depth == g_maxCUDepth && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)<br>
> +                if (cuGeom.log2CUSize == 3 && m_slice->m_sps->quadtreeTULog2MinSize < 3)<br>
>                  {<br>
>                      md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);<br>
>                      checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL, NULL);<br>
> diff -r 59466f1455ce -r 24e3fc60cb41 source/encoder/encoder.cpp<br>
> --- a/source/encoder/encoder.cpp      Mon Feb 16 14:28:19 2015 +0530<br>
> +++ b/source/encoder/encoder.cpp      Mon Feb 16 14:33:08 2015 +0530<br>
> @@ -961,7 +961,7 @@<br>
>                      finalLog.cuInterDistribution[depth][m] += enclog.cuInterDistribution[depth][m];<br>
>                  }<br>
><br>
> -                if (depth == g_maxCUDepth)<br>
> +                if (m_frameEncoder[i]->m_cuGeoms->log2CUSize == 3 && m_sps.quadtreeTULog2MinSize < 3)<br>
>                      finalLog.cntIntraNxN += enclog.cntIntraNxN;<br>
>                  if (sliceType != I_SLICE)<br>
>                  {<br>
> @@ -1054,14 +1054,14 @@<br>
>                                 cuIntraDistribution[1], cuIntraDistribution[2]);<br>
>                  if (sliceType != I_SLICE)<br>
>                  {<br>
> -                    if (depth == g_maxCUDepth)<br>
> +                    if (g_log2Size[cuSize] == 3 && m_sps.quadtreeTULog2MinSize < 3)<br>
>                          len += sprintf(stats + len, " %dx%d "X265_LL "%%", cuSize / 2, cuSize / 2, cntIntraNxN);<br>
>                  }<br>
><br>
>                  len += sprintf(stats + len, ")");<br>
>                  if (sliceType == I_SLICE)<br>
>                  {<br>
> -                    if (depth == g_maxCUDepth)<br>
> +                    if (g_log2Size[cuSize] == 3 && m_sps.quadtreeTULog2MinSize < 3)<br>
>                          len += sprintf(stats + len, " %dx%d: "X265_LL "%%", cuSize / 2, cuSize / 2, cntIntraNxN);<br>
>                  }<br>
>              }<br>
> @@ -1708,10 +1708,10 @@<br>
>      m_conformanceWindow.leftOffset = 0;<br>
><br>
>      /* set pad size if width is not multiple of the minimum CU size */<br>
> -    if (p->sourceWidth & (MIN_CU_SIZE - 1))<br>
> +    if (p->sourceWidth & (p->minCUSize - 1))<br>
>      {<br>
> -        uint32_t rem = p->sourceWidth & (MIN_CU_SIZE - 1);<br>
> -        uint32_t padsize = MIN_CU_SIZE - rem;<br>
> +        uint32_t rem = p->sourceWidth & (p->minCUSize - 1);<br>
> +        uint32_t padsize = p->minCUSize - rem;<br>
>          p->sourceWidth += padsize;<br>
><br>
>          m_conformanceWindow.bEnabled = true;<br>
> @@ -1719,10 +1719,10 @@<br>
>      }<br>
><br>
>      /* set pad size if height is not multiple of the minimum CU size */<br>
> -    if (p->sourceHeight & (MIN_CU_SIZE - 1))<br>
> +    if (p->sourceHeight & (p->minCUSize - 1))<br>
>      {<br>
> -        uint32_t rem = p->sourceHeight & (MIN_CU_SIZE - 1);<br>
> -        uint32_t padsize = MIN_CU_SIZE - rem;<br>
> +        uint32_t rem = p->sourceHeight & (p->minCUSize - 1);<br>
> +        uint32_t padsize = p->minCUSize - rem;<br>
>          p->sourceHeight += padsize;<br>
><br>
>          m_conformanceWindow.bEnabled = true;<br>
> diff -r 59466f1455ce -r 24e3fc60cb41 source/encoder/frameencoder.cpp<br>
> --- a/source/encoder/frameencoder.cpp Mon Feb 16 14:28:19 2015 +0530<br>
> +++ b/source/encoder/frameencoder.cpp Mon Feb 16 14:33:08 2015 +0530<br>
> @@ -143,6 +143,7 @@<br>
>  {<br>
>      /* Geoms only vary between CTUs in the presence of picture edges */<br>
>      int maxCUSize = m_param->maxCUSize;<br>
> +    int minCUSize = m_param->minCUSize;<br>
>      int heightRem = m_param->sourceHeight & (maxCUSize - 1);<br>
>      int widthRem = m_param->sourceWidth & (maxCUSize - 1);<br>
>      int allocGeoms = 1; // body<br>
> @@ -157,7 +158,7 @@<br>
>          return false;<br>
><br>
>      // body<br>
> -    CUData::calcCTUGeoms(maxCUSize, maxCUSize, maxCUSize, m_cuGeoms);<br>
> +    CUData::calcCTUGeoms(maxCUSize, maxCUSize, maxCUSize, minCUSize, m_cuGeoms);<br>
>      memset(m_ctuGeomMap, 0, sizeof(uint32_t) * m_numRows * m_numCols);<br>
>      if (allocGeoms == 1)<br>
>          return true;<br>
> @@ -166,7 +167,7 @@<br>
>      if (widthRem)<br>
>      {<br>
>          // right<br>
> -        CUData::calcCTUGeoms(widthRem, maxCUSize, maxCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);<br>
> +        CUData::calcCTUGeoms(widthRem, maxCUSize, maxCUSize, minCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);<br>
>          for (uint32_t i = 0; i < m_numRows; i++)<br>
>          {<br>
>              uint32_t ctuAddr = m_numCols * (i + 1) - 1;<br>
> @@ -177,7 +178,7 @@<br>
>      if (heightRem)<br>
>      {<br>
>          // bottom<br>
> -        CUData::calcCTUGeoms(maxCUSize, heightRem, maxCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);<br>
> +        CUData::calcCTUGeoms(maxCUSize, heightRem, maxCUSize, minCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);<br>
>          for (uint32_t i = 0; i < m_numCols; i++)<br>
>          {<br>
>              uint32_t ctuAddr = m_numCols * (m_numRows - 1) + i;<br>
> @@ -188,7 +189,7 @@<br>
>          if (widthRem)<br>
>          {<br>
>              // corner<br>
> -            CUData::calcCTUGeoms(widthRem, heightRem, maxCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);<br>
> +            CUData::calcCTUGeoms(widthRem, heightRem, maxCUSize, minCUSize, m_cuGeoms + countGeoms * CUGeom::MAX_GEOMS);<br>
><br>
>              uint32_t ctuAddr = m_numCols * m_numRows - 1;<br>
>              m_ctuGeomMap[ctuAddr] = countGeoms * CUGeom::MAX_GEOMS;<br>
> @@ -1038,7 +1039,7 @@<br>
>              else if (ctu.m_partSize[absPartIdx] != SIZE_2Nx2N)<br>
>              {<br>
>                  /* TODO: log intra modes at absPartIdx +0 to +3 */<br>
> -                X265_CHECK(depth == g_maxCUDepth, "Intra NxN found at improbable depth\n");<br>
> +                X265_CHECK(ctu.m_log2CUSize[absPartIdx] == 3 && ctu.m_slice->m_sps->quadtreeTULog2MinSize < 3, "Intra NxN found at improbable depth\n");<br>
>                  log->cntIntraNxN++;<br>
>                  log->cntIntra[depth]--;<br>
>              }<br>
> @@ -1086,7 +1087,7 @@<br>
><br>
>                  if (ctu.m_partSize[absPartIdx] != SIZE_2Nx2N)<br>
>                  {<br>
> -                    X265_CHECK(depth == g_maxCUDepth, "Intra NxN found at improbable depth\n");<br>
> +                    X265_CHECK(ctu.m_log2CUSize[absPartIdx] == 3 && ctu.m_slice->m_sps->quadtreeTULog2MinSize < 3, "Intra NxN found at improbable depth\n");<br>
>                      log->cntIntraNxN++;<br>
>                      /* TODO: log intra modes at absPartIdx +0 to +3 */<br>
>                  }<br>
> diff -r 59466f1455ce -r 24e3fc60cb41 source/x265.h<br>
> --- a/source/x265.h   Mon Feb 16 14:28:19 2015 +0530<br>
> +++ b/source/x265.h   Mon Feb 16 14:33:08 2015 +0530<br>
> @@ -579,6 +579,10 @@<br>
>       * frame parallelism will become because of the increase in rows. default 64 */<br>
>      uint32_t  maxCUSize;<br>
><br>
> +    /* Miniumum CU width and height in pixels.  The size must be 64, 32, 16, or 8.<br>
> +     * default 8 */<br>
> +    uint32_t  minCUSize;<br>
> +<br>
>      /* Enable rectangular motion prediction partitions (vertical and<br>
>       * horizontal), available at all CU depths from 64x64 to 8x8. Default is<br>
>       * disabled */<br>
> _______________________________________________<br>
> x265-devel mailing list<br>
> <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
> <a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Steve Borho<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</div></div></blockquote></div><br></div>