Skip to content
Snippets Groups Projects
EncReshape.cpp 39.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Taoran Lu's avatar
    Taoran Lu committed
      {
        temp = int64_t((scaleFP*i) * (1 << p2)) + int64_t(offsetFP * (1 << p1));
        temp = temp > maxFP ? maxFP : temp < minFP ? minFP : temp;
        signval = temp >= 0 ? 1 : -1;
        absval = signval * temp;
        dQPDIV6_FP = signval * (((absval + 3) / 6 + (1 << (total_shift - 17))) >> (total_shift - 16));
        SlopeLUT[i] = calcEXP2(dQPDIV6_FP);
      }
    
      if (m_DftModel.FullRangeInputFlag == 0)  
      {
        for (int i = 0; i < 64; i++)                               {      SlopeLUT[i] = 0;    }
        for (int i = 940; i < MAX_LUMA_RESHAPING_LUT_SIZE; i++)    {      SlopeLUT[i] = 0;    }
      }
    
      for (int i = 0; i < MAX_LUMA_RESHAPING_LUT_SIZE - 1; i++)
        fLUT_HP[i + 1] = fLUT_HP[i] + SlopeLUT[i];
      if (SlopeLUT != nullptr)   {    delete[] SlopeLUT;    SlopeLUT = nullptr;  }
    
      int max_Y = (fLUT_HP[MAX_LUMA_RESHAPING_LUT_SIZE - 1] + (1 << 7)) >> 8;
      int Roffset = max_Y >> 1;
      for (int i = 0; i < MAX_LUMA_RESHAPING_LUT_SIZE; i++)
      {
        forwardReshapingLUT[i] = (short)(((fLUT_HP[i] >> 8) * (MAX_LUMA_RESHAPING_LUT_SIZE - 1) + Roffset) / max_Y);
      }
    
      if (fLUT_HP != nullptr)   {    delete[] fLUT_HP;    fLUT_HP = nullptr;  }
      m_sliceReshapeInfo.reshape_model_min_bin_idx = 1;
      m_sliceReshapeInfo.reshape_model_max_bin_idx = 14;
    
      for (int i = 0; i < pwlFwdLUTsize; i++)
      {
        int16_t X1 = i * pwlFwdBinLen;
        m_ReshapePivot[i] = forwardReshapingLUT[X1];
      }
      m_ReshapePivot[pwlFwdLUTsize] = 1023;
    
      for (int i = 0; i < pwlFwdLUTsize; i++)
      {
        m_uiBinCWAll[i] = m_ReshapePivot[i + 1] - m_ReshapePivot[i];
      }
    
      int maxAbsDeltaCW = 0, AbsDeltaCW = 0, DeltaCW = 0;
      for (int i = m_sliceReshapeInfo.reshape_model_min_bin_idx; i <= m_sliceReshapeInfo.reshape_model_max_bin_idx; i++)
      {
        DeltaCW = (int)m_uiBinCWAll[i] - (int)m_uiCWOrg;
        m_sliceReshapeInfo.reshape_model_bin_CW_delta[i] = DeltaCW;
        AbsDeltaCW = (DeltaCW < 0) ? (-DeltaCW) : DeltaCW;
        if (AbsDeltaCW > maxAbsDeltaCW)     {      maxAbsDeltaCW = AbsDeltaCW;    }
      }
      m_sliceReshapeInfo.maxNbitsNeededDeltaCW = g_aucLog2[maxAbsDeltaCW << 1];
    
      for (int i = 0; i < pwlFwdLUTsize; i++)
      {
        int16_t Y1 = m_ReshapePivot[i];
        int16_t Y2 = m_ReshapePivot[i + 1];
        forwardReshapingLUT[i*pwlFwdBinLen] = Clip3((Pel)0, (Pel)1023, (Pel)Y1);
        int log2_pwlFwdBinLen = log2_MAX_LUMA_RESHAPING_LUT_SIZE - log2_PIC_CODE_CW_BINS;
        int32_t scale = ((int32_t)(Y2 - Y1) * (1 << FP_PREC) + (1 << (log2_pwlFwdBinLen - 1))) >> (log2_pwlFwdBinLen);
        for (int j = 1; j < pwlFwdBinLen; j++)
        {
          int tempVal = Y1 + (((int32_t)scale * (int32_t)j + (1 << (FP_PREC - 1))) >> FP_PREC);
          forwardReshapingLUT[i*pwlFwdBinLen + j] = Clip3((Pel)0, (Pel)1023, (Pel)tempVal);
        }
      }
      ReverseLUT(forwardReshapingLUT, inverseReshapingLUT, MAX_LUMA_RESHAPING_LUT_SIZE);
      updateChromaDQPLUT();
    }
    
    
    /**
    -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()
    {
      int used_codewords;
      int tot_cw = MAX_LUMA_RESHAPING_LUT_SIZE;
      int hist_bins = PIC_ANALYZE_CW_BINS;
      int log2_hist_lens = log2_MAX_LUMA_RESHAPING_LUT_SIZE - log2_PIC_ANALYZE_CW_BINS;
      int hist_lens = m_uiCWOrgAnalyze;
      int16_t *Y_LUT_all = new int16_t[MAX_LUMA_RESHAPING_LUT_SIZE + 1]();
      int i, j;
      int cw_scale_bins1, cw_scale_bins2;
      int max_allow_cw = tot_cw;
    
      cw_scale_bins1 = m_reshapeCW.BinCW[0];
      cw_scale_bins2 = m_reshapeCW.BinCW[1];
    
      used_codewords = 0;
      for (i = 0; i < hist_bins; i++)
        used_codewords += m_uiBinCWAll[i];
    
      if (used_codewords > max_allow_cw)
      {
        int cnt0 = 0, cnt1 = 0, cnt2 = 0;
        for (i = 0; i < hist_bins; i++)
        {
          if (m_uiBinCWAll[i] == hist_lens + 1)               cnt0++;
          else if (m_uiBinCWAll[i] == cw_scale_bins1)         cnt1++;
          else if (m_uiBinCWAll[i] == cw_scale_bins2)         cnt2++;
        }
    
        int delta_cw = used_codewords - max_allow_cw;
        int cw_reduce1 = (cw_scale_bins1 - hist_lens - 1) * cnt1;
        int cw_reduce2 = (hist_lens + 1 - cw_scale_bins2) * cnt0;
    
        if (delta_cw <= cw_reduce1)
        {
          int idx = 0;
          while (delta_cw > 0)
          {
            if (m_uiBinCWAll[idx] > (hist_lens + 1))
            {
              m_uiBinCWAll[idx]--;
              delta_cw--;
            }
            idx++;
            if (idx == hist_bins)
              idx = 0;
          }
        }
        else if (delta_cw > cw_reduce1 && delta_cw <= (cw_reduce1 + cw_reduce2))
        {
          delta_cw -= cw_reduce1;
          int idx = 0;
          while (delta_cw > 0)
          {
            if (m_uiBinCWAll[idx] > cw_scale_bins2 && m_uiBinCWAll[idx] < cw_scale_bins1)
            {
              m_uiBinCWAll[idx]--;
              delta_cw--;
            }
            idx++;
            if (idx == hist_bins)
              idx = 0;
          }
          for (i = 0; i < hist_bins; i++)
          {
            if (m_uiBinCWAll[i] == cw_scale_bins1)
              m_uiBinCWAll[i] = hist_lens + 1;
          }
        }
        else if (delta_cw > (cw_reduce1 + cw_reduce2))
        {
          delta_cw -= (cw_reduce1 + cw_reduce2);
          int idx = 0;
          while (delta_cw > 0)
          {
            if (m_uiBinCWAll[idx] > 0 && m_uiBinCWAll[idx] < (hist_lens + 1))
            {
              m_uiBinCWAll[idx]--;
              delta_cw--;
            }
            idx++;
            if (idx == hist_bins)
              idx = 0;
          }
          for (i = 0; i < hist_bins; i++)
          {
            if (m_uiBinCWAll[i] == m_uiCWOrgAnalyze + 1)
              m_uiBinCWAll[i] = cw_scale_bins2;
            if (m_uiBinCWAll[i] == cw_scale_bins1)
              m_uiBinCWAll[i] = m_uiCWOrgAnalyze + 1;
          }
        }
      }
    
      for (int i = 0; i < PIC_CODE_CW_BINS; i++)
      {
        m_uiBinCWAll[i] = m_uiBinCWAll[2 * i] + m_uiBinCWAll[2 * i + 1];
      }
      m_sliceReshapeInfo.reshape_model_min_bin_idx = 0;
      m_sliceReshapeInfo.reshape_model_max_bin_idx = PIC_CODE_CW_BINS - 1;
      for (int i = 0; i < PIC_CODE_CW_BINS; i++)
      {
        if (m_uiBinCWAll[i] > 0)
        {
          m_sliceReshapeInfo.reshape_model_min_bin_idx = i;
          break;
        }
      }
      for (int i = PIC_CODE_CW_BINS - 1; i >= 0; i--)
      {
        if (m_uiBinCWAll[i] > 0)
        {
          m_sliceReshapeInfo.reshape_model_max_bin_idx = i;
          break;
        }
      }
    
      int maxAbsDeltaCW = 0, AbsDeltaCW = 0, DeltaCW = 0;
      for (int i = m_sliceReshapeInfo.reshape_model_min_bin_idx; i <= m_sliceReshapeInfo.reshape_model_max_bin_idx; i++)
      {
        DeltaCW = (int)m_uiBinCWAll[i] - (int)m_uiCWOrg;
        m_sliceReshapeInfo.reshape_model_bin_CW_delta[i] = DeltaCW;
        AbsDeltaCW = (DeltaCW < 0) ? (-DeltaCW) : DeltaCW;
        if (AbsDeltaCW > maxAbsDeltaCW)      {      maxAbsDeltaCW = AbsDeltaCW;    }
      }
      m_sliceReshapeInfo.maxNbitsNeededDeltaCW = g_aucLog2[maxAbsDeltaCW << 1];
    
      hist_bins = PIC_CODE_CW_BINS;
      log2_hist_lens = log2_MAX_LUMA_RESHAPING_LUT_SIZE - log2_PIC_CODE_CW_BINS;
      hist_lens = m_uiCWOrg;
    
      int sum_bins = 0;
      for (i = 0; i < hist_bins; i++)   {    sum_bins += m_uiBinCWAll[i];  }
    
      CHECK(sum_bins > max_allow_cw, "SDR CW assignment is wrong!!");
    
      memset(Y_LUT_all, 0, (MAX_LUMA_RESHAPING_LUT_SIZE + 1) * sizeof(int16_t));
      Y_LUT_all[0] = 0;
    
      for (i = 0; i < hist_bins; i++)
      {
        Y_LUT_all[(i + 1)*hist_lens] = Y_LUT_all[i*hist_lens] + m_uiBinCWAll[i];
        int16_t Y1 = Y_LUT_all[i*hist_lens];
        int16_t Y2 = Y_LUT_all[(i + 1)*hist_lens];
        m_ReshapePivot[i + 1] = Y2;
        int32_t scale = ((int32_t)(Y2 - Y1) * (1 << FP_PREC) + (1 << (log2_hist_lens - 1))) >> (log2_hist_lens);
        forwardReshapingLUT[i*hist_lens] = Clip3((Pel)0, (Pel)1023, (Pel)Y1);
        for (j = 1; j < hist_lens; j++)
        {
          Y_LUT_all[i*hist_lens + j] = Y1 + (((int32_t)scale * (int32_t)j + (1 << (FP_PREC - 1))) >> FP_PREC);
          forwardReshapingLUT[i*hist_lens + j] = Clip3((Pel)0, (Pel)1023, (Pel)Y_LUT_all[i*hist_lens + j]);
        }
      }
    
      for (i = 0; i < PIC_CODE_CW_BINS; i++)
      {
        int i_start = i*hist_lens;
        int i_end = (i + 1)*hist_lens - 1;
        m_cwLumaWeight[i] = forwardReshapingLUT[i_end] - forwardReshapingLUT[i_start];
      }
    
      if (Y_LUT_all != nullptr)   {     delete[] Y_LUT_all;    Y_LUT_all = nullptr;  }
    
      ReverseLUT(forwardReshapingLUT, inverseReshapingLUT, MAX_LUMA_RESHAPING_LUT_SIZE);  
      updateChromaDQPLUT();
    }
    
    #endif
    //
    //! \}