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
          *reshapeTH2 = 4.5;
          *intraAdp = true;
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_rateAdpMode = 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (binVarSortDsdCDF[firstBinVarLessThanVal2] > 0.5 && maxBinVar < 4.7)
    
    Taoran Lu's avatar
    Taoran Lu committed
            *reshapeTH1 = 3.4;
    
    Taoran Lu's avatar
    Taoran Lu committed
          }
        }
      }
    }
    
    void EncReshape::deriveReshapeParameters(double *array, int start, int end, ReshapeCW respCW, double &alpha, double &beta)
    {
      double minVar = 10.0, maxVar = 0.0;
      for (int b = start; b <= end; b++)
      {
        if (array[b] < minVar)       minVar = array[b];
        if (array[b] > maxVar)       maxVar = array[b];
      }
    
    Taoran Lu's avatar
    Taoran Lu committed
      double maxCW = (double)respCW.binCW[0];
      double minCW = (double)respCW.binCW[1];
    
    Taoran Lu's avatar
    Taoran Lu committed
      alpha = (minCW - maxCW) / (maxVar - minVar);
      beta = (maxCW*maxVar - minCW*minVar) / (maxVar - minVar);
    }
    
    /**
    -Init reshaping LUT  from dQP model
    */
    void EncReshape::initLUTfromdQPModel()
    {
      initModelParam();
      int pwlFwdLUTsize = PIC_CODE_CW_BINS;
    
      int pwlFwdBinLen = m_reshapeLUTSize / PIC_CODE_CW_BINS;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int p1 = m_dQPModel.scaleFracPrec;
      int p2 = m_dQPModel.offsetFracPrec;
    
      int totalShift = p1 + p2;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int scaleFP = (1 - 2 * m_dQPModel.scaleSign)  * m_dQPModel.scaleAbs;
      int offsetFP = (1 - 2 * m_dQPModel.offsetSign) * m_dQPModel.offsetAbs;
      int maxQP = (1 - 2 * m_dQPModel.maxQPSign)  * m_dQPModel.maxQPAbs;
      int minQP = (1 - 2 * m_dQPModel.minQPSign)  * m_dQPModel.minQPAbs;
    
      int maxFP = maxQP * (1 << totalShift);
      int minFP = minQP * (1 << totalShift);
    
    Taoran Lu's avatar
    Taoran Lu committed
      int temp, signval, absval;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int dQPDiv6FP;
      int32_t * slopeLUT = new int32_t[m_reshapeLUTSize]();
      int32_t * fwdLUTHighPrec = new int32_t[m_reshapeLUTSize]();
    
      for (int i = 0; i < m_reshapeLUTSize; i++)
    
        int inputY = m_lumaBD < 10 ? i << (10 - m_lumaBD) : m_lumaBD > 10 ? i >> (m_lumaBD - 10) : i;
        temp = int64_t((scaleFP*inputY) * (1 << p2)) + int64_t(offsetFP * (1 << p1));
    
    Taoran Lu's avatar
    Taoran Lu committed
        temp = temp > maxFP ? maxFP : temp < minFP ? minFP : temp;
        signval = temp >= 0 ? 1 : -1;
        absval = signval * temp;
    
        dQPDiv6FP = signval * (((absval + 3) / 6 + (1 << (totalShift - 17))) >> (totalShift - 16));
    
    Taoran Lu's avatar
    Taoran Lu committed
        slopeLUT[i] = calcEXP2(dQPDiv6FP);
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (m_dQPModel.fullRangeInputFlag == 0)
    
    Taoran Lu's avatar
    Taoran Lu committed
        for (int i = 0; i < (16 << (m_lumaBD - 8)); i++)                    {      slopeLUT[i] = 0;    }
        for (int i = (235 << (m_lumaBD - 8)); i < m_reshapeLUTSize; i++)    {      slopeLUT[i] = 0;    }
    
      for (int i = 0; i < m_reshapeLUTSize - 1; i++)
    
    Taoran Lu's avatar
    Taoran Lu committed
        fwdLUTHighPrec[i + 1] = fwdLUTHighPrec[i] + slopeLUT[i];
      if (slopeLUT != nullptr)   {    delete[] slopeLUT;    slopeLUT = nullptr;  }
    
    Taoran Lu's avatar
    Taoran Lu committed
      int max_Y = (fwdLUTHighPrec[m_reshapeLUTSize - 1] + (1 << 7)) >> 8;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int Roffset = max_Y >> 1;
    
      for (int i = 0; i < m_reshapeLUTSize; i++)
    
    Taoran Lu's avatar
    Taoran Lu committed
        m_fwdLUT[i] = (short)(((fwdLUTHighPrec[i] >> 8) * (m_reshapeLUTSize - 1) + Roffset) / max_Y);
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (fwdLUTHighPrec != nullptr)   {    delete[] fwdLUTHighPrec;    fwdLUTHighPrec = nullptr;  }
      m_sliceReshapeInfo.reshaperModelMinBinIdx = 1;
      m_sliceReshapeInfo.reshaperModelMaxBinIdx = 14;
    
    Taoran Lu's avatar
    Taoran Lu committed
    
      for (int i = 0; i < pwlFwdLUTsize; i++)
      {
        int16_t X1 = i * pwlFwdBinLen;
    
    Taoran Lu's avatar
    Taoran Lu committed
        m_reshapePivot[i] = m_fwdLUT[X1];
    
      m_reshapePivot[pwlFwdLUTsize] = ((1 << m_lumaBD) - 1);
    
    Taoran Lu's avatar
    Taoran Lu committed
    
      for (int i = 0; i < pwlFwdLUTsize; i++)
      {
    
        m_binCW[i] = m_reshapePivot[i + 1] - m_reshapePivot[i];
    
    Taoran Lu's avatar
    Taoran Lu committed
      int maxAbsDeltaCW = 0, absDeltaCW = 0, deltaCW = 0;
      for (int i = m_sliceReshapeInfo.reshaperModelMinBinIdx; i <= m_sliceReshapeInfo.reshaperModelMaxBinIdx; i++)
    
    Taoran Lu's avatar
    Taoran Lu committed
        deltaCW = (int)m_binCW[i] - (int)m_initCW;
        m_sliceReshapeInfo.reshaperModelBinCWDelta[i] = deltaCW;
        absDeltaCW = (deltaCW < 0) ? (-deltaCW) : deltaCW;
        if (absDeltaCW > maxAbsDeltaCW)     {      maxAbsDeltaCW = absDeltaCW;    }
    
      m_sliceReshapeInfo.maxNbitsNeededDeltaCW = std::max(1, 1 + floorLog2(maxAbsDeltaCW));
    
    Taoran Lu's avatar
    Taoran Lu committed
    
      for (int i = 0; i < pwlFwdLUTsize; i++)
      {
    
        int16_t Y1 = m_reshapePivot[i];
        int16_t Y2 = m_reshapePivot[i + 1];
    
    Taoran Lu's avatar
    Taoran Lu committed
        m_fwdLUT[i*pwlFwdBinLen] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)Y1);
    
        int log2PwlFwdBinLen = floorLog2(pwlFwdBinLen);
    
    Taoran Lu's avatar
    Taoran Lu committed
        int32_t scale = ((int32_t)(Y2 - Y1) * (1 << FP_PREC) + (1 << (log2PwlFwdBinLen - 1))) >> (log2PwlFwdBinLen);
    
    Taoran Lu's avatar
    Taoran Lu committed
        for (int j = 1; j < pwlFwdBinLen; j++)
        {
          int tempVal = Y1 + (((int32_t)scale * (int32_t)j + (1 << (FP_PREC - 1))) >> FP_PREC);
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_fwdLUT[i*pwlFwdBinLen + j] = Clip3((Pel)0, (Pel)((1<<m_lumaBD) -1), (Pel)tempVal);
    
    Taoran Lu's avatar
    Taoran Lu committed
      reverseLUT(m_fwdLUT, m_invLUT, m_reshapeLUTSize);
      updateChromaScaleLUT();
    
    Taoran Lu's avatar
    Taoran Lu committed
    }
    
    
    /**
    -Perform fixe point exp2 calculation
    \param   val  input value
    \retval  output value = exp2(val)
    */
    int EncReshape::calcEXP2(int val)
    {
      int32_t i, f, r, s;
      r = 0x00000e20;
    
      i = ((int32_t)(val)+0x8000) & ~0xffff;
      f = (int32_t)(val)-i;
      s = ((15 << 16) - i) >> 16;
    
      r = (r * f + 0x3e1cc333) >> 17;
      r = (r * f + 0x58bd46a6) >> 16;
      r = r * f + 0x7ffde4a3;
      return (uint32_t)r >> s;
    }
    
    void EncReshape::constructReshaperSDR()
    {
    
    Taoran Lu's avatar
    Taoran Lu committed
      int bdShift = m_lumaBD - 10;
      int usedCW = 0;
      int totCW = bdShift != 0 ? (bdShift > 0 ? m_reshapeLUTSize / (1<<bdShift) : m_reshapeLUTSize * (1 << (-bdShift))) : m_reshapeLUTSize;
      int histBins = PIC_ANALYZE_CW_BINS;
      int histLenth = totCW/histBins;
    
      int log2HistLenth = floorLog2(histLenth);
    
    Taoran Lu's avatar
    Taoran Lu committed
      int16_t *tempFwdLUT = new int16_t[m_reshapeLUTSize + 1]();
    
    Taoran Lu's avatar
    Taoran Lu committed
      int i, j;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int cwScaleBins1, cwScaleBins2;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int maxAllowedCW = totCW-1;
    
    Taoran Lu's avatar
    Taoran Lu committed
      cwScaleBins1 = m_reshapeCW.binCW[0];
      cwScaleBins2 = m_reshapeCW.binCW[1];
    
    Taoran Lu's avatar
    Taoran Lu committed
      for (i = 0; i < histBins; i++)
        usedCW += m_binCW[i];
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (usedCW > maxAllowedCW)
    
    Taoran Lu's avatar
    Taoran Lu committed
      {
        int cnt0 = 0, cnt1 = 0, cnt2 = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
        for (i = 0; i < histBins; i++)
    
    Taoran Lu's avatar
    Taoran Lu committed
          if (m_binCW[i] == histLenth + 1)             cnt0++;
          else if (m_binCW[i] == cwScaleBins1)         cnt1++;
          else if (m_binCW[i] == cwScaleBins2)         cnt2++;
    
    Taoran Lu's avatar
    Taoran Lu committed
        int resCW = usedCW - maxAllowedCW;
        int cwReduce1 = (cwScaleBins1 - histLenth - 1) * cnt1;
        int cwReduce2 = (histLenth + 1 - cwScaleBins2) * cnt0;
    
    Taoran Lu's avatar
    Taoran Lu committed
        if (resCW <= cwReduce1)
    
    Taoran Lu's avatar
    Taoran Lu committed
        {
          int idx = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          while (resCW > 0)
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (m_binCW[idx] > (histLenth + 1))
    
              m_binCW[idx]--;
    
    Taoran Lu's avatar
    Taoran Lu committed
              resCW--;
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (idx == histBins)
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (resCW > cwReduce1 && resCW <= (cwReduce1 + cwReduce2))
    
    Taoran Lu's avatar
    Taoran Lu committed
          resCW -= cwReduce1;
    
    Taoran Lu's avatar
    Taoran Lu committed
          int idx = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          while (resCW > 0)
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (m_binCW[idx] > cwScaleBins2 && m_binCW[idx] < cwScaleBins1)
    
              m_binCW[idx]--;
    
    Taoran Lu's avatar
    Taoran Lu committed
              resCW--;
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (idx == histBins)
    
    Taoran Lu's avatar
    Taoran Lu committed
              idx = 0;
          }
    
    Taoran Lu's avatar
    Taoran Lu committed
          for (i = 0; i < histBins; i++)
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (m_binCW[i] == cwScaleBins1)
              m_binCW[i] = histLenth + 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
        else if (resCW > (cwReduce1 + cwReduce2))
    
    Taoran Lu's avatar
    Taoran Lu committed
          resCW -= (cwReduce1 + cwReduce2);
    
    Taoran Lu's avatar
    Taoran Lu committed
          int idx = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
          while (resCW > 0)
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (m_binCW[idx] > 0 && m_binCW[idx] < (histLenth + 1))
    
              m_binCW[idx]--;
    
    Taoran Lu's avatar
    Taoran Lu committed
              resCW--;
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (idx == histBins)
    
    Taoran Lu's avatar
    Taoran Lu committed
              idx = 0;
          }
    
    Taoran Lu's avatar
    Taoran Lu committed
          for (i = 0; i < histBins; i++)
    
    Taoran Lu's avatar
    Taoran Lu committed
            if (m_binCW[i] == histLenth + 1)
              m_binCW[i] = cwScaleBins2;
            if (m_binCW[i] == cwScaleBins1)
              m_binCW[i] = histLenth + 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (bdShift != 0)
      {
        for (int i = 0; i < PIC_ANALYZE_CW_BINS; i++)
        {
          m_binCW[i] = bdShift > 0 ? m_binCW[i] * (1 << bdShift) : m_binCW[i] / (1 << (-bdShift));
        }
      }
    
    
    Taoran Lu's avatar
    Taoran Lu committed
      for (int i = 0; i < PIC_CODE_CW_BINS; i++)
      {
    
        m_binCW[i] = m_binCW[2 * i] + m_binCW[2 * i + 1];
    
    Taoran Lu's avatar
    Taoran Lu committed
      m_sliceReshapeInfo.reshaperModelMinBinIdx = 0;
      m_sliceReshapeInfo.reshaperModelMaxBinIdx = PIC_CODE_CW_BINS - 1;
    
    Taoran Lu's avatar
    Taoran Lu committed
      for (int i = 0; i < PIC_CODE_CW_BINS; i++)
      {
    
        if (m_binCW[i] > 0)
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_sliceReshapeInfo.reshaperModelMinBinIdx = i;
    
    Taoran Lu's avatar
    Taoran Lu committed
          break;
        }
      }
      for (int i = PIC_CODE_CW_BINS - 1; i >= 0; i--)
      {
    
        if (m_binCW[i] > 0)
    
    Taoran Lu's avatar
    Taoran Lu committed
          m_sliceReshapeInfo.reshaperModelMaxBinIdx = i;
    
    Taoran Lu's avatar
    Taoran Lu committed
      int maxAbsDeltaCW = 0, absDeltaCW = 0, deltaCW = 0;
      for (int i = m_sliceReshapeInfo.reshaperModelMinBinIdx; i <= m_sliceReshapeInfo.reshaperModelMaxBinIdx; i++)
    
    Taoran Lu's avatar
    Taoran Lu committed
        deltaCW = (int)m_binCW[i] - (int)m_initCW;
        m_sliceReshapeInfo.reshaperModelBinCWDelta[i] = deltaCW;
        absDeltaCW = (deltaCW < 0) ? (-deltaCW) : deltaCW;
        if (absDeltaCW > maxAbsDeltaCW)      {      maxAbsDeltaCW = absDeltaCW;    }
    
      m_sliceReshapeInfo.maxNbitsNeededDeltaCW = std::max(1, 1 + floorLog2(maxAbsDeltaCW));
    
    Taoran Lu's avatar
    Taoran Lu committed
      histLenth = m_initCW;
    
      log2HistLenth = floorLog2(histLenth);
    
      int sumBins = 0;
      for (i = 0; i < PIC_CODE_CW_BINS; i++)   { sumBins += m_binCW[i];  }
    
    Taoran Lu's avatar
    Taoran Lu committed
      CHECK(sumBins >= m_reshapeLUTSize, "SDR CW assignment is wrong!!");
    
    Taoran Lu's avatar
    Taoran Lu committed
      memset(tempFwdLUT, 0, (m_reshapeLUTSize + 1) * sizeof(int16_t));
      tempFwdLUT[0] = 0;
    
    Taoran Lu's avatar
    Taoran Lu committed
      for (i = 0; i < PIC_CODE_CW_BINS; i++)
    
    Taoran Lu's avatar
    Taoran Lu committed
        tempFwdLUT[(i + 1)*histLenth] = tempFwdLUT[i*histLenth] + m_binCW[i];
        int16_t Y1 = tempFwdLUT[i*histLenth];
        int16_t Y2 = tempFwdLUT[(i + 1)*histLenth];
    
        m_reshapePivot[i + 1] = Y2;
    
    Taoran Lu's avatar
    Taoran Lu committed
        int32_t scale = ((int32_t)(Y2 - Y1) * (1 << FP_PREC) + (1 << (log2HistLenth - 1))) >> (log2HistLenth);
        m_fwdLUT[i*histLenth] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)Y1);
        for (j = 1; j < histLenth; j++)
    
    Taoran Lu's avatar
    Taoran Lu committed
          tempFwdLUT[i*histLenth + j] = Y1 + (((int32_t)scale * (int32_t)j + (1 << (FP_PREC - 1))) >> FP_PREC);
          m_fwdLUT[i*histLenth + j] = Clip3((Pel)0, (Pel)((1 << m_lumaBD) - 1), (Pel)tempFwdLUT[i*histLenth + j]);
    
    Taoran Lu's avatar
    Taoran Lu committed
        }
      }
    
      for (i = 0; i < PIC_CODE_CW_BINS; i++)
      {
    
    Taoran Lu's avatar
    Taoran Lu committed
        int start = i*histLenth;
        int end = (i + 1)*histLenth - 1;
        m_cwLumaWeight[i] = m_fwdLUT[end] - m_fwdLUT[start];
    
    Taoran Lu's avatar
    Taoran Lu committed
      if (tempFwdLUT != nullptr)   {     delete[] tempFwdLUT;    tempFwdLUT = nullptr;  }
    
    Taoran Lu's avatar
    Taoran Lu committed
      reverseLUT(m_fwdLUT, m_invLUT, m_reshapeLUTSize);
      updateChromaScaleLUT();