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

📄 tran_rc.cpp

📁 这是在PCA下的基于IPP库示例代码例子,在网上下了IPP的库之后,设置相关参数就可以编译该代码.
💻 CPP
字号:
/*////               INTEL CORPORATION PROPRIETARY INFORMATION//  This software is supplied under the terms of a license agreement or//  nondisclosure agreement with Intel Corporation and may not be copied//  or disclosed except in accordance with the terms of that agreement.//      Copyright (c) 2005 Intel Corporation. All Rights Reserved.////  Purpose//    frame adaptive bitrate control*/#include "mpeg2_defs.h"/* quant scale values table ISO/IEC 13818-2, 7.4.2.2 table 7-6 */static int Val_QScale[2][32] ={  /* linear q_scale */  {0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,  32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62},  /* non-linear q_scale */  {0, 1,  2,  3,  4,  5,  6,  7,  8, 10, 12, 14, 16, 18, 20, 22,  24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96,104,112}};int ippMPEG2VideoEncoder::PictureRateControl(){  int isfield = (picture_structure != FRAME_PICTURE);  double ip_delay;  // secondfield should be moved to class, code to frame start  int secondfield = (encodeInfo.top_field_first == (picture_structure == BOTTOM_FIELD));  if(BitRate <= 0) {    changeQuant(qscale[picture_coding_type-I_TYPE]); // changes also intra_dc_precision, q_scale_type    vbv_delay = 0xffff;    return quantiser_scale_value;  }  if(encodeInfo.prog_seq) {      rc_delay = rc_ave_frame_bits;      if(encodeInfo.repeat_first_field) rc_delay += rc_ave_frame_bits;      if(encodeInfo.top_field_first) rc_delay += rc_ave_frame_bits;  } else {      rc_delay = rc_ave_frame_bits;      if(!isfield) rc_delay += rc_ave_frame_bits;      if(encodeInfo.repeat_first_field) rc_delay += rc_ave_frame_bits;      rc_delay = rc_delay / 2;  }  if(picture_coding_type != B_TYPE) {      ip_delay = rc_delay;      if(!isfield) {          rc_delay = rc_ip_delay;          rc_ip_delay = ip_delay;      } else if(secondfield) {          rc_delay = rc_ip_delay - rc_delay;          rc_ip_delay = 2*ip_delay;      }  }  vbv_delay = (int)(rc_vbv_fullness * 90000.0/BitRate);  if(vbv_delay < 0) vbv_delay = 0; // for a while  // vbv computations for len range  rc_vbv_max = (int)rc_vbv_fullness;  rc_vbv_min = (int)(rc_vbv_fullness - (encodeInfo.VBV_BufferSize*16384 - rc_delay));  int q0, q2, sz1;  q0 = qscale[picture_coding_type-I_TYPE];   // proposed from post picture  q2 = prqscale[picture_coding_type-I_TYPE]; // last used scale  sz1 = prsize[picture_coding_type-I_TYPE];  // last coded size  // compute newscale again  // adaptation to current rate deviation  double target_size = rc_tagsize[picture_coding_type-I_TYPE];  int wanted_size = (int)(target_size - rc_dev / 3 * target_size / rc_tagsize[0]);  if     (sz1 > 2*wanted_size)   q2 = q2 * 3 / 2 + 1;  else if(sz1 > wanted_size+100) q2 ++;  else if(2*sz1 < wanted_size)   q2 = q2 * 3 / 4;  else if(sz1 < wanted_size-100) q2 --;  if(rc_dev > 0) {    q2 = max(q0,q2);  } else {    q2 = min(q0,q2);  }  // this call is used to accept small changes in value, which are mapped to the same code  // changeQuant bothers about to change scale code if value changes  q2 = changeQuant(q2);  qscale[picture_coding_type-I_TYPE] = q2;  return quantiser_scale_value;}// encoded size check, vbv computation, qscale code adaptation// returns positive bitcount when vbv overflow,//         negative bitcount when vbv underflow, 0 if OKint ippMPEG2VideoEncoder::PostPictureRateControl(Ipp64s bits_encoded){  int isfield = (picture_structure != FRAME_PICTURE);  Ipp64s vbv_size = encodeInfo.VBV_BufferSize * 16384;  int ret = 0;  prsize[picture_coding_type-I_TYPE] = (int)bits_encoded << isfield;  prqscale[picture_coding_type-I_TYPE] = qscale[picture_coding_type-I_TYPE];  if(BitRate <= 0) {    return 0;  }  rc_vbv_fullness = rc_vbv_fullness - bits_encoded;  rc_vbv_fullness += rc_delay; //  int cur_qscale = qscale[picture_coding_type-I_TYPE];  double target_size = rc_tagsize[picture_coding_type-I_TYPE];  rc_dev += bits_encoded - (isfield ? target_size/2 : target_size);  int wanted_size = (int)(target_size - rc_dev / 3 * target_size / rc_tagsize[0]);  int newscale;  int del_sc;  newscale = cur_qscale;  wanted_size >>= isfield;  if(bits_encoded > wanted_size) newscale ++;  if(bits_encoded > 2*wanted_size) newscale = cur_qscale * 3 / 2 + 1;  if(bits_encoded < wanted_size) newscale --;  if(2*bits_encoded < wanted_size) newscale = cur_qscale * 3 / 4;  // this call is used to accept small changes in value, which are mapped to the same code  // changeQuant bothers about to change scale code if value changes  newscale = changeQuant(newscale);  if(picture_coding_type == I_TYPE) {    if( newscale+1 > qscale[1] ) qscale[1] = newscale+1;    if( newscale+2 > qscale[2] ) qscale[2] = newscale+2;  } else if(picture_coding_type == P_TYPE) {    if( newscale < qscale[0] ) {      del_sc = qscale[0] - newscale;      qscale[0] -= del_sc/2;      newscale = qscale[0];      newscale = changeQuant(newscale);    }    if( newscale+1 > qscale[2] ) qscale[2] = newscale+1;  } else {    if( newscale < qscale[1] ) {      del_sc = qscale[1] - newscale;      qscale[1] -= del_sc/2;      newscale = qscale[1];      newscale = changeQuant(newscale);      if( qscale[1] < qscale[0] ) qscale[0] = qscale[1];    }  }  qscale[picture_coding_type-I_TYPE] = newscale;  if(rc_vbv_fullness > vbv_size) {    ret = (int)(rc_vbv_fullness - vbv_size);  }  if(rc_vbv_fullness < rc_delay) {    ret = (int)(rc_vbv_fullness - rc_delay);  }  return ret;}int ippMPEG2VideoEncoder::InitRateControl(){  double ppb; //pixels per bit (~ density)  int i;  if (BitRate <= 0) { // not given bitrate    BitRate = 0;    vbv_delay = 0xffff; // unused    qscale[0] = 4;      // values from air    qscale[1] = 6;    qscale[2] = 8;    for (i=0; i<3; i++) { // in old parfile nonLinearQScale used to set qscale, in common - it's 0 or 1      if (encodeInfo.nonLinearQScale[i] > 1) qscale[i] = encodeInfo.nonLinearQScale[i];    }    return 0;  }  // one can vary weights, can be added to API  rc_weight[0] = 120;  rc_weight[1] = 50;  rc_weight[2] = 25;  //M = encodeInfo.IPDistance;  //N = encodeInfo.gopSize;  double nr = N/M;  double gopw = (M-1)*rc_weight[2]*nr + rc_weight[1]*(nr-1) + rc_weight[0];  double u_len = rc_ave_frame_bits * N / gopw;  rc_tagsize[0] = u_len * rc_weight[0];  rc_tagsize[1] = u_len * rc_weight[1];  rc_tagsize[2] = u_len * rc_weight[2];  // if bitrate is 0 - could be no rc  rc_ave_frame_bits = BitRate/FrameRate;  // we want ideal case - I frame to be centered in vbv buffer, compute start pos  rc_vbv_fullness =    encodeInfo.VBV_BufferSize * 16384 / 2 +      // half of vbv_buffer    rc_tagsize[0] / 2 +                          // top to center length of I frame    (M-1) * (rc_ave_frame_bits - rc_tagsize[2]); // first gop has no M-1 B frames: add'em  vbv_delay = (int)(rc_vbv_fullness*90000.0/BitRate); // bits to clocks  rc_vbv_max = (int)(rc_vbv_fullness);  rc_ip_delay = rc_ave_frame_bits;  rc_dev = 0; // deviation from ideal bitrate (should be float or renewed)  double rrel = gopw / (rc_weight[0] * N);  ppb = srcYFrameHSize*srcYFrameVSize*FrameRate/BitRate * (block_count-2) / (6-2);  qscale[0] = (int)(6.0 * rrel * ppb); // numbers are empiric  qscale[1] = (int)(9.0 * rrel * ppb);  qscale[2] = (int)(12.0 * rrel * ppb);  for(i=0; i<3; i++) {    if     (qscale[i]< 1) qscale[i]= 1;    else if(qscale[i]>63) qscale[i]=63; // can be even more    prqscale[i] = qscale[i];    prsize[i] = (int)rc_tagsize[i]; // for first iteration  }  return 0;}int ippMPEG2VideoEncoder::mapQuant(int quant_value){  int qs_type, qs_code;  if(encodeInfo.mpeg1 || (quant_value > 7 && quant_value <= 62)) {    qs_type = 0;    qs_code = (quant_value + 1) >> 1;  } else { // non-linear quantizer    qs_type = 1;    if(quant_value <= 8) qs_code = quant_value;    else /* if(quant_value > 62) */ qs_code = 25+((quant_value-64+4)>>3);  }  if(qs_code < 1) qs_code = 1;  if(qs_code > 31) qs_code = 31;  return Val_QScale[qs_type][qs_code];}int ippMPEG2VideoEncoder::changeQuant(int quant_value){  int curq = quantiser_scale_value;  if(quant_value == quantiser_scale_value) return quantiser_scale_value;  if(encodeInfo.mpeg1 || (quant_value > 7 && quant_value <= 62)) {    q_scale_type = 0;    quantiser_scale_code = (quant_value + 1) >> 1;  } else { // non-linear quantizer    q_scale_type = 1;    if(quant_value <= 8) quantiser_scale_code = quant_value;    else if(quant_value > 62) quantiser_scale_code = 25+((quant_value-64+4)>>3);  }  if(quantiser_scale_code < 1) quantiser_scale_code = 1;  if(quantiser_scale_code > 31) quantiser_scale_code = 31;  quantiser_scale_value = Val_QScale[q_scale_type][quantiser_scale_code];  if(quantiser_scale_value == curq) {    if(quant_value > curq)      if(quantiser_scale_code == 31) return quantiser_scale_value;      else quantiser_scale_code ++;    if(quant_value < curq)      if(quantiser_scale_code == 1) return quantiser_scale_value;      else quantiser_scale_code --;    quantiser_scale_value = Val_QScale[q_scale_type][quantiser_scale_code];  }  if(encodeInfo.mpeg1 || quantiser_scale_value >= 16)    encodeInfo.intra_dc_precision = 0;  else if(quantiser_scale_value >= 4)    encodeInfo.intra_dc_precision = 1;  else    encodeInfo.intra_dc_precision = 2;  // only for High profile  //if(quantiser_scale_value == 1) encodeInfo.intra_dc_precision = 3;  return quantiser_scale_value;}

⌨️ 快捷键说明

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