configfile.c

来自「the newest JM software by h.264 JVT offi」· C语言 代码 · 共 1,541 行 · 第 1/4 页

C
1,541
字号
  {
  case 0:
    params->run_length_minus1=(int *)malloc(sizeof(int)*(params->num_slice_groups_minus1+1));
    if ( NULL==params->run_length_minus1 )
    {
      fclose(sgfile);
      no_mem_exit("PatchInp: params->run_length_minus1");
    }

    // each line contains one 'run_length_minus1' value
    for(i=0;i<=params->num_slice_groups_minus1;i++)
    {
      ret  = fscanf(sgfile,"%d",(params->run_length_minus1+i));
      if ( 1!=ret )
      {
        fclose(sgfile);
        snprintf(errortext, ET_SIZE, "Error while reading slice group config file (line %d)", i+1);
        error (errortext, 500);
      }
      // scan remaining line
      ret = fscanf(sgfile,"%*[^\n]");
    }
    break;

  case 2:
    params->top_left=(int *)malloc(sizeof(int)*params->num_slice_groups_minus1);
    params->bottom_right=(int *)malloc(sizeof(int)*params->num_slice_groups_minus1);
    if (NULL==params->top_left)
    {
      fclose(sgfile);
      no_mem_exit("PatchInp: params->top_left");
    }
    if (NULL==params->bottom_right)
    {
      fclose(sgfile);
      no_mem_exit("PatchInp: params->bottom_right");
    }

    // every two lines contain 'top_left' and 'bottom_right' value
    for(i=0;i<params->num_slice_groups_minus1;i++)
    {
      ret = fscanf(sgfile,"%d",(params->top_left+i));
      if ( 1!=ret )
      {
        fclose(sgfile);
        snprintf(errortext, ET_SIZE, "Error while reading slice group config file (line %d)", 2*i +1);
        error (errortext, 500);
      }
      // scan remaining line
      ret = fscanf(sgfile,"%*[^\n]");
      ret = fscanf(sgfile,"%d",(params->bottom_right+i));
      if ( 1!=ret )
      {
        fclose(sgfile);
        snprintf(errortext, ET_SIZE, "Error while reading slice group config file (line %d)", 2*i + 2);
        error (errortext, 500);
      }
      // scan remaining line
      ret = fscanf(sgfile,"%*[^\n]");
    }
    break;

  case 6:
    {
      int tmp;
      int frame_mb_only;
      int mb_width, mb_height, mapunit_height;

      frame_mb_only = !(params->PicInterlace || params->MbInterlace);
      mb_width  = (params->output.width + img->auto_crop_right)>>4;
      mb_height = (params->output.height + img->auto_crop_bottom)>>4;
      mapunit_height = mb_height / (2-frame_mb_only);

      params->slice_group_id=(byte * ) malloc(sizeof(byte)*mapunit_height*mb_width);
      if (NULL==params->slice_group_id)
      {
        fclose(sgfile);
        no_mem_exit("PatchInp: params->slice_group_id");
      }

      // each line contains slice_group_id for one Macroblock
      for (i=0;i<mapunit_height*mb_width;i++)
      {
        ret = fscanf(sgfile,"%d", &tmp);
        params->slice_group_id[i]= (byte) tmp;
        if ( 1!=ret )
        {
          fclose(sgfile);
          snprintf(errortext, ET_SIZE, "Error while reading slice group config file (line %d)", i + 1);
          error (errortext, 500);
        }
        if ( *(params->slice_group_id+i) > params->num_slice_groups_minus1 )
        {
          fclose(sgfile);
          snprintf(errortext, ET_SIZE, "Error while reading slice group config file: slice_group_id not allowed (line %d)", i + 1);
          error (errortext, 500);
        }
        // scan remaining line
        ret = fscanf(sgfile,"%*[^\n]");
      }
    }
    break;

  default:
    // we should not get here
    error ("Wrong slice group type while reading config file", 500);
    break;
  }

  // close file again
  fclose(sgfile);
}

/*!
 ************************************************************************
 * \brief
 *    Compute frame numbering related parameters
 * \note
 *    The set variables seem to now be primarily useful only for 
 *    RC purposes. Can we ommit them completely? The use of 
 *    lastframe can also be modified as to ommit this parameter.
 *    To be done at a future date.
 *    
 ************************************************************************
 */
static void compute_frameno_params(InputParameters *params)
{
  params->last_frame = 0;
  if (params->idr_period && params->EnableIDRGOP)
  {
    if (params->idr_period == 1)
    {
      params->no_frm_base = params->no_frames;
    }
    else
    {
      int gop_size        = (params->idr_period - 1) * (params->NumberBFrames + 1) + 1;
      int idr_gops        = params->no_frames /gop_size;
      int rem_frames      = params->no_frames - idr_gops * gop_size;
      int last_b_groups   = ((rem_frames > 0) + (rem_frames + params->NumberBFrames - 1)/ (params->NumberBFrames + 1));
      int last_frame      = (rem_frames) - last_b_groups * (params->NumberBFrames + 1);
      params->no_frm_base = idr_gops * params->idr_period + last_b_groups;

      if (last_frame)
        params->last_frame = (params->no_frames - 1) * (params->frame_skip + 1);
    } 
  }
  else
  {
    params->no_frm_base = (int) (params->no_frames + params->NumberBFrames) / (1 + params->NumberBFrames);

    if ((params->no_frm_base - 1)* (1 + params->NumberBFrames) + 1 < params->no_frames)
      params->last_frame = (params->no_frames - 1) * (params->frame_skip + 1);

    if (params->last_frame > 0)
      params->no_frm_base = 1 + (params->last_frame + params->NumberBFrames) / (params->NumberBFrames + 1);
  }
}

/*!
 ***********************************************************************
 * \brief
 *    Checks the input parameters for consistency.
 ***********************************************************************
 */
static void PatchInp (void)
{
  int i,j;
  int storedBplus1;
  int bitdepth_qp_scale[3];

  if (params->src_BitDepthRescale)
  {
    bitdepth_qp_scale [0] = 6*(params->output.bit_depth[0] - 8);
    bitdepth_qp_scale [1] = 6*(params->output.bit_depth[1] - 8);
    bitdepth_qp_scale [2] = 6*(params->output.bit_depth[2] - 8);
  }
  else
  {
    bitdepth_qp_scale [0] = 6*(params->source.bit_depth[0] - 8);
    bitdepth_qp_scale [1] = 6*(params->source.bit_depth[1] - 8);
    bitdepth_qp_scale [2] = 6*(params->source.bit_depth[2] - 8);
  }

  TestEncoderParams(bitdepth_qp_scale);

  if (params->source.frame_rate == 0.0)
    params->source.frame_rate = (double) INIT_FRAME_RATE;

  ParseVideoType(&params->input_file1);
  ParseFrameNoFormatFromString (&params->input_file1);

  // Read resolution from file name
  if (params->source.width == 0 || params->source.height == 0)
  {
    if (ParseSizeFromString (&params->input_file1, &(params->source.width), &(params->source.height), &(params->source.frame_rate)) == 0)
    {
      snprintf(errortext, ET_SIZE, "File name does not contain resolution information.");    
      error (errortext, 500);
    }
  }

  // Currently to simplify things, lets copy everything (overwrites yuv_format)
  params->input_file1.format = params->source;


  // Set block sizes

  // Skip/Direct16x16
  params->part_size[0][0] = 4;
  params->part_size[0][1] = 4;
  // 16x16
  params->part_size[1][0] = 4;
  params->part_size[1][1] = 4;
  // 16x8
  params->part_size[2][0] = 4;
  params->part_size[2][1] = 2;
  // 8x16
  params->part_size[3][0] = 2;
  params->part_size[3][1] = 4;
  // 8x8
  params->part_size[4][0] = 2;
  params->part_size[4][1] = 2;
  // 8x4
  params->part_size[5][0] = 2;
  params->part_size[5][1] = 1;
  // 4x8
  params->part_size[6][0] = 1;
  params->part_size[6][1] = 2;
  // 4x4
  params->part_size[7][0] = 1;
  params->part_size[7][1] = 1;

  for (j = 0; j<8;j++)
  {
    for (i = 0; i<2; i++)
    {
      params->blc_size[j][i] = params->part_size[j][i] * BLOCK_SIZE;
    }
  }

  if (params->idr_period && params->intra_delay && params->idr_period <= params->intra_delay)
  {
    snprintf(errortext, ET_SIZE, " IntraDelay cannot be larger than or equal to IDRPeriod.");
    error (errortext, 500);
  }

  if (params->idr_period && params->intra_delay && params->EnableIDRGOP == 0)
  {
    snprintf(errortext, ET_SIZE, " IntraDelay can only be used with only 1 IDR or with EnableIDRGOP=1.");
    error (errortext, 500);
  }

  if (params->idr_period && params->intra_delay && params->adaptive_idr_period)
  {
    snprintf(errortext, ET_SIZE, " IntraDelay can not be used with AdaptiveIDRPeriod.");
    error (errortext, 500);
  }

  // Let us set up params->jumpd from frame_skip and NumberBFrames
  params->jumpd = (params->NumberBFrames + 1) * (params->frame_skip + 1) - 1;


  updateOutFormat(params);

  if (params->no_frames == -1)
  {
    OpenFiles(&params->input_file1);
    getNumberOfFrames(&params->input_file1);
    CloseFiles(&params->input_file1);
  }

  // Update intra period internally given the number of intermediate frames.
  // This allows Intra period parameters to have similar scemantics as FramesToBeEncoded.  
  if (params->NumberBFrames)
  {
    params->intra_period = (params->intra_period) / (params->NumberBFrames + 1);
    if (params->EnableIDRGOP == 1)
      params->idr_period = (params->idr_period + params->NumberBFrames) / (params->NumberBFrames + 1);
    else
      params->idr_period = (params->idr_period) / (params->NumberBFrames + 1);
  }

  // These seem to be now only (or primarily) useful for RC purposes. 
  // It would be nice to modify all RC implementations to use only params->no_frames and ignore this if possible
  compute_frameno_params(params);

  storedBplus1 = (params->BRefPictures ) ? params->NumberBFrames + 1: 1;
  
  if (params->Log2MaxFNumMinus4 == -1)
  {    
    log2_max_frame_num_minus4 = iClip3(0,12, (int) (CeilLog2(params->no_frm_base * storedBplus1) - 4));    
  }
  else  
    log2_max_frame_num_minus4 = params->Log2MaxFNumMinus4;

  max_frame_num = 1 << (log2_max_frame_num_minus4 + 4);

  if (log2_max_frame_num_minus4 == 0 && params->num_ref_frames == 16)
  {
    snprintf(errortext, ET_SIZE, " NumberReferenceFrames=%d and Log2MaxFNumMinus4=%d may lead to an invalid value of frame_num.", params->num_ref_frames, params-> Log2MaxFNumMinus4);
    error (errortext, 500);
  }

  // set proper log2_max_pic_order_cnt_lsb_minus4.
  if (params->Log2MaxPOCLsbMinus4 == - 1)
    log2_max_pic_order_cnt_lsb_minus4 = iClip3(0,12, (int) (CeilLog2( 2 * params->no_frm_base * (params->jumpd + 1)) - 4));
  else
    log2_max_pic_order_cnt_lsb_minus4 = params->Log2MaxPOCLsbMinus4;

  max_pic_order_cnt_lsb = 1 << (log2_max_pic_order_cnt_lsb_minus4 + 4);

  if (((1<<(log2_max_pic_order_cnt_lsb_minus4 + 3)) < params->jumpd * 4) && params->Log2MaxPOCLsbMinus4 != -1)
    error("log2_max_pic_order_cnt_lsb_minus4 might not be sufficient for encoding. Increase value.",400);

  if (params->no_frames < 1)
  {      
    snprintf(errortext, ET_SIZE, "Not enough frames to encode (%d)", params->no_frames);
    error (errortext, 500);
  }

  // Direct Mode consistency check
  if(params->NumberBFrames && params->direct_spatial_mv_pred_flag != DIR_SPATIAL && params->direct_spatial_mv_pred_flag != DIR_TEMPORAL)
  {
    snprintf(errortext, ET_SIZE, "Unsupported direct mode=%d, use TEMPORAL=0 or SPATIAL=1", params->direct_spatial_mv_pred_flag);
    error (errortext, 400);
  }

  if (params->PicInterlace>0 || params->MbInterlace>0)
  {
    if (params->directInferenceFlag==0)
      printf("\nWarning: DirectInferenceFlag set to 1 due to interlace coding.");
    params->directInferenceFlag = 1;
  }

  if (strlen (params->ReconFile) > 0 && (p_dec=open(params->ReconFile, OPENFLAGS_WRITE, OPEN_PERMISSIONS))==-1)
  {
    snprintf(errortext, ET_SIZE, "Error open file %s", params->ReconFile);
    error (errortext, 500);
  }

#if TRACE
  if (strlen (params->TraceFile) > 0 && (p_trace=fopen(params->TraceFile,"w"))==NULL)
  {
    snprintf(errortext, ET_SIZE, "Error open file %s", params->TraceFile);
    error (errortext, 500);
  }
#endif

  if (params->output.width % 16 != 0)
  {
    img->auto_crop_right = 16 - (params->output.width % 16);
  }
  else
  {
    img->auto_crop_right=0;
  }
  if (params->PicInterlace || params->MbInterlace)
  {
    if ((params->output.height & 0x01) != 0)
    {
      error ("even number of lines required for interlaced coding", 500);
    }
    
    if (params->output.height % 32 != 0)
    {
      img->auto_crop_bottom = 32-(params->output.height % 32);
    }
    else
    {
      img->auto_crop_bottom=0;
    }
  }
  else
  {
    if (params->output.height % 16 != 0)
    {
      img->auto_crop_bottom = 16-(params->output.height % 16);
    }
    else
    {
      img->auto_crop_bottom=0;
    }
  }
  if (img->auto_crop_bottom || img->auto_crop_right)
  {

⌨️ 快捷键说明

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