⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rc_quadratic.c

📁 压缩JM12.3d的完整的全部C语言的代码文档,用于嵌入式系统的压缩编解码
💻 C
📖 第 1 页 / 共 5 页
字号:
      return ((int) floor(nbits * prc->m_Qc + 0.5));
  }
  return 0;
}

void updatePparams( rc_quadratic *prc, int complexity )
{
  prc->Xp = complexity;
  prc->Np--;
  prc->Wp = prc->Xp;
  prc->Pm_Hp = generic_RC->NumberofHeaderBits;
  prc->NumberofCodedPFrame++;
  prc->NumberofPPicture++;
}

void updateBparams( rc_quadratic *prc, int complexity )
{
  prc->Xb = complexity;
  prc->Nb--;
  prc->Wb = prc->Xb / THETA;     
  prc->NumberofBFrames++;
  generic_RC->NumberofCodedBFrame++;
}

/*! 
 *************************************************************************************
 * \brief
 *    update after frame encoding
 *
 * \param nbits
 *    number of bits used for frame
 *
 *************************************************************************************
*/
void rc_update_pict_frame(rc_quadratic *prc, int nbits)
{
  /* update the complexity weight of I, P, B frame */  
  int complexity = 0;

  switch( input->RCUpdateMode )
  {
  case RC_MODE_0:
  case RC_MODE_2:
  default:
    complexity = updateComplexity( prc, (Boolean) (img->type == P_SLICE), nbits );
    if ( img->type == P_SLICE )
    {
      if( generic_RC->NoGranularFieldRC == 0 || generic_RC->FieldControl == 0 )
        updatePparams( prc, complexity );
      else
        generic_RC->NoGranularFieldRC = 0;
    }
    else if ( img->type == B_SLICE )
      updateBparams( prc, complexity );
    break;
  case RC_MODE_1:
    complexity = updateComplexity( prc, (Boolean) (img->number != 0), nbits );
    if ( img->number != 0 )
    {
      if( generic_RC->NoGranularFieldRC == 0 || generic_RC->FieldControl == 0 )
        updatePparams( prc, complexity );
      else
        generic_RC->NoGranularFieldRC = 0;
    }
    break;
  case RC_MODE_3:
    complexity = updateComplexity( prc, (Boolean) (img->type == P_SLICE), nbits );
    if (img->type == I_SLICE && (img->number != 0))
      generic_RC->NIslice--;

    if ( img->type == P_SLICE )
    {
      if( generic_RC->NoGranularFieldRC == 0 || generic_RC->FieldControl == 0 )
      {
        updatePparams( prc, complexity );
        generic_RC->NPslice--;
      }
      else
        generic_RC->NoGranularFieldRC = 0;
    }
    else if ( img->type == B_SLICE )
    {
      updateBparams( prc, complexity );
      generic_RC->hierNb[ input->HierarchicalCoding ? (generic_RC->temporal_levels - 1 - gop_structure[img->b_frame_to_code-1].hierarchy_layer) : 0 ]--;
    }
    break;
  }   
}


/*!
 *************************************************************************************
 * \brief
 *    update the parameters of quadratic R-D model
 *
 *************************************************************************************
*/
void updateRCModel (rc_quadratic *prc)
{
  int n_windowSize;
  int i;
  double std = 0.0, threshold;
  int m_Nc = prc->NumberofCodedPFrame;
  Boolean MADModelFlag = FALSE;
  static Boolean m_rgRejected[RC_MODEL_HISTORY];
  static double  error       [RC_MODEL_HISTORY];

  if( img->type == P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number != 0)) )
  {
    /*frame layer rate control*/
    if(img->BasicUnit == img->FrameSizeInMbs)
    {
      prc->CurrentFrameMAD = ComputeFrameMAD();
      m_Nc=prc->NumberofCodedPFrame;
    }
    /*basic unit layer rate control*/
    else
    {
      /*compute the MAD of the current basic unit*/
      prc->CurrentFrameMAD = (double) ((generic_RC->TotalMADBasicUnit >> 8)/img->BasicUnit);
      generic_RC->TotalMADBasicUnit=0;

      /* compute the average number of header bits*/
      prc->CodedBasicUnit=prc->TotalNumberofBasicUnit-prc->NumberofBasicUnit;
      if(prc->CodedBasicUnit > 0)
      {
        prc->PAveHeaderBits1=(int)((double)(prc->PAveHeaderBits1*(prc->CodedBasicUnit-1)+
          generic_RC->NumberofBasicUnitHeaderBits)/prc->CodedBasicUnit+0.5);
        if(prc->PAveHeaderBits3 == 0)
          prc->PAveHeaderBits2 = prc->PAveHeaderBits1;
        else
        {
          prc->PAveHeaderBits2 = (int)((double)(prc->PAveHeaderBits1 * prc->CodedBasicUnit+
            prc->PAveHeaderBits3 * prc->NumberofBasicUnit)/prc->TotalNumberofBasicUnit+0.5);
        }
      }
      /*update the record of MADs for reference*/
      if(((input->PicInterlace == ADAPTIVE_CODING) || (input->MbInterlace)) && (generic_RC->FieldControl == 1))
        prc->FCBUCFMAD[prc->TotalNumberofBasicUnit-1-prc->NumberofBasicUnit]=prc->CurrentFrameMAD;
      else
        prc->BUCFMAD[prc->TotalNumberofBasicUnit-1-prc->NumberofBasicUnit]=prc->CurrentFrameMAD;

      if(prc->NumberofBasicUnit != 0)
        m_Nc = prc->NumberofCodedPFrame * prc->TotalNumberofBasicUnit + prc->CodedBasicUnit;
      else
        m_Nc = (prc->NumberofCodedPFrame-1) * prc->TotalNumberofBasicUnit + prc->CodedBasicUnit;
    }

    if(m_Nc > 1)
      MADModelFlag=TRUE;

    prc->PPreHeader = generic_RC->NumberofHeaderBits;
    for (i = (RC_MODEL_HISTORY-2); i > 0; i--)
    {// update the history
      prc->Pm_rgQp[i] = prc->Pm_rgQp[i - 1];
      prc->m_rgQp[i]  = prc->Pm_rgQp[i];
      prc->Pm_rgRp[i] = prc->Pm_rgRp[i - 1];
      prc->m_rgRp[i]  = prc->Pm_rgRp[i];
    }
    prc->Pm_rgQp[0] = QP2Qstep(prc->m_Qc); //*1.0/prc->CurrentFrameMAD;
    /*frame layer rate control*/
    if(img->BasicUnit == img->FrameSizeInMbs)
      prc->Pm_rgRp[0] = generic_RC->NumberofTextureBits*1.0/prc->CurrentFrameMAD;
    /*basic unit layer rate control*/
    else
      prc->Pm_rgRp[0] = generic_RC->NumberofBasicUnitTextureBits*1.0/prc->CurrentFrameMAD;

    prc->m_rgQp[0] = prc->Pm_rgQp[0];
    prc->m_rgRp[0] = prc->Pm_rgRp[0];
    prc->m_X1 = prc->Pm_X1;
    prc->m_X2 = prc->Pm_X2;

    /*compute the size of window*/
    n_windowSize = (prc->CurrentFrameMAD>prc->PreviousFrameMAD)
      ? (int)(prc->PreviousFrameMAD/prc->CurrentFrameMAD * (RC_MODEL_HISTORY-1) )
      : (int)(prc->CurrentFrameMAD/prc->PreviousFrameMAD *(RC_MODEL_HISTORY-1));
    n_windowSize=iClip3(1, m_Nc, n_windowSize);
    n_windowSize=imin(n_windowSize,prc->m_windowSize+1);
    n_windowSize=imin(n_windowSize,(RC_MODEL_HISTORY-1));

    /*update the previous window size*/
    prc->m_windowSize=n_windowSize;

    for (i = 0; i < (RC_MODEL_HISTORY-1); i++)
    {
      m_rgRejected[i] = FALSE;
    }

    // initial RD model estimator
    RCModelEstimator (prc, n_windowSize, m_rgRejected);

    n_windowSize = prc->m_windowSize;
    // remove outlier

    for (i = 0; i < (int) n_windowSize; i++)
    {
      error[i] = prc->m_X1 / prc->m_rgQp[i] + prc->m_X2 / (prc->m_rgQp[i] * prc->m_rgQp[i]) - prc->m_rgRp[i];
      std += error[i] * error[i];
    }
    threshold = (n_windowSize == 2) ? 0 : sqrt (std / n_windowSize);
    for (i = 0; i < (int) n_windowSize; i++)
    {
      if (fabs(error[i]) > threshold)
        m_rgRejected[i] = TRUE;
    }
    // always include the last data point
    m_rgRejected[0] = FALSE;

    // second RD model estimator
    RCModelEstimator (prc, n_windowSize, m_rgRejected);

    if( MADModelFlag )
      updateMADModel(prc);
    else if( img->type == P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number != 0)) )
      prc->PPictureMAD[0] = prc->CurrentFrameMAD;
  }
}

/*!
 *************************************************************************************
 * \brief
 *    Model Estimator
 *
 *************************************************************************************
*/
void RCModelEstimator (rc_quadratic *prc, int n_windowSize, Boolean *m_rgRejected)
{
  int n_realSize = n_windowSize;
  int i;
  double oneSampleQ = 0;
  double a00 = 0.0, a01 = 0.0, a10 = 0.0, a11 = 0.0, b0 = 0.0, b1 = 0.0;
  double MatrixValue;
  Boolean estimateX2 = FALSE;

  for (i = 0; i < n_windowSize; i++)
  {// find the number of samples which are not rejected
    if (m_rgRejected[i])
      n_realSize--;
  }

  // default RD model estimation results
  prc->m_X1 = prc->m_X2 = 0.0;

  for (i = 0; i < n_windowSize; i++)
  {
    if (!m_rgRejected[i])
      oneSampleQ = prc->m_rgQp[i];
  }
  for (i = 0; i < n_windowSize; i++)
  {// if all non-rejected Q are the same, take 1st order model
    if ((prc->m_rgQp[i] != oneSampleQ) && !m_rgRejected[i])
      estimateX2 = TRUE;
    if (!m_rgRejected[i])
      prc->m_X1 += (prc->m_rgQp[i] * prc->m_rgRp[i]) / n_realSize;
  }

  // take 2nd order model to estimate X1 and X2
  if ((n_realSize >= 1) && estimateX2)
  {
    for (i = 0; i < n_windowSize; i++)
    {
      if (!m_rgRejected[i])
      {
        a00  = a00 + 1.0;
        a01 += 1.0 / prc->m_rgQp[i];
        a10  = a01;
        a11 += 1.0 / (prc->m_rgQp[i] * prc->m_rgQp[i]);
        b0  += prc->m_rgQp[i] * prc->m_rgRp[i];
        b1  += prc->m_rgRp[i];
      }
    }
    // solve the equation of AX = B
    MatrixValue=a00*a11-a01*a10;
    if(fabs(MatrixValue) > 0.000001)
    {
      prc->m_X1 = (b0 * a11 - b1 * a01) / MatrixValue;
      prc->m_X2 = (b1 * a00 - b0 * a10) / MatrixValue;
    }
    else
    {
      prc->m_X1 = b0 / a00;
      prc->m_X2 = 0.0;
    }
  }
  if( img->type == P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number != 0)) )
  {
    prc->Pm_X1 = prc->m_X1;
    prc->Pm_X2 = prc->m_X2;
  }
}

/*!
 *************************************************************************************
 * \brief
 *    update the parameters of linear prediction model
 *
 *************************************************************************************
*/
void updateMADModel (rc_quadratic *prc)
{
  int    n_windowSize;
  int    i;
  double std = 0.0, threshold;
  int    m_Nc = prc->NumberofCodedPFrame;
  static Boolean PictureRejected[RC_MODEL_HISTORY];
  static double  error          [RC_MODEL_HISTORY];

  if(prc->NumberofCodedPFrame>0)
  {
    //assert (img->type!=P_SLICE);
    /*frame layer rate control*/
    if(img->BasicUnit == img->FrameSizeInMbs)
      m_Nc = prc->NumberofCodedPFrame;
    else // basic unit layer rate control
      m_Nc=prc->NumberofCodedPFrame*prc->TotalNumberofBasicUnit+prc->CodedBasicUnit;

    for (i = (RC_MODEL_HISTORY-2); i > 0; i--)
    {// update the history
      prc->PPictureMAD[i]  = prc->PPictureMAD[i - 1];
      prc->PictureMAD[i]   = prc->PPictureMAD[i];
      prc->ReferenceMAD[i] = prc->ReferenceMAD[i-1];
    }
    prc->PPictureMAD[0] = prc->CurrentFrameMAD;
    prc->PictureMAD[0]  = prc->PPictureMAD[0];

    if(img->BasicUnit == img->FrameSizeInMbs)
      prc->ReferenceMAD[0]=prc->PictureMAD[1];
    else
    {
      if(((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace)) &&(generic_RC->FieldControl==1))
        prc->ReferenceMAD[0]=prc->FCBUPFMAD[prc->TotalNumberofBasicUnit-1-prc->NumberofBasicUnit];
      else
        prc->ReferenceMAD[0]=prc->BUPFMAD[prc->TotalNumberofBasicUnit-1-prc->NumberofBasicUnit];
    }
    prc->MADPictureC1 = prc->PMADPictureC1;
    prc->MADPictureC2 = prc->PMADPictureC2;

    /*compute the size of window*/
    n_windowSize = (prc->CurrentFrameMAD > prc->PreviousFrameMAD)
      ? (int) ((float)(RC_MODEL_HISTORY-1) * prc->PreviousFrameMAD / prc->CurrentFrameMAD)
      : (int) ((float)(RC_MODEL_HISTORY-1) * prc->CurrentFrameMAD / prc->PreviousFrameMAD);
    n_windowSize = iClip3(1, (m_Nc-1), n_windowSize);
    n_windowSize=imin(n_windowSize, imin(20, prc->MADm_windowSize + 1));

    /*update the previous window size*/
    prc->MADm_windowSize=n_windowSize;

    for (i = 0; i < (RC_MODEL_HISTORY-1); i++)
    {
      PictureRejected[i] = FALSE;
    }

    //update the MAD for the previous frame
    if( img->type == P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number != 0)) )
      prc->PreviousFrameMAD=prc->CurrentFrameMAD;

    // initial MAD model estimator
    MADModelEstimator (prc, n_windowSize, PictureRejected);

    // remove outlier
    for (i = 0; i < n_windowSize; i++)
    {
      error[i] = prc->MADPictureC1 * prc->ReferenceMAD[i] + prc->MADPictureC2 - prc->PictureMAD[i];
      std += (error[i] * error[i]);
    }

    threshold = (n_windowSize == 2) ? 0 : sqrt (std / n_windowSize);
    for (i = 0; i < n_windowSize; i++)
    {
      if (fabs(error[i]) > threshold)
        PictureRejected[i] = TRUE;
    }
    // always include the last data point
    PictureRejected[0] = FALSE;

    // second MAD model estimator
    MADModelEstimator (prc, n_windowSize, PictureRejected);
  }
}


/*!
 *************************************************************************************
 * \brief
 *    MAD mode estimator
 *
 *************************************************************************************
*/
void MADModelEstimator (rc_quadratic *prc, int n_windowSize, Boolean *PictureRejected)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -