📄 conformance.c
字号:
{
snprintf(errortext, ET_SIZE, "\nIntraProfile requires IDRPeriod >= 1.");
error (errortext, 500);
}
if (params->IntraProfile && params->intra_period != 1)
{
snprintf(errortext, ET_SIZE, "\nIntraProfile requires IntraPeriod equal 1.");
error (errortext, 500);
}
if (params->IntraProfile && params->num_ref_frames)
{
fprintf( stderr, "\nWarning: Setting NumberReferenceFrames to 0 in IntraProfile.");
params->num_ref_frames = 0;
}
if (params->IntraProfile == 0 && params->num_ref_frames == 0)
{
snprintf(errortext, ET_SIZE, "\nProfiles other than IntraProfile require NumberReferenceFrames > 0.");
error (errortext, 500);
}
}
/*!
***********************************************************************
* \brief
* Check if Level constraints are satisfied
***********************************************************************
*/
void LevelCheck(void)
{
unsigned int PicSizeInMbs = ( (params->output.width + img->auto_crop_right) * (params->output.height + img->auto_crop_bottom) ) >> 8;
unsigned int MBProcessingRate = (unsigned int) (PicSizeInMbs * params->output.frame_rate + 0.5);
if ( (params->LevelIDC>=30) && (params->directInferenceFlag==0))
{
fprintf( stderr, "\nWarning: LevelIDC 3.0 and above require direct_8x8_inference to be set to 1. Please check your settings.\n");
params->directInferenceFlag=1;
}
if ( ((params->LevelIDC<21) || (params->LevelIDC>41)) && (params->PicInterlace > 0 || params->MbInterlace > 0) )
{
snprintf(errortext, ET_SIZE, "\nInterlace modes only supported for LevelIDC in the range of 21 and 41. Please check your settings.\n");
error (errortext, 500);
}
if ( PicSizeInMbs > getMaxFs(params->LevelIDC) )
{
snprintf(errortext, ET_SIZE, "\nPicSizeInMbs exceeds maximum allowed size at specified LevelIdc %.1f\n", (float) params->LevelIDC / 10.0);
error (errortext, 500);
}
if (params->IntraProfile && (PicSizeInMbs > 1620) && params->slice_mode != 1)
{
error ("\nIntraProfile with PicSizeInMbs > 1620 requires SliceMode equal 1.", 500);
}
if (params->IntraProfile && (PicSizeInMbs > 1620) && ((unsigned int)params->slice_argument > ( getMaxFs(params->LevelIDC) >> 2 ) ) )
{
//when PicSizeInMbs is greater than 1620, the number of macroblocks in any coded slice shall not exceed MaxFS / 4
snprintf(errortext, ET_SIZE, "\nIntraProfile requires SliceArgument smaller or equal to 1/4 MaxFs at specified LevelIdc %d.", params->LevelIDC);
error (errortext, 500);
}
if ( MBProcessingRate > getMaxMBPS(params->LevelIDC) )
{
snprintf(errortext, ET_SIZE, "\nMB Processing Rate (%d) exceeds maximum allowed processing rate (%d) at specified LevelIdc %.1f\n",
MBProcessingRate, getMaxMBPS(params->LevelIDC), (float) params->LevelIDC / 10.0);
error (errortext, 500);
}
}
/*!
***********************************************************************
* \brief
* Update Motion Vector Limits
***********************************************************************
*/
void update_mv_limits(ImageParameters *img, byte is_field)
{
memcpy(img->MaxVmvR, LEVELVMVLIMIT[img->LevelIndex], 6 * sizeof(int));
memcpy(img->MaxHmvR, LEVELHMVLIMIT, 6 * sizeof(int));
if (is_field)
{
int i;
for (i = 0; i < 6; i++)
img->MaxVmvR[i] = rshift_rnd(img->MaxVmvR[i], 1);
}
if (params->UseMVLimits)
{
img->MaxVmvR[0] = imax(img->MaxVmvR[0], -(params->SetMVYLimit));
img->MaxVmvR[1] = imin(img->MaxVmvR[1], (params->SetMVYLimit));
img->MaxVmvR[2] = imax(img->MaxVmvR[2], -(params->SetMVYLimit << 1));
img->MaxVmvR[3] = imin(img->MaxVmvR[3], (params->SetMVYLimit << 1));
img->MaxVmvR[4] = imax(img->MaxVmvR[4], -(params->SetMVYLimit << 2));
img->MaxVmvR[5] = imin(img->MaxVmvR[5], (params->SetMVYLimit << 2));
img->MaxHmvR[0] = imax(img->MaxHmvR[0], -(params->SetMVXLimit));
img->MaxHmvR[1] = imin(img->MaxHmvR[1], (params->SetMVXLimit));
img->MaxHmvR[2] = imax(img->MaxHmvR[2], -(params->SetMVXLimit << 1));
img->MaxHmvR[3] = imin(img->MaxHmvR[3], (params->SetMVXLimit << 1));
img->MaxHmvR[4] = imax(img->MaxHmvR[4], -(params->SetMVXLimit << 2));
img->MaxHmvR[5] = imin(img->MaxHmvR[5], (params->SetMVXLimit << 2));
}
}
/*!
***********************************************************************
* \brief
* Clip motion vector range given encoding level
***********************************************************************
*/
void clip_mv_range(ImageParameters *img, int search_range, MotionVector *mv, int res)
{
search_range <<= res;
res <<= 1;
mv->mv_x = iClip3( img->MaxHmvR[0 + res] + search_range, img->MaxHmvR[1 + res] - search_range, mv->mv_x);
mv->mv_y = iClip3( img->MaxVmvR[0 + res] + search_range, img->MaxVmvR[1 + res] - search_range, mv->mv_y);
}
/*!
***********************************************************************
* \brief
* Clip motion vector range given encoding level
***********************************************************************
*/
void test_clip_mvs(ImageParameters *img, short mv[2], Boolean write_mb)
{
if ((mv[0] < img->MaxHmvR[4]) || (mv[0] > img->MaxHmvR[5]) || (mv[1] < img->MaxVmvR[4]) || (mv[1] > img->MaxVmvR[5]))
{
if (write_mb == TRUE)
printf("Warning MVs (%d %d) were out of range x(%d %d) y(%d %d). Clipping mvs before writing\n", mv[0], mv[1], img->MaxHmvR[4], img->MaxHmvR[5], img->MaxVmvR[4], img->MaxVmvR[5]);
mv[0] = iClip3( img->MaxHmvR[4], img->MaxHmvR[5], mv[0]);
mv[1] = iClip3( img->MaxVmvR[4], img->MaxVmvR[5], mv[1]);
}
}
/*!
***********************************************************************
* \brief
* Clip motion vector range given encoding level
***********************************************************************
*/
int out_of_bounds_mvs(ImageParameters *img, short mv[2])
{
return ((mv[0] < img->MaxHmvR[4]) || (mv[0] > img->MaxHmvR[5]) || (mv[1] < img->MaxVmvR[4]) || (mv[1] > img->MaxVmvR[5]));
}
int InvalidWeightsForBiPrediction(Block8x8Info* b8x8info, int mode)
{
int cur_blk, cur_comp;
int best8x8l0ref, best8x8l1ref;
int weight_sum = 0;
int invalid_mode = 0;
int *wbp0, *wbp1;
for (cur_blk = 0; cur_blk < 4; cur_blk ++)
{
if (b8x8info->best8x8pdir[mode][cur_blk] == 2)
{
best8x8l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
best8x8l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
wbp0 = &wbp_weight[LIST_0][best8x8l0ref][best8x8l1ref][0];
wbp1 = &wbp_weight[LIST_1][best8x8l0ref][best8x8l1ref][0];
for (cur_comp = 0; cur_comp < (active_sps->chroma_format_idc == YUV400 ? 1 : 3) ; cur_comp ++)
{
weight_sum = *wbp0++ + *wbp1++;
if (weight_sum < -128 || weight_sum > 127)
{
invalid_mode = 1;
break;
}
}
if (invalid_mode == 1)
break;
}
}
return invalid_mode;
}
int InvalidMotionVectors(Block8x8Info* b8x8info, int mode)
{
int cur_blk;
int l0ref, l1ref;
int invalid_mode = 0;
int i, j;
if (mode > P8x8)
return invalid_mode;
// Brute force method. Note that this ignores currently subpartitions in 8x8 modes
for (cur_blk = 0; cur_blk < 4; cur_blk ++)
{
i = (cur_blk & 0x01) << 1;
j = (cur_blk >> 1) << 1;
switch (b8x8info->best8x8pdir[mode][cur_blk])
{
case 0:
l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
if (out_of_bounds_mvs(img, img->all_mv [LIST_0][l0ref][mode][j][i]))
{
invalid_mode = 1;
return invalid_mode;
}
break;
case 1:
l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
if (out_of_bounds_mvs(img, img->all_mv [LIST_1][l1ref][mode][j][i]))
{
invalid_mode = 1;
return invalid_mode;
}
break;
case 2:
l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
if (out_of_bounds_mvs(img, img->all_mv [LIST_0][l0ref][mode][j][i]))
{
invalid_mode = 1;
return invalid_mode;
}
if (out_of_bounds_mvs(img, img->all_mv [LIST_1][l1ref][mode][j][i]))
{
invalid_mode = 1;
return invalid_mode;
}
break;
default:
break;
}
}
return invalid_mode;
}
int CheckPredictionParams(pic_parameter_set_rbsp_t *active_pps, Block8x8Info *b8x8info, int mode, int bslice)
{
// check if weights are in valid range for biprediction.
if (bslice && active_pps->weighted_bipred_idc == 1 && mode < P8x8)
{
if (InvalidWeightsForBiPrediction(b8x8info, mode))
return 0;
}
if (InvalidMotionVectors(b8x8info, mode))
return 0;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -