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(¶ms->input_file1);
ParseFrameNoFormatFromString (¶ms->input_file1);
// Read resolution from file name
if (params->source.width == 0 || params->source.height == 0)
{
if (ParseSizeFromString (¶ms->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(¶ms->input_file1);
getNumberOfFrames(¶ms->input_file1);
CloseFiles(¶ms->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 + -
显示快捷键?