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

📄 ratecontrol.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 4 页
字号:
  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->lt_rdModel_Rejected[i])      n_realSize--;  }    // default RD model estimation results  bRC->lt_rdModel_X1 = bRC->lt_rdModel_X2= 0.0f;    for (i = 0; i < n_windowSize; i++)  {    if (!bRC->lt_rdModel_Rejected[i])      oneSampleQ = bRC->lt_rdModel_Qstep[i];  }  for (i = 0; i < n_windowSize; i++)  {// if all non-rejected Q are the same, take 1st order model    if ((bRC->lt_rdModel_Qstep[i] != oneSampleQ) && !bRC->lt_rdModel_Rejected[i])      estimateX2 = 1;    if (!bRC->lt_rdModel_Rejected[i])      bRC->lt_rdModel_X1 += (bRC->lt_rdModel_Qstep[i] * bRC->lt_rdModel_TextureBits[i]*1.0f/bRC->lt_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->lt_rdModel_Rejected[i])      {        a00 = a00 + 1.0f;        a01 += 1.0f / bRC->lt_rdModel_Qstep[i];        a10 = a01;        a11 += 1.0f / (bRC->lt_rdModel_Qstep[i] * bRC->lt_rdModel_Qstep[i]);        b0 += (bRC->lt_rdModel_Qstep[i] * bRC->lt_rdModel_TextureBits[i]*1.0f/bRC->lt_rdModel_PictureMAD[i]);        b1 += bRC->lt_rdModel_TextureBits[i]*1.0f/bRC->lt_rdModel_PictureMAD[i];              }    }        // solve the equation of AX = B    MatrixValue=a00*a11-a01*a10;    if(fabs(MatrixValue)>0.000001f)    {      bRC->lt_rdModel_X1 = (b0*a11-b1*a01)/MatrixValue;      bRC->lt_rdModel_X2 = (b1*a00-b0*a10)/MatrixValue;    }     else    {      bRC->lt_rdModel_X1 = b0/a00;      bRC->lt_rdModel_X2 = 0.0f;    }  }  }float ComputePictureMAD(rateCtrl_s *bRC){  float TotalMAD;  int i;  TotalMAD=0.0;    for(i=0;i<bRC->TotalNumberofMB;i++)    TotalMAD +=bRC->MSEofMB[i];    //TotalMAD /=(bRC->TotalNumberofMB*256);  return TotalMAD;}int getQP_UsingRDModel(int targetBits, float mad, float X1, float X2){  float deltaTemp;  float Qstep;  int q;    deltaTemp = mad * X1 * mad * X1  + 4 * X2* mad * targetBits;  if ((X2 == 0.0) || (deltaTemp < 0) || ((sqrt (deltaTemp) - X1 * mad) <= 0.0)) // fall back 1st order mode    Qstep = (float) (X1 * mad / (float) targetBits);  else // 2nd order mode    Qstep = (float) ((2 * X2 * mad) / (sqrt (deltaTemp) - X1 * mad));  q=Qstep2QP(Qstep);  return q;    }int getAverageHeaderBits(rateCtrl_s *bRC, int windowSize, int lt) {  int i;  int headerbits=0;  int  *parr = bRC->rdModel_HeaderBits;    if(lt == 1)    parr = bRC->lt_rdModel_HeaderBits;    for(i=0;i<windowSize;i++)    headerbits+=parr[i];  if(windowSize>0)    headerbits=headerbits/windowSize;  else    headerbits=0;  return headerbits;}int getAverageTextureBits(rateCtrl_s *bRC, int windowSize,int lt) {  int i;  int texbits=0;  int *parr = bRC->rdModel_TextureBits;    if(lt == 1)    parr = bRC->lt_rdModel_TextureBits;    for(i=0;i<windowSize;i++)    texbits+=parr[i];  if(windowSize>0)    texbits=texbits/windowSize;  else    texbits=0;  return texbits;}float getAverageMAD(rateCtrl_s *bRC, int windowSize,int lt) {  int i;  float mad=0.0;  float *parr = bRC->rdModel_PictureMAD;  int *prejected = bRC->rdModel_Rejected;  int n_realSize = windowSize;    if(lt == 1)  {    prejected = bRC->lt_rdModel_Rejected;    parr = bRC->lt_rdModel_PictureMAD;  }    for (i = 0; i < windowSize; i++) {// find the number of samples which are not rejected    if (prejected[i])      n_realSize--;  }    for(i=0;i<windowSize;i++)  {    if (!prejected[i])      mad+=parr[i];  }    if(n_realSize>0)    mad=mad/n_realSize;  else    mad=0;  return mad;}void createBitEnvelope(rateCtrl_s *bRC){  //Creates the upper and lower limits using PI Buffer Regulator  float Et = (bRC->TargetBufferLevel - bRC->CurrentBufferFullness)*1.0f / bRC->TargetBufferLevel; //Proportional    float Etau=0;    float PIError;  int i;    bRC->upperFrameLimit = (int)(bRC->bitsPerPFrame*bRC->UPPER_LIMIT_MULTIPLE);  bRC->lowerFrameLimit = (int)(bRC->bitsPerPFrame/bRC->LOWER_LIMIT_MULTIPLE);      if(bRC->BufferSize > bRC->bit_rate/2)  {    if(bRC->img_type == SLICE_I)    {            bRC->upperFrameLimit = (bRC->bitsPerFrame*bRC->I_P_RATIO);      bRC->lowerFrameLimit = (bRC->upperFrameLimit/2);      return;    }        if(!bRC->bufferStall )    {      for(i=0;i<MIN(30,(bRC->PictureIndex-bRC->playingStartFrame));i++)      {        if(bRC->BufferFullnessArray[i]>0)          Etau+=(bRC->TargetBufferLevel - bRC->BufferFullnessArray[i])*1.0f / bRC->TargetBufferLevel;      }      //Then create upper and lower limits otherwise do not touch      PIError = Kp*(Et+Etau*Ki);        if(PIError<0)      {        bRC->upperFrameLimit = (int)((1+MAX(-0.5f,PIError)) * bRC->bitsPerPFrame*bRC->UPPER_LIMIT_MULTIPLE);        bRC->upperFrameLimit = MIN(bRC->BufferSize - bRC->CurrentBufferFullness , bRC->upperFrameLimit);      }      else      {        if(bRC->nalRefIdc == 1)        {          bRC->lowerFrameLimit = (int)((1+MIN(5,PIError*8)) * bRC->bitsPerPFrame/bRC->LOWER_LIMIT_MULTIPLE);          bRC->lowerFrameLimit = MAX( (2*bRC->bitsPerPFrame - bRC->CurrentBufferFullness) , bRC->lowerFrameLimit);        }        else          bRC->lowerFrameLimit = bRC->bitsPerPFrame - bRC->CurrentBufferFullness;      }      //Check if we are approaching to a start of GOP      if( bRC->GOPSize - (bRC->PictureIndex%bRC->GOPSize) <= 5 )      {        //Check the Buffer size, change the envelope accordingly        if( (bRC->BufferSize - bRC->CurrentBufferFullness) < bRC->bitsPerFrame * 5)        {          bRC->upperFrameLimit = (int)(1.1 * (bRC->CurrentBufferFullness - (bRC->BufferSize - bRC->bitsPerFrame*5))/(1.0*(bRC->GOPSize - (bRC->PictureIndex%bRC->GOPSize))));        }      }    }    else    {            bRC->upperFrameLimit = (int)(bRC->bitsPerPFrame*bRC->UPPER_LIMIT_MULTIPLE);      bRC->lowerFrameLimit = (int)(bRC->bitsPerPFrame/bRC->LOWER_LIMIT_MULTIPLE);                  if(bRC->nalRefIdc == 0)        bRC->lowerFrameLimit = bRC->bitsPerPFrame - bRC->CurrentBufferFullness;    }        /*if(bRC->upperFrameLimit < bRC->bitsPerFrame/LOWER_LIMIT_MULTIPLE)    bRC->upperFrameLimit = (int)(bRC->bitsPerFrame/LOWER_LIMIT_MULTIPLE);    if(bRC->lowerFrameLimit > bRC->bitsPerFrame*UPPER_LIMIT_MULTIPLE)    bRC->upperFrameLimit = (int)(bRC->bitsPerFrame*UPPER_LIMIT_MULTIPLE);*/        if(bRC->lowerFrameLimit < bRC->bitsPerFrame/bRC->LOWER_LIMIT_MULTIPLE)      bRC->lowerFrameLimit = (int)(bRC->bitsPerFrame/bRC->LOWER_LIMIT_MULTIPLE);    if(bRC->upperFrameLimit > bRC->bitsPerFrame*bRC->UPPER_LIMIT_MULTIPLE)      bRC->upperFrameLimit = (int)(bRC->bitsPerFrame*bRC->UPPER_LIMIT_MULTIPLE);  }  else  {        if(bRC->img_type == SLICE_I)    {            bRC->upperFrameLimit = (int)MAX(bRC->bitsPerFrame,MIN(bRC->BufferSize*0.95f-bRC->CurrentBufferFullness+bRC->bitsPerFrame, bRC->bitsPerFrame*bRC->I_P_RATIO));      bRC->lowerFrameLimit = bRC->upperFrameLimit - bRC->bitsPerFrame;      return;    }        bRC->centerFrameBits = bRC->bitsPerPFrame;        if(bRC->CurrentBufferFullness < 0)    {      bRC->upperFrameLimit = (int)(bRC->bitsPerFrame*bRC->UPPER_LIMIT_MULTIPLE);      bRC->lowerFrameLimit = (int)(bRC->bitsPerFrame*1.5f);      bRC->centerFrameBits = bRC->lowerFrameLimit;          }    else    {                  if(bRC->CurrentBufferFullness >= bRC->BufferSize/2)      {                        bRC->upperFrameLimit = (int)(bRC->bitsPerPFrame * (bRC->UPPER_LIMIT_MULTIPLE - (bRC->UPPER_LIMIT_MULTIPLE - 1)*(bRC->CurrentBufferFullness - bRC->BufferSize/2)*1.0f/bRC->BufferSize));        bRC->centerFrameBits = MIN(bRC->upperFrameLimit,bRC->bitsPerPFrame);        bRC->lowerFrameLimit = (int)(bRC->centerFrameBits / bRC->LOWER_LIMIT_MULTIPLE);      }      else      {        bRC->lowerFrameLimit = (int)(bRC->bitsPerFrame * (1-1.0f/bRC->LOWER_LIMIT_MULTIPLE)*2.0f/bRC->BufferSize*bRC->CurrentBufferFullness);         bRC->centerFrameBits = MIN(bRC->upperFrameLimit,bRC->bitsPerPFrame);        bRC->upperFrameLimit = (int)(bRC->centerFrameBits * bRC->UPPER_LIMIT_MULTIPLE);      }      }        if(bRC->CurrentBufferFullness + bRC->upperFrameLimit - bRC->bitsPerFrame > bRC->BufferSize - bRC->bitsPerFrame/5)    {      bRC->upperFrameLimit = -bRC->bitsPerFrame/5 + bRC->BufferSize - bRC->CurrentBufferFullness + bRC->bitsPerFrame;      bRC->lowerFrameLimit = MAX(bRC->bitsPerFrame/4, bRC->upperFrameLimit - bRC->bitsPerFrame);      bRC->centerFrameBits = (bRC->upperFrameLimit + bRC->lowerFrameLimit)/2;    }        if(bRC->CurrentBufferFullness + bRC->lowerFrameLimit - bRC->bitsPerFrame < bRC->bitsPerFrame/5)    {      bRC->lowerFrameLimit = bRC->bitsPerFrame/5 + bRC->bitsPerFrame  - bRC->CurrentBufferFullness;      bRC->upperFrameLimit = bRC->lowerFrameLimit + bRC->bitsPerFrame;      bRC->centerFrameBits = (bRC->upperFrameLimit + bRC->lowerFrameLimit)/2;    }        if(bRC->lowerFrameLimit < bRC->bitsPerFrame/bRC->LOWER_LIMIT_MULTIPLE)    {      bRC->lowerFrameLimit = (int)(bRC->bitsPerFrame/bRC->LOWER_LIMIT_MULTIPLE);      bRC->upperFrameLimit = bRC->lowerFrameLimit + bRC->bitsPerFrame/2;      bRC->centerFrameBits = bRC->lowerFrameLimit + bRC->bitsPerFrame/4;    }        if(bRC->upperFrameLimit > bRC->bitsPerFrame*bRC->UPPER_LIMIT_MULTIPLE)    {      bRC->upperFrameLimit = (int)(bRC->bitsPerFrame*bRC->UPPER_LIMIT_MULTIPLE);      bRC->lowerFrameLimit = bRC->upperFrameLimit - bRC->bitsPerFrame/2;      bRC->centerFrameBits = bRC->upperFrameLimit - bRC->bitsPerFrame/4;    }  }    }  //Fills the necessary HRD parameter syntaxes that should be put in the bitstreamvoid fillHRDParameters(rateCtrl_s *bRC, hrd_parameters_s *hrd){  int i;  hrd->cpb_cnt_minus1 = 0;  //Calculate the bit_rate_scale and bit_rate_value  for(i=1 ; ( ((bRC->bit_rate>>i) & (0x00000001)) != 0x00000001) ;i++);  //i holds the number of zeros  hrd->bit_rate_scale = MAX(0,i-6);  hrd->bit_rate_value_minus1[0] = (int)(bRC->bit_rate >> i) - 1;    //Calculate the bit_rate_scale and bit_rate_value  for(i=1 ; ( ((bRC->BufferSize>>i) & (0x00000001)) != 0x00000001) ;i++);  hrd->cpb_size_scale = MAX(0,i-4);  hrd->cpb_size_value_minus1[0] = (int)(bRC->bit_rate >> (i-1)  ) - 1;    hrd->cbr_flag[0] = 0;   hrd->initial_cpb_removal_delay_length_minus1 = 19;   hrd->cpb_removal_delay_length_minus1 = 19;  hrd->dpb_output_delay_length_minus1 = 19;  hrd->time_offset_length = 0;}void fillBufferingPeriodSEI(rateCtrl_s *bRC){  buffering_period_SEI_s  *bufperiodSEI = &bRC->bufperiodSEI;  bufperiodSEI->initial_cpb_removal_delay = (unsigned int)(bRC->TargetBufferLevel* (90000*1.0/ bRC->bit_rate)) ;  bufperiodSEI->initial_cpb_removal_delay_offset =       bufperiodSEI->seq_parameter_set_id = 0;}void fillPictureTimingSEI(rateCtrl_s *bRC){  picture_timing_SEI_s *pic_timing_SEI = &bRC->picture_timing_SEI;  if(bRC->PictureIndex == 0)  {    pic_timing_SEI->cpb_removal_delay = 0;    pic_timing_SEI->dpb_output_delay = 0;  }  else  {    pic_timing_SEI->cpb_removal_delay = bRC->PictureIndex;    pic_timing_SEI->dpb_output_delay = bRC->PictureIndex;  }}void rc_printDebug(rateCtrl_s *bRC,statSlice_s *frmStat){    fprintf(bRC->rcdebug,"%6d\t%6d\t  %6d\t %6d\t %6d\t %.2f\t %6d\t %6d\t %.2f\t %6d\t %6d\t %6d\t%6d\t%.2f\n",    bRC->srcPicNum,    staGetTotalBits(frmStat),    bRC->TargetBufferLevel,    bRC->CurrentBufferFullness,    bRC->frameReturnedQP,    bRC->averageQPforFrame,    bRC->QP_LW ,    bRC->QP_SW,    frmStat->psnrY,    bRC->upperFrameLimit,    bRC->lowerFrameLimit,    bRC->nalRefIdc,    bRC->bitsPerPFrame,    bRC->rdModel_PictureMAD[0]    );}void rc_update_bitrate(rateCtrl_s *bRC, int bitrate){  int i;  if( abs(bitrate - bRC->bit_rate)*1.0f/bRC->bit_rate > 0.1)  {    bRC->use_lt_RD_Model= 0;    bRC->use_sh_RD_Model= 0;        for(i=0;i<MAX_RD_WINDOW_SIZE;i++)    {      bRC->rdModel_QP[i]    = 0;      bRC->rdModel_Qstep[i]    = 0;      bRC->rdModel_PictureMAD[i]  = 0.0;      bRC->rdModel_TextureBits[i]  = 0;      bRC->rdModel_HeaderBits[i]  = 0;    }    bRC->rdModel_windowSize = 0;     for(i=0;i<MAX_LT_RD_WINDOW_SIZE;i++)    {      bRC->lt_rdModel_Qstep[i]      = 0;      bRC->lt_rdModel_PictureMAD[i]  = 0.0;      bRC->lt_rdModel_TextureBits[i]  = 0;      bRC->lt_rdModel_HeaderBits[i]  = 0;      }    bRC->lt_rdModel_windowSize = 0;  }    if(bitrate!=0)  {    bRC->bitsPerPFrame = (int)(bRC->bitsPerPFrame * (bitrate*1.0f/bRC->bit_rate));    bRC->bitsPerFrame = (int)(bRC->bitsPerFrame * (bitrate*1.0f/bRC->bit_rate));    bRC->BufferSize = (int)(bRC->BufferSize * (bitrate*1.0f / bRC->bit_rate));        if(bRC->CurrentBufferFullness > bRC->BufferSize)      //Assume the extra portion of the underlying data transfers to the Transport Buffer      bRC->CurrentBufferFullness = bRC->BufferSize;      }    bRC->bit_rate = bitrate;  bRC->TargetBufferLevel = bRC->BufferSize/2;  }void rc_updateMB(rateCtrl_s *bRC, int texbits,int headerbits,macroblock_s  *mb,int mbNum){  int totalMB=0,i=0;  int tx_th = 5;#ifndef DISABLE_RDO  if ((bRC->modeDecision & 0x0F) != MODE_DECISION_RDO)     bRC->MSEofMB[mbNum] = mb->minMSE;  else#endif    //bRC->MSEofMB[mbNum] = mb->minSad;    bRC->MSEofMB[mbNum] = (int)(mb->minMSE)>>7;    bRC->currentFrameBits += (headerbits + texbits);  bRC->currentFrame_MBheaderbits[mbNum] = headerbits;  bRC->currentFrame_MBtexbits[mbNum] = texbits;    if(mb->type == MBK_INTER && mb->interMode == MOT_COPY)    bRC->numSkippedMBs++;    if(mbNum == bRC->TotalNumberofMB-1)  {        bRC->averageQPforFrame = 0;        for(i=0;i<bRC->TotalNumberofMB;i++)    {      if(bRC->currentFrame_MBtexbits[i]>tx_th)      {        bRC->averageQPforFrame+=bRC->currentFrame_MBQp[i];        totalMB++;      }    }    if(totalMB < bRC->TotalNumberofMB/4)    {      bRC->averageQPforFrame = 0;      for(i=0;i<bRC->TotalNumberofMB;i++)        bRC->averageQPforFrame+=bRC->currentFrame_MBQp[i];      totalMB = bRC->TotalNumberofMB;    }        bRC->averageQPforFrame=bRC->averageQPforFrame/totalMB;  }  }int rc_getMBQP(rateCtrl_s *bRC, macroblock_s* pMb, int sliceType,int mbNum){    int i=0;  int validQPs[51];  int originalQP;  int currentFrameGeneratedBits=0;  int prevFrameGeneratedBits = 0,prevFrameBits;  int upperlimit= bRC->upperFrameLimit;  int lowerlimit= bRC->lowerFrameLimit;  int currPredFrame;    int QP_buffer;    int firstChangeChance = bRC->TotalNumberofMB/5;  int lastMBIndex = 4*bRC->TotalNumberofMB/5;  int qpUpdateThreshold;     int changeScore=0;    int maxQP = MIN(50,bRC->frameReturnedQP+6);  int minQP = MAX(2,bRC->frameReturnedQP-6);    if(bRC->bit_rate == 0 || bRC->brcdisableMBLevel==1)    return pMb->qp;    //if((sliceType == SLICE_I && bRC->PictureIndex == 0) || ( (sliceType == SLICE_I && bRC->ignoreIDR)) )  if((sliceType == SLICE_I && bRC->ignoreIDR))     return bRC->frameReturnedQP;      qpUpdateThreshold = bRC->TotalNumberofMB / 20;  if(bRC->bit_rate < bRC->BufferSize*3)  {    if(mbNum > bRC->TotalNumberofMB*0.4)      qpUpdateThreshold=qpUpdateThreshold/2;    if(mbNum > bRC->TotalNumberofMB*0.7)      qpUpdateThreshold=qpUpdateThreshold/2;    if(mbNum > bRC->TotalNumberofMB*0.9)      qpUpdateThreshold = 1;

⌨️ 快捷键说明

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