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

📄 rc_quadratic.c

📁 This program can encode the YUV vdieo format to H.264 and decode it.
💻 C
📖 第 1 页 / 共 5 页
字号:
  int    n_realSize = n_windowSize;
  int    i;
  double oneSampleQ = 0.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 (PictureRejected[i])
      n_realSize--;
  }

  // default MAD model estimation results
  prc->MADPictureC1 = prc->MADPictureC2 = 0.0;

  for (i = 0; i < n_windowSize; i++)
  {
    if (!PictureRejected[i])
      oneSampleQ = prc->PictureMAD[i];
  }

  for (i = 0; i < n_windowSize; i++)
  {// if all non-rejected MAD are the same, take 1st order model
    if ((prc->PictureMAD[i] != oneSampleQ) && !PictureRejected[i])
      estimateX2 = TRUE;
    if (!PictureRejected[i])
      prc->MADPictureC1 += prc->PictureMAD[i] / (prc->ReferenceMAD[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 (!PictureRejected[i])
      {
        a00  = a00 + 1.0;
        a01 += prc->ReferenceMAD[i];
        a10  = a01;
        a11 += prc->ReferenceMAD[i] * prc->ReferenceMAD[i];
        b0  += prc->PictureMAD[i];
        b1  += prc->PictureMAD[i]   * prc->ReferenceMAD[i];
      }
    }
    // solve the equation of AX = B
    MatrixValue = a00 * a11 - a01 * a10;
    if(fabs(MatrixValue) > 0.000001)
    {
      prc->MADPictureC2 = (b0 * a11 - b1 * a01) / MatrixValue;
      prc->MADPictureC1 = (b1 * a00 - b0 * a10) / MatrixValue;
    }
    else
    {
      prc->MADPictureC1 = b0/a01;
      prc->MADPictureC2 = 0.0;
    }
  }
  if( img->type == P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number != 0)) )
  {
    prc->PMADPictureC1 = prc->MADPictureC1;
    prc->PMADPictureC2 = prc->MADPictureC2;
  }
}

/*!
 *************************************************************************************
 * \brief
 *    compute a  quantization parameter for each frame (RC_MODE_0)
 *
 *************************************************************************************
*/
int updateQPRC0(rc_quadratic *prc, int topfield)
{
  int m_Bits;
  int BFrameNumber;
  int StepSize;
  int SumofBasicUnit;
  int MaxQpChange, m_Qp, m_Hp;

  /* frame layer rate control */
  if( img->BasicUnit == img->FrameSizeInMbs )
  {
    /* fixed quantization parameter is used to coded I frame, the first P frame and the first B frame
    the quantization parameter is adjusted according the available channel bandwidth and
    the type of video */
    /*top field*/
    if((topfield) || (generic_RC->FieldControl==0))
    {
      if (img->type==I_SLICE)
      {
        prc->m_Qc = prc->MyInitialQp;
        return prc->m_Qc;
      }
      else if(img->type == B_SLICE)
      {
        if(input->successive_Bframe==1)
        {
          if((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))
            updateQPInterlace( prc );

          prc->m_Qc = imin(prc->PrevLastQP, prc->CurrLastQP) + 2;
          prc->m_Qc = imax(prc->m_Qc, imax(prc->PrevLastQP, prc->CurrLastQP));
          prc->m_Qc = imax(prc->m_Qc, prc->CurrLastQP + 1);
          prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
        }
        else
        {
          BFrameNumber = (prc->NumberofBFrames + 1) % input->successive_Bframe;
          if(BFrameNumber==0)
            BFrameNumber = input->successive_Bframe;

          /*adaptive field/frame coding*/
          if(BFrameNumber==1)
          {
            if((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))
              updateQPInterlace( prc );
          }

          if((prc->CurrLastQP-prc->PrevLastQP)<=(-2*input->successive_Bframe-3))
            StepSize=-3;
          else  if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe-2))
            StepSize=-2;
          else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe-1))
            StepSize=-1;
          else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe))
            StepSize=0;
          else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe+1))
            StepSize=1;
          else
            StepSize=2;

          prc->m_Qc  = prc->PrevLastQP + StepSize;
          prc->m_Qc += iClip3( -2 * (BFrameNumber - 1), 2*(BFrameNumber-1),
            (BFrameNumber-1)*(prc->CurrLastQP-prc->PrevLastQP)/(input->successive_Bframe-1));
          prc->m_Qc  = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
        }
        return prc->m_Qc;
      }
      else if( img->type == P_SLICE && prc->NumberofPPicture == 0 )
      {
        prc->m_Qc=prc->MyInitialQp;

        if(generic_RC->FieldControl==0)
          updateQPNonPicAFF( prc );
        return prc->m_Qc;
      }
      else
      {
        /*adaptive field/frame coding*/
        if( ( input->PicInterlace == ADAPTIVE_CODING || input->MbInterlace ) && generic_RC->FieldControl == 0 )
          updateQPInterlaceBU( prc );

        prc->m_X1 = prc->Pm_X1;
        prc->m_X2 = prc->Pm_X2;
        prc->MADPictureC1 = prc->PMADPictureC1;
        prc->MADPictureC2 = prc->PMADPictureC2;
        prc->PreviousPictureMAD = prc->PPictureMAD[0];

        MaxQpChange = prc->PMaxQpChange;
        m_Qp = prc->Pm_Qp;
        m_Hp = prc->PPreHeader;

        /* predict the MAD of current picture*/
        prc->CurrentFrameMAD = prc->MADPictureC1*prc->PreviousPictureMAD + prc->MADPictureC2;

        /*compute the number of bits for the texture*/
        if(prc->Target < 0)
        {
          prc->m_Qc=m_Qp+MaxQpChange;
          prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
        }
        else
        {
          m_Bits = prc->Target-m_Hp;
          m_Bits = imax(m_Bits, (int)(prc->bit_rate/(MINVALUE*prc->frame_rate)));

          updateModelQPFrame( prc, m_Bits );

          prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // clipping
          prc->m_Qc = iClip3(m_Qp-MaxQpChange, m_Qp+MaxQpChange, prc->m_Qc); // control variation
        }

        if( generic_RC->FieldControl == 0 )
          updateQPNonPicAFF( prc );

        return prc->m_Qc;
      }
    }
    /*bottom field*/
    else
    {
      if( img->type == P_SLICE && generic_RC->NoGranularFieldRC == 0 )
        updateBottomField( prc );
      return prc->m_Qc;
    }
  }
  /*basic unit layer rate control*/
  else
  {
    /*top field of I frame*/
    if (img->type == I_SLICE)
    {
      prc->m_Qc = prc->MyInitialQp;
      return prc->m_Qc;
    }
    else if( img->type == B_SLICE )
    {
      /*top field of B frame*/
      if((topfield)||(generic_RC->FieldControl==0))
      {
        if(input->successive_Bframe==1)
        {
          /*adaptive field/frame coding*/
          if((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))
            updateQPInterlace( prc );

          if(prc->PrevLastQP==prc->CurrLastQP)
            prc->m_Qc=prc->PrevLastQP+2;
          else
            prc->m_Qc=(prc->PrevLastQP+prc->CurrLastQP)/2+1;
          prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
        }
        else
        {
          BFrameNumber=(prc->NumberofBFrames+1)%input->successive_Bframe;
          if(BFrameNumber==0)
            BFrameNumber=input->successive_Bframe;

          /*adaptive field/frame coding*/
          if(BFrameNumber==1)
          {
            if((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))
              updateQPInterlace( prc );
          }

          if((prc->CurrLastQP-prc->PrevLastQP)<=(-2*input->successive_Bframe-3))
            StepSize=-3;
          else  if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe-2))
            StepSize=-2;
          else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe-1))
            StepSize=-1;
          else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe))
            StepSize=0;//0
          else if((prc->CurrLastQP-prc->PrevLastQP)==(-2*input->successive_Bframe+1))
            StepSize=1;//1
          else
            StepSize=2;//2
          prc->m_Qc=prc->PrevLastQP+StepSize;
          prc->m_Qc +=
            iClip3( -2*(BFrameNumber-1), 2*(BFrameNumber-1), (BFrameNumber-1)*(prc->CurrLastQP-prc->PrevLastQP)/(input->successive_Bframe-1) );
          prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
        }
        return prc->m_Qc;
      }
      /*bottom field of B frame*/
      else
      {
        return prc->m_Qc;
      }
    }
    else if( img->type == P_SLICE )
    {
      if( (generic_RC->NumberofGOP == 1) && (prc->NumberofPPicture == 0) )
      {
        if((generic_RC->FieldControl==0)||((generic_RC->FieldControl==1) && (generic_RC->NoGranularFieldRC==0)))
          return updateFirstP( prc, topfield );
      }
      else
      {
        prc->m_X1=prc->Pm_X1;
        prc->m_X2=prc->Pm_X2;
        prc->MADPictureC1=prc->PMADPictureC1;
        prc->MADPictureC2=prc->PMADPictureC2;

        m_Qp=prc->Pm_Qp;

        if(generic_RC->FieldControl==0)
          SumofBasicUnit=prc->TotalNumberofBasicUnit;
        else
          SumofBasicUnit=prc->TotalNumberofBasicUnit>>1;

        /*the average QP of the previous frame is used to coded the first basic unit of the current frame or field*/
        if(prc->NumberofBasicUnit==SumofBasicUnit)
          return updateFirstBU( prc, topfield );
        else
        {
          /*compute the number of remaining bits*/
          prc->Target -= (generic_RC->NumberofBasicUnitHeaderBits + generic_RC->NumberofBasicUnitTextureBits);
          generic_RC->NumberofBasicUnitHeaderBits  = 0;
          generic_RC->NumberofBasicUnitTextureBits = 0;
          if(prc->Target<0)
            return updateNegativeTarget( prc, topfield, m_Qp );
          else
          {
            /*predict the MAD of current picture*/
            predictCurrPicMAD( prc );

            /*compute the total number of bits for the current basic unit*/
            updateModelQPBU( prc, topfield, m_Qp );

            prc->TotalFrameQP +=prc->m_Qc;
            prc->Pm_Qp=prc->m_Qc;
            prc->NumberofBasicUnit--;
            if( prc->NumberofBasicUnit == 0 && img->type == P_SLICE )
              updateLastBU( prc, topfield );

            return prc->m_Qc;
          }
        }
      }
    }
  }
  return prc->m_Qc;
}

/*!
 *************************************************************************************
 * \brief
 *    compute a  quantization parameter for each frame
 *
 *************************************************************************************
*/
int updateQPRC1(rc_quadratic *prc, int topfield)
{
  int m_Bits;
  int SumofBasicUnit;
  int MaxQpChange, m_Qp, m_Hp;

  /* frame layer rate control */
  if( img->BasicUnit == img->FrameSizeInMbs )
  {
    /* fixed quantization parameter is used to coded I frame, the first P frame and the first B frame
    the quantization parameter is adjusted according the available channel bandwidth and
    the type of vide */
    /*top field*/
    if((topfield) || (generic_RC->FieldControl==0))
    {
      if (img->number == 0)
      {
        prc->m_Qc = prc->MyInitialQp;
        return prc->m_Qc;
      }
      else if( prc->NumberofPPicture == 0 && (img->number != 0))
      {
        prc->m_Qc=prc->MyInitialQp;

        if(generic_RC->FieldControl==0)
          updateQPNonPicAFF( prc );
        return prc->m_Qc;
      }
      else
      {
        /*adaptive field/frame coding*/
        if( ( input->PicInterlace == ADAPTIVE_CODING || input->MbInterlace ) && generic_RC->FieldControl == 0 )
          updateQPInterlaceBU( prc );

        prc->m_X1 = prc->Pm_X1;
        prc->m_X2 = prc->Pm_X2;
        prc->MADPictureC1 = prc->PMADPictureC1;
        prc->MADPictureC2 = prc->PMADPictureC2;
        prc->PreviousPictureMAD = prc->PPictureMAD[0];

        MaxQpChange = prc->PMaxQpChange;
        m_Qp = prc->Pm_Qp;
        m_Hp = prc->PPreHeader;

        /* predict the MAD of current picture*/
        prc->CurrentFrameMAD=prc->MADPictureC1*prc->PreviousPictureMAD + prc->MADPictureC2;

        /*compute the number of bits for the texture*/
        if(prc->Target < 0)
        {
          prc->m_Qc=m_Qp+MaxQpChange;
          prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // Clipping
        }
        else
        {
          m_Bits = prc->Target-m_Hp;
          m_Bits = imax(m_Bits, (int)(prc->bit_rate/(MINVALUE*prc->frame_rate)));

          updateModelQPFrame( prc, m_Bits );

          prc->m_Qc = iClip3(prc->RC_MIN_QUANT, prc->RC_MAX_QUANT, prc->m_Qc); // clipping
          prc->m_Qc = iClip3(m_Qp-MaxQpChange, m_Qp+MaxQpChange, prc->m_Qc); // control variation
        }

        if( generic_RC->FieldControl == 0 )
          updateQPNonPicAFF( prc );

⌨️ 快捷键说明

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