00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "global.h"
00017
00018
00019
00020 unsigned int MaxFs [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 99, 396, 396, 396, 0, 0, 0, 0, 0, 0, 396, 792, 1620, 0, 0, 0, 0, 0, 0, 0,
00021
00022 1620, 3600, 5120, 0, 0, 0, 0, 0, 0, 0, 8192, 8192, 8704, 0, 0, 0, 0, 0, 0, 0, 22080, 36864 };
00023
00024 unsigned int MaxMBPS[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1485, 1485, 3000, 6000, 11880, 0, 0, 0, 0, 0, 0, 11880, 19800, 20250, 0, 0, 0, 0, 0, 0, 0,
00025 40500, 10800, 216000, 0, 0, 0, 0, 0, 0, 0, 245760, 245760, 522240, 0, 0, 0, 0, 0, 0, 0, 589824, 983040 };
00026
00027
00028
00029
00030
00031 const int LEVELVMVLIMIT[17][6] =
00032 {
00033 { -63, 63, -128, 127, -256, 255},
00034 { -63, 63, -128, 127, -256, 255},
00035 { -127, 127, -256, 255, -512, 511},
00036 { -127, 127, -256, 255, -512, 511},
00037 { -127, 127, -256, 255, -512, 511},
00038 { -127, 127, -256, 255, -512, 511},
00039 { -255, 255, -512, 511, -1024, 1023},
00040 { -255, 255, -512, 511, -1024, 1023},
00041 { -255, 255, -512, 511, -1024, 1023},
00042 { -511, 511, -1024, 1023, -2048, 2047},
00043 { -511, 511, -1024, 1023, -2048, 2047},
00044 { -511, 511, -1024, 1023, -2048, 2047},
00045 { -511, 511, -1024, 1023, -2048, 2047},
00046 { -511, 511, -1024, 1023, -2048, 2047},
00047 { -511, 511, -1024, 1023, -2048, 2047},
00048 { -511, 511, -1024, 1023, -2048, 2047},
00049 { -511, 511, -1024, 1023, -2048, 2047}
00050 };
00051
00052 const int LEVELHMVLIMIT[6] = { -2047, 2047, -4096, 4095, -8192, 8191};
00053
00054
00055
00056
00057
00058
00059
00060 unsigned getMaxFs (unsigned int levelIdc)
00061 {
00062 unsigned int ret;
00063
00064 if ( (levelIdc < 9) || (levelIdc > 51))
00065 error ("getMaxFs: Unknown LevelIdc", 500);
00066
00067
00068
00069 ret = MaxFs[levelIdc];
00070
00071 if ( 0 == ret )
00072 error ("getMaxFs: Unknown LevelIdc", 500);
00073
00074 return ret;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083 unsigned getMaxMBPS (unsigned int levelIdc)
00084 {
00085 unsigned int ret;
00086
00087 if ( (levelIdc < 9) || (levelIdc > 51))
00088 error ("getMaxMBPS: Unknown LevelIdc", 500);
00089
00090
00091
00092 ret = MaxMBPS[levelIdc];
00093
00094 if ( 0 == ret )
00095 error ("getMaxMBPS: Unknown LevelIdc", 500);
00096
00097 return ret;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 void ProfileCheck(void)
00107 {
00108 if((params->ProfileIDC != 66 ) &&
00109 (params->ProfileIDC != 77 ) &&
00110 (params->ProfileIDC != 88 ) &&
00111 (params->ProfileIDC != FREXT_HP ) &&
00112 (params->ProfileIDC != FREXT_Hi10P ) &&
00113 (params->ProfileIDC != FREXT_Hi422 ) &&
00114 (params->ProfileIDC != FREXT_Hi444 ) &&
00115 (params->ProfileIDC != FREXT_CAVLC444 ))
00116 {
00117 snprintf(errortext, ET_SIZE, "Profile must be in\n\n 66 (Baseline),\n 77 (Main),\n 88 (Extended),\n 100 (High),\n 110 (High 10 or High 10 Intra)\n"
00118 " 122 (High 4:2:2 or High 4:2:2 Intra),\n 244 (High 4:4:4 predictive or High 4:4:4 Intra),\n 44 (CAVLC 4:4:4 Intra)\n");
00119 error (errortext, 500);
00120 }
00121
00122 if ((params->partition_mode) && (params->symbol_mode==CABAC))
00123 {
00124 snprintf(errortext, ET_SIZE, "Data partitioning and CABAC is not supported in any profile.");
00125 error (errortext, 500);
00126 }
00127
00128 if (params->redundant_pic_flag)
00129 {
00130 if (params->ProfileIDC != 66)
00131 {
00132 snprintf(errortext, ET_SIZE, "Redundant pictures are only allowed in Baseline profile (ProfileIDC = 66).");
00133 error (errortext, 500);
00134 }
00135 }
00136
00137 if ((params->partition_mode) && (params->ProfileIDC!=88))
00138 {
00139 snprintf(errortext, ET_SIZE, "Data partitioning is only allowed in Extended profile (ProfileIDC = 88).");
00140 error (errortext, 500);
00141 }
00142
00143 if (params->ChromaIntraDisable && params->FastCrIntraDecision)
00144 {
00145 fprintf( stderr, "\n Warning: ChromaIntraDisable and FastCrIntraDecision cannot be combined together.\n Using only Chroma Intra DC mode.\n");
00146 params->FastCrIntraDecision=0;
00147 }
00148
00149 if ((params->sp_periodicity) && (params->ProfileIDC != 88 ))
00150 {
00151 snprintf(errortext, ET_SIZE, "SP pictures are only allowed in Extended profile (ProfileIDC = 88).");
00152 error (errortext, 500);
00153 }
00154
00155
00156 if (params->ProfileIDC == 66 )
00157 {
00158 if ((params->NumberBFrames || params->BRefPictures==2) && params->PReplaceBSlice == 0)
00159 {
00160 snprintf(errortext, ET_SIZE, "B slices are not allowed in Baseline profile (ProfileIDC = 66).");
00161 error (errortext, 500);
00162 }
00163 if (params->WeightedPrediction)
00164 {
00165 snprintf(errortext, ET_SIZE, "Weighted prediction is not allowed in Baseline profile (ProfileIDC = 66).");
00166 error (errortext, 500);
00167 }
00168 if (params->WeightedBiprediction)
00169 {
00170 snprintf(errortext, ET_SIZE, "Weighted prediction is not allowed in Baseline profile (ProfileIDC = 66).");
00171 error (errortext, 500);
00172 }
00173 if (params->symbol_mode == CABAC)
00174 {
00175 snprintf(errortext, ET_SIZE, "CABAC is not allowed in Baseline profile (ProfileIDC = 66).");
00176 error (errortext, 500);
00177 }
00178 if ((params->PicInterlace) ||(params->MbInterlace))
00179 {
00180 snprintf(errortext, ET_SIZE, "Interlace tools are not allowed in Baseline profile (ProfileIDC = 66).");
00181 error (errortext, 500);
00182 }
00183 if (params->GenerateMultiplePPS != 0)
00184 {
00185 snprintf(errortext, ET_SIZE, "GenerateMultiplePPS is not supported for Baseline profile because it requires enabling Weighted prediction.\n");
00186 error (errortext, 400);
00187 }
00188 }
00189
00190
00191 if (params->ProfileIDC == 77 )
00192 {
00193 if (params->num_slice_groups_minus1)
00194 {
00195 snprintf(errortext, ET_SIZE, "num_slice_groups_minus1>0 (FMO) is not allowed in Main profile (ProfileIDC = 77).");
00196 error (errortext, 500);
00197 }
00198 }
00199
00200
00201 if (params->ProfileIDC == 88 )
00202 {
00203 if (!params->directInferenceFlag)
00204 {
00205 snprintf(errortext, ET_SIZE, "direct_8x8_inference flag must be equal to 1 in Extended profile (ProfileIDC = 88).");
00206 error (errortext, 500);
00207 }
00208
00209 if (params->symbol_mode == CABAC)
00210 {
00211 snprintf(errortext, ET_SIZE, "CABAC is not allowed in Extended profile (ProfileIDC = 88).");
00212 error (errortext, 500);
00213 }
00214 }
00215
00216
00217 if ( params->separate_colour_plane_flag )
00218 {
00219 if( params->yuv_format!=3 )
00220 {
00221 fprintf( stderr, "\nWarning: SeparateColourPlane has only effect in 4:4:4 chroma mode (YUVFormat=3),\n disabling SeparateColourPlane.");
00222 params->separate_colour_plane_flag = 0;
00223 }
00224
00225 if ( params->ChromaMEEnable )
00226 {
00227 snprintf(errortext, ET_SIZE, "\nChromaMEEnable is not allowed when SeparateColourPlane is enabled.");
00228 error (errortext, 500);
00229 }
00230 }
00231
00232
00233 if ( params->ProfileIDC == FREXT_CAVLC444 )
00234 {
00235 if ( params->symbol_mode != CAVLC )
00236 {
00237 snprintf(errortext, ET_SIZE, "\nCABAC is not allowed in CAVLC 4:4:4 Intra profile (ProfileIDC = 44).");
00238 error (errortext, 500);
00239 }
00240 if ( !params->IntraProfile )
00241 {
00242 fprintf (stderr, "\nWarning: ProfileIDC equal to 44 implies an Intra only profile, setting IntraProfile = 1.");
00243 params->IntraProfile = 1;
00244 }
00245 }
00246
00247
00248 if (params->IntraProfile && ( params->ProfileIDC<FREXT_HP && params->ProfileIDC!=FREXT_CAVLC444 ))
00249 {
00250 snprintf(errortext, ET_SIZE, "\nIntraProfile is allowed only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444);
00251 error (errortext, 500);
00252 }
00253
00254 if (params->IntraProfile && !params->idr_period)
00255 {
00256 snprintf(errortext, ET_SIZE, "\nIntraProfile requires IDRPeriod >= 1.");
00257 error (errortext, 500);
00258 }
00259
00260 if (params->IntraProfile && params->intra_period != 1)
00261 {
00262 snprintf(errortext, ET_SIZE, "\nIntraProfile requires IntraPeriod equal 1.");
00263 error (errortext, 500);
00264 }
00265
00266 if (params->IntraProfile && params->num_ref_frames)
00267 {
00268 fprintf( stderr, "\nWarning: Setting NumberReferenceFrames to 0 in IntraProfile.");
00269 params->num_ref_frames = 0;
00270 }
00271
00272 if (params->IntraProfile == 0 && params->num_ref_frames == 0)
00273 {
00274 snprintf(errortext, ET_SIZE, "\nProfiles other than IntraProfile require NumberReferenceFrames > 0.");
00275 error (errortext, 500);
00276 }
00277 }
00278
00279
00280
00281
00282
00283
00284
00285 void LevelCheck(void)
00286 {
00287 unsigned int PicSizeInMbs = ( (params->output.width + img->auto_crop_right) * (params->output.height + img->auto_crop_bottom) ) >> 8;
00288 unsigned int MBProcessingRate = (unsigned int) (PicSizeInMbs * params->output.frame_rate + 0.5);
00289
00290 if ( (params->LevelIDC>=30) && (params->directInferenceFlag==0))
00291 {
00292 fprintf( stderr, "\nWarning: LevelIDC 3.0 and above require direct_8x8_inference to be set to 1. Please check your settings.\n");
00293 params->directInferenceFlag=1;
00294 }
00295 if ( ((params->LevelIDC<21) || (params->LevelIDC>41)) && (params->PicInterlace > 0 || params->MbInterlace > 0) )
00296 {
00297 snprintf(errortext, ET_SIZE, "\nInterlace modes only supported for LevelIDC in the range of 21 and 41. Please check your settings.\n");
00298 error (errortext, 500);
00299 }
00300
00301 if ( PicSizeInMbs > getMaxFs(params->LevelIDC) )
00302 {
00303 snprintf(errortext, ET_SIZE, "\nPicSizeInMbs exceeds maximum allowed size at specified LevelIdc %.1f\n", (float) params->LevelIDC / 10.0);
00304 error (errortext, 500);
00305 }
00306
00307 if (params->IntraProfile && (PicSizeInMbs > 1620) && params->slice_mode != 1)
00308 {
00309 error ("\nIntraProfile with PicSizeInMbs > 1620 requires SliceMode equal 1.", 500);
00310 }
00311
00312 if (params->IntraProfile && (PicSizeInMbs > 1620) && ((unsigned int)params->slice_argument > ( getMaxFs(params->LevelIDC) >> 2 ) ) )
00313 {
00314
00315 snprintf(errortext, ET_SIZE, "\nIntraProfile requires SliceArgument smaller or equal to 1/4 MaxFs at specified LevelIdc %d.", params->LevelIDC);
00316 error (errortext, 500);
00317 }
00318
00319 if ( MBProcessingRate > getMaxMBPS(params->LevelIDC) )
00320 {
00321 snprintf(errortext, ET_SIZE, "\nMB Processing Rate (%d) exceeds maximum allowed processing rate (%d) at specified LevelIdc %.1f\n",
00322 MBProcessingRate, getMaxMBPS(params->LevelIDC), (float) params->LevelIDC / 10.0);
00323 error (errortext, 500);
00324 }
00325 }
00326
00327
00328
00329
00330
00331
00332
00333 void update_mv_limits(ImageParameters *img, byte is_field)
00334 {
00335 memcpy(img->MaxVmvR, LEVELVMVLIMIT[img->LevelIndex], 6 * sizeof(int));
00336 memcpy(img->MaxHmvR, LEVELHMVLIMIT, 6 * sizeof(int));
00337 if (is_field)
00338 {
00339 int i;
00340 for (i = 0; i < 6; i++)
00341 img->MaxVmvR[i] = rshift_rnd(img->MaxVmvR[i], 1);
00342 }
00343 if (params->UseMVLimits)
00344 {
00345 img->MaxVmvR[0] = imax(img->MaxVmvR[0], -(params->SetMVYLimit));
00346 img->MaxVmvR[1] = imin(img->MaxVmvR[1], (params->SetMVYLimit));
00347 img->MaxVmvR[2] = imax(img->MaxVmvR[2], -(params->SetMVYLimit << 1));
00348 img->MaxVmvR[3] = imin(img->MaxVmvR[3], (params->SetMVYLimit << 1));
00349 img->MaxVmvR[4] = imax(img->MaxVmvR[4], -(params->SetMVYLimit << 2));
00350 img->MaxVmvR[5] = imin(img->MaxVmvR[5], (params->SetMVYLimit << 2));
00351
00352 img->MaxHmvR[0] = imax(img->MaxHmvR[0], -(params->SetMVXLimit));
00353 img->MaxHmvR[1] = imin(img->MaxHmvR[1], (params->SetMVXLimit));
00354 img->MaxHmvR[2] = imax(img->MaxHmvR[2], -(params->SetMVXLimit << 1));
00355 img->MaxHmvR[3] = imin(img->MaxHmvR[3], (params->SetMVXLimit << 1));
00356 img->MaxHmvR[4] = imax(img->MaxHmvR[4], -(params->SetMVXLimit << 2));
00357 img->MaxHmvR[5] = imin(img->MaxHmvR[5], (params->SetMVXLimit << 2));
00358 }
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368 void clip_mv_range(ImageParameters *img, int search_range, MotionVector *mv, int res)
00369 {
00370 search_range <<= res;
00371 res <<= 1;
00372
00373 mv->mv_x = iClip3( img->MaxHmvR[0 + res] + search_range, img->MaxHmvR[1 + res] - search_range, mv->mv_x);
00374 mv->mv_y = iClip3( img->MaxVmvR[0 + res] + search_range, img->MaxVmvR[1 + res] - search_range, mv->mv_y);
00375 }
00376
00377
00378
00379
00380
00381
00382
00383 void test_clip_mvs(ImageParameters *img, short mv[2], Boolean write_mb)
00384 {
00385 if ((mv[0] < img->MaxHmvR[4]) || (mv[0] > img->MaxHmvR[5]) || (mv[1] < img->MaxVmvR[4]) || (mv[1] > img->MaxVmvR[5]))
00386 {
00387 if (write_mb == TRUE)
00388 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]);
00389 mv[0] = iClip3( img->MaxHmvR[4], img->MaxHmvR[5], mv[0]);
00390 mv[1] = iClip3( img->MaxVmvR[4], img->MaxVmvR[5], mv[1]);
00391 }
00392 }
00393
00394
00395
00396
00397
00398
00399
00400 int out_of_bounds_mvs(ImageParameters *img, short mv[2])
00401 {
00402 return ((mv[0] < img->MaxHmvR[4]) || (mv[0] > img->MaxHmvR[5]) || (mv[1] < img->MaxVmvR[4]) || (mv[1] > img->MaxVmvR[5]));
00403 }
00404
00405 int InvalidWeightsForBiPrediction(Block8x8Info* b8x8info, int mode)
00406 {
00407 int cur_blk, cur_comp;
00408 int best8x8l0ref, best8x8l1ref;
00409 int weight_sum = 0;
00410 int invalid_mode = 0;
00411 int *wbp0, *wbp1;
00412 for (cur_blk = 0; cur_blk < 4; cur_blk ++)
00413 {
00414 if (b8x8info->best8x8pdir[mode][cur_blk] == 2)
00415 {
00416 best8x8l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
00417 best8x8l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
00418 wbp0 = &wbp_weight[LIST_0][best8x8l0ref][best8x8l1ref][0];
00419 wbp1 = &wbp_weight[LIST_1][best8x8l0ref][best8x8l1ref][0];
00420
00421 for (cur_comp = 0; cur_comp < (active_sps->chroma_format_idc == YUV400 ? 1 : 3) ; cur_comp ++)
00422 {
00423 weight_sum = *wbp0++ + *wbp1++;
00424
00425 if (weight_sum < -128 || weight_sum > 127)
00426 {
00427 invalid_mode = 1;
00428 break;
00429 }
00430 }
00431 if (invalid_mode == 1)
00432 break;
00433 }
00434 }
00435 return invalid_mode;
00436 }
00437
00438 int InvalidMotionVectors(Block8x8Info* b8x8info, int mode)
00439 {
00440 int cur_blk;
00441 int l0ref, l1ref;
00442 int invalid_mode = 0;
00443 int i, j;
00444
00445 if (mode > P8x8)
00446 return invalid_mode;
00447
00448
00449 for (cur_blk = 0; cur_blk < 4; cur_blk ++)
00450 {
00451 i = (cur_blk & 0x01) << 1;
00452 j = (cur_blk >> 1) << 1;
00453 switch (b8x8info->best8x8pdir[mode][cur_blk])
00454 {
00455 case 0:
00456 l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
00457 if (out_of_bounds_mvs(img, img->all_mv [LIST_0][l0ref][mode][j][i]))
00458 {
00459 invalid_mode = 1;
00460 return invalid_mode;
00461 }
00462 break;
00463 case 1:
00464 l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
00465 if (out_of_bounds_mvs(img, img->all_mv [LIST_1][l1ref][mode][j][i]))
00466 {
00467 invalid_mode = 1;
00468 return invalid_mode;
00469 }
00470 break;
00471 case 2:
00472 l0ref = (int) b8x8info->best8x8l0ref[mode][cur_blk];
00473 l1ref = (int) b8x8info->best8x8l1ref[mode][cur_blk];
00474 if (out_of_bounds_mvs(img, img->all_mv [LIST_0][l0ref][mode][j][i]))
00475 {
00476 invalid_mode = 1;
00477 return invalid_mode;
00478 }
00479 if (out_of_bounds_mvs(img, img->all_mv [LIST_1][l1ref][mode][j][i]))
00480 {
00481 invalid_mode = 1;
00482 return invalid_mode;
00483 }
00484 break;
00485 default:
00486 break;
00487 }
00488 }
00489
00490 return invalid_mode;
00491 }
00492
00493 int CheckPredictionParams(pic_parameter_set_rbsp_t *active_pps, Block8x8Info *b8x8info, int mode, int bslice)
00494 {
00495
00496 if (bslice && active_pps->weighted_bipred_idc == 1 && mode < P8x8)
00497 {
00498 if (InvalidWeightsForBiPrediction(b8x8info, mode))
00499 return 0;
00500 }
00501
00502 if (InvalidMotionVectors(b8x8info, mode))
00503 return 0;
00504
00505 return 1;
00506 }