Ticket #981: Fixes-for-handling-proper-RDOQTS-and-BDPCM-RDOQ.patch

File Fixes-for-handling-proper-RDOQTS-and-BDPCM-RDOQ.patch, 23.0 KB (added by analci, 19 months ago)
  • source/Lib/CommonLib/QuantRDOQ.cpp

    From 955c0f423a203c7a043a36aca58c2b83067b99ec Mon Sep 17 00:00:00 2001
    From: analci <analci@qti.qualcomm.com>
    Date: Tue, 31 Mar 2020 18:05:41 -0700
    Subject: [PATCH] Fixes for handling proper RDOQTS and BDPCM RDOQ for
     slice_ts_residual_coding_disabled_flag.
    
    ---
     source/Lib/CommonLib/QuantRDOQ.cpp | 420 ++++++++++++++++++++++++++++-
     source/Lib/CommonLib/QuantRDOQ.h   |   7 +
     source/Lib/CommonLib/TypeDef.h     |   3 +
     source/Lib/EncoderLib/EncSlice.cpp |   4 +
     4 files changed, 432 insertions(+), 2 deletions(-)
    
    diff --git a/source/Lib/CommonLib/QuantRDOQ.cpp b/source/Lib/CommonLib/QuantRDOQ.cpp
    index c9d12955..b12133bf 100644
    a b void QuantRDOQ::quant(TransformUnit &tu, const ComponentID &compID, const CCoeff 
    537537      {
    538538        if( (tu.cu->bdpcmMode && isLuma(compID)) || (isChroma(compID) && tu.cu->bdpcmModeChroma ) )
    539539        {
     540#if QC_TS_RRC_RDOQ
     541          if( tu.cs->slice->getTSResidualCodingDisabledFlag() )
     542          {
     543            forwardRRCRDPCM( tu, compID, pSrc, uiAbsSum, cQP, ctx );
     544          }
     545          else
     546          {
     547            forwardRDPCM( tu, compID, pSrc, uiAbsSum, cQP, ctx );
     548          }
     549#else
    540550          forwardRDPCM( tu, compID, pSrc, uiAbsSum, cQP, ctx );
     551#endif
    541552        }
    542553        else
    543554        {
    void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID, 
    635646  memset( m_sigRateDelta, 0, sizeof( int    ) *  uiMaxNumCoeff );
    636647  memset( m_deltaU,       0, sizeof( TCoeff ) *  uiMaxNumCoeff );
    637648
    638 
     649#if QC_TS_RRC_RDOQ
     650  const bool   isTransformSkip  = (tu.mtsIdx[compID] == MTS_SKIP);
     651  const bool needSqrtAdjustment = isTransformSkip ? false : ( TU::needsBlockSizeTrafoScale( tu, compID ) );
     652#else
    639653  const bool needSqrtAdjustment= TU::needsBlockSizeTrafoScale( tu, compID );
    640654  const bool   isTransformSkip = (tu.mtsIdx[compID] == MTS_SKIP);
     655#endif
    641656  const double *const pdErrScale = xGetErrScaleCoeffSL(scalingListType, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem(isTransformSkip));
    642657  const int    *const piQCoef    = getQuantCoeff(scalingListType, cQP.rem(isTransformSkip), uiLog2BlockWidth, uiLog2BlockHeight);
    643658#if JVET_Q0346_SCALING_LIST_USED_IN_SH
    void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID, 
    652667  const bool   enableScalingLists = getUseScalingList(uiWidth, uiHeight, isTransformSkip, tu.cu->lfnstIdx > 0, disableSMForLFNST);
    653668#endif
    654669  const int    defaultQuantisationCoefficient = g_quantScales[ needSqrtAdjustment ?1:0][cQP.rem(isTransformSkip)];
     670#if QC_TS_RRC_RDOQ
     671  double defaultErrorScale;
     672  if( isTransformSkip )
     673  {
     674    defaultErrorScale = xGetErrScaleCoeff(needSqrtAdjustment, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem(isTransformSkip), maxLog2TrDynamicRange, channelBitDepth, isTransformSkip);
     675  }
     676  else
     677  {
     678    defaultErrorScale = xGetErrScaleCoeffNoScalingList(scalingListType, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem(isTransformSkip));
     679  }
     680  const int iQBits    = QUANT_SHIFT + cQP.per(isTransformSkip) + (isTransformSkip ? 0 : iTransformShift) + (needSqrtAdjustment ? -1 : 0);
     681#else
    655682  const double defaultErrorScale              = xGetErrScaleCoeffNoScalingList(scalingListType, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem(isTransformSkip));
    656683  const int iQBits = QUANT_SHIFT + cQP.per(isTransformSkip) + iTransformShift + (needSqrtAdjustment?-1:0);                   // Right shift of non-RDOQ quantizer;  level = (coeff*uiQ + offset)>>q_bits
    657 
     684#endif
    658685
    659686  const TCoeff entropyCodingMinimum = -(1 << maxLog2TrDynamicRange);
    660687  const TCoeff entropyCodingMaximum =  (1 << maxLog2TrDynamicRange) - 1;
    void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI 
    14131440  }
    14141441}
    14151442
     1443#if QC_TS_RRC_RDOQ
     1444void QuantRDOQ::forwardRRCRDPCM(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &pSrc, TCoeff &uiAbsSum, const QpParam &cQP, const Ctx &ctx)
     1445{
     1446  const FracBitsAccess& fracBits = ctx.getFracBitsAcess();
     1447
     1448  const SPS &sps            = *tu.cs->sps;
     1449  const CompArea &rect      = tu.blocks[compID];
     1450  const uint32_t uiWidth    = rect.width;
     1451  const uint32_t uiHeight   = rect.height;
     1452  const ChannelType chType  = toChannelType(compID);
     1453  const int channelBitDepth = sps.getBitDepth( chType );
     1454
     1455  const bool extendedPrecision     = sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag();
     1456  const int  maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange(chType);
     1457
     1458  const int  dirMode = isLuma(compID) ? tu.cu->bdpcmMode : tu.cu->bdpcmModeChroma;
     1459
     1460  // Represents scaling through forward transform
     1461  int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange);
     1462
     1463  if (tu.mtsIdx[compID] == MTS_SKIP && extendedPrecision)
     1464  {
     1465    iTransformShift = std::max<int>(0, iTransformShift);
     1466  }
     1467
     1468  double     d64BlockUncodedCost               = 0;
     1469  const uint32_t uiLog2BlockWidth                  = floorLog2(uiWidth);
     1470  const uint32_t uiLog2BlockHeight                 = floorLog2(uiHeight);
     1471  const uint32_t uiMaxNumCoeff                     = rect.area();
     1472
     1473  CHECK(compID >= MAX_NUM_TBLOCKS, "Invalid component ID");
     1474
     1475  int scalingListType = getScalingListType(tu.cu->predMode, compID);
     1476
     1477  CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list");
     1478
     1479// Rotate block
     1480  const uint32_t  numSamplesInBlock = uiWidth * uiHeight;
     1481
     1482  memset(m_srcCoeffTemp, 0, sizeof(TCoeff) * numSamplesInBlock);
     1483  memset(m_dstCoeffTemp, 0, sizeof(TCoeff) * numSamplesInBlock);
     1484
     1485  const uint32_t uiSizeMinus1 = (numSamplesInBlock)-1;
     1486  for (uint32_t y = 0, coefficientIndex = 0; y < uiHeight; y++)
     1487  {
     1488          for (uint32_t x = 0; x < uiWidth; x++, coefficientIndex++)
     1489          {
     1490                  m_srcCoeffTemp[coefficientIndex] = pSrc.buf[uiSizeMinus1 - coefficientIndex];
     1491          }
     1492  }
     1493  const TCoeff *plSrcCoeff = m_srcCoeffTemp;
     1494        TCoeff *piDstCoeff = tu.getCoeffs(compID).buf;
     1495
     1496  double *pdCostCoeff  = m_pdCostCoeff;
     1497  double *pdCostSig    = m_pdCostSig;
     1498  double *pdCostCoeff0 = m_pdCostCoeff0;
     1499  int    *rateIncUp    = m_rateIncUp;
     1500  int    *rateIncDown  = m_rateIncDown;
     1501  int    *sigRateDelta = m_sigRateDelta;
     1502  TCoeff *deltaU       = m_deltaU;
     1503
     1504  memset(piDstCoeff, 0, sizeof(*piDstCoeff) * uiMaxNumCoeff);
     1505  memset( m_pdCostCoeff,  0, sizeof( double ) *  uiMaxNumCoeff );
     1506  memset( m_pdCostSig,    0, sizeof( double ) *  uiMaxNumCoeff );
     1507  memset( m_rateIncUp,    0, sizeof( int    ) *  uiMaxNumCoeff );
     1508  memset( m_rateIncDown,  0, sizeof( int    ) *  uiMaxNumCoeff );
     1509  memset( m_sigRateDelta, 0, sizeof( int    ) *  uiMaxNumCoeff );
     1510  memset( m_deltaU,       0, sizeof( TCoeff ) *  uiMaxNumCoeff );
     1511  memset( m_fullCoeff,    0, sizeof(TCoeff)   *  uiMaxNumCoeff );
     1512
     1513  m_bdpcm = dirMode;
     1514
     1515  const bool   isTransformSkip  = (tu.mtsIdx[compID] == MTS_SKIP);
     1516  const bool needSqrtAdjustment = isTransformSkip ? false : ( TU::needsBlockSizeTrafoScale( tu, compID ) );
     1517
     1518  const int    defaultQuantisationCoefficient = g_quantScales[ needSqrtAdjustment ?1:0][cQP.rem(isTransformSkip)];
     1519
     1520 double defaultErrorScale;
     1521 if( isTransformSkip )
     1522 {
     1523   defaultErrorScale = xGetErrScaleCoeff(needSqrtAdjustment, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem(isTransformSkip), maxLog2TrDynamicRange, channelBitDepth, isTransformSkip);
     1524 }
     1525 else
     1526 {
     1527   defaultErrorScale = xGetErrScaleCoeffNoScalingList(scalingListType, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem(isTransformSkip));
     1528 }
     1529
     1530 const int iQBits    = QUANT_SHIFT + cQP.per(isTransformSkip) + (isTransformSkip ? 0 : iTransformShift) + (needSqrtAdjustment ? -1 : 0);
     1531
     1532  TrQuantParams trQuantParams;
     1533  trQuantParams.rightShift = (IQUANT_SHIFT - ((isTransformSkip ? 0 : iTransformShift) + cQP.per(isTransformSkip)));
     1534  trQuantParams.qScale     = g_invQuantScales[needSqrtAdjustment ? 1 : 0][cQP.rem(isTransformSkip)];
     1535
     1536  const TCoeff entropyCodingMaximum =  (1 << maxLog2TrDynamicRange) - 1;
     1537
     1538  CoeffCodingContext cctx(tu, compID, tu.cs->picHeader->getSignDataHidingEnabledFlag());
     1539
     1540  const int    iCGSizeM1      = (1 << cctx.log2CGSize()) - 1;
     1541
     1542  int     iCGLastScanPos      = -1;
     1543  double  d64BaseCost         = 0;
     1544  int     iLastScanPos        = -1;
     1545
     1546
     1547  int ctxBinSampleRatio   = (compID == COMPONENT_Y) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA;
     1548  int remRegBins          = (uiWidth * uiHeight * ctxBinSampleRatio) >> 4;
     1549
     1550  uint32_t  goRiceParam   = 0;
     1551
     1552  double *pdCostCoeffGroupSig = m_pdCostCoeffGroupSig;
     1553  memset( pdCostCoeffGroupSig, 0, ( uiMaxNumCoeff >> cctx.log2CGSize() ) * sizeof( double ) );
     1554  int iScanPos;
     1555  coeffGroupRDStats rdStats;
     1556
     1557#if ENABLE_TRACING
     1558  DTRACE( g_trace_ctx, D_RDOQ, "%d: %3d, %3d, %dx%d, comp=%d\n", DTRACE_GET_COUNTER( g_trace_ctx, D_RDOQ ), rect.x, rect.y, rect.width, rect.height, compID );
     1559#endif
     1560
     1561  const uint32_t lfnstIdx = tu.cu->lfnstIdx;
     1562
     1563  const int iCGNum = lfnstIdx > 0 ? 1 : std::min<int>(JVET_C0024_ZERO_OUT_TH, uiWidth) * std::min<int>(JVET_C0024_ZERO_OUT_TH, uiHeight) >> cctx.log2CGSize();
     1564
     1565  for (int subSetId = iCGNum - 1; subSetId >= 0; subSetId--)
     1566  {
     1567    cctx.initSubblock( subSetId );
     1568
     1569    uint32_t maxNonZeroPosInCG = iCGSizeM1;
     1570    if( lfnstIdx > 0 && ( ( uiWidth == 4 && uiHeight == 4 ) || ( uiWidth == 8 && uiHeight == 8 && cctx.cgPosX() == 0 && cctx.cgPosY() == 0 ) ) )
     1571    {
     1572      maxNonZeroPosInCG = 7;
     1573    }
     1574
     1575    memset( &rdStats, 0, sizeof (coeffGroupRDStats));
     1576
     1577
     1578    for( int iScanPosinCG = iCGSizeM1; iScanPosinCG > maxNonZeroPosInCG; iScanPosinCG-- )
     1579    {
     1580      iScanPos = cctx.minSubPos() + iScanPosinCG;
     1581      uint32_t    blkPos = cctx.blockPos( iScanPos );
     1582      piDstCoeff[ blkPos ] = 0;
     1583    }
     1584
     1585
     1586    for( int iScanPosinCG = maxNonZeroPosInCG; iScanPosinCG >= 0; iScanPosinCG-- )
     1587    {
     1588      iScanPos = cctx.minSubPos() + iScanPosinCG;
     1589      //===== quantization =====
     1590      uint32_t    uiBlkPos          = cctx.blockPos(iScanPos);
     1591
     1592            const int posX        = cctx.posX(iScanPos);
     1593      const int posY        = cctx.posY(iScanPos);
     1594      const int posS        = (1 == dirMode) ? posX : posY;
     1595            const int boundaryLim = (1 == dirMode) ? uiWidth-1 : uiHeight-1;
     1596            const int posNb       = (1 == dirMode) ? (posX + 1) + posY * pSrc.stride : posX + (posY + 1) * pSrc.stride;
     1597      TCoeff predCoeff      = (boundaryLim != posS) ? m_fullCoeff[posNb] : 0;
     1598
     1599      // set coeff
     1600      const int    quantisationCoefficient = defaultQuantisationCoefficient;
     1601      const double errorScale              = defaultErrorScale;
     1602
     1603            const int64_t  tmpLevel              = int64_t(abs(plSrcCoeff[ uiBlkPos ] - predCoeff)) * quantisationCoefficient;
     1604
     1605      const Intermediate_Int lLevelDouble  = (Intermediate_Int)std::min<int64_t>(tmpLevel, std::numeric_limits<Intermediate_Int>::max() - (Intermediate_Int(1) << (iQBits - 1)));
     1606
     1607      uint32_t uiMaxAbsLevel        = std::min<uint32_t>(uint32_t(entropyCodingMaximum), uint32_t((lLevelDouble + (Intermediate_Int(1) << (iQBits - 1))) >> iQBits));
     1608
     1609      const double dErr         = double( lLevelDouble );
     1610      pdCostCoeff0[ iScanPos ]  = dErr * dErr * errorScale;
     1611      d64BlockUncodedCost      += pdCostCoeff0[ iScanPos ];
     1612      piDstCoeff[ uiBlkPos ]    = uiMaxAbsLevel;
     1613
     1614
     1615      if ( uiMaxAbsLevel > 0 && iLastScanPos < 0 )
     1616      {
     1617        iLastScanPos            = iScanPos;
     1618        iCGLastScanPos          = cctx.subSetId();
     1619      }
     1620
     1621      if ( iLastScanPos >= 0 )
     1622      {
     1623#if ENABLE_TRACING
     1624        uint32_t uiCGPosY = cctx.cgPosX();
     1625        uint32_t uiCGPosX = cctx.cgPosY();
     1626        uint32_t uiPosY = cctx.posY( iScanPos );
     1627        uint32_t uiPosX = cctx.posX( iScanPos );
     1628        DTRACE( g_trace_ctx, D_RDOQ, "%d [%d][%d][%2d:%2d][%2d:%2d]", DTRACE_GET_COUNTER( g_trace_ctx, D_RDOQ ), iScanPos, uiBlkPos, uiCGPosX, uiCGPosY, uiPosX, uiPosY );
     1629#endif
     1630        //===== coefficient level estimation =====
     1631        unsigned ctxIdSig = 0;
     1632        if( iScanPos != iLastScanPos )
     1633        {
     1634          ctxIdSig = cctx.sigCtxIdAbs( iScanPos, piDstCoeff, 0 );
     1635        }
     1636
     1637
     1638                const uint8_t  sign = (plSrcCoeff[uiBlkPos] - predCoeff) < 0 ? 1 : 0;
     1639
     1640        uint32_t    uiLevel;
     1641        uint8_t ctxOffset     = cctx.ctxOffsetAbs     ();
     1642        uint32_t    uiParCtx      = cctx.parityCtxIdAbs   ( ctxOffset );
     1643        uint32_t    uiGt1Ctx      = cctx.greater1CtxIdAbs ( ctxOffset );
     1644        uint32_t    uiGt2Ctx      = cctx.greater2CtxIdAbs ( ctxOffset );
     1645        uint32_t    goRiceZero    = 0;
     1646        if( remRegBins < 4 )
     1647        {
     1648          unsigned  sumAbs = cctx.templateAbsSum( iScanPos, piDstCoeff, 0 );
     1649          goRiceParam             = g_auiGoRiceParsCoeff   [ sumAbs ];
     1650          goRiceZero              = g_auiGoRicePosCoeff0(0, goRiceParam);
     1651        }
     1652
     1653        const BinFracBits fracBitsPar = fracBits.getFracBitsArray( uiParCtx );
     1654        const BinFracBits fracBitsGt1 = fracBits.getFracBitsArray( uiGt1Ctx );
     1655        const BinFracBits fracBitsGt2 = fracBits.getFracBitsArray( uiGt2Ctx );
     1656
     1657        if( iScanPos == iLastScanPos )
     1658        {
     1659          uiLevel = xGetCodedLevel( pdCostCoeff[ iScanPos ], pdCostCoeff0[ iScanPos ], pdCostSig[ iScanPos ],
     1660                                    lLevelDouble, uiMaxAbsLevel, nullptr, fracBitsPar, fracBitsGt1, fracBitsGt2, remRegBins, goRiceZero, goRiceParam, iQBits, errorScale, 1, extendedPrecision, maxLog2TrDynamicRange );
     1661        }
     1662        else
     1663        {
     1664          DTRACE_COND( ( uiMaxAbsLevel != 0 ), g_trace_ctx, D_RDOQ_MORE, " uiCtxSig=%d", ctxIdSig );
     1665
     1666          const BinFracBits fracBitsSig = fracBits.getFracBitsArray( ctxIdSig );
     1667          uiLevel = xGetCodedLevel( pdCostCoeff[ iScanPos ], pdCostCoeff0[ iScanPos ], pdCostSig[ iScanPos ],
     1668                                    lLevelDouble, uiMaxAbsLevel, &fracBitsSig, fracBitsPar, fracBitsGt1, fracBitsGt2, remRegBins, goRiceZero, goRiceParam, iQBits, errorScale, 0, extendedPrecision, maxLog2TrDynamicRange );
     1669          sigRateDelta[ uiBlkPos ] = ( remRegBins < 4 ? 0 : fracBitsSig.intBits[1] - fracBitsSig.intBits[0] );
     1670        }
     1671
     1672        DTRACE( g_trace_ctx, D_RDOQ, " Lev=%d \n", uiLevel );
     1673        DTRACE_COND( ( uiMaxAbsLevel != 0 ), g_trace_ctx, D_RDOQ, " CostC0=%d\n", (int64_t)( pdCostCoeff0[iScanPos] ) );
     1674        DTRACE_COND( ( uiMaxAbsLevel != 0 ), g_trace_ctx, D_RDOQ, " CostC =%d\n", (int64_t)( pdCostCoeff[iScanPos] ) );
     1675
     1676        deltaU[ uiBlkPos ]        = TCoeff((lLevelDouble - (Intermediate_Int(uiLevel) << iQBits)) >> (iQBits-8));
     1677
     1678        if( uiLevel > 0 )
     1679        {
     1680          int rateNow              = xGetICRate( uiLevel,   fracBitsPar, fracBitsGt1, fracBitsGt2, remRegBins, goRiceZero, goRiceParam, extendedPrecision, maxLog2TrDynamicRange );
     1681          rateIncUp   [ uiBlkPos ] = xGetICRate( uiLevel+1, fracBitsPar, fracBitsGt1, fracBitsGt2, remRegBins, goRiceZero, goRiceParam, extendedPrecision, maxLog2TrDynamicRange ) - rateNow;
     1682          rateIncDown [ uiBlkPos ] = xGetICRate( uiLevel-1, fracBitsPar, fracBitsGt1, fracBitsGt2, remRegBins, goRiceZero, goRiceParam, extendedPrecision, maxLog2TrDynamicRange ) - rateNow;
     1683        }
     1684        else // uiLevel == 0
     1685        {
     1686          if( remRegBins < 4 )
     1687          {
     1688            int rateNow            = xGetICRate( uiLevel,   fracBitsPar, fracBitsGt1, fracBitsGt2, remRegBins, goRiceZero, goRiceParam, extendedPrecision, maxLog2TrDynamicRange );
     1689            rateIncUp [ uiBlkPos ] = xGetICRate( uiLevel+1, fracBitsPar, fracBitsGt1, fracBitsGt2, remRegBins, goRiceZero, goRiceParam, extendedPrecision, maxLog2TrDynamicRange ) - rateNow;
     1690          }
     1691          else
     1692          {
     1693            rateIncUp [ uiBlkPos ] = fracBitsGt1.intBits[ 0 ];
     1694          }
     1695        }
     1696        piDstCoeff[ uiBlkPos ] = uiLevel;
     1697
     1698                    if( sign )
     1699        {
     1700                      piDstCoeff[uiBlkPos] = -piDstCoeff[uiBlkPos];
     1701        }
     1702
     1703                    xDequantSample( m_fullCoeff[uiBlkPos], piDstCoeff[uiBlkPos], trQuantParams );
     1704        m_fullCoeff[uiBlkPos] += predCoeff;
     1705
     1706        d64BaseCost           += pdCostCoeff [ iScanPos ];
     1707
     1708        if( ( (iScanPos & iCGSizeM1) == 0 ) && ( iScanPos > 0 ) )
     1709        {
     1710          goRiceParam   = 0;
     1711        }
     1712        else if( remRegBins >= 4 )
     1713        {
     1714          int  sumAll = cctx.templateAbsSum(iScanPos, piDstCoeff, 4);
     1715          goRiceParam = g_auiGoRiceParsCoeff[sumAll];
     1716          remRegBins -= (uiLevel < 2 ? uiLevel : 3) + (iScanPos != iLastScanPos);
     1717        }
     1718      }
     1719      else
     1720      {
     1721        d64BaseCost    += pdCostCoeff0[ iScanPos ];
     1722      }
     1723      rdStats.d64SigCost += pdCostSig[ iScanPos ];
     1724      if (iScanPosinCG == 0 )
     1725      {
     1726        rdStats.d64SigCost_0 = pdCostSig[ iScanPos ];
     1727      }
     1728      if (piDstCoeff[ uiBlkPos ] )
     1729      {
     1730        cctx.setSigGroup();
     1731        rdStats.d64CodedLevelandDist += pdCostCoeff[ iScanPos ] - pdCostSig[ iScanPos ];
     1732        rdStats.d64UncodedDist += pdCostCoeff0[ iScanPos ];
     1733        if ( iScanPosinCG != 0 )
     1734        {
     1735          rdStats.iNNZbeforePos0++;
     1736        }
     1737      }
     1738    } //end for (iScanPosinCG)
     1739
     1740    if (iCGLastScanPos >= 0)
     1741    {
     1742      if( cctx.subSetId() )
     1743      {
     1744        if( !cctx.isSigGroup() )
     1745        {
     1746          const BinFracBits fracBitsSigGroup = fracBits.getFracBitsArray( cctx.sigGroupCtxId() );
     1747          d64BaseCost += xGetRateSigCoeffGroup(fracBitsSigGroup, 0) - rdStats.d64SigCost;
     1748          pdCostCoeffGroupSig[ cctx.subSetId() ] = xGetRateSigCoeffGroup(fracBitsSigGroup, 0);
     1749        }
     1750        else
     1751        {
     1752          {
     1753            if ( rdStats.iNNZbeforePos0 == 0 )
     1754            {
     1755              d64BaseCost -= rdStats.d64SigCost_0;
     1756              rdStats.d64SigCost -= rdStats.d64SigCost_0;
     1757            }
     1758            // rd-cost if SigCoeffGroupFlag = 0, initialization
     1759            double d64CostZeroCG = d64BaseCost;
     1760
     1761            const BinFracBits fracBitsSigGroup = fracBits.getFracBitsArray( cctx.sigGroupCtxId() );
     1762
     1763
     1764            d64BaseCost  += xGetRateSigCoeffGroup(fracBitsSigGroup,1);
     1765            d64CostZeroCG += xGetRateSigCoeffGroup(fracBitsSigGroup,0);
     1766            pdCostCoeffGroupSig[ cctx.subSetId() ] = xGetRateSigCoeffGroup(fracBitsSigGroup,1);
     1767
     1768            // try to convert the current coeff group from non-zero to all-zero
     1769            d64CostZeroCG += rdStats.d64UncodedDist;  // distortion for resetting non-zero levels to zero levels
     1770            d64CostZeroCG -= rdStats.d64CodedLevelandDist;   // distortion and level cost for keeping all non-zero levels
     1771            d64CostZeroCG -= rdStats.d64SigCost;     // sig cost for all coeffs, including zero levels and non-zerl levels
     1772
     1773                                                     // if we can save cost, change this block to all-zero block
     1774            if ( d64CostZeroCG < d64BaseCost )
     1775            {
     1776              cctx.resetSigGroup();
     1777              d64BaseCost = d64CostZeroCG;
     1778
     1779              pdCostCoeffGroupSig[ cctx.subSetId() ] = xGetRateSigCoeffGroup(fracBitsSigGroup,0);
     1780
     1781              // reset coeffs to 0 in this block
     1782              for( int iScanPosinCG = maxNonZeroPosInCG; iScanPosinCG >= 0; iScanPosinCG-- )
     1783              {
     1784                iScanPos      = cctx.minSubPos() + iScanPosinCG;
     1785                uint32_t uiBlkPos = cctx.blockPos( iScanPos );
     1786                    const int posX        = cctx.posX(iScanPos);
     1787                const int posY        = cctx.posY(iScanPos);
     1788                const int posS        = (1 == dirMode) ? posX : posY;
     1789                    const int boundaryLim = (1 == dirMode) ? uiWidth-1 : uiHeight-1;
     1790                    const int posNb       = (1 == dirMode) ? (posX + 1) + posY * pSrc.stride : posX + (posY + 1) * pSrc.stride;
     1791                    m_fullCoeff[uiBlkPos] = (boundaryLim != posS) ? m_fullCoeff[posNb] : 0;     
     1792
     1793                if (piDstCoeff[ uiBlkPos ])
     1794                {
     1795                  piDstCoeff [ uiBlkPos ] = 0;
     1796                  pdCostCoeff[ iScanPos ] = pdCostCoeff0[ iScanPos ];
     1797                  pdCostSig  [ iScanPos ] = 0;
     1798                }
     1799              }
     1800            }
     1801          }
     1802        } // end if if (uiSigCoeffGroupFlag[ uiCGBlkPos ] == 0)
     1803      }
     1804      else
     1805      {
     1806        cctx.setSigGroup();
     1807      }
     1808    }
     1809  } //end for (cctx.subSetId)
     1810
     1811
     1812  //===== estimate last position =====
     1813  for ( int scanPos = 0; scanPos < uiMaxNumCoeff; scanPos++ )
     1814  {
     1815    int blkPos   = cctx.blockPos( scanPos );
     1816    TCoeff level = piDstCoeff[ blkPos ];
     1817        uiAbsSum    += abs(level);
     1818  }
     1819
     1820  // rotate block
     1821  for (uint32_t y = 0, coefficientIndex = 0; y < uiHeight; y++)
     1822  {
     1823    for (uint32_t x = 0; x < uiWidth; x++, coefficientIndex++)
     1824    {
     1825                m_dstCoeffTemp[coefficientIndex] = tu.getCoeffs(compID).buf[uiSizeMinus1 - coefficientIndex];
     1826    }
     1827  }
     1828  memcpy( tu.getCoeffs(compID).buf, m_dstCoeffTemp, sizeof(TCoeff) * numSamplesInBlock );
     1829}
     1830#endif
     1831
    14161832void QuantRDOQ::forwardRDPCM( TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &coeffs, TCoeff &absSum, const QpParam &qp, const Ctx &ctx )
    14171833{
    14181834  const FracBitsAccess& fracBits = ctx.getFracBitsAcess();
  • source/Lib/CommonLib/QuantRDOQ.h

    diff --git a/source/Lib/CommonLib/QuantRDOQ.h b/source/Lib/CommonLib/QuantRDOQ.h
    index ec3ca1c6..f41828f6 100644
    a b public: 
    6666  // quantization
    6767  void quant                ( TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &pSrc, TCoeff &uiAbsSum, const QpParam &cQP, const Ctx& ctx );
    6868  void forwardRDPCM         ( TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &pSrc, TCoeff &uiAbsSum, const QpParam &cQP, const Ctx &ctx );
     69#if QC_TS_RRC_RDOQ
     70  void forwardRRCRDPCM        ( TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &pSrc, TCoeff &uiAbsSum, const QpParam &cQP, const Ctx &ctx );
     71#endif
    6972
    7073private:
    7174  double* xGetErrScaleCoeffSL            ( uint32_t list, uint32_t sizeX, uint32_t sizeY, int qp ) { return m_errScale[sizeX][sizeY][list][qp]; };  //!< get Error Scale Coefficent
    private: 
    166169  int    m_sigRateDelta       [MAX_TB_SIZEY * MAX_TB_SIZEY];
    167170  TCoeff m_deltaU             [MAX_TB_SIZEY * MAX_TB_SIZEY];
    168171  TCoeff m_fullCoeff          [MAX_TB_SIZEY * MAX_TB_SIZEY];
     172#if QC_TS_RRC_RDOQ
     173  TCoeff m_srcCoeffTemp       [MAX_TB_SIZEY * MAX_TB_SIZEY];
     174  TCoeff m_dstCoeffTemp       [MAX_TB_SIZEY * MAX_TB_SIZEY];
     175#endif
    169176  int   m_bdpcm;
    170177  int   m_testedLevels;
    171178};// END CLASS DEFINITION QuantRDOQ
  • source/Lib/CommonLib/TypeDef.h

    diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
    index 2d4c84c3..6c57352f 100644
    a b  
    5050#include <assert.h>
    5151#include <cassert>
    5252
     53#define QC_TEST_TS_RRC                                    1
     54#define QC_TS_RRC_RDOQ                                    1
     55
    5356#define JVET_Q0237_STSA_TID_ZERO_DEPLAYER                 1 // JVET-Q0237: STSA picture with TemporalId equal to 0 in a dependent layer
    5457
    5558#define JVET_Q0798_SPS_NUMBER_MERGE_CANDIDATE             1 // JVET-Q0798: signal the number of merge candidates in SPS
  • source/Lib/EncoderLib/EncSlice.cpp

    diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
    index a7d4ff10..e6a4d2b9 100644
    a b void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr 
    350350  }
    351351  else
    352352  {
     353#if QC_TEST_TS_RRC
     354    rpcSlice->setTSResidualCodingDisabledFlag(true);
     355#else
    353356    rpcSlice->setTSResidualCodingDisabledFlag(false);
     357#endif
    354358  }
    355359#endif
    356360