Skip to content
Snippets Groups Projects
EncReshape.cpp 40.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Taoran Lu's avatar
    Taoran Lu committed
    /* The copyright in this software is being made available under the BSD
    * License, included below. This software may be subject to other third party
    * and contributor rights, including patent rights, and no such rights are
    * granted under this license.
    *
    * Copyright (c) 2010-2019, ITU/ISO/IEC
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions are met:
    *
    *  * Redistributions of source code must retain the above copyright notice,
    *    this list of conditions and the following disclaimer.
    *  * Redistributions in binary form must reproduce the above copyright notice,
    *    this list of conditions and the following disclaimer in the documentation
    *    and/or other materials provided with the distribution.
    *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
    *    be used to endorse or promote products derived from this software without
    *    specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
    * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
    * THE POSSIBILITY OF SUCH DAMAGE.
    */
    
    /** \file     EncReshape.cpp
    \brief    encoder reshaper class
    */
    #include "EncReshape.h"
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #if JVET_M0427_INLOOP_RESHAPER
    //! \ingroup EncLib
    //! \{
    
    // ====================================================================================================================
    // Constructor / destructor / create / destroy
    // ====================================================================================================================
    
    EncReshape::EncReshape()
    {
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_CTUFlag      = false;
      m_srcReshaped  = false;
      m_recReshaped  = false;
      m_reshape      = true;
      m_exceedSTD    = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_tcase        = 0;
      m_rateAdpMode  = 0;
      m_chromaAdj    = 0;
    }
    
    EncReshape::~EncReshape()
    {
    }
    
    
    void  EncReshape::createEnc(int picWidth, int picHeight, uint32_t maxCUWidth, uint32_t maxCUHeight, int bitDepth)
    
      m_lumaBD = bitDepth;
      m_reshapeLUTSize = 1 << m_lumaBD;
      m_initCWAnalyze = m_reshapeLUTSize / PIC_ANALYZE_CW_BINS;
      m_initCW = m_reshapeLUTSize / PIC_CODE_CW_BINS;
    
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (m_fwdLUT.empty())
        m_fwdLUT.resize(m_reshapeLUTSize, 0);
      if (m_invLUT.empty())
        m_invLUT.resize(m_reshapeLUTSize,0);
    
      if (m_binCW.empty())
        m_binCW.resize(PIC_ANALYZE_CW_BINS);
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (m_binImportance.empty())
        m_binImportance.resize(PIC_ANALYZE_CW_BINS);
    
      if (m_reshapePivot.empty())
        m_reshapePivot.resize(PIC_CODE_CW_BINS + 1, 0);
      if (m_chromaAdjHelpLUT.empty())
        m_chromaAdjHelpLUT.resize(PIC_CODE_CW_BINS, 1<<CSCALE_FP_PREC);
    
    Taoran Lu's avatar
    Taoran Lu committed
    
      m_sliceReshapeInfo.setUseSliceReshaper(true);
      m_sliceReshapeInfo.setSliceReshapeChromaAdj(true);
      m_sliceReshapeInfo.setSliceReshapeModelPresentFlag(true);
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_sliceReshapeInfo.reshaperModelMinBinIdx = 0;
      m_sliceReshapeInfo.reshaperModelMaxBinIdx = PIC_CODE_CW_BINS - 1;
      memset(m_sliceReshapeInfo.reshaperModelBinCWDelta, 0, (PIC_CODE_CW_BINS) * sizeof(int));
    
    Taoran Lu's avatar
    Taoran Lu committed
    
      m_picWidth = picWidth;
      m_picHeight = picHeight;
      m_maxCUWidth = maxCUWidth;
      m_maxCUHeight = maxCUHeight;
      m_widthInCtus = (m_picWidth + m_maxCUWidth - 1) / m_maxCUWidth;
      m_heightInCtus = (m_picHeight + m_maxCUHeight - 1) / m_maxCUHeight;
      m_numCtuInFrame = m_widthInCtus * m_heightInCtus;
    }
    
    void  EncReshape::destroy()
    {
    }
    
    /**
    -Perform HDR set up
    \param   pcPic describe pointer of current coding picture
    \param   sliceType describe the slice type
    */
    
    Taoran Lu's avatar
    Taoran Lu committed
    void EncReshape::preAnalyzerHDR(Picture *pcPic, const SliceType sliceType, const ReshapeCW& reshapeCW, bool isDualT)
    
    #else
    void EncReshape::preAnalyzerHDR(Picture *pcPic, const SliceType sliceType, const ReshapeCW& reshapeCW, bool isDualT, bool isIBC)
    #endif
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (m_lumaBD >= 10)
    
    Taoran Lu's avatar
    Taoran Lu committed
        m_sliceReshapeInfo.sliceReshaperEnableFlag = true;
        if (reshapeCW.rspIntraPeriod == 1)
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (pcPic->getPOC() == 0)          { m_sliceReshapeInfo.sliceReshaperModelPresentFlag = true;  }
          else                               { m_sliceReshapeInfo.sliceReshaperModelPresentFlag = false; }
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (sliceType == I_SLICE )                                              { m_sliceReshapeInfo.sliceReshaperModelPresentFlag = true;  }
    
    #else
          if (sliceType == I_SLICE || (sliceType == P_SLICE && isIBC))            { m_sliceReshapeInfo.sliceReshaperModelPresentFlag = true;  }
    #endif
    
    Taoran Lu's avatar
    Taoran Lu committed
          else                                                                    { m_sliceReshapeInfo.sliceReshaperModelPresentFlag = false; }
    
    Taoran Lu's avatar
    Taoran Lu committed
        if (sliceType == I_SLICE  && isDualT)                                     { m_sliceReshapeInfo.enableChromaAdj = 0;                   }
    
    #else
        if ((sliceType == I_SLICE || (sliceType == P_SLICE && isIBC)) && isDualT) { m_sliceReshapeInfo.enableChromaAdj = 0;                   }
    #endif
    
    Taoran Lu's avatar
    Taoran Lu committed
        else                                                                      { m_sliceReshapeInfo.enableChromaAdj = 1;                   }
    
    Taoran Lu's avatar
    Taoran Lu committed
        m_sliceReshapeInfo.sliceReshaperEnableFlag = false;
        m_sliceReshapeInfo.sliceReshaperModelPresentFlag = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
      }
    }
    
    /**
    -Perform picture analysis for SDR
    \param   pcPic describe pointer of current coding picture
    \param   sliceType describe the slice type
    \param   reshapeCW describe some input info
    */
    
    Taoran Lu's avatar
    Taoran Lu committed
    void EncReshape::preAnalyzerSDR(Picture *pcPic, const SliceType sliceType, const ReshapeCW& reshapeCW, bool isDualT)
    
    #else
    void EncReshape::preAnalyzerSDR(Picture *pcPic, const SliceType sliceType, const ReshapeCW& reshapeCW, bool isDualT, bool isIBC)
    #endif
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_sliceReshapeInfo.sliceReshaperModelPresentFlag = true;
      m_sliceReshapeInfo.sliceReshaperEnableFlag = true;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int modIP = pcPic->getPOC() - pcPic->getPOC() / reshapeCW.rspFpsToIp * reshapeCW.rspFpsToIp;
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (sliceType == I_SLICE || (reshapeCW.rspIntraPeriod == -1 && modIP == 0))
    
    #else
      if (sliceType == I_SLICE || (reshapeCW.rspIntraPeriod == -1 && modIP == 0) || (sliceType == P_SLICE && isIBC))
    #endif
    
    Taoran Lu's avatar
    Taoran Lu committed
        if (m_sliceReshapeInfo.sliceReshaperModelPresentFlag == true)
    
    Taoran Lu's avatar
    Taoran Lu committed
          int stdMin = 16 <<(m_lumaBD-8);
          int stdMax = 235 << (m_lumaBD - 8);
    
          int  binLen = m_reshapeLUTSize / PIC_ANALYZE_CW_BINS;
    
    Taoran Lu's avatar
    Taoran Lu committed
    
          m_reshapeCW = reshapeCW;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_initCWAnalyze = binLen;
    
    Taoran Lu's avatar
    Taoran Lu committed
    
          for (int b = 0; b < PIC_ANALYZE_CW_BINS; b++)
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_binImportance[b] = 0;
    
            m_binCW[b] = binLen;
    
    Taoran Lu's avatar
    Taoran Lu committed
          int startBinIdx = stdMin / binLen;
          int endBinIdx = stdMax / binLen;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_sliceReshapeInfo.reshaperModelMinBinIdx = startBinIdx;
          m_sliceReshapeInfo.reshaperModelMaxBinIdx = endBinIdx;
    
    Taoran Lu's avatar
    Taoran Lu committed
    
          PelBuf picY = pcPic->getOrigBuf(COMPONENT_Y);
    
    Taoran Lu's avatar
    Taoran Lu committed
          const int width = picY.width;
          const int height = picY.height;
          const int stride = picY.stride;
    
    Taoran Lu's avatar
    Taoran Lu committed
          double blockBinVarSum[PIC_ANALYZE_CW_BINS] = { 0.0 };
          uint32_t   bockBinCnt[PIC_ANALYZE_CW_BINS] = { 0 };
    
          const int PIC_ANALYZE_WIN_SIZE = 5;
    
          const uint32_t winSize = PIC_ANALYZE_WIN_SIZE;
          const uint32_t winLens = (winSize - 1) >> 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
    
          int64_t tempSq = 0;
          int64_t leftSum = 0, leftSumSq = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          int64_t *leftColSum = new int64_t[width];
          int64_t *leftColSumSq = new int64_t[width];
          memset(leftColSum, 0, width * sizeof(int64_t));
          memset(leftColSumSq, 0, width * sizeof(int64_t));
    
    Taoran Lu's avatar
    Taoran Lu committed
          int64_t topSum = 0, topSumSq = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          int64_t *topRowSum = new int64_t[height];
          int64_t *topRowSumSq = new int64_t[height];
          memset(topRowSum, 0, height * sizeof(int64_t));
          memset(topRowSumSq, 0, height * sizeof(int64_t));
          int64_t *topColSum = new int64_t[width];
          int64_t *topColSumSq = new int64_t[width];
          memset(topColSum, 0, width * sizeof(int64_t));
          memset(topColSumSq, 0, width * sizeof(int64_t));
    
          for (uint32_t y = 0; y < height; y++)
    
    Taoran Lu's avatar
    Taoran Lu committed
            for (uint32_t x = 0; x < width; x++)
    
    Taoran Lu's avatar
    Taoran Lu committed
              const Pel pxlY = picY.buf[x];
              int64_t sum = 0;
              int64_t sumSq = 0;
              uint32_t numPixInPart = 0;
    
              uint32_t y1 = std::max((int)(y - winLens), 0);
              uint32_t y2 = std::min((int)(y + winLens), (height - 1));
              uint32_t x1 = std::max((int)(x - winLens), 0);
              uint32_t x2 = std::min((int)(x + winLens), (width - 1));
    
    Taoran Lu's avatar
    Taoran Lu committed
    
    
              uint32_t bx = 0, by = 0;
              const Pel *pWinY = &picY.buf[0];
    
    Taoran Lu's avatar
    Taoran Lu committed
              numPixInPart = (x2 - x1 + 1) * (y2 - y1 + 1);
    
    Taoran Lu's avatar
    Taoran Lu committed
    
              if (x == 0 && y == 0)           // for the 1st Pixel, calc all points
              {
                for (by = y1; by <= y2; by++)
                {
                  for (bx = x1; bx <= x2; bx++)
                  {
                    tempSq = pWinY[bx] * pWinY[bx];
                    leftSum += pWinY[bx];
                    leftSumSq += tempSq;
                    leftColSum[bx] += pWinY[bx];
                    leftColSumSq[bx] += tempSq;
                    topColSum[bx] += pWinY[bx];
                    topColSumSq[bx] += tempSq;
                    topRowSum[by] += pWinY[bx];
                    topRowSumSq[by] += tempSq;
                  }
    
    Taoran Lu's avatar
    Taoran Lu committed
                  pWinY += stride;
    
    Taoran Lu's avatar
    Taoran Lu committed
                }
                topSum = leftSum;
                topSumSq = leftSumSq;
    
    Taoran Lu's avatar
    Taoran Lu committed
                sum = leftSum;
                sumSq = leftSumSq;
    
    Taoran Lu's avatar
    Taoran Lu committed
              }
              else if (x == 0 && y > 0)       // for the 1st column, calc the bottom stripe
              {
    
                if (y < height - winLens)
    
                  pWinY += winLens*stride;
                  topRowSum[y + winLens] = 0;
                  topRowSumSq[y + winLens] = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
                  for (bx = x1; bx <= x2; bx++)
                  {
    
                    topRowSum[y + winLens] += pWinY[bx];
                    topRowSumSq[y + winLens] += pWinY[bx] * pWinY[bx];
    
                  topSum += topRowSum[y + winLens];
                  topSumSq += topRowSumSq[y + winLens];
    
                  topSum -= topRowSum[y - 1 - winLens];
                  topSumSq -= topRowSumSq[y - 1 - winLens];
    
    Taoran Lu's avatar
    Taoran Lu committed
                memset(leftColSum, 0, width * sizeof(int64_t));
                memset(leftColSumSq, 0, width * sizeof(int64_t));
    
    Taoran Lu's avatar
    Taoran Lu committed
                pWinY = &picY.buf[0];
    
                pWinY -= (y <= winLens ? y : winLens)*stride;
    
    Taoran Lu's avatar
    Taoran Lu committed
                for (by = y1; by <= y2; by++)
                {
                  for (bx = x1; bx <= x2; bx++)
                  {
                    leftColSum[bx] += pWinY[bx];
                    leftColSumSq[bx] += pWinY[bx] * pWinY[bx];
                  }
    
    Taoran Lu's avatar
    Taoran Lu committed
                  pWinY += stride;
    
    Taoran Lu's avatar
    Taoran Lu committed
                }
    
                leftSum = topSum;
                leftSumSq = topSumSq;
    
    Taoran Lu's avatar
    Taoran Lu committed
                sum = topSum;
                sumSq = topSumSq;
    
    Taoran Lu's avatar
    Taoran Lu committed
              }
    
              else if (x > 0)
              {
    
                if (x < width - winLens)
    
                  pWinY -= (y <= winLens ? y : winLens)*stride;
    
    Taoran Lu's avatar
    Taoran Lu committed
                  if (y == 0)                 // for the 1st row, calc the right stripe
                  {
    
                    leftColSum[x + winLens] = 0;
                    leftColSumSq[x + winLens] = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
                    for (by = y1; by <= y2; by++)
                    {
    
                      leftColSum[x + winLens] += pWinY[x + winLens];
                      leftColSumSq[x + winLens] += pWinY[x + winLens] * pWinY[x + winLens];
    
    Taoran Lu's avatar
    Taoran Lu committed
                      pWinY += stride;
    
                  else                        // for the main area, calc the B-R point
    
                    leftColSum[x + winLens] = topColSum[x + winLens];
                    leftColSumSq[x + winLens] = topColSumSq[x + winLens];
                    if (y < height - winLens)
    
    Taoran Lu's avatar
    Taoran Lu committed
                    {
                      pWinY = &picY.buf[0];
    
                      pWinY += winLens * stride;
                      leftColSum[x + winLens] += pWinY[x + winLens];
                      leftColSumSq[x + winLens] += pWinY[x + winLens] * pWinY[x + winLens];
    
    Taoran Lu's avatar
    Taoran Lu committed
                    {
                      pWinY = &picY.buf[0];
    
                      pWinY -= (winLens + 1) * stride;
                      leftColSum[x + winLens] -= pWinY[x + winLens];
                      leftColSumSq[x + winLens] -= pWinY[x + winLens] * pWinY[x + winLens];
    
                  topColSum[x + winLens] = leftColSum[x + winLens];
                  topColSumSq[x + winLens] = leftColSumSq[x + winLens];
                  leftSum += leftColSum[x + winLens];
                  leftSumSq += leftColSumSq[x + winLens];
    
                  leftSum -= leftColSum[x - 1 - winLens];
                  leftSumSq -= leftColSumSq[x - 1 - winLens];
    
    Taoran Lu's avatar
    Taoran Lu committed
                sum = leftSum;
                sumSq = leftSumSq;
    
    Taoran Lu's avatar
    Taoran Lu committed
              double average = double(sum) / numPixInPart;
              double variance = double(sumSq) / numPixInPart - average * average;
    
              uint32_t binNum = (uint32_t)(pxlY/PIC_ANALYZE_CW_BINS);
    
    
              if (m_lumaBD > 10)
              {
    
    Taoran Lu's avatar
    Taoran Lu committed
                average = average / (double)(1<<(m_lumaBD - 10));
                variance = variance / (double)(1 << (2*m_lumaBD - 20));
    
                binNum = (uint32_t)((pxlY>>(m_lumaBD - 10)) / PIC_ANALYZE_CW_BINS);
    
              }
              else if (m_lumaBD < 10)
              {
    
    Taoran Lu's avatar
    Taoran Lu committed
                average = average * (double)(1 << (10 - m_lumaBD));
                variance = variance * (double)(1 << (20-2*m_lumaBD));
    
                binNum = (uint32_t)((pxlY << (10 - m_lumaBD)) / PIC_ANALYZE_CW_BINS);
    
    Taoran Lu's avatar
    Taoran Lu committed
              double varLog10 = log10(variance + 1.0);
    
              blockBinVarSum[binNum] += varLog10;
              bockBinCnt[binNum]++;
    
    Taoran Lu's avatar
    Taoran Lu committed
            picY.buf += stride;
    
    Taoran Lu's avatar
    Taoran Lu committed
          }
    
          delete[] topColSum;
          delete[] topColSumSq;
          delete[] topRowSum;
          delete[] topRowSumSq;
          delete[] leftColSum;
          delete[] leftColSumSq;
    
          for (int b = 0; b < PIC_ANALYZE_CW_BINS; b++)
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (bockBinCnt[b] > 0)
              blockBinVarSum[b] = blockBinVarSum[b] / bockBinCnt[b];
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshape = true;
          m_exceedSTD = false;
          m_useAdpCW = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_chromaWeight = 1.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_sliceReshapeInfo.enableChromaAdj = 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
          bool   intraAdp = false;
          bool   interAdp = true;
          double reshapeTH1 = 0.0;
          double reshapeTH2 = 5.0;
          deriveReshapeParametersSDRfromStats(bockBinCnt, blockBinVarSum, &reshapeTH1, &reshapeTH2, &intraAdp, &interAdp);
    
          if (m_rateAdpMode == 2 && reshapeCW.rspBaseQP <= 22)
    
    Taoran Lu's avatar
    Taoran Lu committed
            intraAdp = false;
            interAdp = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_sliceReshapeInfo.sliceReshaperEnableFlag = intraAdp;
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (!intraAdp && !interAdp)
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_sliceReshapeInfo.sliceReshaperModelPresentFlag = false;
            m_reshape = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (m_exceedSTD)
    
            startBinIdx = 2;
            endBinIdx = 29;
    
    Taoran Lu's avatar
    Taoran Lu committed
            for (int b = 0; b < PIC_ANALYZE_CW_BINS; b++)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              if (bockBinCnt[b] > 0 && b < startBinIdx)
    
                startBinIdx = b;
    
    Taoran Lu's avatar
    Taoran Lu committed
              if (bockBinCnt[b] > 0 && b > endBinIdx)
    
                endBinIdx = b;
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_sliceReshapeInfo.reshaperModelMinBinIdx = startBinIdx;
            m_sliceReshapeInfo.reshaperModelMaxBinIdx = endBinIdx;
    
          m_initCWAnalyze = m_lumaBD > 10 ? (m_initCWAnalyze >> (m_lumaBD - 10)) : m_lumaBD < 10 ? (m_initCWAnalyze << (10 - m_lumaBD)) : m_initCWAnalyze;
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (reshapeCW.rspBaseQP <= 22 && m_rateAdpMode == 1)
    
    Taoran Lu's avatar
    Taoran Lu committed
          {
            for (int i = 0; i < PIC_ANALYZE_CW_BINS; i++)
            {
    
              if (i >= startBinIdx && i <= endBinIdx)
                m_binCW[i] = m_initCWAnalyze + 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
              else
    
                m_binCW[i] = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          else if (m_useAdpCW)
    
    Taoran Lu's avatar
    Taoran Lu committed
          {
            double Alpha = 1.0, Beta = 0.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
            deriveReshapeParameters(blockBinVarSum, startBinIdx, endBinIdx, m_reshapeCW, Alpha, Beta);
    
    Taoran Lu's avatar
    Taoran Lu committed
            for (int i = 0; i < PIC_ANALYZE_CW_BINS; i++)
            {
    
              if (i >= startBinIdx && i <= endBinIdx)
    
    Taoran Lu's avatar
    Taoran Lu committed
                m_binCW[i] = (uint32_t)round(Alpha*blockBinVarSum[i] + Beta);
    
    Taoran Lu's avatar
    Taoran Lu committed
              else
    
                m_binCW[i] = 0;
    
            for (int b = startBinIdx; b <= endBinIdx; b++)
    
    Taoran Lu's avatar
    Taoran Lu committed
              if (blockBinVarSum[b] < reshapeTH1)
                m_binImportance[b] = 2;
              else if (blockBinVarSum[b] > reshapeTH2)
                m_binImportance[b] = 3;
    
    Taoran Lu's avatar
    Taoran Lu committed
              else
    
    Taoran Lu's avatar
    Taoran Lu committed
                m_binImportance[b] = 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
            }
    
            for (int i = 0; i < PIC_ANALYZE_CW_BINS; i++)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              if (m_binImportance[i] == 0)
    
                m_binCW[i] = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
              else if (m_binImportance[i] == 1)
    
                m_binCW[i] = m_initCWAnalyze + 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
              else if (m_binImportance[i] == 2)
                m_binCW[i] = m_reshapeCW.binCW[0];
              else if (m_binImportance[i] == 3)
                m_binCW[i] = m_reshapeCW.binCW[1];
    
    Taoran Lu's avatar
    Taoran Lu committed
              else
                THROW("SDR Reshape Bin Importance not supported");
            }
          }
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (m_reshapeCW.rspPicSize <= 1497600 && reshapeCW.rspIntraPeriod == -1 && modIP == 0 && sliceType != I_SLICE)
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_sliceReshapeInfo.sliceReshaperEnableFlag = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
        m_chromaAdj = m_sliceReshapeInfo.enableChromaAdj;
    
    Taoran Lu's avatar
    Taoran Lu committed
        if (sliceType == I_SLICE && isDualT)
    
    #else
        if ((sliceType == I_SLICE || (sliceType == P_SLICE && isIBC)) && isDualT)
    #endif
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_sliceReshapeInfo.enableChromaAdj = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
        }
      }
      else // Inter slices
      {
    
    Taoran Lu's avatar
    Taoran Lu committed
        m_sliceReshapeInfo.sliceReshaperModelPresentFlag = false;
        m_sliceReshapeInfo.enableChromaAdj = m_chromaAdj;
    
    Taoran Lu's avatar
    Taoran Lu committed
        if (!m_reshape)
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_sliceReshapeInfo.sliceReshaperEnableFlag = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
          const int cTid = m_reshapeCW.rspTid;
    
    Taoran Lu's avatar
    Taoran Lu committed
          bool enableRsp = m_tcase == 5 ? false : (m_tcase < 5 ? (cTid < m_tcase + 1 ? false : true) : (cTid <= 10 - m_tcase ? true : false));
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_sliceReshapeInfo.sliceReshaperEnableFlag = enableRsp;
    
    Taoran Lu's avatar
    Taoran Lu committed
        }
      }
    }
    
    // Bubble Sort to  descending order with index
    void EncReshape::bubbleSortDsd(double* array, int * idx, int n)
    {
      int i, j;
      bool swapped;
      for (i = 0; i < n - 1; i++)
      {
        swapped = false;
        for (j = 0; j < n - i - 1; j++)
        {
          if (array[j] < array[j + 1])
          {
            swap(&array[j], &array[j + 1]);
            swap(&idx[j], &idx[j + 1]);
            swapped = true;
          }
        }
        if (swapped == false)
          break;
      }
    }
    
    
    Taoran Lu's avatar
    Taoran Lu committed
    void EncReshape::deriveReshapeParametersSDRfromStats(uint32_t * blockBinCnt, double *blockBinVarSum, double* reshapeTH1, double* reshapeTH2, bool *intraAdp, bool *interAdp)
    
    Taoran Lu's avatar
    Taoran Lu committed
      int    binIdxSortDsd[PIC_ANALYZE_CW_BINS]    = { 0 };
      double binVarSortDsd[PIC_ANALYZE_CW_BINS]    = { 0.0 };
      double binHist[PIC_ANALYZE_CW_BINS]          = { 0.0 };
      double binVarSortDsdCDF[PIC_ANALYZE_CW_BINS] = { 0.0 };
    
    Taoran Lu's avatar
    Taoran Lu committed
      double maxBinVar = 0.0, meanBinVar = 0.0, minBinVar = 5.0;
      int    nonZeroBinCt = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int    firstBinVarLessThanVal1 = 0;
      int    firstBinVarLessThanVal2 = 0;
      int    firstBinVarLessThanVal3 = 0;
      int    firstBinVarLessThanVal4 = 0;
    
    
    Taoran Lu's avatar
    Taoran Lu committed
      for (int b = 0; b < PIC_ANALYZE_CW_BINS; b++)
      {
    
    Taoran Lu's avatar
    Taoran Lu committed
        binHist[b] = (double) blockBinCnt[b] / (double)(m_reshapeCW.rspPicSize);
        if (binHist[b] > 0.001)
    
    Taoran Lu's avatar
    Taoran Lu committed
        {
          nonZeroBinCt++;
    
    Taoran Lu's avatar
    Taoran Lu committed
          meanBinVar += blockBinVarSum[b];
          if (blockBinVarSum[b] > maxBinVar)        {        maxBinVar = blockBinVarSum[b];      }
          if (blockBinVarSum[b] < minBinVar)        {        minBinVar = blockBinVarSum[b];      }
    
    Taoran Lu's avatar
    Taoran Lu committed
        binVarSortDsd[b] = blockBinVarSum[b];
        binIdxSortDsd[b] = b;
    
    Taoran Lu's avatar
    Taoran Lu committed
      if ((binHist[0] + binHist[1] + binHist[PIC_ANALYZE_CW_BINS - 2] + binHist[PIC_ANALYZE_CW_BINS - 1]) > 0.01)   {    m_exceedSTD = true;  }
      if ((binHist[PIC_ANALYZE_CW_BINS - 2] + binHist[PIC_ANALYZE_CW_BINS - 1]) > 0.01)   {    *interAdp = false;    return;   }
      else                                                                                {    *interAdp = true;               }
    
    Taoran Lu's avatar
    Taoran Lu committed
    
      meanBinVar = meanBinVar / (double)nonZeroBinCt;
    
    Taoran Lu's avatar
    Taoran Lu committed
      bubbleSortDsd(binVarSortDsd, binIdxSortDsd, PIC_ANALYZE_CW_BINS);
      binVarSortDsdCDF[0] = binHist[binIdxSortDsd[0]];
    
    
    Taoran Lu's avatar
    Taoran Lu committed
      for (int b = 1; b < PIC_ANALYZE_CW_BINS; b++)
      {
    
    Taoran Lu's avatar
    Taoran Lu committed
        binVarSortDsdCDF[b] = binVarSortDsdCDF[b - 1] + binHist[binIdxSortDsd[b]];
    
    Taoran Lu's avatar
    Taoran Lu committed
      }
    
      for (int b = 0; b < PIC_ANALYZE_CW_BINS - 1; b++)
      {
    
    Taoran Lu's avatar
    Taoran Lu committed
        if (binVarSortDsd[b] > 3.5)     {      firstBinVarLessThanVal1 = b + 1;    }
        if (binVarSortDsd[b] > 3.0)     {      firstBinVarLessThanVal2 = b + 1;    }
        if (binVarSortDsd[b] > 2.5)     {      firstBinVarLessThanVal3 = b + 1;    }
        if (binVarSortDsd[b] > 2.0)     {      firstBinVarLessThanVal4 = b + 1;    }
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_reshapeCW.binCW[0] = 38;
      m_reshapeCW.binCW[1] = 28;
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (m_reshapeCW.rspIntraPeriod == -1)
    
    Taoran Lu's avatar
    Taoran Lu committed
        *intraAdp = true;
        if (m_reshapeCW.rspPicSize > 1497600)
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshapeCW.binCW[0] = 36;
          *reshapeTH1 = 2.4;
          *reshapeTH2 = 4.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_rateAdpMode = 2;
    
          if (meanBinVar >= 2.52)
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.5)
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.5;
              *reshapeTH2 = 3.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
            else if (binVarSortDsdCDF[firstBinVarLessThanVal2] < 0.1 && binVarSortDsdCDF[firstBinVarLessThanVal1] > 0.02)
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.2;
    
    Taoran Lu's avatar
    Taoran Lu committed
            else if (binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.25)
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[1] = 30;
              *reshapeTH1 = 2.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_rateAdpMode = 0;
            }
            else
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[1] = 30;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_rateAdpMode = 1;
            }
          }
        }
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (m_reshapeCW.rspPicSize > 660480)
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshapeCW.binCW[0] = 34;
          *reshapeTH1 = 3.4;
          *reshapeTH2 = 4.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_rateAdpMode = 2;
    
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (binVarSortDsdCDF[firstBinVarLessThanVal4] > 0.6)
    
    Taoran Lu's avatar
    Taoran Lu committed
          {
            if (maxBinVar < 3.5)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_useAdpCW = true;
              m_reshapeCW.binCW[0] = 38;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[0] = 40;
              *reshapeTH1 = 2.2;
              *reshapeTH2 = 4.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_rateAdpMode = 0;
            }
          }
          else
          {
            if (maxBinVar > 3.3)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[1] = 30;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[1] = 28;
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (m_reshapeCW.rspPicSize > 249600)
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshapeCW.binCW[0] = 36;
          *reshapeTH1 = 2.5;
          *reshapeTH2 = 4.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (m_exceedSTD)
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_reshapeCW.binCW[0] = 36;
            m_reshapeCW.binCW[1] = 30;
    
    Taoran Lu's avatar
    Taoran Lu committed
          }
          if (minBinVar > 2.6)
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            *reshapeTH1 = 3.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          }
          else {
    
    Taoran Lu's avatar
    Taoran Lu committed
            double diff1 = binVarSortDsdCDF[firstBinVarLessThanVal4] - binVarSortDsdCDF[firstBinVarLessThanVal3];
            double diff2 = binVarSortDsdCDF[firstBinVarLessThanVal2] - binVarSortDsdCDF[firstBinVarLessThanVal1];
            if (diff1 > 0.4 || binVarSortDsdCDF[firstBinVarLessThanVal1] > 0.1)
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_useAdpCW = true;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_rateAdpMode = 1;
            }
    
    Taoran Lu's avatar
    Taoran Lu committed
            else if (diff2 <= 0.1 && binVarSortDsdCDF[firstBinVarLessThanVal4] > 0.99 && binVarSortDsdCDF[firstBinVarLessThanVal3] > 0.642 && binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.03)
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_useAdpCW = true;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_rateAdpMode = 1;
            }
            else
            {
              m_rateAdpMode = 2;
            }
          }
        }
        else
        {
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshapeCW.binCW[0] = 36;
          *reshapeTH1 = 2.6;
          *reshapeTH2 = 4.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.5 && maxBinVar < 4.7)
    
    Taoran Lu's avatar
    Taoran Lu committed
            *reshapeTH1 = 3.2;
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_rateAdpMode = 1;
          }
        }
      }
    
    Taoran Lu's avatar
    Taoran Lu committed
      else if (m_reshapeCW.rspIntraPeriod == 1)
    
    Taoran Lu's avatar
    Taoran Lu committed
        *intraAdp = true;
        if (m_reshapeCW.rspPicSize > 5184000)
    
    Taoran Lu's avatar
    Taoran Lu committed
          *reshapeTH1 = 2.0;
          *reshapeTH2 = 3.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_rateAdpMode = 2;
    
          if (maxBinVar > 2.4)
          {
    
            if (binVarSortDsdCDF[firstBinVarLessThanVal4] > 0.88)
    
    Taoran Lu's avatar
    Taoran Lu committed
            {
              if (maxBinVar < 2.695)
              {
    
    Taoran Lu's avatar
    Taoran Lu committed
                *reshapeTH2 = 2.2;
    
    Taoran Lu's avatar
    Taoran Lu committed
                if (binVarSortDsdCDF[firstBinVarLessThanVal3] < 0.45)
    
    Taoran Lu's avatar
    Taoran Lu committed
                  *reshapeTH1 = 2.5;
                  *reshapeTH2 = 4.0;
                  m_reshapeCW.binCW[0] = 36;
                  m_sliceReshapeInfo.enableChromaAdj = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
                  m_rateAdpMode = 0;
                }
                else
                {
    
    Taoran Lu's avatar
    Taoran Lu committed
                  m_useAdpCW = true;
                  m_reshapeCW.binCW[0] = 36;
                  m_reshapeCW.binCW[1] = 30;
    
    Taoran Lu's avatar
    Taoran Lu committed
            {
              if (maxBinVar > 2.8)
              {
    
    Taoran Lu's avatar
    Taoran Lu committed
                *reshapeTH1 = 2.2;
                *reshapeTH2 = 4.0;
                m_reshapeCW.binCW[0] = 36;
                m_sliceReshapeInfo.enableChromaAdj = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
                m_useAdpCW = true;
                m_reshapeCW.binCW[0] = 38;
                m_reshapeCW.binCW[1] = 28;
    
    Taoran Lu's avatar
    Taoran Lu committed
              }
            }
          }
          else
          {
            if (maxBinVar > 2.24)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_useAdpCW = true;
              m_reshapeCW.binCW[0] = 34;
              m_reshapeCW.binCW[1] = 30;
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (m_reshapeCW.rspPicSize > 1497600)
    
    Taoran Lu's avatar
    Taoran Lu committed
          *reshapeTH1 = 2.0;
          *reshapeTH2 = 4.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_rateAdpMode = 2;
    
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.25)
    
    Taoran Lu's avatar
    Taoran Lu committed
          {
            int firstVarCDFLargerThanVal = 1;
            for (int b = 0; b < PIC_ANALYZE_CW_BINS; b++)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              if (binVarSortDsdCDF[b] > 0.7)
    
    Taoran Lu's avatar
    Taoran Lu committed
              {
                firstVarCDFLargerThanVal = b;
                break;
              }
            }
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (meanBinVar < 2.52 || binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.5)
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.2;
              *reshapeTH2 = (binVarSortDsd[firstVarCDFLargerThanVal] + binVarSortDsd[firstVarCDFLargerThanVal - 1]) / 2.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[1] = 30;
              *reshapeTH2 = 2.8;
    
    Taoran Lu's avatar
    Taoran Lu committed
          else if (binVarSortDsdCDF[firstBinVarLessThanVal2] < 0.1 && binVarSortDsdCDF[firstBinVarLessThanVal1] > 0.02)
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_reshapeCW.binCW[0] = 36;
            *reshapeTH1 = 3.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_rateAdpMode = 1;
          }
        }
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (m_reshapeCW.rspPicSize > 660480)
    
    Taoran Lu's avatar
    Taoran Lu committed
          *reshapeTH1 = 2.5;
          *reshapeTH2 = 4.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_rateAdpMode = 1;
    
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (binVarSortDsdCDF[firstBinVarLessThanVal4] > 0.6)
    
    Taoran Lu's avatar
    Taoran Lu committed
          {
            if (maxBinVar < 3.5)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
            }
          }
          else
          {
            if (maxBinVar > 3.3)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[0] = 35;
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.8;
              m_reshapeCW.binCW[0] = 35;
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (m_reshapeCW.rspPicSize > 249600)
    
    Taoran Lu's avatar
    Taoran Lu committed
        {
          m_rateAdpMode = 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshapeCW.binCW[0] = 36;
          *reshapeTH1 = 2.5;
          *reshapeTH2 = 4.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (binVarSortDsdCDF[firstBinVarLessThanVal2] < 0.33 && m_reshapeCW.rspFps>40)
    
    Taoran Lu's avatar
    Taoran Lu committed
            *intraAdp = false;
            *interAdp = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
          }
          else
          {
            m_rateAdpMode = 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_reshapeCW.binCW[0] = 36;
            *reshapeTH1 = 3.0;
            *reshapeTH2 = 4.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
        if (m_reshapeCW.rspPicSize > 5184000)
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshapeCW.binCW[0] = 40;
          *reshapeTH2 = 4.0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_rateAdpMode = 2;
    
          if (maxBinVar < 2.4)
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            *reshapeTH1 = 3.0;
            if (m_reshapeCW.rspBaseQP <= 22)
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_tcase = 3;
          }
          else if (maxBinVar > 3.0)
          {
            if (minBinVar > 1)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[0] = 36;
              *reshapeTH1 = 2.8;
              *reshapeTH2 = 3.5;
              m_sliceReshapeInfo.enableChromaAdj = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_chromaWeight = 1.05;
              m_rateAdpMode = 0;
            }
            else
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_reshapeCW.binCW[0] = 36;
              *reshapeTH1 = 2.2;
              *reshapeTH2 = 3.5;
              m_sliceReshapeInfo.enableChromaAdj = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_chromaWeight = 0.95;
            }
          }
          else
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            *reshapeTH1 = 1.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (m_reshapeCW.rspPicSize > 1497600)
    
    Taoran Lu's avatar
    Taoran Lu committed
          *reshapeTH1 = 2.5;
          *reshapeTH2 = 4.5;
    
          m_rateAdpMode = 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
    
          if (meanBinVar < 2.52)
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            *intraAdp = true;
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_rateAdpMode = 0;
            m_tcase = 9;
          }
          else
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.5)
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH2 = 3.0;
              *intraAdp = true;
    
    Taoran Lu's avatar
    Taoran Lu committed
            else if (binVarSortDsdCDF[firstBinVarLessThanVal2] < 0.1 && binVarSortDsdCDF[firstBinVarLessThanVal1] > 0.02)
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 3.0;
              *intraAdp = true;
    
    Taoran Lu's avatar
    Taoran Lu committed
              m_rateAdpMode = 0;
              m_tcase = 9;
            }
    
    Taoran Lu's avatar
    Taoran Lu committed
            else if (binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.25)
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.4;
              m_reshapeCW.binCW[0] = 36;
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.4;
              m_reshapeCW.binCW[0] = 36;
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (m_reshapeCW.rspPicSize > 660480)
    
    Taoran Lu's avatar
    Taoran Lu committed
          *intraAdp = true;
    
          m_rateAdpMode = 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (binVarSortDsdCDF[firstBinVarLessThanVal4] > 0.6)
    
    Taoran Lu's avatar
    Taoran Lu committed
          {
            if (maxBinVar < 3.5)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.1;
              *reshapeTH2 = 3.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.4;
              *reshapeTH2 = 4.5;
              m_reshapeCW.binCW[0] = 40;
    
              m_rateAdpMode = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
            }
          }
          else
          {
            if (maxBinVar > 3.3)
            {
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 3.5;
              *reshapeTH2 = 3.8;
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 3.0;
              *reshapeTH2 = 4.0;
              m_reshapeCW.binCW[1] = 30;
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (m_reshapeCW.rspPicSize > 249600)
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshapeCW.binCW[1] = 30;
          *reshapeTH1 = 2.5;
          *reshapeTH2 = 4.5;
          *intraAdp = true;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_rateAdpMode = 1;
    
          if (minBinVar > 2.6)
          {
    
    Taoran Lu's avatar
    Taoran Lu committed
            *reshapeTH1 = 3.2;
    
    Taoran Lu's avatar
    Taoran Lu committed
            m_rateAdpMode = 0;
            m_tcase = 9;
          }
          else {
    
    Taoran Lu's avatar
    Taoran Lu committed
            double diff1 = binVarSortDsdCDF[firstBinVarLessThanVal4] - binVarSortDsdCDF[firstBinVarLessThanVal3];
            double diff2 = binVarSortDsdCDF[firstBinVarLessThanVal2] - binVarSortDsdCDF[firstBinVarLessThanVal1];
            if (diff1 > 0.4 || binVarSortDsdCDF[firstBinVarLessThanVal1] > 0.1)
    
    Taoran Lu's avatar
    Taoran Lu committed
              *reshapeTH1 = 2.9;
              *intraAdp = false;
    
    Taoran Lu's avatar
    Taoran Lu committed
            }
            else
            {
              if (diff2 > 0.1)
              {
    
    Taoran Lu's avatar
    Taoran Lu committed
                *reshapeTH1 = 2.5;
    
    Taoran Lu's avatar
    Taoran Lu committed
                *reshapeTH1 = 2.9;
                if (binVarSortDsdCDF[firstBinVarLessThanVal4] > 0.99 && binVarSortDsdCDF[firstBinVarLessThanVal3] > 0.642 && binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.03)
    
    Taoran Lu's avatar
    Taoran Lu committed
                {
                  m_rateAdpMode = 0;
                  m_tcase = 9;
                }
              }
            }
          }
        }
        else
        {
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_reshapeCW.binCW[0] = 36;
          m_reshapeCW.binCW[1] = 30;
          *reshapeTH1 = 2.6;