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

📄 rc_quadratic.c

📁 This program can encode the YUV vdieo format to H.264 and decode it.
💻 C
📖 第 1 页 / 共 5 页
字号:
        denom += (float)input->RCISliceBitRatio - 1.0F;
      }

      // set bit targets for each type of frame
      generic_RC->RCPSliceBits = (int) floor( numer / denom + 0.5F );
      generic_RC->RCISliceBits = (input->intra_period) ? (int)(input->RCISliceBitRatio * generic_RC->RCPSliceBits + 0.5) : 0;

      for ( level = 0; level < levels; level++ )
      {
        generic_RC->RCBSliceBits[level] = (int)floor(input->RCBSliceBitRatio[level] * generic_RC->RCPSliceBits + 0.5);
      }

      generic_RC->NIslice = (input->intra_period) ? ((input->no_frames - 1) / input->intra_period) : 0;
      generic_RC->NPslice = input->no_frames - 1 - generic_RC->NIslice;
    }
    break;
  default:
    break;
  }

  /* check if the last GOP over uses its budget. If yes, the initial QP of the I frame in
  the coming  GOP will be increased.*/

  if(generic_RC->RemainingBits<0)
    Overum=TRUE;
  OverBits=-(int)(generic_RC->RemainingBits);

  /*initialize the lower bound and the upper bound for the target bits of each frame, HRD consideration*/
  prc->LowerBound  = (int)(generic_RC->RemainingBits + prc->bit_rate / prc->frame_rate);
  prc->UpperBound1 = (int)(generic_RC->RemainingBits + (prc->bit_rate * 2.048));

  /*compute the total number of bits for the current GOP*/
  AllocatedBits = (int) floor((1 + np + nb) * prc->bit_rate / prc->frame_rate + 0.5);
  generic_RC->RemainingBits += AllocatedBits;
  prc->Np = np;
  prc->Nb = nb;

  OverDuantQp=(int)(8 * OverBits/AllocatedBits+0.5);
  prc->GOPOverdue=FALSE;

  /*field coding*/
  //generic_RC->NoGranularFieldRC = ( input->PicInterlace || !input->MbInterlace || input->basicunit != img->FrameSizeInMbs );
  if ( !input->PicInterlace && input->MbInterlace && input->basicunit == img->FrameSizeInMbs )
    generic_RC->NoGranularFieldRC = 0;
  else
    generic_RC->NoGranularFieldRC = 1;

  /*Compute InitialQp for each GOP*/
  prc->TotalPFrame=np;
  generic_RC->NumberofGOP++;
  if(generic_RC->NumberofGOP==1)
  {
    prc->MyInitialQp = input->SeinitialQP;
    prc->CurrLastQP = prc->MyInitialQp - 1; //recent change -0;
    prc->QPLastGOP   = prc->MyInitialQp;

    prc->PAveFrameQP   = prc->MyInitialQp;
    prc->m_Qc          = prc->PAveFrameQP;
    prc->FieldQPBuffer = prc->PAveFrameQP;
    prc->FrameQPBuffer = prc->PAveFrameQP;
    prc->PAverageQp    = prc->PAveFrameQP;
  }
  else
  {
    /*adaptive field/frame coding*/
    if( input->PicInterlace == ADAPTIVE_CODING || input->MbInterlace )
    {
      if (generic_RC->FieldFrame == 1)
      {
        prc->TotalQpforPPicture += prc->FrameQPBuffer;
        prc->QPLastPFrame = prc->FrameQPBuffer;
      }
      else
      {
        prc->TotalQpforPPicture += prc->FieldQPBuffer;
        prc->QPLastPFrame = prc->FieldQPBuffer;
      }
    }
    /*compute the average QP of P frames in the previous GOP*/
    prc->PAverageQp=(int)(1.0 * prc->TotalQpforPPicture / prc->NumberofPPicture+0.5);

    GOPDquant=(int)((1.0*(np+nb+1)/15.0) + 0.5);
    if(GOPDquant>2)
      GOPDquant=2;

    prc->PAverageQp -= GOPDquant;

    if (prc->PAverageQp > (prc->QPLastPFrame - 2))
      prc->PAverageQp--;

    // QP is constrained by QP of previous QP
    prc->PAverageQp = iClip3(prc->QPLastGOP - 2, prc->QPLastGOP + 2, prc->PAverageQp);
    // Also clipped within range.
    prc->PAverageQp = iClip3(prc->RC_MIN_QUANT,  prc->RC_MAX_QUANT,  prc->PAverageQp);

    prc->MyInitialQp = prc->PAverageQp;
    prc->Pm_Qp       = prc->PAverageQp;
    prc->PAveFrameQP = prc->PAverageQp;
    prc->QPLastGOP   = prc->MyInitialQp;
    prc->PrevLastQP = prc->CurrLastQP;
    prc->CurrLastQP = prc->MyInitialQp - 1;
  }

  prc->TotalQpforPPicture=0;
  prc->NumberofPPicture=0;
  prc->NumberofBFrames=0;
}


/*!
 *************************************************************************************
 * \brief
 *    Initialize one picture
 *
 *************************************************************************************
*/
void rc_init_pict(rc_quadratic *prc, int fieldpic,int topfield,int targetcomputation, float mult)
{
  int tmp_T;

  /* compute the total number of basic units in a frame */
  if(input->MbInterlace)
    prc->TotalNumberofBasicUnit = img->FrameSizeInMbs / img->BasicUnit;
  else
    prc->TotalNumberofBasicUnit = img->FrameSizeInMbs / input->basicunit;

  img->NumberofCodedMacroBlocks = 0;

  /* Normally, the bandwidth for the VBR case is estimated by
     a congestion control algorithm. A bandwidth curve can be predefined if we only want to
     test the proposed algorithm */
  if(input->channel_type==1)
  {
    if(prc->NumberofCodedPFrame==58)
      prc->bit_rate *= 1.5;
    else if(prc->NumberofCodedPFrame==59)
      prc->PrevBitRate = prc->bit_rate;
  }

  /* predefine a target buffer level for each frame */
  if((fieldpic||topfield) && targetcomputation)
  {
    if ( img->type == P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number !=0)) )
    {
      /* Since the available bandwidth may vary at any time, the total number of
      bits is updated picture by picture*/
      if(prc->PrevBitRate!=prc->bit_rate)
        generic_RC->RemainingBits +=(int) floor((prc->bit_rate-prc->PrevBitRate)*(prc->Np + prc->Nb)/prc->frame_rate+0.5);

      /* predefine the  target buffer level for each picture.
      frame layer rate control */
      if(img->BasicUnit == img->FrameSizeInMbs)
      {
        if(prc->NumberofPPicture==1)
        {
          prc->TargetBufferLevel = (double) generic_RC->CurrentBufferFullness;
          prc->DeltaP = (generic_RC->CurrentBufferFullness - prc->GOPTargetBufferLevel) / (prc->TotalPFrame-1);
          prc->TargetBufferLevel -= prc->DeltaP;
        }
        else if(prc->NumberofPPicture>1)
          prc->TargetBufferLevel -= prc->DeltaP;
      }
      /* basic unit layer rate control */
      else
      {
        if(prc->NumberofCodedPFrame>0)
        {
          /* adaptive frame/field coding */
          if(((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))&&(generic_RC->FieldControl==1))
            memcpy((void *)prc->FCBUPFMAD,(void *)prc->FCBUCFMAD, prc->TotalNumberofBasicUnit * sizeof(double));
          else
            memcpy((void *)prc->BUPFMAD,(void *)prc->BUCFMAD, prc->TotalNumberofBasicUnit * sizeof(double));
        }

        if(generic_RC->NumberofGOP==1)
        {
          if(prc->NumberofPPicture==1)
          {
            prc->TargetBufferLevel = (double) generic_RC->CurrentBufferFullness;
            prc->DeltaP = (generic_RC->CurrentBufferFullness - prc->GOPTargetBufferLevel)/(prc->TotalPFrame - 1);
            prc->TargetBufferLevel -= prc->DeltaP;
          }
          else if(prc->NumberofPPicture>1)
            prc->TargetBufferLevel -= prc->DeltaP;
        }
        else if(generic_RC->NumberofGOP>1)
        {
          if(prc->NumberofPPicture==0)
          {
            prc->TargetBufferLevel = (double) generic_RC->CurrentBufferFullness;
            prc->DeltaP = (generic_RC->CurrentBufferFullness - prc->GOPTargetBufferLevel) / prc->TotalPFrame;
            prc->TargetBufferLevel -= prc->DeltaP;
          }
          else if(prc->NumberofPPicture>0)
            prc->TargetBufferLevel -= prc->DeltaP;
        }
      }

      if(prc->NumberofCodedPFrame==1)
        prc->AveWp = prc->Wp;

      if((prc->NumberofCodedPFrame<8)&&(prc->NumberofCodedPFrame>1))
        prc->AveWp = (prc->AveWp + prc->Wp * (prc->NumberofCodedPFrame-1))/prc->NumberofCodedPFrame;
      else if(prc->NumberofCodedPFrame>1)
        prc->AveWp = (prc->Wp + 7 * prc->AveWp) / 8;

      // compute the average complexity of B frames
      if(input->successive_Bframe>0)
      {
        // compute the target buffer level
        prc->TargetBufferLevel += (prc->AveWp * (input->successive_Bframe + 1)*prc->bit_rate\
          /(prc->frame_rate*(prc->AveWp+prc->AveWb*input->successive_Bframe))-prc->bit_rate/prc->frame_rate);
      }
    }
    else if ( img->type == B_SLICE )
    {
      /* update the total number of bits if the bandwidth is changed*/
      if(prc->PrevBitRate != prc->bit_rate)
        generic_RC->RemainingBits +=(int) floor((prc->bit_rate-prc->PrevBitRate) * (prc->Np + prc->Nb) / prc->frame_rate+0.5);
      if((prc->NumberofCodedPFrame==1)&&(generic_RC->NumberofCodedBFrame==1))
      {
        prc->AveWp = prc->Wp;
        prc->AveWb = prc->Wb;
      }
      else if(generic_RC->NumberofCodedBFrame > 1)
      {
        //compute the average weight
        if(generic_RC->NumberofCodedBFrame<8)
          prc->AveWb = (prc->AveWb + prc->Wb*(generic_RC->NumberofCodedBFrame-1)) / generic_RC->NumberofCodedBFrame;
        else
          prc->AveWb = (prc->Wb + 7 * prc->AveWb) / 8;
      }
    }
    /* Compute the target bit for each frame */
    if( img->type == P_SLICE || ( (img->number != 0) && (input->RCUpdateMode == RC_MODE_1 || input->RCUpdateMode == RC_MODE_3 ) ) )
    {
      /* frame layer rate control */
      if(img->BasicUnit == img->FrameSizeInMbs || (input->RCUpdateMode == RC_MODE_3) )
      {
        if(prc->NumberofCodedPFrame>0)
        {
          if (input->RCUpdateMode == RC_MODE_3)
          {
            int level_idx = (img->type == B_SLICE && input->HierarchicalCoding) ? (generic_RC->temporal_levels - 1 - gop_structure[img->b_frame_to_code-1].hierarchy_layer) : 0;
            int bitrate = (img->type == B_SLICE) ? generic_RC->RCBSliceBits[ level_idx ]
            : ( img->type == P_SLICE ? generic_RC->RCPSliceBits : generic_RC->RCISliceBits );
            int level, denom = generic_RC->NIslice * generic_RC->RCISliceBits + generic_RC->NPslice * generic_RC->RCPSliceBits;
            if ( input->HierarchicalCoding )
            {
              for ( level = 0; level < generic_RC->temporal_levels; level++ )
                denom += generic_RC->hierNb[ level ] * generic_RC->RCBSliceBits[ level ];
            }
            else
            {
              denom += generic_RC->hierNb[0] * generic_RC->RCBSliceBits[0];
            }
            // target due to remaining bits
            prc->Target = (int) floor( (float)(1.0 * bitrate * generic_RC->RemainingBits) / (float)denom + 0.5F );
            // target given original taget rate and buffer considerations
            tmp_T  = imax(0, (int) floor( (double)bitrate - prc->GAMMAP * (generic_RC->CurrentBufferFullness-prc->TargetBufferLevel) + 0.5) );
            // translate Target rate from B or I "domain" to P domain since the P RC model is going to be used to select the QP
            // for hierarchical coding adjust the target QP to account for different temporal levels
            switch( img->type )
            {
            case B_SLICE:
              prc->Target = (int) floor( (float)prc->Target / input->RCBoverPRatio + 0.5F);
              break;
            case I_SLICE:
              prc->Target = (int) floor( (float)prc->Target / (input->RCIoverPRatio * 4.0) + 0.5F); // 4x accounts for the fact that header bits reduce the percentage of texture
              break;
            case P_SLICE:
            default:
              break;
            }
          }
          else
          {
            prc->Target = (int) floor( prc->Wp * generic_RC->RemainingBits / (prc->Np * prc->Wp + prc->Nb * prc->Wb) + 0.5);
            tmp_T  = imax(0, (int) floor(prc->bit_rate / prc->frame_rate - prc->GAMMAP * (generic_RC->CurrentBufferFullness-prc->TargetBufferLevel) + 0.5));
            prc->Target = (int) floor(prc->BETAP * (prc->Target - tmp_T) + tmp_T + 0.5);
          }
        }
      }
      /* basic unit layer rate control */
      else
      {
        if(((generic_RC->NumberofGOP == 1)&&(prc->NumberofCodedPFrame>0))
          || (generic_RC->NumberofGOP > 1))
        {
          prc->Target = (int) (floor( prc->Wp * generic_RC->RemainingBits / (prc->Np * prc->Wp + prc->Nb * prc->Wb) + 0.5));
          tmp_T  = imax(0, (int) (floor(prc->bit_rate / prc->frame_rate - prc->GAMMAP * (generic_RC->CurrentBufferFullness-prc->TargetBufferLevel) + 0.5)));
          prc->Target = (int) (floor(prc->BETAP * (prc->Target - tmp_T) + tmp_T + 0.5));
        }
      }
      prc->Target = (int)(mult * prc->Target);

      /* reserve some bits for smoothing */
      prc->Target = (int)((1.0 - 0.0 * input->successive_Bframe) * prc->Target);

      /* HRD consideration */
      if ( input->RCUpdateMode != RC_MODE_3 || img->type == P_SLICE )
        prc->Target = iClip3(prc->LowerBound, prc->UpperBound2, prc->Target);
      if((topfield) || (fieldpic && ((input->PicInterlace==ADAPTIVE_CODING)||(input->MbInterlace))))
        prc->TargetField=prc->Target;
    }
  }

  if(fieldpic || topfield)
  {
    /* frame layer rate control */
    generic_RC->NumberofHeaderBits  = 0;
    generic_RC->NumberofTextureBits = 0;

    /* basic unit layer rate control */
    if(img->BasicUnit < img->FrameSizeInMbs)
    {
      prc->TotalFrameQP = 0;
      generic_RC->NumberofBasicUnitHeaderBits  = 0;
      generic_RC->NumberofBasicUnitTextureBits = 0;
      generic_RC->TotalMADBasicUnit = 0;
      if(generic_RC->FieldControl==0)
        prc->NumberofBasicUnit = prc->TotalNumberofBasicUnit;
      else
        prc->NumberofBasicUnit = prc->TotalNumberofBasicUnit >> 1;
    }
  }

  if( ( img->type==P_SLICE || (input->RCUpdateMode == RC_MODE_1 && (img->number != 0)) ) && img->BasicUnit < img->FrameSizeInMbs && generic_RC->FieldControl == 1 )
  {
    /* top field at basic unit layer rate control */
    if(topfield)
    {
      prc->bits_topfield=0;
      prc->Target=(int)(prc->TargetField*0.6);
    }
    /* bottom field at basic unit layer rate control */
    else
    {
      prc->Target=prc->TargetField-prc->bits_topfield;
      generic_RC->NumberofBasicUnitHeaderBits=0;
      generic_RC->NumberofBasicUnitTextureBits=0;
      generic_RC->TotalMADBasicUnit=0;
      prc->NumberofBasicUnit=prc->TotalNumberofBasicUnit >> 1;
    }
  }
}

/*!
 *************************************************************************************
 * \brief
 *    update one picture after frame/field encoding
 *
 * \param nbits
 *    number of bits used for picture
 *
 *************************************************************************************
*/
void rc_update_pict(rc_quadratic *prc, int nbits)
{
  int delta_bits = (nbits - (int)floor(prc->bit_rate / prc->frame_rate + 0.5F) );
  generic_RC->RemainingBits -= nbits; /* remaining # of bits in GOP */
  generic_RC->CurrentBufferFullness += delta_bits;

  /*update the lower bound and the upper bound for the target bits of each frame, HRD consideration*/
  prc->LowerBound  -= (int) delta_bits;
  prc->UpperBound1 -= (int) delta_bits;
  prc->UpperBound2  = (int)(OMEGA * prc->UpperBound1);

  return;
}

int updateComplexity( rc_quadratic *prc, Boolean is_updated, int nbits )
{
  double Avem_Qc;

  /* frame layer rate control */
  if(img->BasicUnit == img->FrameSizeInMbs)
    return ((int) floor(nbits * prc->m_Qc + 0.5));
  /* basic unit layer rate control */
  else
  {
    if( is_updated )
    {
      if( generic_RC->NoGranularFieldRC == 0 || generic_RC->FieldControl == 0 )
      {
        Avem_Qc = (double)prc->TotalFrameQP / (double)prc->TotalNumberofBasicUnit;
        return ((int)floor(nbits * Avem_Qc + 0.5));
      }
    }
    else if( img->type == B_SLICE )

⌨️ 快捷键说明

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