Skip to content
Snippets Groups Projects
EncGOP.cpp 292 KiB
Newer Older
  • Learn to ignore specific revisions
  • Yao-Jen Chang's avatar
    Yao-Jen Chang committed
              const int currPOC = pcSlice->getPOC();
              const int colPOC = pColPic->getPOC();
    
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
              pcSlice->resizeImBuf(pColPic->numSlices, colFrameIdx);
    #else
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
              pcSlice->resizeImBuf(pColPic->numSlices);
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
              Slice *pColSlice = nullptr;
              for (int sliceIdx = 0; sliceIdx < pColPic->numSlices; sliceIdx++)
              {
                pColSlice = pColPic->slices[sliceIdx];
                if (pColSlice->isIntra())
                {
                  continue;
                }
    
                for (int colRefPicListIdx = 0; colRefPicListIdx < (pColSlice->isInterB() ? 2 : 1); colRefPicListIdx++)
                {
                  for (int colRefIdx = 0; colRefIdx < pColSlice->getNumRefIdx(RefPicList(colRefPicListIdx)); colRefIdx++)
                  {
    
    #if JVET_AI0183_MVP_EXTENSION
                    const bool bIsColRefLongTerm = pColSlice->getIsUsedAsLongTerm(RefPicList(colRefPicListIdx), colRefIdx);
                    const int colRefPOC = pColSlice->getRefPOC(RefPicList(colRefPicListIdx), colRefIdx);
                    for (int curRefPicListIdx = 0; curRefPicListIdx < (pcSlice->isInterB() ? 2 : 1); curRefPicListIdx++)
                    {
                      double bestDistScale = MAX_DOUBLE;
                      int targetRefIdx = -1;
                      for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx)); curRefIdx++)
                      {
                        const int currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
                        const bool bIsCurrRefLongTerm = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
                        if (bIsCurrRefLongTerm != bIsColRefLongTerm)
                        {
                          continue;
                        }
                        if (bIsCurrRefLongTerm)
                        {
                          targetRefIdx = curRefIdx;
                          bestDistScale = 1;
                          break;
                        }
                        else if (colPOC - colRefPOC == currPOC - currRefPOC)
                        {
                          targetRefIdx = curRefIdx;
                          bestDistScale = 1;
                          break;
                        }
                        else
                        {
                          if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)) < bestDistScale)
                          {
                            bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
                            targetRefIdx = curRefIdx;
                          }
                        }
                      } // curRefIdx
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
                      pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx, colFrameIdx);
    #else
                      pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx);
    #endif
                      if (pcSlice->getCheckLDC() == true)
                      {
                        continue;
                      }
                      int targetRefIdx1st = targetRefIdx;
                      double bestOverScale = 0;
                      double scale         = 0;
                      int    curPOCMax, curPOCMin;
                      int    colPOCMax, colPOCMin;
                      int    bestTargetRefIdx = -1;
                      bestDistScale = MAX_DOUBLE;
                      targetRefIdx  = -1;
                      for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx)); curRefIdx++)
                      {
                        if (curRefIdx == targetRefIdx1st)
                        {
                          continue;
                        }
                        const int  currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
                        const bool bIsCurrRefLongTerm =
                          pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
                        if (bIsCurrRefLongTerm != bIsColRefLongTerm)
                        {
                          continue;
                        }
                        if (bIsCurrRefLongTerm)
                        {
                          targetRefIdx  = curRefIdx;
                          bestDistScale = 1;
                          bestTargetRefIdx = -1;
                          break;
                        }
                        else if (colRefPOC == currRefPOC)
                        {
                          targetRefIdx  = curRefIdx;
                          bestDistScale = 1;
                          bestTargetRefIdx = -1;
                          break;
                        }
                        else
                        {
                          curPOCMax = std::max(currPOC, currRefPOC);
                          curPOCMin = std::min(currPOC, currRefPOC);
                          colPOCMax = std::max(colPOC, colRefPOC);
                          colPOCMin = std::min(colPOC, colRefPOC);
                          scale = std::max(0, std::min(curPOCMax, colPOCMax) - std::max(curPOCMin, colPOCMin));
                          scale = scale * scale / (abs(currPOC - currRefPOC) * abs(colPOC - colRefPOC));
                          if (scale > bestOverScale)
                          {
                            bestOverScale    = scale;
                            bestTargetRefIdx = curRefIdx;
                          }
                          if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)) < bestDistScale)
                          {
                            bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
                            targetRefIdx  = curRefIdx;
                          }
                        }
                      }   // curRefIdx
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
                      if (bestTargetRefIdx != -1)
                      {
                        targetRefIdx = bestTargetRefIdx;
                      }
                      if (targetRefIdx == -1)
                      {
                        targetRefIdx = 0;
                      }
                      pcSlice->setImRefIdx2nd(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx,
                                           targetRefIdx, colFrameIdx  );
    #else
                      pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx,
                                           targetRefIdx);
    #endif
                        bestOverScale = 0;
                        scale         = 0;
                        bestTargetRefIdx = -1;
                        bestDistScale = MAX_DOUBLE;
                        targetRefIdx  = -1;
                        for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx));
                             curRefIdx++)
                        {
                          const int  currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
                          const bool bIsCurrRefLongTerm =
                            pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
                          if (bIsCurrRefLongTerm != bIsColRefLongTerm)
                          {
                            continue;
                          }
                          if (bIsCurrRefLongTerm)
                          {
                            targetRefIdx  = curRefIdx;
                            bestDistScale = 1;
                            bestTargetRefIdx = -1;
                            break;
                          }
                          else if (colRefPOC == currRefPOC)
                          {
                            targetRefIdx  = curRefIdx;
                            bestDistScale = 1;
                            bestTargetRefIdx = -1;
                            break;
                          }
                          else
                          {
                            curPOCMax = std::max(currPOC, currRefPOC);
                            curPOCMin = std::min(currPOC, currRefPOC);
                            colPOCMax = std::max(colPOC, colRefPOC);
                            colPOCMin = std::min(colPOC, colRefPOC);
                            scale = std::max(0, std::min(curPOCMax, colPOCMax) - std::max(curPOCMin, colPOCMin));
                            scale = scale * scale / (abs(currPOC - currRefPOC) * abs(colPOC - colRefPOC));
                            if (scale > bestOverScale)
                            {
                              bestOverScale    = scale;
                              bestTargetRefIdx = curRefIdx;
                            }
                            if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0))
                                < bestDistScale)
                            {
                              bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
                              targetRefIdx  = curRefIdx;
                            }
                          }
                        }   // curRefIdx
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
                        if (bestTargetRefIdx != -1)
                        {
                          targetRefIdx = bestTargetRefIdx;
                        }
                        if (targetRefIdx == -1)
                        {
                          targetRefIdx = 0;
                        }
                        pcSlice->setImRefIdx3rd(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx),
                                                colRefIdx, targetRefIdx, colFrameIdx);
    #else
                        pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx),
                                             colRefIdx, targetRefIdx);
    #endif
                    } // curRefPicListIdx
    #else
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
                    const bool bIsColRefLongTerm = pColSlice->getIsUsedAsLongTerm(RefPicList(colRefPicListIdx), colRefIdx);
                    const int colRefPOC = pColSlice->getRefPOC(RefPicList(colRefPicListIdx), colRefIdx);
    
                    for (int curRefPicListIdx = 0; curRefPicListIdx < (pcSlice->isInterB() ? 2 : 1); curRefPicListIdx++)
                    {
    
                      double bestDistScale = MAX_DOUBLE;
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
                      int targetRefIdx = -1;
                      for (int curRefIdx = 0; curRefIdx < pcSlice->getNumRefIdx(RefPicList(curRefPicListIdx)); curRefIdx++)
                      {
                        const int currRefPOC = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->getPOC();
                        const bool bIsCurrRefLongTerm = pcSlice->getRefPic(RefPicList(curRefPicListIdx), curRefIdx)->longTerm;
                        if (bIsCurrRefLongTerm != bIsColRefLongTerm)
                        {
                          continue;
                        }
                        if (bIsCurrRefLongTerm)
                        {
                          targetRefIdx = curRefIdx;
                          bestDistScale = 1;
                          break;
                        }
                        else if (colPOC - colRefPOC == currPOC - currRefPOC)
                        {
                          targetRefIdx = curRefIdx;
                          bestDistScale = 1;
                          break;
                        }
                        else
                        {
                          //printf("colRefPicListIdx:%d, curRefPicListIdx:%d, colRefIdx:%d, targetRefIdx:%d, curRefIdx:%d\n", colRefPicListIdx, curRefPicListIdx, colRefIdx, targetRefIdx, curRefIdx);
                          //printf("currPOC:%d, currRefPOC:%d, colPOC:%d, colRefPOC:%d\n", currPOC, currRefPOC, colPOC, colRefPOC);
                          //printf("bestDistScale:%.2f %.2f\n", bestDistScale, abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)));
                          if (abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0)) < bestDistScale)
                          {
                            bestDistScale = abs(1.0 - (abs(currPOC - currRefPOC) * 1.0 / abs(colPOC - colRefPOC) * 1.0));
                            targetRefIdx = curRefIdx;
                          }
                        }
                      } // curRefIdx
                        //printf("sliceIdx:%d, colRefPicListIdx:%d, curRefPicListIdx:%d, colRefIdx:%d, targetRefIdx:%d\n", sliceIdx, colRefPicListIdx, curRefPicListIdx, colRefIdx, targetRefIdx);
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
                      pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx, colFrameIdx);
    #else
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
                      pcSlice->setImRefIdx(sliceIdx, RefPicList(colRefPicListIdx), RefPicList(curRefPicListIdx), colRefIdx, targetRefIdx);
    
    Yao-Jen Chang's avatar
    Yao-Jen Chang committed
                    } // curRefPicListIdx
    
    #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
            }
    #endif
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #if JVET_Z0118_GDR // scaleRefPicList
    
    Seungwook Hong's avatar
    Seungwook Hong committed
        bool  bDisableTMVP;
        if (pcPic->cs->isGdrEnabled())
        {
          PicHeader *picHeader = new PicHeader;
          *picHeader = *pcPic->cs->picHeader;
    
    Luhang Xu's avatar
    Luhang Xu committed
    #if JVET_AK0065_TALF
          bDisableTMVP = pcSlice->scaleRefPicList(scaledRefPic, picHeader, m_pcEncLib->getApss(), m_pcEncLib->getApss2(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
    #else
    
    Seungwook Hong's avatar
    Seungwook Hong committed
          bDisableTMVP = pcSlice->scaleRefPicList(scaledRefPic, picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
    
    Luhang Xu's avatar
    Luhang Xu committed
    #endif
    
    Luhang Xu's avatar
    Luhang Xu committed
    #if JVET_AK0065_TALF
          bDisableTMVP = pcSlice->scaleRefPicList(scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), m_pcEncLib->getApss2(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
    #else
    
    Seungwook Hong's avatar
    Seungwook Hong committed
          bDisableTMVP = pcSlice->scaleRefPicList(scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false);
    
    Luhang Xu's avatar
    Luhang Xu committed
    #endif
    
    Seungwook Hong's avatar
    Seungwook Hong committed
        }
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #else
    
        bool  bDisableTMVP = pcSlice->scaleRefPicList( scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #endif
    
        if ( picHeader->getEnableTMVPFlag() && bDisableTMVP )
        {
          picHeader->setEnableTMVPFlag( 0 );
        }
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #else
    #if JVET_Z0118_GDR
        PicHeader *picHeader = new PicHeader;
        *picHeader = *pcPic->cs->picHeader;
        pcSlice->scaleRefPicList( scaledRefPic, picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
        picHeader = pcPic->cs->picHeader;
    
    Brian Heng's avatar
    Brian Heng committed
        pcSlice->scaleRefPicList( scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #endif
    
        // set adaptive search range for non-intra-slices
    
        if (m_pcCfg->getUseASR() && !pcSlice->isIntra())
    
        {
          m_pcSliceEncoder->setSearchRange(pcSlice);
        }
    
        bool bGPBcheck=false;
        if ( pcSlice->getSliceType() == B_SLICE)
        {
          if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
          {
            bGPBcheck=true;
            int i;
            for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
            {
              if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) )
              {
                bGPBcheck=false;
                break;
              }
            }
          }
        }
        if(bGPBcheck)
        {
    
    Brian Heng's avatar
    Brian Heng committed
          picHeader->setMvdL1ZeroFlag(true);
    
    Brian Heng's avatar
    Brian Heng committed
          picHeader->setMvdL1ZeroFlag(false);
    
        if ( pcSlice->getSPS()->getUseSMVD() && pcSlice->getCheckLDC() == false
    
    Brian Heng's avatar
    Brian Heng committed
          && picHeader->getMvdL1ZeroFlag() == false
    
        {
          int currPOC = pcSlice->getPOC();
    
          int forwardPOC = currPOC;
    
    Daniel's avatar
    Daniel committed
          int backwardPOC = currPOC;
    
          int ref = 0, refIdx0 = -1, refIdx1 = -1;
    
          // search nearest forward POC in List 0
          for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); ref++ )
          {
            int poc = pcSlice->getRefPic( REF_PIC_LIST_0, ref )->getPOC();
    
            const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_0, ref)->longTerm;
            if ( poc < currPOC && (poc > forwardPOC || refIdx0 == -1) && !isRefLongTerm )
    
            {
              forwardPOC = poc;
              refIdx0 = ref;
            }
          }
    
          // search nearest backward POC in List 1
          for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); ref++ )
          {
            int poc = pcSlice->getRefPic( REF_PIC_LIST_1, ref )->getPOC();
    
            const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_1, ref)->longTerm;
            if ( poc > currPOC && (poc < backwardPOC || refIdx1 == -1) && !isRefLongTerm )
    
    Daniel's avatar
    Daniel committed
              backwardPOC = poc;
    
    Daniel's avatar
    Daniel committed
          if ( !(forwardPOC < currPOC && backwardPOC > currPOC) )
    
          {
            forwardPOC = currPOC;
    
    Daniel's avatar
    Daniel committed
            backwardPOC = currPOC;
    
            refIdx0 = -1;
            refIdx1 = -1;
    
            // search nearest backward POC in List 0
            for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); ref++ )
            {
              int poc = pcSlice->getRefPic( REF_PIC_LIST_0, ref )->getPOC();
    
              const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_0, ref)->longTerm;
              if ( poc > currPOC && (poc < backwardPOC || refIdx0 == -1) && !isRefLongTerm )
    
    Daniel's avatar
    Daniel committed
                backwardPOC = poc;
    
                refIdx0 = ref;
              }
            }
    
            // search nearest forward POC in List 1
            for ( ref = 0; ref < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); ref++ )
            {
              int poc = pcSlice->getRefPic( REF_PIC_LIST_1, ref )->getPOC();
    
              const bool isRefLongTerm = pcSlice->getRefPic(REF_PIC_LIST_1, ref)->longTerm;
              if ( poc < currPOC && (poc > forwardPOC || refIdx1 == -1) && !isRefLongTerm )
    
    Daniel's avatar
    Daniel committed
          if ( forwardPOC < currPOC && backwardPOC > currPOC )
    
          {
            pcSlice->setBiDirPred( true, refIdx0, refIdx1 );
          }
          else
          {
            pcSlice->setBiDirPred( false, -1, -1 );
          }
        }
        else
        {
          pcSlice->setBiDirPred( false, -1, -1 );
        }
    
    #if JVET_Y0128_NON_CTC
        pcSlice->checkBMAvailability(pcSlice);
        pcSlice->checkAmvpMergeModeAvailability(pcSlice);
    #endif
    
    #if JVET_Z0054_BLK_REF_PIC_REORDER
        if (pcSlice->getSPS()->getUseARL())
        {
          pcSlice->generateCombinedList();
          pcSlice->generateRefPicPairList();
        }
    #endif
    
    #if JVET_AF0159_AFFINE_SUBPU_BDOF_REFINEMENT
        pcSlice->generateEqualPocDist();
    #endif
    
    #if JVET_AI0183_MVP_EXTENSION
        pcSlice->generateIntersectingMv();
    #endif
    
    
        double lambda            = 0.0;
        int actualHeadBits       = 0;
        int actualTotalBits      = 0;
        int estimatedBits        = 0;
        int tmpBitsBeforeWriting = 0;
    
        xPicInitRateControl(estimatedBits, iGOPid, lambda, pcPic, pcSlice);
    
    
        uint32_t uiNumSliceSegments = 1;
    
        {
          pcSlice->setDefaultClpRng( *pcSlice->getSPS() );
        }
    
        // Allocate some coders, now the number of tiles are known.
        const uint32_t numberOfCtusInFrame = pcPic->cs->pcv->sizeInCtus;
    
        const int numSubstreamsColumns = pcSlice->getPPS()->getNumTileColumns();
    
    Hendry's avatar
    Hendry committed
        const int numSubstreamRows     = pcSlice->getSPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->cs->pcv->heightInCtus : (pcSlice->getPPS()->getNumTileRows());
    
        const int numSubstreams        = std::max<int> (numSubstreamRows * numSubstreamsColumns, (int) pcPic->cs->pps->getNumSlicesInPic());
    
        std::vector<OutputBitstream> substreamsOut(numSubstreams);
    
    #if ENABLE_QPA
    
        pcPic->m_uEnerHpCtu.resize (numberOfCtusInFrame);
        pcPic->m_iOffsetCtu.resize (numberOfCtusInFrame);
    
    #if ENABLE_QPA_SUB_CTU
    
    Brian Heng's avatar
    Brian Heng committed
        if (pcSlice->getPPS()->getUseDQP() && pcSlice->getCuQpDeltaSubdiv() > 0)
    
          const unsigned   mtsLog2 = (unsigned)floorLog2(std::min (pcPic->cs->sps->getMaxTbSize(), pcv.maxCUWidth));
    
          pcPic->m_subCtuQP.resize ((pcv.maxCUWidth >> mtsLog2) * (pcv.maxCUHeight >> mtsLog2));
        }
    
    #if JVET_V0094_BILATERAL_FILTER
    
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
    
        if (pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() || pcSlice->getPPS()->getUseChromaBIF())
    
    Vadim Seregin's avatar
    Vadim Seregin committed
        // BIF happens in SAO code so this needs to be done
        // even if SAO=0 if BIF=1.
        if (pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() )
    
    #endif
    #else
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
    
        if (pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseChromaBIF())
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #else
    
        if (pcSlice->getSPS()->getSAOEnabledFlag())
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
        {
          pcPic->resizeSAO( numberOfCtusInFrame, 0 );
          pcPic->resizeSAO( numberOfCtusInFrame, 1 );
        }
    
        // it is used for signalling during CTU mode decision, i.e. before ALF processing
    
        if( pcSlice->getSPS()->getALFEnabledFlag() )
    
        {
          pcPic->resizeAlfCtuEnableFlag( numberOfCtusInFrame );
    
          pcPic->resizeAlfCtuAlternative( numberOfCtusInFrame );
    
          pcPic->resizeAlfCtbFilterIndex(numberOfCtusInFrame);
    
        }
    
        bool decPic = false;
        bool encPic = false;
        // test if we can skip the picture entirely or decode instead of encoding
    
        try
        {
          trySkipOrDecodePicture(decPic, encPic, *m_pcCfg, pcPic, m_pcEncLib->getApsMap());
        }
        catch(const std::exception&)
        {
          decPic = false;
    
          tryDecodePicture(nullptr, 0, std::string(""));
        }
     
    
    
    #if JVET_AI0084_ALF_RESIDUALS_SCALING
        if ( decPic && pcPic != nullptr && pcPic->cs->sps->getALFEnabledFlag() )
        {
          m_pcALF->restoreAlfScalePrev( pcPic->m_alfScalePrev );
        }
    #endif
    
    #if JVET_AI0136_ADAPTIVE_DUAL_TREE
        if ( pcSlice->getPPS()->getSliceChromaQpFlag() && pcSlice->getPic()->cs->slice->isIntra() && !pcSlice->getPic()->cs->pcv->ISingleTree && !m_pcCfg->getUsePerceptQPA() && (m_pcCfg->getSliceChromaOffsetQpPeriodicity() == 0))
    #else
    
        if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree (*pcSlice->getPic()->cs) && !m_pcCfg->getUsePerceptQPA() && (m_pcCfg->getSliceChromaOffsetQpPeriodicity() == 0))
    
    #else
        if (pcSlice->getPPS()->getSliceChromaQpFlag() && CS::isDualITree (*pcSlice->getPic()->cs))
    #endif
    
    #if JVET_AC0096
          if (!(pcSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR || pcSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR2 || pcSlice->getPPS()->getPPSId() == ENC_PPS_ID_RPR3))
    
    Fangdong Chen's avatar
    Fangdong Chen committed
          {
    
    #endif
            // overwrite chroma qp offset for dual tree
            pcSlice->setSliceChromaQpDelta(COMPONENT_Cb, m_pcCfg->getChromaCbQpOffsetDualTree());
            pcSlice->setSliceChromaQpDelta(COMPONENT_Cr, m_pcCfg->getChromaCrQpOffsetDualTree());
            if (pcSlice->getSPS()->getJointCbCrEnabledFlag())
            {
              pcSlice->setSliceChromaQpDelta(JOINT_CbCr, m_pcCfg->getChromaCbCrQpOffsetDualTree());
            }
            m_pcSliceEncoder->setUpLambda(pcSlice, pcSlice->getLambdas()[0], pcSlice->getSliceQp());
    #if JVET_AC0096
    
    Fangdong Chen's avatar
    Fangdong Chen committed
          }
    
    Vadim Seregin's avatar
    Vadim Seregin committed
        }
    
    Brian Heng's avatar
    Brian Heng committed
        xPicInitLMCS(pcPic, picHeader, pcSlice);
    
    #if JVET_AG0145_ADAPTIVE_CLIPPING
        if (m_pcCfg->getIntraPeriod() == -1)
        {
          if (pcPic->cs->slice->getSliceType() == I_SLICE)
          {
            pcSlice->setLumaPelMax((1 << pcPic->cs->sps->getBitDepth(toChannelType(COMPONENT_Y))) - 1);
            pcSlice->setLumaPelMin(0);
          }
        }
    #endif
    
    
        if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
        {
    
          picHeader->setExplicitScalingListEnabledFlag( true );
          pcSlice->setExplicitScalingListUsed( true );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    
    
          int apsId = std::min<int>( 7, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) );
    
    Brian Heng's avatar
    Brian Heng committed
          picHeader->setScalingListAPSId( apsId );
    
    
          ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
          APS*  scalingListAPS = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
          assert( scalingListAPS != NULL );
    
    Brian Heng's avatar
    Brian Heng committed
          picHeader->setScalingListAPS( scalingListAPS );
    
    Brian Heng's avatar
    Brian Heng committed
        pcPic->cs->picHeader->setPic(pcPic);
        pcPic->cs->picHeader->setValid();
    
        if(pcPic->cs->sps->getFpelMmvdEnabledFlag())
    
          // cannot set ph_fpel_mmvd_enabled_flag at slice level - need new picture-level version of checkDisFracMmvd algorithm?
    
    Brian Heng's avatar
    Brian Heng committed
          // m_pcSliceEncoder->checkDisFracMmvd( pcPic, 0, numberOfCtusInFrame );
          bool useIntegerMVD = (pcPic->lwidth()*pcPic->lheight() > 1920 * 1080);
          pcPic->cs->picHeader->setDisFracMMVD( useIntegerMVD );
        }
        if (pcSlice->getSPS()->getJointCbCrEnabledFlag())
        {
          m_pcSliceEncoder->setJointCbCrModes(*pcPic->cs, Position(0, 0), pcPic->cs->area.lumaSize());
        }
    
        if( encPic )
        // now compress (trial encode) the various slice segments (slices, and dependent slices)
        {
          DTRACE_UPDATE( g_trace_ctx, ( std::make_pair( "poc", pocCurr ) ) );
    
          const std::vector<uint16_t> sliceLosslessArray = *(m_pcCfg->getSliceLosslessArray());
          bool mixedLossyLossless = m_pcCfg->getMixedLossyLossless();
          if (m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
          {
            pcPic->fillSliceLossyLosslessArray(sliceLosslessArray, mixedLossyLossless);
          }
    
          for(uint32_t sliceIdx = 0; sliceIdx < pcPic->cs->pps->getNumSlicesInPic(); sliceIdx++ )
          {
            pcSlice->setSliceMap( pcPic->cs->pps->getSliceMap( sliceIdx ) );
    
              Position firstCtu;
              firstCtu.x = pcSlice->getFirstCtuRsAddrInSlice() % pcPic->cs->pps->getPicWidthInCtu();
              firstCtu.y = pcSlice->getFirstCtuRsAddrInSlice() / pcPic->cs->pps->getPicWidthInCtu();
    
              int subPicIdx = NOT_VALID;
              for( int sp = 0; sp < pcPic->cs->pps->getNumSubPics(); sp++ )
    
                if( pcPic->cs->pps->getSubPic( sp ).containsCtu( firstCtu ) )
    
              CHECK( subPicIdx == NOT_VALID, "Sub-picture was not found" );
    
              pcSlice->setSliceSubPicId( pcPic->cs->pps->getSubPic( subPicIdx ).getSubPicID() );
            }
    
            if (pcPic->cs->sps->getUseLmcs())
            {
              pcSlice->setLmcsEnabledFlag(picHeader->getLmcsEnabledFlag());
              if (pcSlice->getSliceType() == I_SLICE)
              {
                //reshape original signal
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                if( m_pcCfg->getGopBasedTemporalFilterEnabled() )
                {
                  pcPic->getOrigBuf().copyFrom( pcPic->getFilteredOrigBuf() );
                }
                else
                {
                  pcPic->getOrigBuf().copyFrom( pcPic->getTrueOrigBuf() );
                }
    
    
                if (pcSlice->getLmcsEnabledFlag())
                {
                  pcPic->getOrigBuf(COMPONENT_Y).rspSignal(m_pcReshaper->getFwdLUT());
                  m_pcReshaper->setSrcReshaped(true);
                  m_pcReshaper->setRecReshaped(true);
                }
                else
                {
                  m_pcReshaper->setSrcReshaped(false);
                  m_pcReshaper->setRecReshaped(false);
                }
              }
            }
    
    
            bool isLossless = false;
            if (m_pcCfg->getCostMode() == COST_LOSSLESS_CODING)
            {
    
              isLossless = pcPic->losslessSlice(sliceIdx);
    
            }
            m_pcSliceEncoder->setLosslessSlice(pcPic, isLossless);
    
    
    #if JVET_S0258_SUBPIC_CONSTRAINTS
            if( pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic( REF_PIC_LIST_0, 0 )->subPictures.size() > 1 )
    #else
    
            if (pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic(REF_PIC_LIST_0, 0)->numSubpics > 1)
    
    #if JVET_AJ0158_SUBBLOCK_INTER_EXTENSION
              clipMv2 = clipMvInSubpic2;
    #endif
    
              m_pcEncLib->getInterSearch()->setClipMvInSubPic(true);
    
    #if JVET_AJ0158_SUBBLOCK_INTER_EXTENSION
              clipMv2 = clipMvInPic2;
    #endif
    
              m_pcEncLib->getInterSearch()->setClipMvInSubPic(false);
    
            m_pcSliceEncoder->precompressSlice( pcPic );
    
    #if JVET_AJ0249_NEURAL_NETWORK_BASED 
            pcSlice->setPnnMode(m_pcCfg->getNnipMode());
    #endif
    
            m_pcSliceEncoder->compressSlice   ( pcPic, false, false );
    
    
            if(sliceIdx < pcPic->cs->pps->getNumSlicesInPic() - 1)
    
            {
              uint32_t independentSliceIdx = pcSlice->getIndependentSliceIdx();
              pcPic->allocateNewSlice();
              m_pcSliceEncoder->setSliceSegmentIdx      (uiNumSliceSegments);
              // prepare for next slice
              pcSlice = pcPic->slices[uiNumSliceSegments];
              CHECK(!(pcSlice->getPPS() != 0), "Unspecified error");
              pcSlice->copySliceInfo(pcPic->slices[uiNumSliceSegments - 1]);
              pcSlice->setSliceBits(0);
              independentSliceIdx++;
              pcSlice->setIndependentSliceIdx(independentSliceIdx);
              uiNumSliceSegments++;
            }
          }
    
          duData.clear();
    
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if DUMP_BEFORE_INLOOP
          if( m_pcEncLib->getDumpBeforeInloop() )
          {
            static VideoIOYuv ioBeforeInLoop;
    
            if( pcPic )
            {
              if( !ioBeforeInLoop.isOpen() )
              {
                std::string reconFileName = m_pcEncLib->m_reconFileName;
                size_t pos = reconFileName.find_last_of( '.' );
                if( pos != string::npos )
                {
                  reconFileName.insert( pos, "beforeInloop" );
                }
                else
                {
                  reconFileName.append( "beforeInloop" );
                }
                const BitDepths &bitDepths = pcPic->cs->sps->getBitDepths();
    
                ioBeforeInLoop.open( reconFileName, true, bitDepths.recon, bitDepths.recon, bitDepths.recon );
              }
    
              const Window &conf = pcPic->getConformanceWindow();
              const SPS* sps = pcPic->cs->sps;
              ChromaFormat chromaFormatIDC = sps->getChromaFormatIdc();
    
              InputColourSpaceConversion outputColourSpaceConvert = IPCOLOURSPACE_UNCHANGED;
              bool packedYUVMode = false;
              bool clipOutputVideoToRec709Range = false;
              if( m_pcCfg->getUpscaledOutput() )
              {
    
    #if JVET_AB0082
                ioBeforeInLoop.writeUpscaledPicture(*sps, *pcPic->cs->pps, pcPic->getRecoBuf(), outputColourSpaceConvert, packedYUVMode, m_pcCfg->getUpscaledOutput(), NUM_CHROMA_FORMAT, clipOutputVideoToRec709Range, m_pcCfg->getUpscaleFilerForDisplay());
    #else
    
    Vadim Seregin's avatar
    Vadim Seregin committed
                ioBeforeInLoop.writeUpscaledPicture( *sps, *pcPic->cs->pps, pcPic->getRecoBuf(), outputColourSpaceConvert, packedYUVMode, m_pcCfg->getUpscaledOutput(), NUM_CHROMA_FORMAT, clipOutputVideoToRec709Range );
    
    Vadim Seregin's avatar
    Vadim Seregin committed
              }
              else
              {
                ioBeforeInLoop.write( pcPic->getRecoBuf().get( COMPONENT_Y ).width, pcPic->getRecoBuf().get( COMPONENT_Y ).height, pcPic->getRecoBuf(),
                  outputColourSpaceConvert,
                  packedYUVMode,
                  conf.getWindowLeftOffset() * SPS::getWinUnitX( chromaFormatIDC ),
                  conf.getWindowRightOffset() * SPS::getWinUnitX( chromaFormatIDC ),
                  conf.getWindowTopOffset() * SPS::getWinUnitY( chromaFormatIDC ),
                  conf.getWindowBottomOffset() * SPS::getWinUnitY( chromaFormatIDC ),
                  NUM_CHROMA_FORMAT, clipOutputVideoToRec709Range );
              }
            }
          }
    #endif
    
    
    Seungwook Hong's avatar
    Seungwook Hong committed
    #if JVET_Z0118_GDR
          pcPic->setCleanDirty(false); 
    #endif
    
    
          CodingStructure& cs = *pcPic->cs;
          pcSlice = pcPic->slices[0];
    
    
          if (cs.sps->getUseLmcs() && m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper())
          {
            picHeader->setLmcsEnabledFlag(true);
            int apsId = std::min<int>(3, m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx(m_pcEncLib->getLayerId()));
            picHeader->setLmcsAPSId(apsId);
    
            const PreCalcValues& pcv = *cs.pcv;
            for (uint32_t yPos = 0; yPos < pcv.lumaHeight; yPos += pcv.maxCUHeight)
            {
              for (uint32_t xPos = 0; xPos < pcv.lumaWidth; xPos += pcv.maxCUWidth)
              {
                const CodingUnit* cu = cs.getCU(Position(xPos, yPos), CHANNEL_TYPE_LUMA);
                if (cu->slice->getLmcsEnabledFlag())
                {
                  const uint32_t width = (xPos + pcv.maxCUWidth > pcv.lumaWidth) ? (pcv.lumaWidth - xPos) : pcv.maxCUWidth;
                  const uint32_t height = (yPos + pcv.maxCUHeight > pcv.lumaHeight) ? (pcv.lumaHeight - yPos) : pcv.maxCUHeight;
                  const UnitArea area(cs.area.chromaFormat, Area(xPos, yPos, width, height));
                  cs.getRecoBuf(area).get(COMPONENT_Y).rspSignal(m_pcReshaper->getInvLUT());
                }
              }
            }
            m_pcReshaper->setRecReshaped(false);
    
    Vadim Seregin's avatar
    Vadim Seregin committed
            if( m_pcCfg->getGopBasedTemporalFilterEnabled() )
            {
              pcPic->getOrigBuf().copyFrom( pcPic->getFilteredOrigBuf() );
            }
            else
            {
              pcPic->getOrigBuf().copyFrom( pcPic->getTrueOrigBuf() );
            }
    
    #if JVET_AA0095_ALF_WITH_SAMPLES_BEFORE_DBF
          if (pcSlice->getSPS()->getALFEnabledFlag())
          {
    
            // create ALF object based on the picture size
            Size alfSize = m_pcALF->getAlfSize();
            if (alfSize.width != picWidth || alfSize.height != picHeight)
            {
              m_pcALF->destroy();
              m_pcALF->create(m_pcCfg, picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, m_pcCfg->getBitDepth(), m_pcCfg->getInputBitDepth());
            }
    
    
    #if JVET_AC0162_ALF_RESIDUAL_SAMPLES_INPUT
          if (pcSlice->getSPS()->getALFEnabledFlag())
          {
            // create ALF object based on the picture size
            Size alfSize = m_pcALF->getAlfSize();
            if (alfSize.width != picWidth || alfSize.height != picHeight)
            {
              m_pcALF->destroy();
              m_pcALF->create(m_pcCfg, picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth,
                              m_pcCfg->getBitDepth(), m_pcCfg->getInputBitDepth());
            }
    
            m_pcALF->copyResiData(cs);
          }
    #endif
    
    #if JVET_AJ0188_CODING_INFO_CLASSIFICATION || JVET_AK0091_LAPLACIAN_INFO_IN_ALF
    
          m_pcALF->callCodingInfoBuf( cs ).fill( 0 );
    #endif
    
    Philippe Bordes's avatar
    Philippe Bordes committed
          // create SAO object based on the picture size
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          if( pcSlice->getSPS()->getSAOEnabledFlag()
    
    #if JVET_W0066_CCSAO
              || pcSlice->getSPS()->getCCSAOEnabledFlag()
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if JVET_V0094_BILATERAL_FILTER
              || pcSlice->getPPS()->getUseBIF()
    
    #endif
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
              || pcSlice->getPPS()->getUseChromaBIF()
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
              )
    
    Philippe Bordes's avatar
    Philippe Bordes committed
          {
            Size saoSize = m_pcSAO->getSaoSize();
    
            const uint32_t widthInCtus = (picWidth + maxCUWidth - 1) / maxCUWidth;
            const uint32_t heightInCtus = (picHeight + maxCUHeight - 1) / maxCUHeight;
            const uint32_t numCtuInFrame = widthInCtus * heightInCtus;
            const uint32_t  log2SaoOffsetScaleLuma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - MAX_SAO_TRUNCATED_BITDEPTH);
            const uint32_t  log2SaoOffsetScaleChroma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - MAX_SAO_TRUNCATED_BITDEPTH);
    
            if ( saoSize.width != picWidth || saoSize.height != picHeight ) 
            {
    
    Philippe Bordes's avatar
    Philippe Bordes committed
              m_pcSAO->create(picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, log2SaoOffsetScaleLuma, log2SaoOffsetScaleChroma);
    
    #if JVET_AJ0237_INTERNAL_12BIT
              m_pcSAO->m_bilateralFilter.setInternalBitDepth(pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA));
    #endif
    
    Philippe Bordes's avatar
    Philippe Bordes committed
              m_pcSAO->setReshaper(m_pcReshaper);
            }
    
    
            // create SAO encoder data based on the picture size
            m_pcSAO->destroyEncData();
            m_pcSAO->createEncData(m_pcCfg->getSaoCtuBoundary(), numCtuInFrame);
    
          if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
          {
    
            picHeader->setExplicitScalingListEnabledFlag(true);
            pcSlice->setExplicitScalingListUsed(true);
    
    Brian Heng's avatar
    Brian Heng committed
            int apsId = 0;
            picHeader->setScalingListAPSId( apsId );
    
          // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
    
          if( pcSlice->getSPS()->getSAOEnabledFlag() && m_pcCfg->getSaoCtuBoundary() )
    
    Vadim Seregin's avatar
    Vadim Seregin committed
            // This is fine to skip even if SAO=0 and BIF=1.
    
            m_pcSAO->getPreDBFStatistics( cs );
          }
    
          //-- Loop filter
          if ( m_pcCfg->getDeblockingFilterMetric() )
          {
      #if W0038_DB_OPT
            if ( m_pcCfg->getDeblockingFilterMetric()==2 )
            {
              applyDeblockingFilterParameterSelection(pcPic, uiNumSliceSegments, iGOPid);
            }
            else
            {
      #endif
              applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);
      #if W0038_DB_OPT
            }
      #endif
          }
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if DB_PARAM_TID
          else
          {
            applyDeblockingFilterParameterSelection( pcPic, pcSlice, uiNumSliceSegments, iGOPid );
          }
    #endif
    
    
          if (m_pcCfg->getCostMode() == COST_LOSSLESS_CODING) 
          {
            for (int s = 0; s < uiNumSliceSegments; s++)
            {
              if (pcPic->slices[s]->isLossless())
              {
                pcPic->slices[s]->setDeblockingFilterDisable(true);
              }
            }
          }
    
    #if JVET_AB0171_ASYMMETRIC_DB_FOR_GDR
          if (m_pcCfg->getAsymmetricILF() && (pcPic->cs->picHeader->getInGdrInterval() || pcPic->cs->picHeader->getIsGdrRecoveryPocPic()))
          {
            m_pcLoopFilter->setAsymmetricDB(true);
          }
          else
          {
            m_pcLoopFilter->setAsymmetricDB(false);
          }
    #endif
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    
    
    #if JVET_AJ0188_CODING_INFO_CLASSIFICATION || JVET_AK0091_LAPLACIAN_INFO_IN_ALF
    
          const bool storeCodingInfo = cs.sps->getALFEnabledFlag();
          PelUnitBuf codingInfoBuf = storeCodingInfo ? m_pcALF->callCodingInfoBuf( cs ) : PelUnitBuf();
          m_pcLoopFilter->loopFilterPic( cs, codingInfoBuf, storeCodingInfo );
    
    #if JVET_AK0121_LOOPFILTER_OFFSET_REFINEMENT
          if( cs.sps->getALFEnabledFlag() )
          {
            bool sliceTypeCondition = true;
            bool enableRefinement = false;
            bool dbfEnabled = !cs.slice->getDeblockingFilterDisable();
            PelUnitBuf dbfInput = m_pcALF->callRecBeforeDbfBuf();
            PelUnitBuf dbfOutput = cs.getRecoBuf();
    
            PelUnitBuf dbfOffsetRefine0 = m_pcALF->callRecAfterSaoBuf();
            PelUnitBuf dbfOffsetRefine1 = m_pcALF->callRecBeforeAlfBuf();
    
            int stageIdx = 0;
            int refineIdx = 0;
    
            if( sliceTypeCondition && dbfEnabled )
            {
              m_pcALF->calcOffsetRefinement(cs, dbfInput, dbfOutput, dbfOffsetRefine0, stageIdx, 0 );
              m_pcALF->calcOffsetRefinement(cs, dbfInput, dbfOutput, dbfOffsetRefine1, stageIdx, 1 );
              enableRefinement = m_pcALF->calcOffsetRefinementOnOff(cs, dbfOutput, dbfOffsetRefine0, dbfOffsetRefine1, refineIdx );
            }
    
            if( sliceTypeCondition && enableRefinement )
            {
              cs.slice->setOffsetRefinementDbf( true );
              cs.slice->setOffsetRefinementDbfIdx( refineIdx );
              m_pcALF->copyOffsetRefinement(cs, refineIdx ? dbfOffsetRefine1 : dbfOffsetRefine0, dbfOutput);
            }
            else
            {
              cs.slice->setOffsetRefinementDbf( false );
              cs.slice->setOffsetRefinementDbfIdx( false );
            }
          }
    #endif
    
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #if !MULTI_PASS_DMVR
    
          CS::setRefinedMotionField(cs);
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
    #if JVET_AE0043_CCP_MERGE_TEMPORAL
          if ((pcPic->temporalId == 0) || (pcPic->temporalId < pcSlice->getSPS()->getMaxTLayers() - 1))
          {
            CS::saveTemporalCcpModel(cs);
          }
    #endif
    
    #if JVET_AG0058_EIP
          if ((pcPic->temporalId == 0) || (pcPic->temporalId < pcSlice->getSPS()->getMaxTLayers() - 1))
          {
            CS::saveTemporalEipModel(cs);
          }
    #endif
    
    Xiaoyu Xiu's avatar
    Xiaoyu Xiu committed
    #if JVET_W0066_CCSAO
          if ( cs.sps->getCCSAOEnabledFlag() )
          {
            m_pcSAO->getCcSaoBuf().copyFrom( cs.getRecoBuf() );
          }
    #endif
    
    
    #if JVET_V0094_BILATERAL_FILTER
    
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
    
          if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() || pcSlice->getPPS()->getUseChromaBIF())
    
    Vadim Seregin's avatar
    Vadim Seregin committed
          // We need to do this step if at least one of BIF or SAO are enabled.
          if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF())
    
    #endif
    #else
    #if JVET_X0071_CHROMA_BILATERAL_FILTER
    
          if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseChromaBIF())
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #else
    
          if( pcSlice->getSPS()->getSAOEnabledFlag() )
    
    Vadim Seregin's avatar
    Vadim Seregin committed
    #endif
    
          {
            bool sliceEnabled[MAX_NUM_COMPONENT];
            m_pcSAO->initCABACEstimator( m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice );
    
    #if JVET_V0094_BILATERAL_FILTER
    
    Vadim Seregin's avatar
    Vadim Seregin committed
            BIFCabacEstImp est(m_pcEncLib->getCABACEncoder()->getCABACEstimator(cs.slice->getSPS()));