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

📄 umc_mpeg2_enc_params.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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) 2002-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "umc_defs.h"
#if defined (UMC_ENABLE_MPEG2_VIDEO_ENCODER)

#include "umc_mpeg2_enc_defs.h"
#include "vm_strings.h"
#include <ipps.h>

using namespace UMC;

///* identifies valid profile/level combinations */
//static Ipp8u Profile_Level_Defined[5][4] =
//{
///* HL   H-14 ML   LL  */
//  {1,   1,   1,   0},  /* HP   */
//  {0,   1,   0,   0},  /* Spat */
//  {0,   0,   1,   1},  /* SNR  */
//  {1,   1,   1,   1},  /* MP   */
//  {0,   0,   1,   0}   /* SP   */
//};

static struct LevelLimits
{
  Ipp32s f_code[2];
  Ipp32s hor_size;
  Ipp32s vert_size;
  Ipp32s sample_rate;
  Ipp32s bit_rate;         /* Mbit/s */
  Ipp32s vbv_buffer_size;  /* 16384 bit steps */
} MaxValTbl[5] =
{
  {{9, 5}, 1920, 1152, 62668800, 80, 597}, /* HL */
  {{9, 5}, 1440, 1152, 47001600, 60, 448}, /* H-14 */
  {{8, 5},  720,  576, 10368000, 15, 112}, /* ML */
  {{7, 4},  352,  288,  3041280,  4,  29}, /* LL */
  {{9, 9}, 8192, 8192, 0x7fffffff, 1000,  10000}  /* some limitations for unlimited */
};

#define SP   5
#define MP   4
#define SNR  3
#define SPAT 2
#define HP   1

#define LL  10
#define ML   8
#define H14  6
#define HL   4

/* chroma_format for MPEG2EncoderParams::chroma_format*/
#define CHROMA420 1
#define CHROMA422 2
#define CHROMA444 3

#define error(Message) \
{ \
  vm_debug_trace(VM_DEBUG_ERROR, VM_STRING(Message)); \
  return UMC_ERR_FAILED; \
}

/* ISO/IEC 13818-2, 6.3.11 */
/*  this pretty table was designed to
    avoid coincidences with any GPL code */
static VM_ALIGN16_DECL(Ipp16s) DefaultIntraQuantMatrix[64] =
{
     8,
     16,

     19,        22, 26, 27,             29, 34, 16,
     16,        22,         24,         27,         29,
     34,        37,             19,     22,             26,
     27,        29,             34,     34,             38,
     22,        22,             26,     27,             29,
     34,        37,             40,     22,             26,
     27,        29,         32,         35,         40,
     48,        26, 27, 29,             32, 35, 40,
     48,        58,                     26,
     27,        29,                     34,
     38,        46,                     56,
     69,        27,                     29,
     35,        38,                     46,
     56,        69,                     83
};

static const Ipp64f ratetab[8]=
    {24000.0/1001.0,24.0,25.0,30000.0/1001.0,30.0,50.0,60000.0/1001.0,60.0};
static const Ipp32s aspecttab[3][2] =
    {{4,3},{16,9},{221,100}};

MPEG2EncoderParams::MPEG2EncoderParams()
{
  Ipp32s i;

  *IntraQMatrix = 0;
  *NonIntraQMatrix = 0;

  lFlags = FLAG_VENC_REORDER;
  info.bitrate = 5000000;
  info.framerate = 30;
  numEncodedFrames = 0;
  qualityMeasure = -1;

  info.interlace_type = PROGRESSIVE;          // progressive sequence
  CustomIntraQMatrix = 0;
  CustomNonIntraQMatrix = 0;
  for(i=0; i<64; i++) {   // for reconstruction
    IntraQMatrix[i] = DefaultIntraQuantMatrix[i];
    NonIntraQMatrix[i] = 16;
  }
  IPDistance = 3;         // distance between key-frames
  gopSize = 15;           // size of GOP
  info.framerate = 30;
  info.aspect_ratio_width = 4;
  info.aspect_ratio_height = 3;
  profile = MP;
  level = ML;
  info.color_format = YUV420;
  FieldPicture = 0;       // field or frame picture (if progframe=> frame)
  VBV_BufferSize = 112;
  low_delay = 0;
  frame_pred_frame_dct[0] = 1;
  frame_pred_frame_dct[1] = 1;
  frame_pred_frame_dct[2] = 1;
  intraVLCFormat[0] = 1;
  intraVLCFormat[1] = 1;
  intraVLCFormat[2] = 1;
  altscan_tab[0] = 0;
  altscan_tab[1] = 0;
  altscan_tab[2] = 0;
  mpeg1 = 0;               // 1 - mpeg1 (unsupported), 0 - mpeg2
  *idStr = 0;              // user data to put to each sequence
  UserData = idStr;
  UserDataLen = 0;
  numThreads = 1;
  performance = 0;
  encode_time = 0;
  motion_estimation_perf = 0;
  me_alg_num = 3;
  me_auto_range = 1;
  allow_prediction16x8 = 0;
  rc_mode = RC_CBR;
  quant_vbr[0] = 0;
  quant_vbr[1] = 0;
  quant_vbr[2] = 0;

  rangeP[0] = 8*IPDistance;
  rangeP[1] = 4*IPDistance;
  rangeB[0][0] = rangeB[1][0] = rangeP[0] >> 1;
  rangeB[0][1] = rangeB[1][1] = rangeP[1] >> 1;

}

MPEG2EncoderParams::~MPEG2EncoderParams()
{
}

Status MPEG2EncoderParams::ReadQMatrices(vm_char* IntraQMatrixFName, vm_char* NonIntraQMatrixFName)
{
  Ipp32s i, temp;
  vm_file *InputFile;

  if( IntraQMatrixFName==0 || IntraQMatrixFName[0] == 0 || IntraQMatrixFName[0] == '-' )
  {
    // use default intra matrix
    CustomIntraQMatrix = 0;
    for(i=0; i<64; i++)
      IntraQMatrix[i] = DefaultIntraQuantMatrix[i];
  }
  else
  {
    // load custom intra matrix
    CustomIntraQMatrix = 1;
    if( 0 == (InputFile = vm_file_open(IntraQMatrixFName,VM_STRING("rt"))) )
    {
      vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Can't open quant matrix file %s\n"), IntraQMatrixFName);
      return UMC_ERR_OPEN_FAILED;
    }

    for(i=0; i<64; i++)
    {
      vm_file_fscanf( InputFile, VM_STRING("%d"), &temp );
      if( temp < 1 || temp > 255 )
        error("invalid value in quant matrix\n");
      IntraQMatrix[i] = (Ipp16s)temp;
    }

    vm_file_fclose( InputFile );
  }

  if (NonIntraQMatrixFName == 0 || NonIntraQMatrixFName[0] == 0 || NonIntraQMatrixFName[0] == '-')
  {
    // use default non-intra matrix
    CustomNonIntraQMatrix = 0;
    for(i=0; i<64; i++)
      NonIntraQMatrix[i] = 16;
  }
  else
  {
    // load custom non-intra matrix
    CustomNonIntraQMatrix = 1;
    if( 0 == (InputFile = vm_file_open(NonIntraQMatrixFName,VM_STRING("rt"))) )
    {
      vm_debug_trace1(VM_DEBUG_ERROR, VM_STRING("Couldn't open quant matrix file %s\n"), NonIntraQMatrixFName);
      return UMC_ERR_OPEN_FAILED;
    }

    for(i=0; i<64; i++)
    {
      vm_file_fscanf( InputFile, VM_STRING("%d"), &temp );
      if( temp < 1 || temp > 255 )
        error("invalid value in quant matrix\n");
      NonIntraQMatrix[i] = (Ipp16s)temp;
    }

    vm_file_fclose( InputFile );
  }

  return UMC_OK;
}

Status MPEG2EncoderParams::Profile_and_Level_Checks()
{
  Ipp32s i,j,k;
  struct LevelLimits *MaxVal;
  Ipp32s newLevel = level;
  Ipp32s newProfile = profile;
  Status ret = UMC_OK;

  if( profile == SNR || profile == SPAT )
    error("The encoder doesn't support scalable profiles\n");

  // check level, select appropriate when it is wrong
  if( newLevel < HL ||
    newLevel > LL ||
    newLevel & 1 )
    newLevel = LL;
  if(info.color_format != YUV420 && newLevel == LL )
    newLevel = ML;
  if( info.framerate > ratetab[5 - 1] && newLevel >= ML )
    newLevel = H14;

  MaxVal = &MaxValTbl[(newLevel - 4) >> 1];
  while( info.clip_info.width > MaxVal->hor_size ||
         info.clip_info.height > MaxVal->vert_size ||
         info.clip_info.width * info.clip_info.height * info.framerate > MaxVal->sample_rate ||
         info.bitrate > 1000000 * (Ipp32u)MaxVal->bit_rate )
  {
    if(newLevel > HL) {
      newLevel -= 2;
      MaxVal --;
    } else {
      vm_debug_trace(VM_DEBUG_WARNING, VM_STRING("encoding parameters exceed highest level limitations\n"));
      MaxVal = &MaxValTbl[4];
      break;
    }
  }

  // check profile values
  if( newProfile < HP || newProfile > SP ) {
    newProfile = MP;
  }
  if(info.color_format != YUV420) {
    newProfile = HP;
    if(info.color_format == YUV444) {
      vm_debug_trace(VM_DEBUG_WARNING, VM_STRING("CHROMA444 has no appropriate prifile\n"));
    }
  }

  // check profile constraints
  if( newProfile == SP && IPDistance != 1 ) {
    newProfile = MP;
  }

  // check profile - level combination
  if(newProfile == SP && newLevel != ML)
    newProfile = MP;
  if(newProfile == HP && newLevel == LL) {
    newLevel = ML;
    MaxVal = &MaxValTbl[(newLevel - 4) >> 1];
  }

  if(IPDistance < 1) IPDistance = 1;
  if(gopSize < 1)    gopSize = 1;
  if(gopSize > 132)  gopSize = 132;
  if(IPDistance > gopSize) IPDistance = gopSize;

  // compute f_codes from ranges, check limits, extend to the f_code limit
  for(i = 0; i < IPP_MIN(IPDistance,2); i++) // P, B
    for(k=0; k<2; k++) {                     // FW, BW
      Ipp32s* prange;
      if (i == 0) {
        if( k==1)
          continue; // no backward for P-frame
        prange = rangeP;
      } else {
        prange = rangeB[k];
      }
      for(j=0; j<2; j++) {                   // x, y
        Ipp32s req_f_code;
        RANGE_TO_F_CODE(prange[j], req_f_code);
        if( req_f_code > MaxVal->f_code[j] ) {
          vm_debug_trace(VM_DEBUG_WARNING, VM_STRING("search range is greater than permitted in specified Level\n"));
          req_f_code = MaxVal->f_code[j];
          prange[j] = 4<<req_f_code;
        }
        if (i==0) // extend range only for P
          prange[j] = 4<<req_f_code;
      }
    }

  // Table 8-13
  if( VBV_BufferSize > MaxVal->vbv_buffer_size )
    VBV_BufferSize = MaxVal->vbv_buffer_size;

  if(newLevel != level) {
    vm_debug_trace(VM_DEBUG_WARNING, VM_STRING("Level changed\n"));
    level = newLevel;
  }
  if(newProfile != profile) {
    vm_debug_trace(VM_DEBUG_WARNING, VM_STRING("Profile changed\n"));
    profile = newProfile;
  }

  return ret;

⌨️ 快捷键说明

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