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

📄 ratecontrol.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 4 页
字号:
  bRC->PPictureIndexinGOP++;  if(!(bRC->ignoreIDR && img_type == SLICE_I))    bRC->bitDifference += (texbits+headerbits-bRC->bitsPerFrame);  bRC->TotalBits += (texbits+headerbits);  if(img_type ==SLICE_P){    if( ((bRC->PictureIndex % bRC->BIT_ADJUST_FREQUENCY) == 0) && (bRC->PictureIndex > 0))    {      if(bRC->numFrms>0)      {        //Number of frames to code is known#ifdef STRICT_FILE_SIZE_CONTROL        bRC->bitsPerPFrame = bRC->bitsPerFrame - (bRC->bitDifference)/(MIN(bRC->BIT_ADJUST_WINDOW,bRC->numFrms - bRC->PictureIndex+1)) ;        bRC->bitsPerPFrame = (int)((bRC->bitsPerPFrame)*(bRC->numNonref+1)*1.0/(1+0.5*bRC->numNonref));        #else                    bRC->bitsPerPFrame = bRC->bitsPerFrame - (bRC->bitDifference)/(bRC->BIT_ADJUST_WINDOW) ;        bRC->bitsPerPFrame = (int)(bRC->bitsPerPFrame)*(bRC->numNonref+1)*1.0/(1+0.5*bRC->numNonref);#endif      }      else                {        bRC->bitsPerPFrame = bRC->bitsPerFrame - (bRC->bitDifference)/(bRC->BIT_ADJUST_WINDOW);          bRC->bitsPerPFrame = (int)((bRC->bitsPerPFrame)*(bRC->numNonref+1)*1.0/(1+0.5*bRC->numNonref));      }            if(bRC->bitsPerPFrame < bRC->bitsPerFrame)        bRC->bitsPerPFrame = (int)(MAX(bRC->bitsPerPFrame,bRC->bitsPerFrame/2.0));            }  }  else if(img_type == SLICE_I)  {    bRC->bitsPerPFrame = bRC->bitsPerFrame - (bRC->bitDifference)/(MAX(15,bRC->GOPSize));      bRC->bitsPerPFrame = (int)((bRC->bitsPerPFrame)*(bRC->numNonref+1)*1.0/(1+0.5*bRC->numNonref));        if(bRC->bitsPerPFrame < bRC->bitsPerFrame)      bRC->bitsPerPFrame = (int)(MAX(bRC->bitsPerPFrame,bRC->bitsPerFrame/2.0));                }      if(bRC->PPictureIndexinGOP >= 2)    bRC->use_sh_RD_Model= 1;    if(bRC->PictureIndex>= 3 ||bRC->PPictureIndexinGOP >= 2)  {    bRC->use_lt_RD_Model= 1;  }  #ifdef USE_SPP  if(bRC->SPPPictureCounter == 0)    bRC->SPPPictureCounter = SPP_PICTURE_FREQ;#endif    picqstep=QP2Qstep((int)floor(bRC->averageQPforFrame));    if(bRC->bufferStall)  {    //    if(!(img_type == SLICE_I && bRC->ignoreIDR == 1))    bRC->CurrentBufferFullness += texbits + headerbits ;        if(bRC->CurrentBufferFullness > bRC->TargetBufferLevel)    {      bRC->playingStartFrame = bRC->PictureIndex;      bRC->CurrentBufferFullness -= bRC->bitsPerFrame;      bRC->bufferStall = 0;              }  }  else  {    //    if(!(img_type == SLICE_I && bRC->ignoreIDR == 1))    bRC->CurrentBufferFullness += texbits + headerbits - bRC->bitsPerFrame ;  }    bRC->CurrentBufferFullness = MIN(bRC->BufferSize,MAX(bRC->CurrentBufferFullness,0)); //Overflow and Underflow handled elsewhere      for(i=MAX_LT_RD_WINDOW_SIZE-1;i>0;i--)    bRC->BufferFullnessArray[i]  = bRC->BufferFullnessArray[i-1];    bRC->BufferFullnessArray[0] = bRC->CurrentBufferFullness;      //Update the Model Parameters    for(i=0;i<bRC->TotalNumberofMB;i++)  {    bRC->prevFrame_MBsad[i]=bRC->currentFrame_MBsad[i];    bRC->prevFrame_MBQp[i]=bRC->currentFrame_MBQp[i];    bRC->prevFrame_MBtexbits[i]=bRC->currentFrame_MBtexbits[i];    bRC->prevFrame_MBheaderbits[i]=bRC->currentFrame_MBheaderbits[i];        }    for(i=MAX_LT_RD_WINDOW_SIZE-1;i>0;i--)    bRC->framePSNR[i] = bRC->framePSNR[i-1];    bRC->framePSNR[i] = psnrY;    if(img_type == SLICE_I)  {    if(bRC->scut != 1)    {        //Due to GOP start      if(bRC->GOPSize > 1)      {        bRC->bitsPerPFrame = bRC->bitsPerFrame - (texbits+headerbits - bRC->bitsPerPFrame) / (bRC->GOPSize - 1)  ;                if(bRC->numFrms>0)          //Number of frames to code is known          bRC->bitsPerPFrame -= (bRC->bitDifference-texbits-headerbits+bRC->bitsPerFrame)/(bRC->numFrms - bRC->PictureIndex + 1) ;        else          bRC->bitsPerPFrame -= (bRC->bitDifference-texbits-headerbits+bRC->bitsPerFrame)/(100) ;      }    }    else    {            //Due to Scene cut      if(bRC->GOPSize > 1)      {        //Compensate the additional I frame over the course of 30 frames        bRC->bitsPerPFrame = bRC->bitsPerFrame - (texbits+headerbits - bRC->bitsPerPFrame) / (30)  ;                if(bRC->numFrms>0)          //Number of frames to code is known          bRC->bitsPerPFrame -= (bRC->bitDifference-texbits-headerbits+bRC->bitsPerFrame)/(bRC->numFrms - bRC->PictureIndex + 1) ;        else          bRC->bitsPerPFrame -= (bRC->bitDifference-texbits-headerbits+bRC->bitsPerFrame)/(100) ;            }    }      }  else if(img_type == SLICE_P)  {#ifdef USE_SPP    bRC->SPPPictureCounter--;#endif    //Update the Bit, MAD and RD Arrays    for(i=MAX_RD_WINDOW_SIZE-1;i>0;i--)    {      bRC->rdModel_QP[i]      = bRC->rdModel_QP[i-1];      if(texbits > 0 && headerbits > 0)      {        bRC->rdModel_TextureBits[i]  = bRC->rdModel_TextureBits[i-1];        bRC->rdModel_HeaderBits[i]  = bRC->rdModel_HeaderBits[i-1];        bRC->rdModel_PictureMAD[i]  = bRC->rdModel_PictureMAD[i-1];        bRC->rdModel_Qstep[i]      = bRC->rdModel_Qstep[i-1];      }    }        for(i=MAX_LT_RD_WINDOW_SIZE-1;i>0;i--)    {      if(texbits > 0 && headerbits > 0)      {        bRC->lt_rdModel_TextureBits[i]  = bRC->lt_rdModel_TextureBits[i-1];        bRC->lt_rdModel_HeaderBits[i]  = bRC->lt_rdModel_HeaderBits[i-1];        bRC->lt_rdModel_PictureMAD[i]  = bRC->lt_rdModel_PictureMAD[i-1];        bRC->lt_rdModel_Qstep[i]      = bRC->lt_rdModel_Qstep[i-1];              }          }    if(texbits > 0 || headerbits > 0)    {            if(headerbits > 0)      {        bRC->rdModel_HeaderBits[0]  = headerbits;        bRC->lt_rdModel_HeaderBits[0]  = headerbits;      }      if(texbits > 0)      {        bRC->rdModel_TextureBits[0]  = texbits;        bRC->lt_rdModel_TextureBits[0]  = texbits;      }      if(ComputePictureMAD(bRC) > 0)      {        bRC->rdModel_PictureMAD[0]  = ComputePictureMAD(bRC);        bRC->lt_rdModel_PictureMAD[0]  = bRC->rdModel_PictureMAD[0];      }            bRC->rdModel_Qstep[0]      = picqstep;      bRC->lt_rdModel_Qstep[0]      = picqstep;            bRC->rdModel_QP[0]      = bRC->averageQPforFrame;    }    MADUpdateFlag=1;  }    if(img_type == SLICE_P)  {    //Compute the size of windows    tempRDSize = (bRC->rdModel_PictureMAD[0]>bRC->rdModel_PictureMAD[1])?(int)(bRC->rdModel_PictureMAD[1]/bRC->rdModel_PictureMAD[0]*MAX_RD_WINDOW_SIZE)      :(int)(bRC->rdModel_PictureMAD[0]/bRC->rdModel_PictureMAD[1]*MAX_RD_WINDOW_SIZE);    tempRDSize=MAX(tempRDSize, 1);    tempRDSize=MIN(tempRDSize,bRC->rdModel_windowSize+1);    tempRDSize=MIN(tempRDSize,MAX_RD_WINDOW_SIZE);            lt_tempRDSize = (bRC->lt_rdModel_PictureMAD[0]>bRC->lt_rdModel_PictureMAD[1])?(int)(bRC->lt_rdModel_PictureMAD[1]/bRC->lt_rdModel_PictureMAD[0]*MAX_LT_RD_WINDOW_SIZE)      :(int)(bRC->lt_rdModel_PictureMAD[0]/bRC->lt_rdModel_PictureMAD[1]*MAX_LT_RD_WINDOW_SIZE);    lt_tempRDSize=MAX(lt_tempRDSize, 1);    lt_tempRDSize=MIN(lt_tempRDSize,bRC->lt_rdModel_windowSize+1);    lt_tempRDSize=MIN(lt_tempRDSize,MAX_LT_RD_WINDOW_SIZE);        bRC->rdModel_windowSize=tempRDSize;    bRC->lt_rdModel_windowSize=lt_tempRDSize;            //Update the RD Model    for (i = 0; i < MAX_RD_WINDOW_SIZE; i++)       bRC->rdModel_Rejected[i] = 0;        // initial RD model estimator    RDModelEstimator (bRC,img_type);        // remove outlier     for (i = 0; i < (int) tempRDSize; i++)     {      error[i] = 1.0f*bRC->rdModel_X1 /( bRC->rdModel_Qstep[i]) + 1.0f*bRC->rdModel_X2 /( bRC->rdModel_Qstep[i] * bRC->rdModel_Qstep[i]) - bRC->rdModel_TextureBits[i]*1.0f/bRC->rdModel_PictureMAD[i];      std += error[i] * error[i];     }    threshold = (float)((tempRDSize == 2) ? 0 : sqrt (std / tempRDSize));        for (i = 0; i < (int) tempRDSize; i++)    {      if (fabs(error[i]) > threshold)        bRC->rdModel_Rejected[i] = 1;    }    // always include the last data point    bRC->rdModel_Rejected[0] = 0;        // second RD model estimator    RDModelEstimator (bRC, img_type);        //************** Update the long term RD Model *******************    //Update the RD Model    for (i = 0; i < MAX_LT_RD_WINDOW_SIZE; i++)       bRC->lt_rdModel_Rejected[i] = 0;        // initial RD model estimator    lt_RDModelEstimator (bRC,img_type);        // remove outlier     for (i = 0; i < (int) lt_tempRDSize; i++)     {      lt_error[i] = bRC->lt_rdModel_X1 /( bRC->lt_rdModel_Qstep[i]) + bRC->lt_rdModel_X2 /( bRC->lt_rdModel_Qstep[i] * bRC->lt_rdModel_Qstep[i]) - bRC->lt_rdModel_TextureBits[i]*1.0f/bRC->lt_rdModel_PictureMAD[i];      lt_std += lt_error[i] * lt_error[i];     }    threshold = (lt_tempRDSize == 2) ? 0 :(float) sqrt (lt_std / lt_tempRDSize);        for (i = 0; i < (int) lt_tempRDSize; i++)    {      if (fabs(lt_error[i]) > threshold)        bRC->lt_rdModel_Rejected[i] = 1;    }    // always include the last data point    bRC->lt_rdModel_Rejected[0] = 0;        // second RD model estimator    lt_RDModelEstimator (bRC, img_type);  }    hdrSize=bRC->lt_rdModel_windowSize;  hdrSize=MIN(hdrSize,MAX_LT_RD_WINDOW_SIZE);    if(bRC->use_lt_RD_Model== 1 && img_type == SLICE_P)  {        avgHeaderBits = getAverageHeaderBits(bRC,hdrSize,1);    avgTextureBits = getAverageTextureBits(bRC,hdrSize,1);    avgMAD = getAverageMAD(bRC,hdrSize,1);    tex = bRC->bitsPerPFrame*avgTextureBits/(avgTextureBits+avgHeaderBits);    if(avgTextureBits > 0 )    {            Qaver =  getQP_UsingRDModel(tex, avgMAD, bRC->lt_rdModel_X1, bRC->lt_rdModel_X2);    }    else      Qaver = (int) bRC->averageQPforFrame-1;          }  else    Qaver = (int) bRC->averageQPforFrame;        if(bRC->GOPSize == 0)  {    //No GOPs    if(bRC->PictureIndex%bRC->LT_WINDOW_QP_UPDATE_FREQ == 0 || bRC->PictureIndex<15 || bRC->PPictureIndexinGOP == 0)    {      if(bRC->PictureIndex > 3)      {        if( avgHeaderBits<bRC->bitsPerPFrame )        {          if(Qaver > bRC->QP_LW)            bRC->QP_LW = MIN(Qaver, bRC->QP_LW+2);          else             bRC->QP_LW = MAX(Qaver, bRC->QP_LW-2);        }        else          bRC->QP_LW++;      }      else if(img_type == SLICE_P)        bRC->QP_LW = Qaver;          }  }  else if(bRC->PictureIndex%bRC->GOPSize == 0 || bRC->PictureIndex%bRC->LT_WINDOW_QP_UPDATE_FREQ==0 || bRC->PictureIndex<15 || bRC->PPictureIndexinGOP == 0 || bRC->use_lt_RD_Model == 0)  {    if(bRC->PictureIndex > 3)    {      if( avgHeaderBits<bRC->bitsPerPFrame )      {        if(Qaver > bRC->QP_LW)          bRC->QP_LW = MIN(Qaver, bRC->QP_LW+2);        else           bRC->QP_LW = MAX(Qaver, bRC->QP_LW-2);      }      else        bRC->QP_LW++;    }        else if(img_type == SLICE_P)      bRC->QP_LW = Qaver;  }    bRC->QP_LW = MIN(50,MAX(1,bRC->QP_LW));  return AVCE_OK;    }//compute a  quantization parameter for each frameint rc_getFrameQP(rateCtrl_s *bRC, int img_type){  /*frame layer rate control*/  if(img_type==SLICE_I && bRC->PictureIndex == 0)  {    bRC->averageQPforFrame = (float) bRC->InitialQP;        bRC->frameReturnedQP = (int)bRC->InitialQP;    return bRC->frameReturnedQP;  }  else if(img_type == SLICE_I)    return bRC->frameReturnedQP = bRC->frameComputedQP;      else if((img_type==SLICE_P)&&(bRC->PPictureIndexinGOP==0))  {#ifdef USE_SPP    if(bRC->SPPPictureCounter == 0)      return bRC->frameReturnedQP = bRC->SPPframeComputedQP;    else#endif      if(bRC->BufferSize < bRC->bit_rate)        return bRC->frameComputedQP = bRC->frameReturnedQP = (int)(bRC->averageQPforFrame)+2;      else      {        if(bRC->use_lt_RD_Model == 0 && bRC->use_sh_RD_Model == 0)          return bRC->frameComputedQP = bRC->frameReturnedQP = (int)(bRC->averageQPforFrame);        else          return bRC->frameReturnedQP=bRC->frameComputedQP;      }        }    else    #ifdef USE_SPP    if(bRC->SPPPictureCounter == 0)      return bRC->frameReturnedQP = bRC->SPPframeComputedQP;    else#endif      return bRC->frameReturnedQP = bRC->frameComputedQP;        }int Qstep2QP( float Qstep ){  int q_per = 0, q_rem = 0;    if( Qstep < QP2Qstep(0))    return 0;  else if (Qstep > QP2Qstep(51) )    return 51;    while( Qstep > QP2Qstep(5) )  {    Qstep /= 2;    q_per += 1;  }    if (Qstep <= (0.625+0.6875)/2)   {    Qstep = 0.625;    q_rem = 0;  }  else if (Qstep <= (0.6875+0.8125)/2)  {    Qstep = 0.6875;    q_rem = 1;  }  else if (Qstep <= (0.8125+0.875)/2)  {    Qstep = 0.8125;    q_rem = 2;  }  else if (Qstep <= (0.875+1.0)/2)  {    Qstep = 0.875;    q_rem = 3;  }  else if (Qstep <= (1.0+1.125)/2)  {    Qstep = 1.0;      q_rem = 4;  }  else   {    Qstep = 1.125;    q_rem = 5;  }    return (q_per * 6 + q_rem);}float QP2Qstep( int QP ){  int i;   float Qstep;  static const float QP2QSTEP[6] = { 0.625, 0.6875, 0.8125, 0.875, 1.0, 1.125 };    Qstep = QP2QSTEP[QP % 6];  for( i=0; i<(QP/6); i++)    Qstep *= 2;    return Qstep;}void RDModelEstimator (rateCtrl_s *bRC, int img_type){  int n_windowSize = bRC->rdModel_windowSize;  int n_realSize = n_windowSize;  int i;  float oneSampleQ=0.0;  float a00 = 0.0f, a01 = 0.0f, a10 = 0.0f, a11 = 0.0f, b0 = 0.0f, b1 = 0.0f;  float MatrixValue;  Boolean estimateX2 = 0;    if(img_type == SLICE_I)    return;    for (i = 0; i < n_windowSize; i++) {// find the number of samples which are not rejected    if (bRC->rdModel_Rejected[i])      n_realSize--;  }    // default RD model estimation results  bRC->rdModel_X1 = bRC->rdModel_X2= 0.0f;    for (i = 0; i < n_windowSize; i++)  {    if (!bRC->rdModel_Rejected[i])      oneSampleQ = bRC->rdModel_Qstep[i];  }    for (i = 0; i < n_windowSize; i++)  {// if all non-rejected Q are the same, take 1st order model    if ((bRC->rdModel_Qstep[i] != oneSampleQ) && !bRC->rdModel_Rejected[i])      estimateX2 = 1;    if (!bRC->rdModel_Rejected[i])      bRC->rdModel_X1 += (bRC->rdModel_Qstep[i] * bRC->rdModel_TextureBits[i]*1.0f/bRC->rdModel_PictureMAD[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 (!bRC->rdModel_Rejected[i])      {        a00 = a00 + 1.0f;        a01 += 1.0f / bRC->rdModel_Qstep[i];        a10 = a01;        a11 += 1.0f / (bRC->rdModel_Qstep[i] * bRC->rdModel_Qstep[i]);        b0 += (bRC->rdModel_Qstep[i] * bRC->rdModel_TextureBits[i]*1.0f/bRC->rdModel_PictureMAD[i]);        b1 += bRC->rdModel_TextureBits[i]*1.0f/bRC->rdModel_PictureMAD[i];              }    }        // solve the equation of AX = B    MatrixValue=a00*a11-a01*a10;    if(fabs(MatrixValue)>0.000001f)    {      bRC->rdModel_X1 = (b0*a11-b1*a01)/MatrixValue;      bRC->rdModel_X2 = (b1*a00-b0*a10)/MatrixValue;    }     else    {      bRC->rdModel_X1 = b0/a00;      bRC->rdModel_X2 = 0.0f;    }  }  }void lt_RDModelEstimator(rateCtrl_s *bRC, int img_type){  int n_windowSize = bRC->lt_rdModel_windowSize;  int n_realSize = n_windowSize;  int i;

⌨️ 快捷键说明

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