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

📄 ldecod.c

📁 H.264基于baseline解码器的C++实现源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  g_nFrame = 0;

  init_out_buffer();  

  // B pictures
  Bframe_ctr = snr->frame_ctr = 0;

  // time for total decoding session
  tot_time = 0;

  // reference flag initialization
  for(i=0;i<17;i++)
  {
    ref_flag[i] = 1;
  }

  while (decode_one_frame(img, params, snr) != EOS)
    ;

  report(params, img, snr);
  free_slice(img);
  FmoFinit();
  free_global_buffers();

  flush_dpb();

#if (PAIR_FIELDS_IN_OUTPUT)
  flush_pending_output(p_out);
#endif

  bitsfile.CloseBitsFile();

  close(p_out);
  if (p_ref!=-1)
    close(p_ref);

#if TRACE
  fclose(p_trace);
#endif

  ercClose(erc_errorVar);

  CleanUpPPS();

  free_dpb();
  uninit_out_buffer();
  if( IS_INDEPENDENT(img) )
  {
    for( nplane = 0; nplane < MAX_PLANE; nplane++ )
    {
      free_colocated(Co_located_JV[nplane]);   
    }
  }
  else
  {
    free_colocated(Co_located);
  }
  free (params);
  free (snr);
  free_img (img);

  return 0;
}


/*!
 ***********************************************************************
 * \brief
 *    Initilize some arrays
 ***********************************************************************
 */
void init(ImageParameters *img)  //!< image parameters
{
  img->oldFrameSizeInMbs = -1;

  imgY_ref  = NULL;
  imgUV_ref = NULL;

  img->recovery_point = 0;
  img->recovery_point_found = 0;
  img->recovery_poc = 0x7fffffff; /* set to a max value */

  img->idr_psnr_number = params->ref_offset;
  img->psnr_number=0;

  img->number = 0;
  img->type = I_SLICE;

  img->dec_ref_pic_marking_buffer = NULL;

#if (ENABLE_OUTPUT_TONEMAPPING)
  init_tone_mapping_sei();
#endif
}

/*!
 ***********************************************************************
 * \brief
 *    Initialize FREXT variables
 ***********************************************************************
 */
void init_frext(ImageParameters *img)  //!< image parameters
{
  //pel bitdepth init
  img->bitdepth_luma_qp_scale   = 6 * (img->bitdepth_luma - 8);
  if(img->bitdepth_luma > img->bitdepth_chroma || active_sps->chroma_format_idc == YUV400)
    img->pic_unit_bitsize_on_disk = (img->bitdepth_luma > 8)? 16:8;
  else
    img->pic_unit_bitsize_on_disk = (img->bitdepth_chroma > 8)? 16:8;
  img->dc_pred_value_comp[0]    = 1<<(img->bitdepth_luma - 1);
  img->max_imgpel_value_comp[0] = (1<<img->bitdepth_luma) - 1;
  img->mb_size[0][0] = img->mb_size[0][1] = MB_BLOCK_SIZE;

  if (active_sps->chroma_format_idc != YUV400)
  {
    //for chrominance part
    img->bitdepth_chroma_qp_scale = 6 * (img->bitdepth_chroma - 8);
    img->dc_pred_value_comp[1]    = (1 << (img->bitdepth_chroma - 1));
    img->dc_pred_value_comp[2]    = img->dc_pred_value_comp[1];
    img->max_imgpel_value_comp[1] = (1 << img->bitdepth_chroma) - 1;
    img->max_imgpel_value_comp[2] = (1 << img->bitdepth_chroma) - 1;
    img->num_blk8x8_uv = (1 << active_sps->chroma_format_idc) & (~(0x1));
    img->num_uv_blocks = (img->num_blk8x8_uv >> 1);
    img->num_cdc_coeff = (img->num_blk8x8_uv << 1);
    img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x  = (active_sps->chroma_format_idc==YUV420 || active_sps->chroma_format_idc==YUV422)?  8 : 16;
    img->mb_size[1][1] = img->mb_size[2][1] = img->mb_cr_size_y  = (active_sps->chroma_format_idc==YUV444 || active_sps->chroma_format_idc==YUV422)? 16 :  8;
  }
  else
  {
    img->bitdepth_chroma_qp_scale = 0;
    img->max_imgpel_value_comp[1] = 0;
    img->max_imgpel_value_comp[2] = 0;
    img->num_blk8x8_uv = 0;
    img->num_uv_blocks = 0;
    img->num_cdc_coeff = 0;
    img->mb_size[1][0] = img->mb_size[2][0] = img->mb_cr_size_x  = 0;
    img->mb_size[1][1] = img->mb_size[2][1] = img->mb_cr_size_y  = 0;
  }
  img->mb_size_blk[0][0] = img->mb_size_blk[0][1] = img->mb_size[0][0] >> 2;
  img->mb_size_blk[1][0] = img->mb_size_blk[2][0] = img->mb_size[1][0] >> 2;
  img->mb_size_blk[1][1] = img->mb_size_blk[2][1] = img->mb_size[1][1] >> 2;

  img->mb_size_shift[0][0] = img->mb_size_shift[0][1] = CeilLog2_sf (img->mb_size[0][0]);
  img->mb_size_shift[1][0] = img->mb_size_shift[2][0] = CeilLog2_sf (img->mb_size[1][0]);
  img->mb_size_shift[1][1] = img->mb_size_shift[2][1] = CeilLog2_sf (img->mb_size[1][1]);

  init_qp_process(img);
}

/*!
************************************************************************
* \brief
*    exit with error message if reading from config file failed
************************************************************************
*/
inline static void conf_read_check (int val, int expected)
{
  if (val != expected)
  {
    error ("init_conf: error reading from config file", 500);
  }
}

/*!
 ************************************************************************
 * \brief
 *    Read parameters from configuration file
 *
 * \par Input:
 *    Name of configuration filename
 *
 * \par Output
 *    none
 ************************************************************************
 */
void init_conf(struct inp_par *inp, char *config_filename)
{
  FILE *fd;
  int NAL_mode;

  // picture error concealment
  long int temp;
  char tempval[100];

  // read the decoder configuration file
  if((fd=fopen(config_filename,"r")) == NULL)
  {
    snprintf(errortext, ET_SIZE, "Error: Control file %s not found\n",config_filename);
    error(errortext, 300);
  }

  conf_read_check (fscanf(fd,"%s",inp->infile), 1);                // H.264 compressed input bitstream
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);

  conf_read_check (fscanf(fd,"%s",inp->outfile), 1);               // RAW (YUV/RGB) output file
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);

  conf_read_check (fscanf(fd,"%s",inp->reffile), 1);               // reference file
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);

  conf_read_check (fscanf(fd,"%d",&(inp->write_uv)), 1);           // write UV in YUV 4:0:0 mode
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);

  conf_read_check (fscanf(fd,"%d",&(NAL_mode)), 1);                // NAL mode
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);

  switch(NAL_mode)
  {
  case 0:
    inp->FileFormat = PAR_OF_ANNEXB;
    break;
  case 1:
    inp->FileFormat = PAR_OF_RTP;
    break;
  default:
    snprintf(errortext, ET_SIZE, "NAL mode %i is not supported", NAL_mode);
    error(errortext,400);
  }

  conf_read_check (fscanf(fd,"%d,",&inp->ref_offset), 1);   // offset used for SNR computation
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);

  conf_read_check (fscanf(fd,"%d,",&inp->poc_scale), 1);   // offset used for SNR computation
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);


  if (inp->poc_scale < 1 || inp->poc_scale > 10)
  {
    snprintf(errortext, ET_SIZE, "Poc Scale is %d. It has to be within range 1 to 10",inp->poc_scale);
    error(errortext,1);
  }

  inp->write_uv=1;

  // picture error concealment
  img->conceal_mode = inp->conceal_mode = 0;
  img->ref_poc_gap = inp->ref_poc_gap = 2;
  img->poc_gap = inp->poc_gap = 2;

#ifdef _LEAKYBUCKET_
  conf_read_check (fscanf(fd,"%ld,",&inp->R_decoder), 1);             // Decoder rate
  conf_read_check (fscanf(fd, "%*[^\n]"), 0);
  conf_read_check (fscanf(fd,"%ld,",&inp->B_decoder), 1);             // Decoder buffer size
  conf_read_check (fscanf(fd, "%*[^\n]"), 0);
  conf_read_check (fscanf(fd,"%ld,",&inp->F_decoder), 1);             // Decoder initial delay
  conf_read_check (fscanf(fd, "%*[^\n]"), 0);
  conf_read_check (fscanf(fd,"%s",inp->LeakyBucketParamFile), 1);    // file where Leaky Bucket params (computed by encoder) are stored
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);
#endif

  /* since error concealment parameters are added at the end of
  decoder conf file we need to read the leakybucket params to get to
  those parameters */
#ifndef _LEAKYBUCKET_
  conf_read_check (fscanf(fd,"%ld,",&temp), 1);
  conf_read_check (fscanf(fd, "%*[^\n]"), 0);
  conf_read_check (fscanf(fd,"%ld,",&temp), 1);
  conf_read_check (fscanf(fd, "%*[^\n]"), 0);
  conf_read_check (fscanf(fd,"%ld,",&temp), 1);
  conf_read_check (fscanf(fd, "%*[^\n]"), 0);
  conf_read_check (fscanf(fd,"%s",tempval), 1);
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);
#endif

  conf_read_check (fscanf(fd,"%d",&inp->conceal_mode), 1);   // Mode of Error Concealment
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);
  img->conceal_mode = inp->conceal_mode;
  conf_read_check (fscanf(fd,"%d",&inp->ref_poc_gap), 1);   // POC gap depending on pattern
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);
  img->ref_poc_gap = inp->ref_poc_gap;
  conf_read_check (fscanf(fd,"%d",&inp->poc_gap), 1);   // POC gap between consecutive frames in display order
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);
  img->poc_gap = inp->poc_gap;
  conf_read_check (fscanf(fd,"%d,",&inp->silent), 1);     // use silent decode mode
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);
  conf_read_check (fscanf(fd,"%d,",&inp->intra_profile_deblocking), 1);     // use deblocking filter in intra only profile
  conf_read_check (fscanf(fd,"%*[^\n]"), 0);

  fclose (fd);
}

/*!
 ************************************************************************
 * \brief
 *    Reports the gathered information to appropriate outputs
 *
 * \par Input:
 *    struct inp_par *inp,
 *    ImageParameters *img,
 *    struct snr_par *stat
 *
 * \par Output:
 *    None
 ************************************************************************
 */
void report(struct inp_par *inp, ImageParameters *img, struct snr_par *snr)
{
#define OUTSTRING_SIZE 255
  char string[OUTSTRING_SIZE];
  FILE *p_log;
  char yuv_formats[4][4]= { {"400"}, {"420"}, {"422"}, {"444"} };

#ifndef WIN32
  time_t  now;
  struct tm *l_time;
#else
  char timebuf[128];
#endif

  // normalize time
  tot_time  = timenorm(tot_time);

  if (params->silent == FALSE)
  {
    fprintf(stdout,"-------------------- Average SNR all frames ------------------------------\n");
    fprintf(stdout," SNR Y(dB)           : %5.2f\n",snr->snra[0]);
    fprintf(stdout," SNR U(dB)           : %5.2f\n",snr->snra[1]);
    fprintf(stdout," SNR V(dB)           : %5.2f\n",snr->snra[2]);
    fprintf(stdout," Total decoding time : %.3f sec (%.3f fps)\n",tot_time*0.001,(snr->frame_ctr ) * 1000.0 / tot_time);
    fprintf(stdout,"--------------------------------------------------------------------------\n");
    fprintf(stdout," Exit JM %s decoder, ver %s ",JM, VERSION);
    fprintf(stdout,"\n");
  }
  else
  {
    fprintf(stdout,"\n----------------------- Decoding Completed -------------------------------\n");
    fprintf(stdout," Total decoding time : %.3f sec (%.3f fps)\n",tot_time*0.001, (snr->frame_ctr) * 1000.0 / tot_time);
    fprintf(stdout,"--------------------------------------------------------------------------\n");
    fprintf(stdout," Exit JM %s decoder, ver %s ",JM, VERSION);
    fprintf(stdout,"\n");
  }

  // write to log file

  snprintf(string, OUTSTRING_SIZE, "%s", LOGFILE);

  if ((p_log=fopen(string,"r"))==0)                    // check if file exist
  {
    if ((p_log=fopen(string,"a"))==0)
    {
      snprintf(errortext, ET_SIZE, "Error open file %s for appending",string);
      error(errortext, 500);
    }
    else                                              // Create header to new file
    {
      fprintf(p_log," -------------------------------------------------------------------------------------------------------------------\n");
      fprintf(p_log,"|  Decoder statistics. This file is made first time, later runs are appended               |\n");
      fprintf(p_log," ------------------------------------------------------------------------------------------------------------------- \n");
      fprintf(p_log,"|   ver  | Date  | Time  |    Sequence        |#Img| Format  | YUV |Coding|SNRY 1|SNRU 1|SNRV 1|SNRY N|SNRU N|SNRV N|\n");
      fprintf(p_log," -------------------------------------------------------------------------------------------------------------------\n");
    }
  }
  else
  {
    fclose(p_log);
    p_log=fopen(string,"a");                    // File exist,just open for appending
  }

⌨️ 快捷键说明

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