<div dir="ltr">Ashok is already working on pre-calculating these inside-picture flags along with more refactors. After his refactors are in, we can check whether padding will improve performance. <br><br>In fact, very likely he already has a local version of the logic in this patch. <br>

</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Aug 25, 2014 at 10:46 PM, 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="">On 08/25, Satoshi Nakagawa wrote:<br>
> # HG changeset patch<br>
> # User Satoshi Nakagawa <<a href="mailto:nakagawa424@oki.com">nakagawa424@oki.com</a>><br>
> # Date 1408956792 -32400<br>
> #      Mon Aug 25 17:53:12 2014 +0900<br>
> # Node ID 7145e57c722a94a06faec33e3041442032a1892f<br>
> # Parent  6e6756f94b27c3ef30f6159f1880112a7ff978e3<br>
> replace g_rasterToPelX[g_zscanToRaster[idx]] by g_zscanToPelX[idx]<br>
<br>
</div>Queued for default, thanks.<br>
<br>
There seems to be a lot of logic that checks for 'inside picture<br>
bounds'. It seems like we could save a lot of CPU cycles if we padded<br>
input pictures to the max-ctu size instead of the min-ctu size and<br>
adjusted the conformance window accordingly.<br>
<div class="HOEnZb"><div class="h5"><br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/Lib/TLibCommon/TComDataCU.cpp<br>
> --- a/source/Lib/TLibCommon/TComDataCU.cpp    Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/Lib/TLibCommon/TComDataCU.cpp    Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -816,12 +816,12 @@<br>
><br>
>  TComDataCU* TComDataCU::getPUAboveRight(uint32_t& arPartUnitIdx, uint32_t curPartUnitIdx)<br>
>  {<br>
> +    if ((m_pic->getCU(m_cuAddr)->getCUPelX() + g_zscanToPelX[curPartUnitIdx] + UNIT_SIZE) >= m_slice->m_sps->picWidthInLumaSamples)<br>
> +        return NULL;<br>
> +<br>
>      uint32_t absPartIdxRT    = g_zscanToRaster[curPartUnitIdx];<br>
>      uint32_t numPartInCUSize = m_pic->getNumPartInCUSize();<br>
><br>
> -    if ((m_pic->getCU(m_cuAddr)->getCUPelX() + g_rasterToPelX[absPartIdxRT] + UNIT_SIZE) >= m_slice->m_sps->picWidthInLumaSamples)<br>
> -        return NULL;<br>
> -<br>
>      if (RasterAddress::lessThanCol(absPartIdxRT, numPartInCUSize - 1, numPartInCUSize))<br>
>      {<br>
>          if (!RasterAddress::isZeroRow(absPartIdxRT, numPartInCUSize))<br>
> @@ -857,14 +857,11 @@<br>
><br>
>  TComDataCU* TComDataCU::getPUBelowLeft(uint32_t& blPartUnitIdx, uint32_t curPartUnitIdx)<br>
>  {<br>
> -    uint32_t absPartIdxLB     = g_zscanToRaster[curPartUnitIdx];<br>
> +    if ((m_pic->getCU(m_cuAddr)->getCUPelY() + g_zscanToPelY[curPartUnitIdx] + UNIT_SIZE) >= m_slice->m_sps->picHeightInLumaSamples)<br>
> +        return NULL;<br>
><br>
> -    if ((m_pic->getCU(m_cuAddr)->getCUPelY() + g_rasterToPelY[absPartIdxLB] + UNIT_SIZE) >= m_slice->m_sps->picHeightInLumaSamples)<br>
> -    {<br>
> -        return NULL;<br>
> -    }<br>
> -<br>
> -    uint32_t numPartInCUSize  = m_pic->getNumPartInCUSize();<br>
> +    uint32_t absPartIdxLB    = g_zscanToRaster[curPartUnitIdx];<br>
> +    uint32_t numPartInCUSize = m_pic->getNumPartInCUSize();<br>
><br>
>      if (RasterAddress::lessThanRow(absPartIdxLB, numPartInCUSize - 1, numPartInCUSize))<br>
>      {<br>
> @@ -895,15 +892,14 @@<br>
><br>
>  TComDataCU* TComDataCU::getPUBelowLeftAdi(uint32_t& blPartUnitIdx,  uint32_t curPartUnitIdx, uint32_t partUnitOffset)<br>
>  {<br>
> -    uint32_t absPartIdxLB     = g_zscanToRaster[curPartUnitIdx];<br>
> -<br>
> -    if ((m_pic->getCU(m_cuAddr)->getCUPelY() + g_rasterToPelY[absPartIdxLB] + (partUnitOffset << LOG2_UNIT_SIZE)) >=<br>
> +    if ((m_pic->getCU(m_cuAddr)->getCUPelY() + g_zscanToPelY[curPartUnitIdx] + (partUnitOffset << LOG2_UNIT_SIZE)) >=<br>
>          m_slice->m_sps->picHeightInLumaSamples)<br>
>      {<br>
>          return NULL;<br>
>      }<br>
><br>
> -    uint32_t numPartInCUSize  = m_pic->getNumPartInCUSize();<br>
> +    uint32_t absPartIdxLB    = g_zscanToRaster[curPartUnitIdx];<br>
> +    uint32_t numPartInCUSize = m_pic->getNumPartInCUSize();<br>
><br>
>      if (RasterAddress::lessThanRow(absPartIdxLB, numPartInCUSize - partUnitOffset, numPartInCUSize))<br>
>      {<br>
> @@ -938,14 +934,13 @@<br>
><br>
>  TComDataCU* TComDataCU::getPUAboveRightAdi(uint32_t& arPartUnitIdx, uint32_t curPartUnitIdx, uint32_t partUnitOffset)<br>
>  {<br>
> -    uint32_t absPartIdxRT    = g_zscanToRaster[curPartUnitIdx];<br>
> -<br>
> -    if ((m_pic->getCU(m_cuAddr)->getCUPelX() + g_rasterToPelX[absPartIdxRT] + (partUnitOffset << LOG2_UNIT_SIZE)) >=<br>
> +    if ((m_pic->getCU(m_cuAddr)->getCUPelX() + g_zscanToPelX[curPartUnitIdx] + (partUnitOffset << LOG2_UNIT_SIZE)) >=<br>
>          m_slice->m_sps->picWidthInLumaSamples)<br>
>      {<br>
>          return NULL;<br>
>      }<br>
><br>
> +    uint32_t absPartIdxRT    = g_zscanToRaster[curPartUnitIdx];<br>
>      uint32_t numPartInCUSize = m_pic->getNumPartInCUSize();<br>
><br>
>      if (RasterAddress::lessThanCol(absPartIdxRT, numPartInCUSize - partUnitOffset, numPartInCUSize))<br>
> @@ -954,7 +949,7 @@<br>
>          {<br>
>              if (curPartUnitIdx > g_rasterToZscan[absPartIdxRT - numPartInCUSize + partUnitOffset])<br>
>              {<br>
> -                uint32_t absZorderCUIdx  = g_zscanToRaster[m_absIdxInLCU] + (1 << (m_log2CUSize[0] - LOG2_UNIT_SIZE)) - 1;<br>
> +                uint32_t absZorderCUIdx = g_zscanToRaster[m_absIdxInLCU] + (1 << (m_log2CUSize[0] - LOG2_UNIT_SIZE)) - 1;<br>
>                  arPartUnitIdx = g_rasterToZscan[absPartIdxRT - numPartInCUSize + partUnitOffset];<br>
>                  if (RasterAddress::isEqualRowOrCol(absPartIdxRT, absZorderCUIdx, numPartInCUSize))<br>
>                  {<br>
> @@ -1817,48 +1812,42 @@<br>
>      }<br>
>      // TMVP always enabled<br>
>      {<br>
> -        //>> MTK colocated-RightBottom<br>
> +        MV colmv;<br>
>          uint32_t partIdxRB;<br>
><br>
>          deriveRightBottomIdx(puIdx, partIdxRB);<br>
><br>
> -        uint32_t absPartIdxTmp = g_zscanToRaster[partIdxRB];<br>
> -        uint32_t numPartInCUSize = m_pic->getNumPartInCUSize();<br>
> -<br>
> -        MV colmv;<br>
> -        int refIdx;<br>
>          int lcuIdx = -1;<br>
><br>
> -        if ((m_pic->getCU(m_cuAddr)->getCUPelX() + g_rasterToPelX[absPartIdxTmp] + UNIT_SIZE) >= m_slice->m_sps->picWidthInLumaSamples)  // image boundary check<br>
> +        // image boundary check<br>
> +        if (m_pic->getCU(m_cuAddr)->getCUPelX() + g_zscanToPelX[partIdxRB] + UNIT_SIZE < m_slice->m_sps->picWidthInLumaSamples &&<br>
> +            m_pic->getCU(m_cuAddr)->getCUPelY() + g_zscanToPelY[partIdxRB] + UNIT_SIZE < m_slice->m_sps->picHeightInLumaSamples)<br>
>          {<br>
> -        }<br>
> -        else if ((m_pic->getCU(m_cuAddr)->getCUPelY() + g_rasterToPelY[absPartIdxTmp] + UNIT_SIZE) >= m_slice->m_sps->picHeightInLumaSamples)<br>
> -        {<br>
> -        }<br>
> -        else<br>
> -        {<br>
> -            if ((absPartIdxTmp % numPartInCUSize < numPartInCUSize - 1) &&        // is not at the last column of LCU<br>
> -                (absPartIdxTmp / numPartInCUSize < numPartInCUSize - 1)) // is not at the last row    of LCU<br>
> +            uint32_t absPartIdxRB = g_zscanToRaster[partIdxRB];<br>
> +            uint32_t numPartInCUSize = m_pic->getNumPartInCUSize();<br>
> +            bool bNotLastCol = RasterAddress::lessThanCol(absPartIdxRB, numPartInCUSize - 1, numPartInCUSize); // is not at the last column of LCU<br>
> +            bool bNotLastRow = RasterAddress::lessThanRow(absPartIdxRB, numPartInCUSize - 1, numPartInCUSize); // is not at the last row    of LCU<br>
> +<br>
> +            if (bNotLastCol && bNotLastRow)<br>
>              {<br>
> -                absPartAddr = g_rasterToZscan[absPartIdxTmp + numPartInCUSize + 1];<br>
> +                absPartAddr = g_rasterToZscan[absPartIdxRB + numPartInCUSize + 1];<br>
>                  lcuIdx = getAddr();<br>
>              }<br>
> -            else if (absPartIdxTmp % numPartInCUSize < numPartInCUSize - 1)       // is not at the last column of LCU But is last row of LCU<br>
> -                absPartAddr = g_rasterToZscan[(absPartIdxTmp + numPartInCUSize + 1) % m_pic->getNumPartInCU()];<br>
> -            else if (absPartIdxTmp / numPartInCUSize < numPartInCUSize - 1) // is not at the last row of LCU But is last column of LCU<br>
> +            else if (bNotLastCol)<br>
> +                absPartAddr = g_rasterToZscan[(absPartIdxRB + numPartInCUSize + 1) & (numPartInCUSize - 1)];<br>
> +            else if (bNotLastRow)<br>
>              {<br>
> -                absPartAddr = g_rasterToZscan[absPartIdxTmp + 1];<br>
> +                absPartAddr = g_rasterToZscan[absPartIdxRB + 1];<br>
>                  lcuIdx = getAddr() + 1;<br>
>              }<br>
> -            else //is the right bottom corner of LCU<br>
> +            else // is the right bottom corner of LCU<br>
>                  absPartAddr = 0;<br>
>          }<br>
><br>
> -        refIdx = 0;<br>
> +        int refIdx = 0;<br>
>          uint32_t partIdxCenter;<br>
>          uint32_t curLCUIdx = getAddr();<br>
>          int dir = 0;<br>
> -        uint32_t arrayAddr = count;<br>
>          xDeriveCenterIdx(puIdx, partIdxCenter);<br>
>          bool bExistMV = lcuIdx >= 0 && xGetColMVP(REF_PIC_LIST_0, lcuIdx, absPartAddr, colmv, refIdx);<br>
>          if (!bExistMV)<br>
> @@ -1866,7 +1855,7 @@<br>
>          if (bExistMV)<br>
>          {<br>
>              dir |= 1;<br>
> -            mvFieldNeighbours[arrayAddr][0].setMvField(colmv, refIdx);<br>
> +            mvFieldNeighbours[count][0].setMvField(colmv, refIdx);<br>
>          }<br>
><br>
>          if (isInterB)<br>
> @@ -1878,13 +1867,13 @@<br>
>              if (bExistMV)<br>
>              {<br>
>                  dir |= 2;<br>
> -                mvFieldNeighbours[arrayAddr][1].setMvField(colmv, refIdx);<br>
> +                mvFieldNeighbours[count][1].setMvField(colmv, refIdx);<br>
>              }<br>
>          }<br>
><br>
>          if (dir != 0)<br>
>          {<br>
> -            interDirNeighbours[arrayAddr] = dir;<br>
> +            interDirNeighbours[count] = dir;<br>
><br>
>              count++;<br>
><br>
> @@ -1893,8 +1882,6 @@<br>
>          }<br>
>      }<br>
><br>
> -    uint32_t arrayAddr = count;<br>
> -<br>
>      if (isInterB)<br>
>      {<br>
>          const uint32_t cutoff = count * (count - 1);<br>
> @@ -1917,13 +1904,13 @@<br>
>                  int refPOCL1 = m_slice->m_refPOCList[1][refIdxL1];<br>
>                  if (!(refPOCL0 == refPOCL1 && mvFieldNeighbours[i][0].mv == mvFieldNeighbours[j][1].mv))<br>
>                  {<br>
> -                    mvFieldNeighbours[arrayAddr][0].setMvField(mvFieldNeighbours[i][0].mv, refIdxL0);<br>
> -                    mvFieldNeighbours[arrayAddr][1].setMvField(mvFieldNeighbours[j][1].mv, refIdxL1);<br>
> -                    interDirNeighbours[arrayAddr] = 3;<br>
> +                    mvFieldNeighbours[count][0].setMvField(mvFieldNeighbours[i][0].mv, refIdxL0);<br>
> +                    mvFieldNeighbours[count][1].setMvField(mvFieldNeighbours[j][1].mv, refIdxL1);<br>
> +                    interDirNeighbours[count] = 3;<br>
><br>
> -                    arrayAddr++;<br>
> +                    count++;<br>
><br>
> -                    if (arrayAddr == maxNumMergeCand)<br>
> +                    if (count == maxNumMergeCand)<br>
>                          return;<br>
>                  }<br>
>              }<br>
> @@ -1932,18 +1919,18 @@<br>
>      int numRefIdx = (isInterB) ? X265_MIN(m_slice->m_numRefIdx[0], m_slice->m_numRefIdx[1]) : m_slice->m_numRefIdx[0];<br>
>      int r = 0;<br>
>      int refcnt = 0;<br>
> -    while (arrayAddr < maxNumMergeCand)<br>
> +    while (count < maxNumMergeCand)<br>
>      {<br>
> -        interDirNeighbours[arrayAddr] = 1;<br>
> -        mvFieldNeighbours[arrayAddr][0].setMvField(MV(0, 0), r);<br>
> +        interDirNeighbours[count] = 1;<br>
> +        mvFieldNeighbours[count][0].setMvField(MV(0, 0), r);<br>
><br>
>          if (isInterB)<br>
>          {<br>
> -            interDirNeighbours[arrayAddr] = 3;<br>
> -            mvFieldNeighbours[arrayAddr][1].setMvField(MV(0, 0), r);<br>
> +            interDirNeighbours[count] = 3;<br>
> +            mvFieldNeighbours[count][1].setMvField(MV(0, 0), r);<br>
>          }<br>
><br>
> -        arrayAddr++;<br>
> +        count++;<br>
><br>
>          if (refcnt == numRefIdx - 1)<br>
>              r = 0;<br>
> @@ -2078,45 +2065,40 @@<br>
><br>
>      // TMVP always enabled<br>
>      {<br>
> -        // Get Temporal Motion Predictor<br>
> -        int refIdxCol = refIdx;<br>
> -        MV  colmv;<br>
> +        uint32_t absPartAddr = m_absIdxInLCU + partAddr;<br>
> +        MV colmv;<br>
>          uint32_t partIdxRB;<br>
> -        uint32_t absPartIdx;<br>
> -        uint32_t absPartAddr;<br>
><br>
>          deriveRightBottomIdx(partIdx, partIdxRB);<br>
> -        absPartAddr = m_absIdxInLCU + partAddr;<br>
><br>
>          //----  co-located RightBottom Temporal Predictor (H) ---//<br>
> -        absPartIdx = g_zscanToRaster[partIdxRB];<br>
>          int lcuIdx = -1;<br>
> -        if ((m_pic->getCU(m_cuAddr)->getCUPelX() + g_rasterToPelX[absPartIdx] + UNIT_SIZE) >= m_slice->m_sps->picWidthInLumaSamples)  // image boundary check<br>
> +<br>
> +        // image boundary check<br>
> +        if (m_pic->getCU(m_cuAddr)->getCUPelX() + g_zscanToPelX[partIdxRB] + UNIT_SIZE < m_slice->m_sps->picWidthInLumaSamples &&<br>
> +            m_pic->getCU(m_cuAddr)->getCUPelY() + g_zscanToPelY[partIdxRB] + UNIT_SIZE < m_slice->m_sps->picHeightInLumaSamples)<br>
>          {<br>
> -        }<br>
> -        else if ((m_pic->getCU(m_cuAddr)->getCUPelY() + g_rasterToPelY[absPartIdx] + UNIT_SIZE) >= m_slice->m_sps->picHeightInLumaSamples)<br>
> -        {<br>
> -        }<br>
> -        else<br>
> -        {<br>
> +            uint32_t absPartIdxRB = g_zscanToRaster[partIdxRB];<br>
>              uint32_t numPartInCUSize = m_pic->getNumPartInCUSize();<br>
> -            if ((absPartIdx % numPartInCUSize < numPartInCUSize - 1) && // is not at the last column of LCU<br>
> -                (absPartIdx / numPartInCUSize < numPartInCUSize - 1))   // is not at the last row    of LCU<br>
> +            bool bNotLastCol = RasterAddress::lessThanCol(absPartIdxRB, numPartInCUSize - 1, numPartInCUSize); // is not at the last column of LCU<br>
> +            bool bNotLastRow = RasterAddress::lessThanRow(absPartIdxRB, numPartInCUSize - 1, numPartInCUSize); // is not at the last row    of LCU<br>
> +<br>
> +            if (bNotLastCol && bNotLastRow)<br>
>              {<br>
> -                absPartAddr = g_rasterToZscan[absPartIdx + numPartInCUSize + 1];<br>
> +                absPartAddr = g_rasterToZscan[absPartIdxRB + numPartInCUSize + 1];<br>
>                  lcuIdx = getAddr();<br>
>              }<br>
> -            else if (absPartIdx % numPartInCUSize < numPartInCUSize - 1) // is not at the last column of LCU But is last row of LCU<br>
> -                absPartAddr = g_rasterToZscan[(absPartIdx + numPartInCUSize + 1) % m_pic->getNumPartInCU()];<br>
> -            else if (absPartIdx / numPartInCUSize < numPartInCUSize - 1) // is not at the last row of LCU But is last column of LCU<br>
> +            else if (bNotLastCol)<br>
> +                absPartAddr = g_rasterToZscan[(absPartIdxRB + numPartInCUSize + 1) & (numPartInCUSize - 1)];<br>
> +            else if (bNotLastRow)<br>
>              {<br>
> -                absPartAddr = g_rasterToZscan[absPartIdx + 1];<br>
> +                absPartAddr = g_rasterToZscan[absPartIdxRB + 1];<br>
>                  lcuIdx = getAddr() + 1;<br>
>              }<br>
>              else // is the right bottom corner of LCU<br>
>                  absPartAddr = 0;<br>
>          }<br>
> -        if (lcuIdx >= 0 && xGetColMVP(picList, lcuIdx, absPartAddr, colmv, refIdxCol))<br>
> +        if (lcuIdx >= 0 && xGetColMVP(picList, lcuIdx, absPartAddr, colmv, refIdx))<br>
>          {<br>
>              amvpCand[num++] = colmv;<br>
>              mvc[numMvc++] = colmv;<br>
> @@ -2126,7 +2108,7 @@<br>
>              uint32_t partIdxCenter;<br>
>              uint32_t curLCUIdx = getAddr();<br>
>              xDeriveCenterIdx(partIdx, partIdxCenter);<br>
> -            if (xGetColMVP(picList, curLCUIdx, partIdxCenter, colmv, refIdxCol))<br>
> +            if (xGetColMVP(picList, curLCUIdx, partIdxCenter, colmv, refIdx))<br>
>              {<br>
>                  amvpCand[num++] = colmv;<br>
>                  mvc[numMvc++] = colmv;<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/Lib/TLibCommon/TComRom.cpp<br>
> --- a/source/Lib/TLibCommon/TComRom.cpp       Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/Lib/TLibCommon/TComRom.cpp       Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -117,8 +117,46 @@<br>
>  uint32_t g_maxCUDepth    = NUM_CU_DEPTH - 1;<br>
>  uint32_t g_zscanToRaster[MAX_NUM_SPU_W * MAX_NUM_SPU_W] = { 0, };<br>
>  uint32_t g_rasterToZscan[MAX_NUM_SPU_W * MAX_NUM_SPU_W] = { 0, };<br>
> -uint32_t g_rasterToPelX[MAX_NUM_SPU_W * MAX_NUM_SPU_W] = { 0, };<br>
> -uint32_t g_rasterToPelY[MAX_NUM_SPU_W * MAX_NUM_SPU_W] = { 0, };<br>
> +<br>
> +const uint8_t g_zscanToPelX[MAX_NUM_SPU_W * MAX_NUM_SPU_W] =<br>
> +{<br>
> +    0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12,<br>
> +    16, 20, 16, 20, 24, 28, 24, 28, 16, 20, 16, 20, 24, 28, 24, 28,<br>
> +    0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12,<br>
> +    16, 20, 16, 20, 24, 28, 24, 28, 16, 20, 16, 20, 24, 28, 24, 28,<br>
> +    32, 36, 32, 36, 40, 44, 40, 44, 32, 36, 32, 36, 40, 44, 40, 44,<br>
> +    48, 52, 48, 52, 56, 60, 56, 60, 48, 52, 48, 52, 56, 60, 56, 60,<br>
> +    32, 36, 32, 36, 40, 44, 40, 44, 32, 36, 32, 36, 40, 44, 40, 44,<br>
> +    48, 52, 48, 52, 56, 60, 56, 60, 48, 52, 48, 52, 56, 60, 56, 60,<br>
> +    0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12,<br>
> +    16, 20, 16, 20, 24, 28, 24, 28, 16, 20, 16, 20, 24, 28, 24, 28,<br>
> +    0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12,<br>
> +    16, 20, 16, 20, 24, 28, 24, 28, 16, 20, 16, 20, 24, 28, 24, 28,<br>
> +    32, 36, 32, 36, 40, 44, 40, 44, 32, 36, 32, 36, 40, 44, 40, 44,<br>
> +    48, 52, 48, 52, 56, 60, 56, 60, 48, 52, 48, 52, 56, 60, 56, 60,<br>
> +    32, 36, 32, 36, 40, 44, 40, 44, 32, 36, 32, 36, 40, 44, 40, 44,<br>
> +    48, 52, 48, 52, 56, 60, 56, 60, 48, 52, 48, 52, 56, 60, 56, 60<br>
> +};<br>
> +<br>
> +const uint8_t g_zscanToPelY[MAX_NUM_SPU_W * MAX_NUM_SPU_W] =<br>
> +{<br>
> +    0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12,<br>
> +    0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12,<br>
> +    16, 16, 20, 20, 16, 16, 20, 20, 24, 24, 28, 28, 24, 24, 28, 28,<br>
> +    16, 16, 20, 20, 16, 16, 20, 20, 24, 24, 28, 28, 24, 24, 28, 28,<br>
> +    0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12,<br>
> +    0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12,<br>
> +    16, 16, 20, 20, 16, 16, 20, 20, 24, 24, 28, 28, 24, 24, 28, 28,<br>
> +    16, 16, 20, 20, 16, 16, 20, 20, 24, 24, 28, 28, 24, 24, 28, 28,<br>
> +    32, 32, 36, 36, 32, 32, 36, 36, 40, 40, 44, 44, 40, 40, 44, 44,<br>
> +    32, 32, 36, 36, 32, 32, 36, 36, 40, 40, 44, 44, 40, 40, 44, 44,<br>
> +    48, 48, 52, 52, 48, 48, 52, 52, 56, 56, 60, 60, 56, 56, 60, 60,<br>
> +    48, 48, 52, 52, 48, 48, 52, 52, 56, 56, 60, 60, 56, 56, 60, 60,<br>
> +    32, 32, 36, 36, 32, 32, 36, 36, 40, 40, 44, 44, 40, 40, 44, 44,<br>
> +    32, 32, 36, 36, 32, 32, 36, 36, 40, 40, 44, 44, 40, 40, 44, 44,<br>
> +    48, 48, 52, 52, 48, 48, 52, 52, 56, 56, 60, 60, 56, 56, 60, 60,<br>
> +    48, 48, 52, 52, 48, 48, 52, 52, 56, 56, 60, 60, 56, 56, 60, 60<br>
> +};<br>
><br>
>  const uint32_t g_puOffset[8] = { 0, 8, 4, 4, 2, 10, 1, 5 };<br>
><br>
> @@ -151,36 +189,6 @@<br>
>      }<br>
>  }<br>
><br>
> -void initRasterToPelXY(uint32_t maxFullDepth)<br>
> -{<br>
> -    uint32_t i;<br>
> -<br>
> -    uint32_t* tempX = &g_rasterToPelX[0];<br>
> -    uint32_t* tempY = &g_rasterToPelY[0];<br>
> -<br>
> -    uint32_t numPartInCUSize = 1 << maxFullDepth;<br>
> -    uint32_t numPartitions   = 1 << maxFullDepth * 2;<br>
> -<br>
> -    tempX[0] = 0;<br>
> -    tempX++;<br>
> -    for (i = 1; i < numPartInCUSize; i++)<br>
> -    {<br>
> -        tempX[0] = tempX[-1] + UNIT_SIZE;<br>
> -        tempX++;<br>
> -    }<br>
> -<br>
> -    for (i = 1; i < numPartInCUSize; i++)<br>
> -    {<br>
> -        memcpy(tempX, tempX - numPartInCUSize, sizeof(uint32_t) * numPartInCUSize);<br>
> -        tempX += numPartInCUSize;<br>
> -    }<br>
> -<br>
> -    for (i = 1; i < numPartitions; i++)<br>
> -    {<br>
> -        tempY[i] = (i >> maxFullDepth) * UNIT_SIZE;<br>
> -    }<br>
> -}<br>
> -<br>
>  const int16_t g_lumaFilter[4][NTAPS_LUMA] =<br>
>  {<br>
>      {  0, 0,   0, 64,  0,   0, 0,  0 },<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/Lib/TLibCommon/TComRom.h<br>
> --- a/source/Lib/TLibCommon/TComRom.h Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/Lib/TLibCommon/TComRom.h Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -82,10 +82,8 @@<br>
>  void initRasterToZscan(uint32_t maxFullDepth);<br>
><br>
>  // conversion of partition index to picture pel position<br>
> -extern uint32_t g_rasterToPelX[MAX_NUM_SPU_W * MAX_NUM_SPU_W];<br>
> -extern uint32_t g_rasterToPelY[MAX_NUM_SPU_W * MAX_NUM_SPU_W];<br>
> -<br>
> -void initRasterToPelXY(uint32_t maxFullDepth);<br>
> +extern const uint8_t g_zscanToPelX[MAX_NUM_SPU_W * MAX_NUM_SPU_W];<br>
> +extern const uint8_t g_zscanToPelY[MAX_NUM_SPU_W * MAX_NUM_SPU_W];<br>
><br>
>  // global variable (LCU width/height, max. CU depth)<br>
>  extern uint32_t g_maxLog2CUSize;<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/Lib/TLibCommon/TComYuv.h<br>
> --- a/source/Lib/TLibCommon/TComYuv.h Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/Lib/TLibCommon/TComYuv.h Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -80,18 +80,18 @@<br>
>      int m_vChromaShift;<br>
>      int m_csp;<br>
><br>
> -    int getChromaAddrOffset(uint32_t partUnitIdx, uint32_t width)<br>
> +    int getChromaAddrOffset(uint32_t idx, uint32_t width)<br>
>      {<br>
> -        int blkX = g_rasterToPelX[g_zscanToRaster[partUnitIdx]] >> m_hChromaShift;<br>
> -        int blkY = g_rasterToPelY[g_zscanToRaster[partUnitIdx]] >> m_vChromaShift;<br>
> +        int blkX = g_zscanToPelX[idx] >> m_hChromaShift;<br>
> +        int blkY = g_zscanToPelY[idx] >> m_vChromaShift;<br>
><br>
>          return blkX + blkY * width;<br>
>      }<br>
><br>
> -    static int getAddrOffset(uint32_t partUnitIdx, uint32_t width)<br>
> +    static int getAddrOffset(uint32_t idx, uint32_t width)<br>
>      {<br>
> -        int blkX = g_rasterToPelX[g_zscanToRaster[partUnitIdx]];<br>
> -        int blkY = g_rasterToPelY[g_zscanToRaster[partUnitIdx]];<br>
> +        int blkX = g_zscanToPelX[idx];<br>
> +        int blkY = g_zscanToPelY[idx];<br>
><br>
>          return blkX + blkY * width;<br>
>      }<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/common/deblock.cpp<br>
> --- a/source/common/deblock.cpp       Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/common/deblock.cpp       Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -49,15 +49,15 @@<br>
><br>
>      Frame* pic = cu->m_pic;<br>
>      uint32_t curNumParts = pic->getNumPartInCU() >> (depth << 1);<br>
> -    uint32_t qNumParts   = curNumParts >> 2;<br>
><br>
>      if (cu->getDepth(absZOrderIdx) > depth)<br>
>      {<br>
> +        uint32_t qNumParts   = curNumParts >> 2;<br>
> +        uint32_t xmax = cu->m_slice->m_sps->picWidthInLumaSamples  - cu->getCUPelX();<br>
> +        uint32_t ymax = cu->m_slice->m_sps->picHeightInLumaSamples - cu->getCUPelY();<br>
>          for (uint32_t partIdx = 0; partIdx < 4; partIdx++, absZOrderIdx += qNumParts)<br>
>          {<br>
> -            uint32_t lpelx = cu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absZOrderIdx]];<br>
> -            uint32_t tpely = cu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absZOrderIdx]];<br>
> -            if ((lpelx < cu->m_slice->m_sps->picWidthInLumaSamples) && (tpely < cu->m_slice->m_sps->picHeightInLumaSamples))<br>
> +            if (g_zscanToPelX[absZOrderIdx] < xmax && g_zscanToPelY[absZOrderIdx] < ymax)<br>
>                  deblockCU(cu, absZOrderIdx, depth + 1, dir, edgeFilter, blockingStrength);<br>
>          }<br>
>          return;<br>
> @@ -184,8 +184,8 @@<br>
><br>
>  void Deblock::setLoopfilterParam(TComDataCU* cu, uint32_t absZOrderIdx, Param *params)<br>
>  {<br>
> -    uint32_t x = cu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absZOrderIdx]];<br>
> -    uint32_t y = cu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absZOrderIdx]];<br>
> +    uint32_t x = cu->getCUPelX() + g_zscanToPelX[absZOrderIdx];<br>
> +    uint32_t y = cu->getCUPelY() + g_zscanToPelY[absZOrderIdx];<br>
><br>
>      TComDataCU* tempCU;<br>
>      uint32_t    tempPartIdx;<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/common/param.cpp<br>
> --- a/source/common/param.cpp Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/common/param.cpp Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -1071,9 +1071,6 @@<br>
>          uint32_t* tmp = &g_zscanToRaster[0];<br>
>          initZscanToRaster(g_maxFullDepth, 1, 0, tmp);<br>
>          initRasterToZscan(g_maxFullDepth);<br>
> -<br>
> -        // initialize conversion matrix from partition index to pel<br>
> -        initRasterToPelXY(g_maxFullDepth);<br>
>      }<br>
>      return 0;<br>
>  }<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/common/shortyuv.h<br>
> --- a/source/common/shortyuv.h        Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/common/shortyuv.h        Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -51,18 +51,18 @@<br>
>      ShortYuv();<br>
>      ~ShortYuv();<br>
><br>
> -    int getChromaAddrOffset(uint32_t partUnitIdx, uint32_t width)<br>
> +    int getChromaAddrOffset(uint32_t idx, uint32_t width)<br>
>      {<br>
> -        int blkX = g_rasterToPelX[g_zscanToRaster[partUnitIdx]] >> m_hChromaShift;<br>
> -        int blkY = g_rasterToPelY[g_zscanToRaster[partUnitIdx]] >> m_vChromaShift;<br>
> +        int blkX = g_zscanToPelX[idx] >> m_hChromaShift;<br>
> +        int blkY = g_zscanToPelY[idx] >> m_vChromaShift;<br>
><br>
>          return blkX + blkY * width;<br>
>      }<br>
><br>
>      static int getAddrOffset(uint32_t idx, uint32_t width)<br>
>      {<br>
> -        int blkX = g_rasterToPelX[g_zscanToRaster[idx]];<br>
> -        int blkY = g_rasterToPelY[g_zscanToRaster[idx]];<br>
> +        int blkX = g_zscanToPelX[idx];<br>
> +        int blkY = g_zscanToPelY[idx];<br>
><br>
>          return blkX + blkY * width;<br>
>      }<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/common/slice.cpp<br>
> --- a/source/common/slice.cpp Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/common/slice.cpp Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -178,3 +178,26 @@<br>
>          bUsed[k] = used;<br>
>      }<br>
>  }<br>
> +<br>
> +uint32_t Slice::realEndAddress(uint32_t endCUAddr)<br>
> +{<br>
> +    // Calculate end address<br>
> +    uint32_t internalAddress = (endCUAddr - 1) % m_pic->getNumPartInCU();<br>
> +    uint32_t externalAddress = (endCUAddr - 1) / m_pic->getNumPartInCU();<br>
> +    uint32_t xmax = m_sps->picWidthInLumaSamples  - (externalAddress % m_pic->getFrameWidthInCU()) * g_maxCUSize;<br>
> +    uint32_t ymax = m_sps->picHeightInLumaSamples - (externalAddress / m_pic->getFrameWidthInCU()) * g_maxCUSize;<br>
> +<br>
> +    while (g_zscanToPelX[internalAddress] >= xmax || g_zscanToPelY[internalAddress] >= ymax)<br>
> +        internalAddress--;<br>
> +<br>
> +    internalAddress++;<br>
> +    if (internalAddress == m_pic->getNumPartInCU())<br>
> +    {<br>
> +        internalAddress = 0;<br>
> +        externalAddress++;<br>
> +    }<br>
> +<br>
> +    return externalAddress * m_pic->getNumPartInCU() + internalAddress;<br>
> +}<br>
> +<br>
> +<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/common/slice.h<br>
> --- a/source/common/slice.h   Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/common/slice.h   Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -335,6 +335,8 @@<br>
>      bool isInterB() const { return m_sliceType == B_SLICE; }<br>
><br>
>      bool isInterP() const { return m_sliceType == P_SLICE; }<br>
> +<br>
> +    uint32_t realEndAddress(uint32_t endCUAddr);<br>
>  };<br>
><br>
>  #define IS_REFERENCED(slice) (slice->m_pic->m_lowres.sliceType != X265_TYPE_B)<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/encoder/analysis.cpp<br>
> --- a/source/encoder/analysis.cpp     Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/encoder/analysis.cpp     Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -548,7 +548,7 @@<br>
>      Slice* slice = outTempCU->m_slice;<br>
>      if (!bInsidePicture)<br>
>      {<br>
> -        int cuSize = 1 << outTempCU->getLog2CUSize(0);<br>
> +        uint32_t cuSize = 1 << outTempCU->getLog2CUSize(0);<br>
>          uint32_t lpelx = outTempCU->getCUPelX();<br>
>          uint32_t tpely = outTempCU->getCUPelY();<br>
>          uint32_t rpelx = lpelx + cuSize;<br>
> @@ -1875,15 +1875,14 @@<br>
>          uint32_t nextDepth = depth + 1;<br>
>          TComDataCU* subTempPartCU = m_tempCU[nextDepth];<br>
>          uint32_t qNumParts = (pic->getNumPartInCU() >> (depth << 1)) >> 2;<br>
> +        uint32_t xmax = slice->m_sps->picWidthInLumaSamples  - lcu->getCUPelX();<br>
> +        uint32_t ymax = slice->m_sps->picHeightInLumaSamples - lcu->getCUPelY();<br>
>          for (uint32_t partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++, absPartIdx += qNumParts)<br>
>          {<br>
> -            uint32_t lpelx = lcu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absPartIdx]];<br>
> -            uint32_t tpely = lcu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absPartIdx]];<br>
> -            if ((lpelx < slice->m_sps->picWidthInLumaSamples) &&<br>
> -                (tpely < slice->m_sps->picHeightInLumaSamples))<br>
> +            if (g_zscanToPelX[absPartIdx] < xmax && g_zscanToPelY[absPartIdx] < ymax)<br>
>              {<br>
> -                subTempPartCU->copyToSubCU(cu, partUnitIdx, depth + 1);<br>
> -                encodeResidue(lcu, subTempPartCU, absPartIdx, depth + 1);<br>
> +                subTempPartCU->copyToSubCU(cu, partUnitIdx, nextDepth);<br>
> +                encodeResidue(lcu, subTempPartCU, absPartIdx, nextDepth);<br>
>              }<br>
>          }<br>
><br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/encoder/encoder.cpp<br>
> --- a/source/encoder/encoder.cpp      Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/encoder/encoder.cpp      Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -441,10 +441,12 @@<br>
>          else<br>
>          {<br>
>              fenc->allocPicSym(m_param);<br>
> -            fenc->m_picSym->m_slice->m_sps = &m_sps;<br>
> -            fenc->m_picSym->m_slice->m_pps = &m_pps;<br>
> -            fenc->m_picSym->m_slice->m_maxNumMergeCand = m_param->maxNumMergeCand;<br>
> -            fenc->m_picSym->m_slice->m_endCUAddr = fenc->getNumCUsInFrame() * fenc->getNumPartInCU();<br>
> +            Slice* slice = fenc->m_picSym->m_slice;<br>
> +            slice->m_pic = fenc;<br>
> +            slice->m_sps = &m_sps;<br>
> +            slice->m_pps = &m_pps;<br>
> +            slice->m_maxNumMergeCand = m_param->maxNumMergeCand;<br>
> +            slice->m_endCUAddr = slice->realEndAddress(fenc->getNumCUsInFrame() * fenc->getNumPartInCU());<br>
>          }<br>
>          curEncoder->m_rce.encodeOrder = m_encodedFrameNum++;<br>
>          if (m_bframeDelay)<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/encoder/entropy.cpp<br>
> --- a/source/encoder/entropy.cpp      Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/encoder/entropy.cpp      Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -493,41 +493,35 @@<br>
>      Frame* pic = cu->m_pic;<br>
>      Slice* slice = cu->m_slice;<br>
><br>
> +    if (depth <= slice->m_pps->maxCuDQPDepth && slice->m_pps->bUseDQP)<br>
> +        bEncodeDQP = true;<br>
> +<br>
>      if (!bInsidePicture)<br>
>      {<br>
> -        uint32_t lpelx = cu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absPartIdx]];<br>
> -        uint32_t tpely = cu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absPartIdx]];<br>
> -        uint32_t rpelx = lpelx + (g_maxCUSize >> depth);<br>
> -        uint32_t bpely = tpely + (g_maxCUSize >> depth);<br>
> -        bInsidePicture = (rpelx <= slice->m_sps->picWidthInLumaSamples &&<br>
> -                          bpely <= slice->m_sps->picHeightInLumaSamples);<br>
> +        uint32_t xmax = slice->m_sps->picWidthInLumaSamples  - cu->getCUPelX();<br>
> +        uint32_t ymax = slice->m_sps->picHeightInLumaSamples - cu->getCUPelY();<br>
> +        uint32_t cuSize = g_maxCUSize >> depth;<br>
> +<br>
> +        bInsidePicture = (g_zscanToPelX[absPartIdx] + cuSize <= xmax &&<br>
> +                          g_zscanToPelY[absPartIdx] + cuSize <= ymax);<br>
> +<br>
> +        if (!bInsidePicture)<br>
> +        {<br>
> +            uint32_t qNumParts = (pic->getNumPartInCU() >> (depth << 1)) >> 2;<br>
> +            for (uint32_t partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++, absPartIdx += qNumParts)<br>
> +            {<br>
> +                if (g_zscanToPelX[absPartIdx] < xmax && g_zscanToPelY[absPartIdx] < ymax)<br>
> +                    encodeCU(cu, absPartIdx, depth + 1, bInsidePicture, bEncodeDQP);<br>
> +            }<br>
> +<br>
> +            return;<br>
> +        }<br>
>      }<br>
><br>
>      // We need to split, so don't try these modes.<br>
>      if (bInsidePicture && depth < g_maxCUDepth)<br>
>          codeSplitFlag(cu, absPartIdx, depth);<br>
><br>
> -    if (depth <= slice->m_pps->maxCuDQPDepth && slice->m_pps->bUseDQP)<br>
> -        bEncodeDQP = true;<br>
> -<br>
> -    if (!bInsidePicture)<br>
> -    {<br>
> -        uint32_t qNumParts = (pic->getNumPartInCU() >> (depth << 1)) >> 2;<br>
> -<br>
> -        for (uint32_t partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++, absPartIdx += qNumParts)<br>
> -        {<br>
> -            uint32_t lpelx = cu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absPartIdx]];<br>
> -            uint32_t tpely = cu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absPartIdx]];<br>
> -            if ((lpelx < slice->m_sps->picWidthInLumaSamples) &&<br>
> -                (tpely < slice->m_sps->picHeightInLumaSamples))<br>
> -            {<br>
> -                encodeCU(cu, absPartIdx, depth + 1, bInsidePicture, bEncodeDQP);<br>
> -            }<br>
> -        }<br>
> -<br>
> -        return;<br>
> -    }<br>
> -<br>
>      if (depth < cu->getDepth(absPartIdx) && depth < g_maxCUDepth)<br>
>      {<br>
>          uint32_t qNumParts = (pic->getNumPartInCU() >> (depth << 1)) >> 2;<br>
> @@ -568,45 +562,24 @@<br>
>  /* finish encoding a cu and handle end-of-slice conditions */<br>
>  void Entropy::finishCU(TComDataCU* cu, uint32_t absPartIdx, uint32_t depth)<br>
>  {<br>
> -    Frame* pic = cu->m_pic;<br>
>      Slice* slice = cu->m_slice;<br>
><br>
>      // Calculate end address<br>
> +    X265_CHECK(slice->m_endCUAddr == slice->realEndAddress(slice->m_endCUAddr), "real end address expected\n");<br>
> +    uint32_t realEndAddress = slice->m_endCUAddr;<br>
>      uint32_t cuAddr = cu->getSCUAddr() + absPartIdx;<br>
><br>
> -    uint32_t internalAddress = (slice->m_endCUAddr - 1) % pic->getNumPartInCU();<br>
> -    uint32_t externalAddress = (slice->m_endCUAddr - 1) / pic->getNumPartInCU();<br>
> -    uint32_t posx = (externalAddress % pic->getFrameWidthInCU()) * g_maxCUSize + g_rasterToPelX[g_zscanToRaster[internalAddress]];<br>
> -    uint32_t posy = (externalAddress / pic->getFrameWidthInCU()) * g_maxCUSize + g_rasterToPelY[g_zscanToRaster[internalAddress]];<br>
> -    uint32_t width = slice->m_sps->picWidthInLumaSamples;<br>
> -    uint32_t height = slice->m_sps->picHeightInLumaSamples;<br>
> -    uint32_t cuSize = 1 << cu->getLog2CUSize(absPartIdx);<br>
> -<br>
> -    while (posx >= width || posy >= height)<br>
> -    {<br>
> -        internalAddress--;<br>
> -        posx = (externalAddress % pic->getFrameWidthInCU()) * g_maxCUSize + g_rasterToPelX[g_zscanToRaster[internalAddress]];<br>
> -        posy = (externalAddress / pic->getFrameWidthInCU()) * g_maxCUSize + g_rasterToPelY[g_zscanToRaster[internalAddress]];<br>
> -    }<br>
> -<br>
> -    internalAddress++;<br>
> -    if (internalAddress == cu->m_pic->getNumPartInCU())<br>
> -    {<br>
> -        internalAddress = 0;<br>
> -        externalAddress = (externalAddress + 1);<br>
> -    }<br>
> -    uint32_t realEndAddress = (externalAddress * pic->getNumPartInCU() + internalAddress);<br>
> -<br>
>      // Encode slice finish<br>
>      bool bTerminateSlice = false;<br>
>      if (cuAddr + (cu->m_pic->getNumPartInCU() >> (depth << 1)) == realEndAddress)<br>
>          bTerminateSlice = true;<br>
><br>
> -    uint32_t granularityWidth = g_maxCUSize;<br>
> -    posx = cu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absPartIdx]];<br>
> -    posy = cu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absPartIdx]];<br>
> -    bool granularityBoundary = ((posx + cuSize) % granularityWidth == 0 || (posx + cuSize == width))<br>
> -                            && ((posy + cuSize) % granularityWidth == 0 || (posy + cuSize == height));<br>
> +    uint32_t granularityMask = g_maxCUSize - 1;<br>
> +    uint32_t cuSize = 1 << cu->getLog2CUSize(absPartIdx);<br>
> +    uint32_t rpelx = cu->getCUPelX() + g_zscanToPelX[absPartIdx] + cuSize;<br>
> +    uint32_t bpely = cu->getCUPelY() + g_zscanToPelY[absPartIdx] + cuSize;<br>
> +    bool granularityBoundary = (((rpelx & granularityMask) == 0 || (rpelx == slice->m_sps->picWidthInLumaSamples )) &&<br>
> +                                ((bpely & granularityMask) == 0 || (bpely == slice->m_sps->picHeightInLumaSamples)));<br>
><br>
>      if (granularityBoundary)<br>
>      {<br>
> diff -r 6e6756f94b27 -r 7145e57c722a source/encoder/sao.cpp<br>
> --- a/source/encoder/sao.cpp  Fri Aug 22 15:53:34 2014 -0500<br>
> +++ b/source/encoder/sao.cpp  Mon Aug 25 17:53:12 2014 +0900<br>
> @@ -2535,18 +2535,17 @@<br>
>  /* Original YUV restoration for CU in lossless coding */<br>
>  void origCUSampleRestoration(TComDataCU* cu, uint32_t absZOrderIdx, uint32_t depth)<br>
>  {<br>
> -    Frame* pic = cu->m_pic;<br>
> -    uint32_t curNumParts = pic->getNumPartInCU() >> (depth << 1);<br>
> -    uint32_t qNumParts   = curNumParts >> 2;<br>
> -<br>
>      // go to sub-CU<br>
>      if (cu->getDepth(absZOrderIdx) > depth)<br>
>      {<br>
> +        Frame* pic = cu->m_pic;<br>
> +        uint32_t curNumParts = pic->getNumPartInCU() >> (depth << 1);<br>
> +        uint32_t qNumParts   = curNumParts >> 2;<br>
> +        uint32_t xmax = cu->m_slice->m_sps->picWidthInLumaSamples  - cu->getCUPelX();<br>
> +        uint32_t ymax = cu->m_slice->m_sps->picHeightInLumaSamples - cu->getCUPelY();<br>
>          for (uint32_t partIdx = 0; partIdx < 4; partIdx++, absZOrderIdx += qNumParts)<br>
>          {<br>
> -            uint32_t lpelx = cu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absZOrderIdx]];<br>
> -            uint32_t tpely = cu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absZOrderIdx]];<br>
> -            if ((lpelx < cu->m_slice->m_sps->picWidthInLumaSamples) && (tpely < cu->m_slice->m_sps->picHeightInLumaSamples))<br>
> +            if (g_zscanToPelX[absZOrderIdx] < xmax && g_zscanToPelY[absZOrderIdx] < ymax)<br>
>                  origCUSampleRestoration(cu, absZOrderIdx, depth + 1);<br>
>          }<br>
><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>
<br>
</div></div></blockquote></div><br></div>