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

📄 lencod.c

📁 H.264编码实现
💻 C
📖 第 1 页 / 共 4 页
字号:
  }

  if (params->RestrictRef)
  {
    free(pixel_map[0]);
    free(pixel_map);
    free(refresh_map[0]);
    free(refresh_map);
  }

  if (!active_sps->frame_mbs_only_flag)
  {
    free_mem2Dpel(imgY_com);
    if (img->yuv_format != YUV400)
    {
      free_mem3Dpel(imgUV_com);
    }
  }

  free_mem3Dint(img->nz_coeff);

  free_mem2Dolm     (img->lambda, img->bitdepth_luma_qp_scale);
  free_mem2Dodouble (img->lambda_md, img->bitdepth_luma_qp_scale);
  free_mem3Dodouble (img->lambda_me, 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale);
  free_mem3Doint    (img->lambda_mf, 10, 52 + img->bitdepth_luma_qp_scale, img->bitdepth_luma_qp_scale);

  if (params->CtxAdptLagrangeMult == 1)
  {
    free_mem2Dodouble(img->lambda_mf_factor, img->bitdepth_luma_qp_scale);
  }

  if (!params->IntraProfile)
  {
    if (params->SearchMode == UM_HEX)
    {
      UMHEX_free_mem();
    }
    else if (params->SearchMode == UM_HEX_SIMPLE)
    {
      smpUMHEX_free_mem();
    }
    else if (params->SearchMode == EPZS)
    {
      EPZSDelete(params);
    }
  }


  if (params->RCEnable)
    rc_free_memory();

  if (params->redundant_pic_flag)
  {
    free_mem2Dpel(imgY_tmp);
    free_mem2Dpel(imgUV_tmp[0]);
    free_mem2Dpel(imgUV_tmp[1]);
  }

  // Again process should be moved into cconv_yuv2rgb.c file for cleanliness
  // These should not be globals but instead only be visible through that code.
  if(params->DistortionYUVtoRGB)
  {
    delete_RGB_memory();
  }
}

/*!
 ************************************************************************
 * \brief
 *    Allocate memory for mv
 * \par Input:
 *    Image Parameters ImageParameters *img                             \n
 *    int****** mv
 * \return memory size in bytes
 ************************************************************************
 */
int get_mem_mv (short ******* mv)
{
  // LIST, reference, block_type, block_y, block_x, component
  get_mem6Dshort(mv, 2, img->max_num_references, 9, 4, 4, 2);

  return 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short);
}

/*!
 ************************************************************************
 * \brief
 *    Allocate memory for bipredictive mv 
 * \par Input:
 *    Image Parameters ImageParameters *img                             \n
 *    int****** mv
 * \return memory size in bytes
 ************************************************************************
 */
int get_mem_bipred_mv (short******** bipred_mv) 
{
  if(((*bipred_mv) = (short*******)calloc(2, sizeof(short******))) == NULL)
    no_mem_exit("get_mem_bipred_mv: bipred_mv");
  
  get_mem6Dshort(*bipred_mv, 2 * 2, img->max_num_references, 9, 4, 4, 2);
  (*bipred_mv)[1] =  (*bipred_mv)[0] + 2;
  
  return 2 * 2 * img->max_num_references * 9 * 4 * 4 * 2 * sizeof(short);
}

/*!
 ************************************************************************
 * \brief
 *    Free memory from mv
 * \par Input:
 *    int****** mv
 ************************************************************************
 */
void free_mem_mv (short****** mv)
{
  free_mem6Dshort(mv);
}


/*!
 ************************************************************************
 * \brief
 *    Free memory from mv
 * \par Input:
 *    int****** mv
 ************************************************************************
 */
void free_mem_bipred_mv (short******* bipred_mv) 
{
  if (bipred_mv)
  {
    free_mem6Dshort(*bipred_mv);
    free (bipred_mv);
  }
  else
  {
    error ("free_mem_bipred_mv: trying to free unused memory",100);
  }
}

/*!
 ************************************************************************
 * \brief
 *    Allocate memory for AC coefficients
 ************************************************************************
 */
int get_mem_ACcoeff (int***** cofAC)
{
  int num_blk8x8 = 4 + img->num_blk8x8_uv;
  
  get_mem4Dint(cofAC, num_blk8x8, 4, 2, 65);
  return num_blk8x8*4*2*65*sizeof(int);// 18->65 for ABT
}

/*!
 ************************************************************************
 * \brief
 *    Allocate memory for DC coefficients
 ************************************************************************
 */
int get_mem_DCcoeff (int**** cofDC)
{
  get_mem3Dint(cofDC, 3, 2, 18);
  return 3 * 2 * 18 * sizeof(int); 
}


/*!
 ************************************************************************
 * \brief
 *    Free memory of AC coefficients
 ************************************************************************
 */
void free_mem_ACcoeff (int**** cofAC)
{
  free_mem4Dint(cofAC);
}

/*!
 ************************************************************************
 * \brief
 *    Free memory of DC coefficients
 ************************************************************************
 */
void free_mem_DCcoeff (int*** cofDC)
{
  free_mem3Dint(cofDC);
}



/*!
 ************************************************************************
 * \brief
 *    Set the image type for I,P and SP pictures (not B!)
 ************************************************************************
 */
static void SetImgType(void)
{
  int intra_refresh = (params->intra_period == 0) ? (IMG_NUMBER == 0) : (( ( img->frm_number - img->lastIntraNumber) % params->intra_period ) == 0);
  int idr_refresh;

  if ( params->idr_period && !params->adaptive_idr_period )
    idr_refresh = (( ( img->frm_number - img->lastIDRnumber  ) % params->idr_period   ) == 0);
  else if ( params->idr_period && params->adaptive_idr_period == 1 )
    idr_refresh = (( ( img->frm_number - imax(img->lastIntraNumber, img->lastIDRnumber)  ) % params->idr_period   ) == 0);
  else
    idr_refresh = (IMG_NUMBER == 0);

  if (intra_refresh || idr_refresh)
  {
    set_slice_type( I_SLICE );        // set image type for first image to I-frame
  }
  else
  {
    set_slice_type((params->sp_periodicity && ((IMG_NUMBER % params->sp_periodicity) == 0))
      ? SP_SLICE  : ((params->BRefPictures == 2) ? B_SLICE : P_SLICE) );
  }
}

/*!
 ************************************************************************
 * \brief
 *    Sets indices to appropriate level constraints, depending on 
 *    current level_idc
 ************************************************************************
 */
void SetLevelIndices(void)
{
  switch(active_sps->level_idc)
  {
  case 9:
    img->LevelIndex=1;
    break;
  case 10:
    img->LevelIndex=0;
    break;
  case 11:
    if (!IS_FREXT_PROFILE(active_sps->profile_idc) && (active_sps->constrained_set3_flag == 0))
      img->LevelIndex=2;
    else
      img->LevelIndex=1;
    break;
  case 12:
    img->LevelIndex=3;
    break;
  case 13:
    img->LevelIndex=4;
    break;
  case 20:
    img->LevelIndex=5;
    break;
  case 21:
    img->LevelIndex=6;
    break;
  case 22:
    img->LevelIndex=7;
    break;
  case 30:
    img->LevelIndex=8;
    break;
  case 31:
    img->LevelIndex=9;
    break;
  case 32:
    img->LevelIndex=10;
    break;
  case 40:
    img->LevelIndex=11;
    break;
  case 41:
    img->LevelIndex=12;
    break;
  case 42:
    if (!IS_FREXT_PROFILE(active_sps->profile_idc))
      img->LevelIndex=13;
    else
      img->LevelIndex=14;
    break;
  case 50:
    img->LevelIndex=15;
    break;
  case 51:
    img->LevelIndex=16;
    break;
  default:
    fprintf ( stderr, "Warning: unknown LevelIDC, using maximum level 5.1 \n" );
    img->LevelIndex=16;
    break;
  }
}

/*!
 ************************************************************************
 * \brief
 *    initialize key frames and corresponding redundant frames.
 ************************************************************************
 */
void Init_redundant_frame()
{
  if (params->redundant_pic_flag)
  {
    if (params->successive_Bframe)
    {
      error("B frame not supported when redundant picture used!", 100);
    }

    if (params->PicInterlace)
    {
      error("Interlace not supported when redundant picture used!", 100);
    }

    if (params->num_ref_frames < params->PrimaryGOPLength)
    {
      error("NumberReferenceFrames must be no less than PrimaryGOPLength", 100);
    }

    if ((1<<params->NumRedundantHierarchy) > params->PrimaryGOPLength)
    {
      error("PrimaryGOPLength must be greater than 2^NumRedundantHeirarchy", 100);
    }

    if (params->Verbose != 1)
    {
      error("Redundant slices not supported when Verbose != 1", 100);
    }
  }

  key_frame = 0;
  redundant_coding = 0;
  img->redundant_pic_cnt = 0;
  frameNuminGOP = img->frm_number % params->PrimaryGOPLength;
  if (img->frm_number == 0)
  {
    frameNuminGOP = -1;
  }
}

/*!
 ************************************************************************
 * \brief
 *    allocate redundant frames in a primary GOP.
 ************************************************************************
 */
void Set_redundant_frame()
{
  int GOPlength = params->PrimaryGOPLength;

  //start frame of GOP
  if (frameNuminGOP == 0)
  {
    redundant_coding = 0;
    key_frame = 1;
    redundant_ref_idx = GOPlength;
  }

  //1/2 position
  if (params->NumRedundantHierarchy > 0)
  {
    if (frameNuminGOP == GOPlength/2)
    {
      redundant_coding = 0;
      key_frame = 1;
      redundant_ref_idx = GOPlength/2;
    }
  }

  //1/4, 3/4 position
  if (params->NumRedundantHierarchy > 1)
  {
    if (frameNuminGOP == GOPlength/4 || frameNuminGOP == GOPlength*3/4)
    {
      redundant_coding = 0;
      key_frame = 1;
      redundant_ref_idx = GOPlength/4;
    }
  }

  //1/8, 3/8, 5/8, 7/8 position
  if (params->NumRedundantHierarchy > 2)
  {
    if (frameNuminGOP == GOPlength/8 || frameNuminGOP == GOPlength*3/8
      || frameNuminGOP == GOPlength*5/8 || frameNuminGOP == GOPlength*7/8)
    {
      redundant_coding = 0;
      key_frame = 1;
      redundant_ref_idx = GOPlength/8;
    }
  }

  //1/16, 3/16, 5/16, 7/16, 9/16, 11/16, 13/16 position
  if (params->NumRedundantHierarchy > 3)
  {
    if (frameNuminGOP == GOPlength/16 || frameNuminGOP == GOPlength*3/16
      || frameNuminGOP == GOPlength*5/16 || frameNuminGOP == GOPlength*7/16
      || frameNuminGOP == GOPlength*9/16 || frameNuminGOP == GOPlength*11/16
      || frameNuminGOP == GOPlength*13/16)
    {
      redundant_coding = 0;
      key_frame = 1;
      redundant_ref_idx = GOPlength/16;
    }
  }
}

/*!
 ************************************************************************
 * \brief
 *    encode on redundant frame.
 ************************************************************************
 */
void encode_one_redundant_frame()
{
  key_frame = 0;
  redundant_coding = 1;
  img->redundant_pic_cnt = 1;

  if (img->type == I_SLICE)
  {
    set_slice_type( P_SLICE );
  }

  encode_one_frame();
}

/*!
 ************************************************************************
 * \brief
 *    Setup Chroma MC Variables
 ************************************************************************
 */
void chroma_mc_setup(void)
{
  // initialize global variables used for chroma interpolation and buffering
  if ( img->yuv_format == YUV420 )
  {
    img_pad_size_uv_x = IMG_PAD_SIZE >> 1;
    img_pad_size_uv_y = IMG_PAD_SIZE >> 1;
    chroma_mask_mv_y = 7;
    chroma_mask_mv_x = 7;
    chroma_shift_x = 3;
    chroma_shift_y = 3;
  }
  else if ( img->yuv_format == YUV422 )
  {
    img_pad_size_uv_x = IMG_PAD_SIZE >> 1;
    img_pad_size_uv_y = IMG_PAD_SIZE;
    chroma_mask_mv_y = 3;
    chroma_mask_mv_x = 7;
    chroma_shift_y = 2;
    chroma_shift_x = 3;
  }
  else
  { // YUV444
    img_pad_size_uv_x = IMG_PAD_SIZE;
    img_pad_size_uv_y = IMG_PAD_SIZE;
    chroma_mask_mv_y = 3;
    chroma_mask_mv_x = 3;
    chroma_shift_y = 2;
    chroma_shift_x = 2;
  }
  shift_cr_y  = chroma_shift_y - 2;
  shift_cr_x  = chroma_shift_x - 2;
}

⌨️ 快捷键说明

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