Skip to content
Snippets Groups Projects
QuantRDOQ.cpp 45.5 KiB
Newer Older
  • Learn to ignore specific revisions
  •     int dim2 = std::min<int>(JVET_C0024_ZERO_OUT_TH, uiHeight);
    
    #endif
        int bitsX = 0;
        int bitsY = 0;
        int ctxId;
        //X-coordinate
        for ( ctxId = 0; ctxId < g_uiGroupIdx[dim1-1]; ctxId++)
        {
          const BinFracBits fB = fracBits.getFracBitsArray( cctx.lastXCtxId(ctxId) );
          lastBitsX[ ctxId ]   = bitsX + fB.intBits[ 0 ];
          bitsX               +=         fB.intBits[ 1 ];
        }
        lastBitsX[ctxId] = bitsX;
        //Y-coordinate
        for ( ctxId = 0; ctxId < g_uiGroupIdx[dim2-1]; ctxId++)
        {
          const BinFracBits fB = fracBits.getFracBitsArray( cctx.lastYCtxId(ctxId) );
          lastBitsY[ ctxId ]   = bitsY + fB.intBits[ 0 ];
          bitsY               +=         fB.intBits[ 1 ];
        }
        lastBitsY[ctxId] = bitsY;
      }
    
    
      bool bFoundLast = false;
      for (int iCGScanPos = iCGLastScanPos; iCGScanPos >= 0; iCGScanPos--)
      {
        d64BaseCost -= pdCostCoeffGroupSig [ iCGScanPos ];
        if (cctx.isSigGroup( iCGScanPos ) )
        {
          for (int iScanPosinCG = iCGSizeM1; iScanPosinCG >= 0; iScanPosinCG--)
          {
            iScanPos = iCGScanPos * (iCGSizeM1 + 1) + iScanPosinCG;
    
            if (iScanPos > iLastScanPos)
            {
              continue;
            }
            uint32_t   uiBlkPos     = cctx.blockPos( iScanPos );
    
            if( piDstCoeff[ uiBlkPos ] )
            {
              uint32_t   uiPosY = uiBlkPos >> uiLog2BlockWidth;
              uint32_t   uiPosX = uiBlkPos - ( uiPosY << uiLog2BlockWidth );
    #if HEVC_USE_MDCS
              double d64CostLast  = ( cctx.scanType() == SCAN_VER ? xGetRateLast( lastBitsX, lastBitsY, uiPosY, uiPosX ) : xGetRateLast( lastBitsX, lastBitsY, uiPosX, uiPosY ) );
    #else
              double d64CostLast  = xGetRateLast( lastBitsX, lastBitsY, uiPosX, uiPosY );
    #endif
    
              double totalCost = d64BaseCost + d64CostLast - pdCostSig[ iScanPos ];
    
              if( totalCost < d64BestCost )
              {
                iBestLastIdxP1  = iScanPos + 1;
                d64BestCost     = totalCost;
              }
              if( piDstCoeff[ uiBlkPos ] > 1 )
              {
                bFoundLast = true;
                break;
              }
              d64BaseCost      -= pdCostCoeff[ iScanPos ];
              d64BaseCost      += pdCostCoeff0[ iScanPos ];
            }
            else
            {
              d64BaseCost      -= pdCostSig[ iScanPos ];
            }
          } //end for
          if (bFoundLast)
          {
            break;
          }
        } // end if (uiSigCoeffGroupFlag[ uiCGBlkPos ])
        DTRACE( g_trace_ctx, D_RDOQ_COST, "%d: %3d, %3d, %dx%d, comp=%d\n", DTRACE_GET_COUNTER( g_trace_ctx, D_RDOQ_COST ), rect.x, rect.y, rect.width, rect.height, compID );
        DTRACE( g_trace_ctx, D_RDOQ_COST, "Uncoded=%d\n", (int64_t)( d64BlockUncodedCost ) );
        DTRACE( g_trace_ctx, D_RDOQ_COST, "Coded  =%d\n", (int64_t)( d64BaseCost ) );
    
      } // end for
    
    
      for ( int scanPos = 0; scanPos < iBestLastIdxP1; scanPos++ )
      {
        int blkPos = cctx.blockPos( scanPos );
        TCoeff level = piDstCoeff[ blkPos ];
        uiAbsSum += level;
        piDstCoeff[ blkPos ] = ( plSrcCoeff[ blkPos ] < 0 ) ? -level : level;
      }
    
      //===== clean uncoded coefficients =====
      for ( int scanPos = iBestLastIdxP1; scanPos <= iLastScanPos; scanPos++ )
      {
        piDstCoeff[ cctx.blockPos( scanPos ) ] = 0;
      }
    
    #if HEVC_USE_SIGN_HIDING
      if( cctx.signHiding() && uiAbsSum>=2)
      {
        const double inverseQuantScale = double(g_invQuantScales[cQP.rem]);
        int64_t rdFactor = (int64_t)(inverseQuantScale * inverseQuantScale * (1 << (2 * cQP.per)) / m_dLambda / 16
                                   / (1 << (2 * DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth)))
    #if HM_QTBT_AS_IN_JEM_QUANT
    #else
                                  * blkErrScale
    #endif
                                 + 0.5);
    
        int lastCG = -1;
        int absSum = 0 ;
        int n ;
    
        for (int subSet = iCGNum - 1; subSet >= 0; subSet--)
    
        {
          int  subPos         = subSet << cctx.log2CGSize();
          int  firstNZPosInCG = iCGSizeM1 + 1, lastNZPosInCG = -1;
          absSum = 0 ;
    
          for( n = iCGSizeM1; n >= 0; --n )
          {
            if( piDstCoeff[ cctx.blockPos( n + subPos )] )
            {
              lastNZPosInCG = n;
              break;
            }
          }
    
          for( n = 0; n <= iCGSizeM1; n++ )
          {
            if( piDstCoeff[ cctx.blockPos( n + subPos )] )
            {
              firstNZPosInCG = n;
              break;
            }
          }
    
          for( n = firstNZPosInCG; n <= lastNZPosInCG; n++ )
          {
            absSum += int(piDstCoeff[ cctx.blockPos( n + subPos )]);
          }
    
          if(lastNZPosInCG>=0 && lastCG==-1)
          {
            lastCG = 1;
          }
    
          if( lastNZPosInCG-firstNZPosInCG>=SBH_THRESHOLD )
          {
            uint32_t signbit = (piDstCoeff[cctx.blockPos(subPos+firstNZPosInCG)]>0?0:1);
            if( signbit!=(absSum&0x1) )  // hide but need tune
            {
              // calculate the cost
              int64_t minCostInc = std::numeric_limits<int64_t>::max(), curCost = std::numeric_limits<int64_t>::max();
              int minPos = -1, finalChange = 0, curChange = 0;
    
              for( n = (lastCG == 1 ? lastNZPosInCG : iCGSizeM1); n >= 0; --n )
              {
                uint32_t uiBlkPos   = cctx.blockPos( n + subPos );
                if(piDstCoeff[ uiBlkPos ] != 0 )
                {
                  int64_t costUp   = rdFactor * ( - deltaU[uiBlkPos] ) + rateIncUp[uiBlkPos];
                  int64_t costDown = rdFactor * (   deltaU[uiBlkPos] ) + rateIncDown[uiBlkPos]
                    -   ((abs(piDstCoeff[uiBlkPos]) == 1) ? sigRateDelta[uiBlkPos] : 0);
    
                  if(lastCG==1 && lastNZPosInCG==n && abs(piDstCoeff[uiBlkPos])==1)
                  {
                    costDown -= (4<<SCALE_BITS);
                  }
    
                  if(costUp<costDown)
                  {
                    curCost = costUp;
                    curChange =  1;
                  }
                  else
                  {
                    curChange = -1;
                    if(n==firstNZPosInCG && abs(piDstCoeff[uiBlkPos])==1)
                    {
                      curCost = std::numeric_limits<int64_t>::max();
                    }
                    else
                    {
                      curCost = costDown;
                    }
                  }
                }
                else
                {
                  curCost = rdFactor * ( - (abs(deltaU[uiBlkPos])) ) + (1<<SCALE_BITS) + rateIncUp[uiBlkPos] + sigRateDelta[uiBlkPos] ;
                  curChange = 1 ;
    
                  if(n<firstNZPosInCG)
                  {
                    uint32_t thissignbit = (plSrcCoeff[uiBlkPos]>=0?0:1);
                    if(thissignbit != signbit )
                    {
                      curCost = std::numeric_limits<int64_t>::max();
                    }
                  }
                }
    
                if( curCost<minCostInc)
                {
                  minCostInc = curCost;
                  finalChange = curChange;
                  minPos = uiBlkPos;
                }
              }
    
              if(piDstCoeff[minPos] == entropyCodingMaximum || piDstCoeff[minPos] == entropyCodingMinimum)
              {
                finalChange = -1;
              }
    
              if(plSrcCoeff[minPos]>=0)
              {
                piDstCoeff[minPos] += finalChange ;
              }
              else
              {
                piDstCoeff[minPos] -= finalChange ;
              }
            }
          }
    
          if(lastCG==1)
          {
            lastCG=0 ;
          }
        }
      }
    #endif
    }
    
    //! \}