00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #define INCLUDED_BY_CONFIGFILE_C
00060
00061 #include <sys/stat.h>
00062
00063 #include "global.h"
00064 #include "configfile.h"
00065 #include "fmo.h"
00066 #include "conformance.h"
00067 #include "mc_prediction.h"
00068 #include "mv_search.h"
00069 #include "img_io.h"
00070 #include "ratectl.h"
00071
00072 char *GetConfigFileContent (char *Filename);
00073 static void ParseContent (InputParameters *p_Inp, Mapping *Map, char *buf, int bufsize);
00074 static void PatchInp (ImageParameters *p_Img, InputParameters *p_Inp);
00075 static int ParameterNameToMapIndex (Mapping *Map, char *s);
00076 static int InitEncoderParams (Mapping *Map);
00077 static int TestEncoderParams (Mapping *Map, int bitdepth_qp_scale[3]);
00078 static int DisplayEncoderParams (Mapping *Map);
00079
00080 static const int mb_width_cr[4] = {0,8, 8,16};
00081 static const int mb_height_cr[4]= {0,8,16,16};
00082
00083 #define MAX_ITEMS_TO_PARSE 10000
00084
00085
00086
00087
00088
00089
00090
00091
00092 void JMHelpExit (void)
00093 {
00094 fprintf( stderr, "\n lencod [-h] [-d defenc.cfg] {[-f curenc1.cfg]...[-f curencN.cfg]}"
00095 " {[-p EncParam1=EncValue1]..[-p EncParamM=EncValueM]}\n\n"
00096 "## Parameters\n\n"
00097
00098 "## Options\n"
00099 " -h : prints function usage\n"
00100 " -d : use <defenc.cfg> as default file for parameter initializations.\n"
00101 " If not used then file defaults to encoder.cfg in local directory.\n"
00102 " -f : read <curencM.cfg> for reseting selected encoder parameters.\n"
00103 " Multiple files could be used that set different parameters\n"
00104 " -p : Set parameter <EncParamM> to <EncValueM>.\n"
00105 " See default encoder.cfg file for description of all parameters.\n\n"
00106
00107 "## Supported video file formats\n"
00108 " RAW: .yuv -> YUV 4:2:0\n\n"
00109
00110 "## Examples of usage:\n"
00111 " lencod\n"
00112 " lencod -h\n"
00113 " lencod -d default.cfg\n"
00114 " lencod -f curenc1.cfg\n"
00115 " lencod -f curenc1.cfg -p InputFile=\"e:\\data\\container_qcif_30.yuv\" -p SourceWidth=176 -p SourceHeight=144\n"
00116 " lencod -f curenc1.cfg -p FramesToBeEncoded=30 -p QPISlice=28 -p QPPSlice=28 -p QPBSlice=30\n");
00117
00118 exit(-1);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128 int64 getVideoFileSize(int video_file)
00129 {
00130 int64 fsize;
00131
00132 lseek(video_file, 0, SEEK_END);
00133 fsize = tell((int) video_file);
00134 lseek(video_file, 0, SEEK_SET);
00135
00136 return fsize;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 static void getNumberOfFrames (InputParameters *p_Inp, VideoDataFile *input_file)
00147 {
00148 int64 fsize = getVideoFileSize(input_file->f_num);
00149 int64 isize = (int64) p_Inp->source.size;
00150 int maxBitDepth = imax(p_Inp->source.bit_depth[0], p_Inp->source.bit_depth[1]);
00151
00152 isize <<= (maxBitDepth > 8)? 1: 0;
00153 p_Inp->no_frames = (int) (((fsize - p_Inp->infile_header)/ isize) - p_Inp->start_frame);
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163 static void updateMaxValue(FrameFormat *format)
00164 {
00165 format->max_value[0] = (1 << format->bit_depth[0]) - 1;
00166 format->max_value_sq[0] = format->max_value[0] * format->max_value[0];
00167 format->max_value[1] = (1 << format->bit_depth[1]) - 1;
00168 format->max_value_sq[1] = format->max_value[1] * format->max_value[1];
00169 format->max_value[2] = (1 << format->bit_depth[2]) - 1;
00170 format->max_value_sq[2] = format->max_value[2] * format->max_value[2];
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180 static void updateOutFormat(InputParameters *p_Inp)
00181 {
00182 FrameFormat *output = &p_Inp->output;
00183 FrameFormat *source = &p_Inp->source;
00184 output->yuv_format = (ColorFormat) p_Inp->yuv_format;
00185 source->yuv_format = (ColorFormat) p_Inp->yuv_format;
00186
00187 if (p_Inp->src_resize == 0)
00188 {
00189 output->width = source->width;
00190 output->height = source->height;
00191 }
00192
00193 if (p_Inp->yuv_format == YUV400)
00194 {
00195 source->bit_depth[1] = 8;
00196 output->bit_depth[1] = 8;
00197 source->width_cr = 0;
00198 source->height_cr = 0;
00199 output->width_cr = 0;
00200 output->height_cr = 0;
00201 }
00202 else
00203 {
00204 source->width_cr = (source->width * mb_width_cr [output->yuv_format]) >> 4;
00205 source->height_cr = (source->height * mb_height_cr[output->yuv_format]) >> 4;
00206 output->width_cr = (output->width * mb_width_cr [output->yuv_format]) >> 4;
00207 output->height_cr = (output->height * mb_height_cr[output->yuv_format]) >> 4;
00208 }
00209
00210
00211 source->size_cmp[0] = source->width * source->height;
00212 source->size_cmp[1] = source->width_cr * source->height_cr;
00213 source->size_cmp[2] = source->size_cmp[1];
00214 source->size = source->size_cmp[0] + source->size_cmp[1] + source->size_cmp[2];
00215 source->mb_width = source->width / MB_BLOCK_SIZE;
00216 source->mb_height = source->height / MB_BLOCK_SIZE;
00217 source->pic_unit_size_on_disk = (imax(source->bit_depth[0], source->bit_depth[1]) > 8) ? 16 : 8;
00218 source->pic_unit_size_shift3 = source->pic_unit_size_on_disk >> 3;
00219
00220
00221
00222 output->size_cmp[0] = output->width * output->height;
00223 output->size_cmp[1] = output->width_cr * output->height_cr;
00224 output->size_cmp[2] = output->size_cmp[1];
00225 output->size = output->size_cmp[0] + output->size_cmp[1] + output->size_cmp[2];
00226 output->mb_width = output->width / MB_BLOCK_SIZE;
00227 output->mb_height = output->height / MB_BLOCK_SIZE;
00228
00229
00230
00231 source->bit_depth[2] = source->bit_depth[1];
00232 output->bit_depth[2] = output->bit_depth[1];
00233
00234
00235 if (p_Inp->src_BitDepthRescale == 0)
00236 {
00237 output->bit_depth[0] = source->bit_depth[0];
00238 output->bit_depth[1] = source->bit_depth[1];
00239 output->bit_depth[2] = source->bit_depth[2];
00240 }
00241 output->pic_unit_size_on_disk = (imax(output->bit_depth[0], output->bit_depth[1]) > 8) ? 16 : 8;
00242 output->pic_unit_size_shift3 = output->pic_unit_size_on_disk >> 3;
00243
00244 output->frame_rate = source->frame_rate / (p_Inp->frame_skip + 1);
00245 output->color_model = source->color_model;
00246
00247 updateMaxValue(source);
00248 updateMaxValue(output);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 void Configure (ImageParameters *p_Img, InputParameters *p_Inp, int ac, char *av[])
00267 {
00268 char *content = NULL;
00269 int CLcount, ContentLen, NumberParams;
00270 char *filename=DEFAULTCONFIGFILENAME;
00271
00272 if (ac==2)
00273 {
00274 if (0 == strncmp (av[1], "-v", 2))
00275 {
00276 printf("JM " JM ": compiled " __DATE__ " " __TIME__ "\n");
00277 exit(-1);
00278 }
00279
00280 if (0 == strncmp (av[1], "-h", 2))
00281 {
00282 JMHelpExit();
00283 }
00284 }
00285
00286 memset (&cfgparams, 0, sizeof (InputParameters));
00287
00288 printf ("Setting Default Parameters...\n");
00289 InitEncoderParams(Map);
00290
00291
00292 CLcount = 1;
00293
00294 if (ac>=3)
00295 {
00296 if (0 == strncmp (av[1], "-d", 2))
00297 {
00298 filename=av[2];
00299 CLcount = 3;
00300 }
00301 if (0 == strncmp (av[1], "-h", 2))
00302 {
00303 JMHelpExit();
00304 }
00305 }
00306 printf ("Parsing Configfile %s", filename);
00307 content = GetConfigFileContent (filename);
00308 if (NULL==content)
00309 error (errortext, 300);
00310 ParseContent (p_Inp, Map, content, strlen(content));
00311 printf ("\n");
00312 free (content);
00313
00314
00315
00316 while (CLcount < ac)
00317 {
00318 if (0 == strncmp (av[CLcount], "-h", 2))
00319 {
00320 JMHelpExit();
00321 }
00322
00323 if (0 == strncmp (av[CLcount], "-f", 2) || 0 == strncmp (av[CLcount], "-F", 2))
00324 {
00325 content = GetConfigFileContent (av[CLcount+1]);
00326 if (NULL==content)
00327 error (errortext, 300);
00328 printf ("Parsing Configfile %s", av[CLcount+1]);
00329 ParseContent (p_Inp, Map, content, strlen (content));
00330 printf ("\n");
00331 free (content);
00332 CLcount += 2;
00333 }
00334 else
00335 {
00336 if (0 == strncmp (av[CLcount], "-p", 2) || 0 == strncmp (av[CLcount], "-P", 2))
00337 {
00338
00339
00340
00341 ++CLcount;
00342 ContentLen = 0;
00343 NumberParams = CLcount;
00344
00345
00346 while (NumberParams < ac && av[NumberParams][0] != '-')
00347 ContentLen += strlen (av[NumberParams++]);
00348 ContentLen += 1000;
00349
00350
00351 if ((content = malloc (ContentLen))==NULL) no_mem_exit("Configure: content");;
00352 content[0] = '\0';
00353
00354
00355
00356 while (CLcount < NumberParams)
00357 {
00358 char *source = &av[CLcount][0];
00359 char *destin = &content[strlen (content)];
00360
00361 while (*source != '\0')
00362 {
00363 if (*source == '=')
00364 {
00365 *destin++=' '; *destin++='='; *destin++=' ';
00366 }
00367 else
00368 *destin++=*source;
00369 source++;
00370 }
00371 *destin = '\0';
00372 CLcount++;
00373 }
00374 printf ("Parsing command line string '%s'", content);
00375 ParseContent (p_Inp, Map, content, strlen(content));
00376 free (content);
00377 printf ("\n");
00378 }
00379 else
00380 {
00381 snprintf (errortext, ET_SIZE, "Error in command line, ac %d, around string '%s', missing -f or -p parameters?", CLcount, av[CLcount]);
00382 error (errortext, 300);
00383 }
00384 }
00385 }
00386 printf ("\n");
00387 PatchInp(p_Img, p_Inp);
00388
00389 memcpy (&cfgparams, p_Inp, sizeof (InputParameters));
00390
00391 if (p_Inp->DisplayEncParams)
00392 DisplayEncoderParams(Map);
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 char *GetConfigFileContent (char *Filename)
00408 {
00409 long FileSize;
00410 FILE *f;
00411 char *buf;
00412
00413 if (NULL == (f = fopen (Filename, "r")))
00414 {
00415 snprintf (errortext, ET_SIZE, "Cannot open configuration file %s.", Filename);
00416 return NULL;
00417 }
00418
00419 if (0 != fseek (f, 0, SEEK_END))
00420 {
00421 snprintf (errortext, ET_SIZE, "Cannot fseek in configuration file %s.", Filename);
00422 return NULL;
00423 }
00424
00425 FileSize = ftell (f);
00426 if (FileSize < 0 || FileSize > 100000)
00427 {
00428 snprintf (errortext, ET_SIZE, "Unreasonable Filesize %ld reported by ftell for configuration file %s.", FileSize, Filename);
00429 return NULL;
00430 }
00431 if (0 != fseek (f, 0, SEEK_SET))
00432 {
00433 snprintf (errortext, ET_SIZE, "Cannot fseek in configuration file %s.", Filename);
00434 return NULL;
00435 }
00436
00437 if ((buf = malloc (FileSize + 1))==NULL) no_mem_exit("GetConfigFileContent: buf");
00438
00439
00440
00441
00442
00443 FileSize = fread (buf, 1, FileSize, f);
00444 buf[FileSize] = '\0';
00445
00446
00447 fclose (f);
00448 return buf;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 void ParseContent (InputParameters *p_Inp, Mapping *Map, char *buf, int bufsize)
00469 {
00470 char *items[MAX_ITEMS_TO_PARSE] = {NULL};
00471 int MapIdx;
00472 int item = 0;
00473 int InString = 0, InItem = 0;
00474 char *p = buf;
00475 char *bufend = &buf[bufsize];
00476 int IntContent;
00477 double DoubleContent;
00478 int i;
00479
00480
00481
00482
00483 while (p < bufend)
00484 {
00485 switch (*p)
00486 {
00487 case 13:
00488 ++p;
00489 break;
00490 case '#':
00491 *p = '\0';
00492 while (*p != '\n' && p < bufend)
00493 ++p;
00494 InString = 0;
00495 InItem = 0;
00496 break;
00497 case '\n':
00498 InItem = 0;
00499 InString = 0;
00500 *p++='\0';
00501 break;
00502 case ' ':
00503 case '\t':
00504 if (InString)
00505 p++;
00506 else
00507 {
00508 *p++ = '\0';
00509 InItem = 0;
00510 }
00511 break;
00512
00513 case '"':
00514 *p++ = '\0';
00515 if (!InString)
00516 {
00517 items[item++] = p;
00518 InItem = ~InItem;
00519 }
00520 else
00521 InItem = 0;
00522 InString = ~InString;
00523 break;
00524
00525 default:
00526 if (!InItem)
00527 {
00528 items[item++] = p;
00529 InItem = ~InItem;
00530 }
00531 p++;
00532 }
00533 }
00534
00535 item--;
00536
00537 for (i=0; i<item; i+= 3)
00538 {
00539 if (0 > (MapIdx = ParameterNameToMapIndex (Map, items[i])))
00540 {
00541
00542
00543 printf ("\n\tParsing error in config file: Parameter Name '%s' not recognized.", items[i]);
00544 continue;
00545 }
00546 if (strcasecmp ("=", items[i+1]))
00547 {
00548 snprintf (errortext, ET_SIZE, " Parsing error in config file: '=' expected as the second token in each line.");
00549 error (errortext, 300);
00550 }
00551
00552
00553
00554 switch (Map[MapIdx].Type)
00555 {
00556 case 0:
00557 if (1 != sscanf (items[i+2], "%d", &IntContent))
00558 {
00559 snprintf (errortext, ET_SIZE, " Parsing error: Expected numerical value for Parameter of %s, found '%s'.", items[i], items[i+2]);
00560 error (errortext, 300);
00561 }
00562 * (int *) (Map[MapIdx].Place) = IntContent;
00563 printf (".");
00564 break;
00565 case 1:
00566 if (items[i + 2] == NULL)
00567 memset((char *) Map[MapIdx].Place, 0, Map[MapIdx].char_size);
00568 else
00569 strncpy ((char *) Map[MapIdx].Place, items [i+2], Map[MapIdx].char_size);
00570 printf (".");
00571 break;
00572 case 2:
00573 if (1 != sscanf (items[i+2], "%lf", &DoubleContent))
00574 {
00575 snprintf (errortext, ET_SIZE, " Parsing error: Expected numerical value for Parameter of %s, found '%s'.", items[i], items[i+2]);
00576 error (errortext, 300);
00577 }
00578 * (double *) (Map[MapIdx].Place) = DoubleContent;
00579 printf (".");
00580 break;
00581 default:
00582 error ("Unknown value type in the map definition of configfile.h",-1);
00583 }
00584 }
00585 memcpy (p_Inp, &cfgparams, sizeof (InputParameters));
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601 static int ParameterNameToMapIndex (Mapping *Map, char *s)
00602 {
00603 int i = 0;
00604
00605 while (Map[i].TokenName != NULL)
00606 if (0==strcasecmp (Map[i].TokenName, s))
00607 return i;
00608 else
00609 i++;
00610 return -1;
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 static int InitEncoderParams(Mapping *Map)
00622 {
00623 int i = 0;
00624
00625 while (Map[i].TokenName != NULL)
00626 {
00627 if (Map[i].Type == 0)
00628 * (int *) (Map[i].Place) = (int) Map[i].Default;
00629 else if (Map[i].Type == 2)
00630 * (double *) (Map[i].Place) = Map[i].Default;
00631 i++;
00632 }
00633 return -1;
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 static int TestEncoderParams(Mapping *Map, int bitdepth_qp_scale[3])
00645 {
00646 int i = 0;
00647
00648 while (Map[i].TokenName != NULL)
00649 {
00650 if (Map[i].param_limits == 1)
00651 {
00652 if (Map[i].Type == 0)
00653 {
00654 if ( * (int *) (Map[i].Place) < (int) Map[i].min_limit || * (int *) (Map[i].Place) > (int) Map[i].max_limit )
00655 {
00656 snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should be in [%d, %d] range.", Map[i].TokenName, (int) Map[i].min_limit,(int)Map[i].max_limit );
00657 error (errortext, 400);
00658 }
00659
00660 }
00661 else if (Map[i].Type == 2)
00662 {
00663 if ( * (double *) (Map[i].Place) < Map[i].min_limit || * (double *) (Map[i].Place) > Map[i].max_limit )
00664 {
00665 snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should be in [%.2f, %.2f] range.", Map[i].TokenName,Map[i].min_limit ,Map[i].max_limit );
00666 error (errortext, 400);
00667 }
00668 }
00669 }
00670 else if (Map[i].param_limits == 2)
00671 {
00672 if (Map[i].Type == 0)
00673 {
00674 if ( * (int *) (Map[i].Place) < (int) Map[i].min_limit )
00675 {
00676 snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should not be smaller than %d.", Map[i].TokenName, (int) Map[i].min_limit);
00677 error (errortext, 400);
00678 }
00679 }
00680 else if (Map[i].Type == 2)
00681 {
00682 if ( * (double *) (Map[i].Place) < Map[i].min_limit )
00683 {
00684 snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should not be smaller than %2.f.", Map[i].TokenName,Map[i].min_limit);
00685 error (errortext, 400);
00686 }
00687 }
00688 }
00689 else if (Map[i].param_limits == 3)
00690 {
00691
00692 if (Map[i].Type == 0)
00693 {
00694 int cur_qp = * (int *) (Map[i].Place);
00695 int min_qp = (int) (Map[i].min_limit - bitdepth_qp_scale[0]);
00696 int max_qp = (int) Map[i].max_limit;
00697
00698 if (( cur_qp < min_qp ) || ( cur_qp > max_qp ))
00699 {
00700 snprintf(errortext, ET_SIZE, "Error in input parameter %s. Check configuration file. Value should be in [%d, %d] range.", Map[i].TokenName, min_qp, max_qp );
00701 error (errortext, 400);
00702 }
00703 }
00704 }
00705
00706 i++;
00707 }
00708 return -1;
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 static int DisplayEncoderParams(Mapping *Map)
00722 {
00723 int i = 0;
00724
00725 printf("******************************************************\n");
00726 printf("* Encoder Parameters *\n");
00727 printf("******************************************************\n");
00728 while (Map[i].TokenName != NULL)
00729 {
00730 if (Map[i].Type == 0)
00731 printf("Parameter %s = %d\n",Map[i].TokenName,* (int *) (Map[i].Place));
00732 else if (Map[i].Type == 1)
00733 printf("Parameter %s = ""%s""\n",Map[i].TokenName,(char *) (Map[i].Place));
00734 else if (Map[i].Type == 2)
00735 printf("Parameter %s = %.2f\n",Map[i].TokenName,* (double *) (Map[i].Place));
00736 i++;
00737 }
00738 printf("******************************************************\n");
00739 return -1;
00740 }
00741
00742
00743
00744
00745
00746
00747
00748 unsigned CeilLog2( unsigned uiVal)
00749 {
00750 unsigned uiTmp = uiVal-1;
00751 unsigned uiRet = 0;
00752
00753 while( uiTmp != 0 )
00754 {
00755 uiTmp >>= 1;
00756 uiRet++;
00757 }
00758 return uiRet;
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768 void read_slice_group_info(ImageParameters *p_Img, InputParameters *p_Inp)
00769 {
00770 FILE * sgfile=NULL;
00771 int i;
00772 int ret;
00773
00774 if ((p_Inp->slice_group_map_type != 0) && (p_Inp->slice_group_map_type != 2) && (p_Inp->slice_group_map_type != 6))
00775 {
00776
00777 return;
00778 }
00779
00780
00781 if (strlen (p_Inp->SliceGroupConfigFileName) <= 1)
00782 error ("No slice group config file name specified", 500);
00783
00784
00785 sgfile = fopen(p_Inp->SliceGroupConfigFileName,"r");
00786
00787 if ( NULL==sgfile )
00788 {
00789 snprintf(errortext, ET_SIZE, "Error opening slice group file %s", p_Inp->SliceGroupConfigFileName);
00790 error (errortext, 500);
00791 }
00792
00793 switch (p_Inp->slice_group_map_type)
00794 {
00795 case 0:
00796 p_Inp->run_length_minus1=(int *)malloc(sizeof(int)*(p_Inp->num_slice_groups_minus1+1));
00797 if ( NULL==p_Inp->run_length_minus1 )
00798 {
00799 fclose(sgfile);
00800 no_mem_exit("PatchInp: p_Inp->run_length_minus1");
00801 }
00802
00803
00804 for(i=0;i<=p_Inp->num_slice_groups_minus1;i++)
00805 {
00806 ret = fscanf(sgfile,"%d",(p_Inp->run_length_minus1+i));
00807 if ( 1!=ret )
00808 {
00809 fclose(sgfile);
00810 snprintf(errortext, ET_SIZE, "Error while reading slice group config file (line %d)", i+1);
00811 error (errortext, 500);
00812 }
00813
00814 ret = fscanf(sgfile,"%*[^\n]");
00815 }
00816 break;
00817
00818 case 2:
00819 p_Inp->top_left=(int *)malloc(sizeof(int)*p_Inp->num_slice_groups_minus1);
00820 p_Inp->bottom_right=(int *)malloc(sizeof(int)*p_Inp->num_slice_groups_minus1);
00821
00822 if (NULL==p_Inp->top_left)
00823 {
00824 fclose(sgfile);
00825 no_mem_exit("PatchInp: p_Inp->top_left");
00826 }
00827
00828 if (NULL==p_Inp->bottom_right)
00829 {
00830 fclose(sgfile);
00831 no_mem_exit("PatchInp: p_Inp->bottom_right");
00832 }
00833
00834
00835 for(i=0;i<p_Inp->num_slice_groups_minus1;i++)
00836 {
00837 ret = fscanf(sgfile,"%d",(p_Inp->top_left+i));
00838 if ( 1!=ret )
00839 {
00840 fclose(sgfile);
00841 snprintf(errortext, ET_SIZE, "Error while reading slice group config file (line %d)", 2*i +1);
00842 error (errortext, 500);
00843 }
00844
00845 ret = fscanf(sgfile,"%*[^\n]");
00846 ret = fscanf(sgfile,"%d",(p_Inp->bottom_right+i));
00847 if ( 1!=ret )
00848 {
00849 fclose(sgfile);
00850 snprintf(errortext, ET_SIZE, "Error while reading slice group config file (line %d)", 2*i + 2);
00851 error (errortext, 500);
00852 }
00853
00854 ret = fscanf(sgfile,"%*[^\n]");
00855 }
00856 break;
00857 case 6:
00858 {
00859 int tmp;
00860 int frame_mb_only;
00861 int mb_width, mb_height, mapunit_height;
00862
00863 frame_mb_only = !(p_Inp->PicInterlace || p_Inp->MbInterlace);
00864 mb_width = (p_Inp->output.width + p_Img->auto_crop_right)>>4;
00865 mb_height = (p_Inp->output.height + p_Img->auto_crop_bottom)>>4;
00866 mapunit_height = mb_height / (2-frame_mb_only);
00867
00868 p_Inp->slice_group_id=(byte * ) malloc(sizeof(byte)*mapunit_height*mb_width);
00869 if (NULL==p_Inp->slice_group_id)
00870 {
00871 fclose(sgfile);
00872 no_mem_exit("PatchInp: p_Inp->slice_group_id");
00873 }
00874
00875
00876 for (i=0;i<mapunit_height*mb_width;i++)
00877 {
00878 ret = fscanf(sgfile,"%d", &tmp);
00879 p_Inp->slice_group_id[i]= (byte) tmp;
00880 if ( 1!=ret )
00881 {
00882 fclose(sgfile);
00883 snprintf(errortext, ET_SIZE, "Error while reading slice group config file (line %d)", i + 1);
00884 error (errortext, 500);
00885 }
00886 if ( *(p_Inp->slice_group_id+i) > p_Inp->num_slice_groups_minus1 )
00887 {
00888 fclose(sgfile);
00889 snprintf(errortext, ET_SIZE, "Error while reading slice group config file: slice_group_id not allowed (line %d)", i + 1);
00890 error (errortext, 500);
00891 }
00892
00893 ret = fscanf(sgfile,"%*[^\n]");
00894 }
00895 }
00896 break;
00897 default:
00898
00899 error ("Wrong slice group type while reading config file", 500);
00900 break;
00901 }
00902
00903
00904 fclose(sgfile);
00905 }
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919 static void compute_frameno_params(InputParameters *p_Inp)
00920 {
00921 p_Inp->last_frame = 0;
00922 if (p_Inp->idr_period && p_Inp->EnableIDRGOP)
00923 {
00924 if (p_Inp->idr_period == 1)
00925 {
00926 p_Inp->no_frm_base = p_Inp->no_frames;
00927 }
00928 else
00929 {
00930 int gop_size = (p_Inp->idr_period - 1) * (p_Inp->NumberBFrames + 1) + 1;
00931 int idr_gops = p_Inp->no_frames /gop_size;
00932 int rem_frames = p_Inp->no_frames - idr_gops * gop_size;
00933 int last_b_groups = ((rem_frames > 0) + (rem_frames + p_Inp->NumberBFrames - 1)/ (p_Inp->NumberBFrames + 1));
00934 int last_frame = (rem_frames) - last_b_groups * (p_Inp->NumberBFrames + 1);
00935 p_Inp->no_frm_base = idr_gops * p_Inp->idr_period + last_b_groups;
00936
00937 if (last_frame)
00938 p_Inp->last_frame = (p_Inp->no_frames - 1) * (p_Inp->frame_skip + 1);
00939 }
00940 }
00941 else
00942 {
00943 p_Inp->no_frm_base = (int) (p_Inp->no_frames + p_Inp->NumberBFrames) / (1 + p_Inp->NumberBFrames);
00944
00945 if ((p_Inp->no_frm_base - 1)* (1 + p_Inp->NumberBFrames) + 1 < p_Inp->no_frames)
00946 p_Inp->last_frame = (p_Inp->no_frames - 1) * (p_Inp->frame_skip + 1);
00947
00948 if (p_Inp->last_frame > 0)
00949 p_Inp->no_frm_base = 1 + (p_Inp->last_frame + p_Inp->NumberBFrames) / (p_Inp->NumberBFrames + 1);
00950 }
00951 }
00952
00953
00954
00955
00956
00957
00958
00959 static void PatchInp (ImageParameters *p_Img, InputParameters *p_Inp)
00960 {
00961 int i;
00962 int storedBplus1;
00963 int bitdepth_qp_scale[3];
00964
00965 if (p_Inp->src_BitDepthRescale)
00966 {
00967 bitdepth_qp_scale [0] = 6*(p_Inp->output.bit_depth[0] - 8);
00968 bitdepth_qp_scale [1] = 6*(p_Inp->output.bit_depth[1] - 8);
00969 bitdepth_qp_scale [2] = 6*(p_Inp->output.bit_depth[2] - 8);
00970 }
00971 else
00972 {
00973 bitdepth_qp_scale [0] = 6*(p_Inp->source.bit_depth[0] - 8);
00974 bitdepth_qp_scale [1] = 6*(p_Inp->source.bit_depth[1] - 8);
00975 bitdepth_qp_scale [2] = 6*(p_Inp->source.bit_depth[2] - 8);
00976 }
00977
00978 TestEncoderParams(Map, bitdepth_qp_scale);
00979
00980 if (p_Inp->source.frame_rate == 0.0)
00981 p_Inp->source.frame_rate = (double) INIT_FRAME_RATE;
00982
00983 ParseVideoType(&p_Inp->input_file1);
00984 ParseFrameNoFormatFromString (&p_Inp->input_file1);
00985
00986
00987 if (p_Inp->source.width == 0 || p_Inp->source.height == 0)
00988 {
00989 if (ParseSizeFromString (&p_Inp->input_file1, &(p_Inp->source.width), &(p_Inp->source.height), &(p_Inp->source.frame_rate)) == 0)
00990 {
00991 snprintf(errortext, ET_SIZE, "File name does not contain resolution information.");
00992 error (errortext, 500);
00993 }
00994 }
00995
00996 #if (!ENABLE_FIELD_CTX)
00997 if ( (p_Inp->PicInterlace || p_Inp->MbInterlace) && p_Inp->symbol_mode )
00998 {
00999 snprintf(errortext, ET_SIZE, "Recompile with ENABLE_FIELD_CTX set to one to enable interlaced coding with CABAC.");
01000 error (errortext, 500);
01001 }
01002 #endif
01003 #if (!ENABLE_HIGH444_CTX)
01004 if ( p_Inp->ProfileIDC == 244 && p_Inp->symbol_mode )
01005 {
01006 snprintf(errortext, ET_SIZE, "Recompile with ENABLE_HIGH444_CTX set to one to enable the High 4:4:4 Profile with CABAC.");
01007 error (errortext, 500);
01008 }
01009 #endif
01010
01011
01012 p_Inp->input_file1.format = p_Inp->source;
01013
01014
01015 if (p_Inp->idr_period && p_Inp->intra_delay && p_Inp->idr_period <= p_Inp->intra_delay)
01016 {
01017 snprintf(errortext, ET_SIZE, " IntraDelay cannot be larger than or equal to IDRPeriod.");
01018 error (errortext, 500);
01019 }
01020
01021 if (p_Inp->idr_period && p_Inp->intra_delay && p_Inp->EnableIDRGOP == 0)
01022 {
01023 snprintf(errortext, ET_SIZE, " IntraDelay can only be used with only 1 IDR or with EnableIDRGOP=1.");
01024 error (errortext, 500);
01025 }
01026
01027 if (p_Inp->idr_period && p_Inp->intra_delay && p_Inp->adaptive_idr_period)
01028 {
01029 snprintf(errortext, ET_SIZE, " IntraDelay can not be used with AdaptiveIDRPeriod.");
01030 error (errortext, 500);
01031 }
01032
01033
01034 p_Inp->jumpd = (p_Inp->NumberBFrames + 1) * (p_Inp->frame_skip + 1) - 1;
01035
01036 updateOutFormat(p_Inp);
01037
01038 if (p_Inp->no_frames == -1)
01039 {
01040 OpenFiles(&p_Inp->input_file1);
01041 getNumberOfFrames(p_Inp, &p_Inp->input_file1);
01042 CloseFiles(&p_Inp->input_file1);
01043 }
01044
01045
01046
01047 if (p_Inp->NumberBFrames)
01048 {
01049 p_Inp->intra_period = (p_Inp->intra_period) / (p_Inp->NumberBFrames + 1);
01050 if (p_Inp->EnableIDRGOP == 1)
01051 p_Inp->idr_period = (p_Inp->idr_period + p_Inp->NumberBFrames) / (p_Inp->NumberBFrames + 1);
01052 else
01053 p_Inp->idr_period = (p_Inp->idr_period) / (p_Inp->NumberBFrames + 1);
01054 }
01055
01056
01057
01058 compute_frameno_params(p_Inp);
01059
01060 storedBplus1 = (p_Inp->BRefPictures ) ? p_Inp->NumberBFrames + 1: 1;
01061
01062 if (p_Inp->Log2MaxFNumMinus4 == -1)
01063 {
01064 p_Img->log2_max_frame_num_minus4 = iClip3(0,12, (int) (CeilLog2(p_Inp->no_frm_base * storedBplus1) - 4));
01065 }
01066 else
01067 p_Img->log2_max_frame_num_minus4 = p_Inp->Log2MaxFNumMinus4;
01068
01069 if (p_Img->log2_max_frame_num_minus4 == 0 && p_Inp->num_ref_frames == 16)
01070 {
01071 snprintf(errortext, ET_SIZE, " NumberReferenceFrames=%d and Log2MaxFNumMinus4=%d may lead to an invalid value of frame_num.", p_Inp->num_ref_frames, p_Inp-> Log2MaxFNumMinus4);
01072 error (errortext, 500);
01073 }
01074
01075
01076 if (p_Inp->Log2MaxPOCLsbMinus4 == - 1)
01077 p_Img->log2_max_pic_order_cnt_lsb_minus4 = iClip3(0,12, (int) (CeilLog2( 2 * p_Inp->no_frm_base * (p_Inp->jumpd + 1)) - 4));
01078 else
01079 p_Img->log2_max_pic_order_cnt_lsb_minus4 = p_Inp->Log2MaxPOCLsbMinus4;
01080
01081
01082 if (((1<<(p_Img->log2_max_pic_order_cnt_lsb_minus4 + 3)) < p_Inp->jumpd * 4) && p_Inp->Log2MaxPOCLsbMinus4 != -1)
01083 error("log2_max_pic_order_cnt_lsb_minus4 might not be sufficient for encoding. Increase value.",400);
01084
01085 if (p_Inp->no_frames < 1)
01086 {
01087 snprintf(errortext, ET_SIZE, "Not enough frames to encode (%d)", p_Inp->no_frames);
01088 error (errortext, 500);
01089 }
01090
01091
01092 if(p_Inp->NumberBFrames && p_Inp->direct_spatial_mv_pred_flag != DIR_SPATIAL && p_Inp->direct_spatial_mv_pred_flag != DIR_TEMPORAL)
01093 {
01094 snprintf(errortext, ET_SIZE, "Unsupported direct mode=%d, use TEMPORAL=0 or SPATIAL=1", p_Inp->direct_spatial_mv_pred_flag);
01095 error (errortext, 400);
01096 }
01097
01098 if (p_Inp->PicInterlace>0 || p_Inp->MbInterlace>0)
01099 {
01100 if (p_Inp->directInferenceFlag==0)
01101 printf("\nWarning: DirectInferenceFlag set to 1 due to interlace coding.");
01102 p_Inp->directInferenceFlag = 1;
01103 }
01104
01105 if (strlen (p_Inp->ReconFile) > 0 && (p_Img->p_dec = open(p_Inp->ReconFile, OPENFLAGS_WRITE, OPEN_PERMISSIONS))==-1)
01106 {
01107 snprintf(errortext, ET_SIZE, "Error open file %s", p_Inp->ReconFile);
01108 error (errortext, 500);
01109 }
01110
01111 #if TRACE
01112 if (strlen (p_Inp->TraceFile) > 0 && (p_Enc->p_trace = fopen(p_Inp->TraceFile,"w"))==NULL)
01113 {
01114 snprintf(errortext, ET_SIZE, "Error open file %s", p_Inp->TraceFile);
01115 error (errortext, 500);
01116 }
01117 #endif
01118
01119 if ((p_Inp->output.width & 0x0F) != 0)
01120 {
01121 p_Img->auto_crop_right = 16 - (p_Inp->output.width & 0x0F);
01122 }
01123 else
01124 {
01125 p_Img->auto_crop_right = 0;
01126 }
01127
01128 if (p_Inp->PicInterlace || p_Inp->MbInterlace)
01129 {
01130 if ((p_Inp->output.height & 0x01) != 0)
01131 {
01132 error ("even number of lines required for interlaced coding", 500);
01133 }
01134
01135 if ((p_Inp->output.height & 0x1F) != 0)
01136 {
01137 p_Img->auto_crop_bottom = 32 - (p_Inp->output.height & 0x1F);
01138 }
01139 else
01140 {
01141 p_Img->auto_crop_bottom=0;
01142 }
01143 }
01144 else
01145 {
01146 if ((p_Inp->output.height & 0x0F) != 0)
01147 {
01148 p_Img->auto_crop_bottom = 16 - (p_Inp->output.height & 0x0F);
01149 }
01150 else
01151 {
01152 p_Img->auto_crop_bottom = 0;
01153 }
01154 }
01155 if (p_Img->auto_crop_bottom || p_Img->auto_crop_right)
01156 {
01157 fprintf (stderr, "Warning: Automatic cropping activated: Coded frame Size: %dx%d\n",
01158 p_Inp->output.width + p_Img->auto_crop_right, p_Inp->output.height + p_Img->auto_crop_bottom);
01159 }
01160
01161 if ((p_Inp->slice_mode == 1)&&(p_Inp->MbInterlace != 0))
01162 {
01163 if ((p_Inp->slice_argument & 0x01)!=0)
01164 {
01165 fprintf ( stderr, "Warning: slice border within macroblock pair. ");
01166 if (p_Inp->slice_argument > 1)
01167 {
01168 p_Inp->slice_argument--;
01169 }
01170 else
01171 {
01172 p_Inp->slice_argument++;
01173 }
01174 fprintf ( stderr, "Using %d MBs per slice.\n", p_Inp->slice_argument);
01175 }
01176 }
01177
01178
01179 if ( 0 != p_Inp->num_slice_groups_minus1 )
01180 {
01181 read_slice_group_info(p_Img, p_Inp);
01182 }
01183
01184 if (p_Inp->WPMCPrecision && (p_Inp->RDPictureDecision != 1 || p_Inp->GenerateMultiplePPS != 1) )
01185 {
01186 snprintf(errortext, ET_SIZE, "WPMCPrecision requires both RDPictureDecision=1 and GenerateMultiplePPS=1.\n");
01187 error (errortext, 400);
01188 }
01189 if (p_Inp->WPMCPrecision && p_Inp->WPMCPrecFullRef && p_Inp->num_ref_frames < 16 )
01190 {
01191 p_Inp->num_ref_frames++;
01192 if ( p_Inp->P_List0_refs )
01193 p_Inp->P_List0_refs++;
01194 else
01195 p_Inp->P_List0_refs = p_Inp->num_ref_frames;
01196 if ( p_Inp->B_List0_refs )
01197 p_Inp->B_List0_refs++;
01198 else
01199 p_Inp->B_List0_refs = p_Inp->num_ref_frames;
01200 if ( p_Inp->B_List1_refs )
01201 p_Inp->B_List1_refs++;
01202 else
01203 p_Inp->B_List1_refs = p_Inp->num_ref_frames;
01204 }
01205 else if ( p_Inp->WPMCPrecision && p_Inp->WPMCPrecFullRef )
01206 {
01207 snprintf(errortext, ET_SIZE, "WPMCPrecFullRef requires NumberReferenceFrames < 16.\n");
01208 error (errortext, 400);
01209 }
01210
01211 if (p_Inp->ReferenceReorder && p_Inp->MbInterlace )
01212 {
01213 snprintf(errortext, ET_SIZE, "ReferenceReorder not supported with MBAFF\n");
01214 error (errortext, 400);
01215 }
01216
01217 if (p_Inp->SetFirstAsLongTerm && p_Inp->ReferenceReorder == 1)
01218 {
01219 printf("SetFirstAsLongTerm is set. ReferenceReorder is not supported and therefore disabled. \n");
01220 p_Inp->ReferenceReorder = 0;
01221 }
01222
01223 if (p_Inp->PocMemoryManagement && p_Inp->MbInterlace )
01224 {
01225 snprintf(errortext, ET_SIZE, "PocMemoryManagement not supported with MBAFF\n");
01226 error (errortext, 400);
01227 }
01228
01229 if ((!p_Inp->rdopt)&&(p_Inp->MbInterlace==2))
01230 {
01231 snprintf(errortext, ET_SIZE, "MB AFF is not compatible with non-rd-optimized coding.");
01232 error (errortext, 500);
01233 }
01234
01235
01236 if (p_Inp->rdopt==2 && ( p_Inp->ProfileIDC>=FREXT_HP || p_Inp->ProfileIDC==FREXT_CAVLC444 ))
01237 {
01238 snprintf(errortext, ET_SIZE, "Fast Mode Decision methods not supported in FREX Profiles");
01239 error (errortext, 500);
01240 }
01241
01242
01243
01244
01245 if ( p_Inp->NumFramesInELSubSeq > p_Inp->num_ref_frames || p_Inp->NumFramesInELSubSeq < 0 )
01246 {
01247 snprintf(errortext, ET_SIZE, "NumFramesInELSubSeq (%d) is out of range [0,%d).", p_Inp->NumFramesInELSubSeq, p_Inp->num_ref_frames);
01248 error (errortext, 500);
01249 }
01250
01251 if ( p_Inp->NumFramesInELSubSeq > 0 && p_Inp->of_mode == PAR_OF_ANNEXB )
01252 {
01253 snprintf(errortext, ET_SIZE, "Enhanced GOP is not supported in bitstream mode and RTP mode yet.");
01254 error (errortext, 500);
01255 }
01256
01257
01258 if ((p_Inp->PicInterlace || p_Inp->MbInterlace) && p_Inp->SparePictureOption == TRUE)
01259 {
01260 snprintf(errortext, ET_SIZE, "AFF is not compatible with spare picture.");
01261 error (errortext, 500);
01262 }
01263
01264
01265 if (p_Inp->of_mode != PAR_OF_RTP && p_Inp->SparePictureOption == TRUE)
01266 {
01267 snprintf(errortext, ET_SIZE, "Only RTP output mode is compatible with spare picture features.");
01268 error (errortext, 500);
01269 }
01270
01271 if( (p_Inp->WeightedPrediction > 0 || p_Inp->WeightedBiprediction > 0) && (p_Inp->MbInterlace))
01272 {
01273 snprintf(errortext, ET_SIZE, "Weighted prediction coding is not supported for MB AFF currently.");
01274 error (errortext, 500);
01275 }
01276 if ( p_Inp->NumFramesInELSubSeq > 0 && p_Inp->WeightedPrediction > 0)
01277 {
01278 snprintf(errortext, ET_SIZE, "Enhanced GOP is not supported in weighted prediction coding mode yet.");
01279 error (errortext, 500);
01280 }
01281
01282
01283 if(p_Inp->num_slice_groups_minus1 > 0)
01284 {
01285 if( (p_Inp->slice_group_map_type >= 3) && (p_Inp->slice_group_map_type<=5) )
01286 p_Inp->num_slice_groups_minus1 = 1;
01287 }
01288
01289
01290 if(p_Inp->RCEnable)
01291 {
01292 if (p_Inp->basicunit == 0)
01293 p_Inp->basicunit = (p_Inp->output.height + p_Img->auto_crop_bottom)*(p_Inp->output.width + p_Img->auto_crop_right)/256;
01294
01295 if ( ((p_Inp->output.height + p_Img->auto_crop_bottom)*(p_Inp->output.width + p_Img->auto_crop_right)/256) % p_Inp->basicunit != 0)
01296 {
01297 snprintf(errortext, ET_SIZE, "Frame size in macroblocks must be a multiple of BasicUnit.");
01298 error (errortext, 500);
01299 }
01300
01301 if ( p_Inp->RCUpdateMode == RC_MODE_1 &&
01302 !( (p_Inp->intra_period == 1 || p_Inp->idr_period == 1 || p_Inp->BRefPictures == 2 ) && !p_Inp->NumberBFrames ) )
01303 {
01304 snprintf(errortext, ET_SIZE, "Use RCUpdateMode = 1 only for all intra or all B-slice coding.");
01305 error (errortext, 500);
01306 }
01307
01308 if ( p_Inp->BRefPictures == 2 && p_Inp->intra_period == 0 && p_Inp->RCUpdateMode != RC_MODE_1 )
01309 {
01310 snprintf(errortext, ET_SIZE, "Use RCUpdateMode = 1 for all B-slice coding.");
01311 error (errortext, 500);
01312 }
01313
01314 if ( p_Inp->HierarchicalCoding && p_Inp->RCUpdateMode != RC_MODE_2 && p_Inp->RCUpdateMode != RC_MODE_3 )
01315 {
01316 snprintf(errortext, ET_SIZE, "Use RCUpdateMode = 2 or 3 for hierarchical B-picture coding.");
01317 error (errortext, 500);
01318 }
01319 if ( (p_Inp->RCUpdateMode != RC_MODE_1) && (p_Inp->intra_period == 1) )
01320 {
01321 snprintf(errortext, ET_SIZE, "Use RCUpdateMode = 1 for all intra coding.");
01322 error (errortext, 500);
01323 }
01324 }
01325
01326 if ((p_Inp->NumberBFrames)&&(p_Inp->BRefPictures)&&(p_Inp->idr_period)&&(p_Inp->pic_order_cnt_type!=0))
01327 {
01328 error("Stored B pictures combined with IDR pictures only supported in Picture Order Count type 0\n",-1000);
01329 }
01330
01331 if( !p_Inp->direct_spatial_mv_pred_flag && p_Inp->num_ref_frames<2 && p_Inp->NumberBFrames >0)
01332 error("temporal direct needs at least 2 ref frames\n",-1000);
01333
01334 if (p_Inp->SearchMode == FAST_FULL_SEARCH && p_Inp->MEErrorMetric[F_PEL] > ERROR_SSE)
01335 {
01336 snprintf(errortext, ET_SIZE, "\nOnly SAD and SSE distortion computation supported with Fast Full Search.");
01337 error (errortext, 500);
01338 }
01339
01340 if (p_Inp->rdopt == 0)
01341 {
01342 if (p_Inp->DisableSubpelME)
01343 {
01344 if (p_Inp->MEErrorMetric[F_PEL] != p_Inp->ModeDecisionMetric)
01345 {
01346 snprintf(errortext, ET_SIZE, "\nLast refinement level (FPel) distortion not the same as Mode decision distortion.\nPlease update MEDistortionFPel (%d) and/or MDDistortion(%d).", p_Inp->MEErrorMetric[F_PEL], p_Inp->ModeDecisionMetric);
01347 error (errortext, 500);
01348 }
01349 }
01350 else if (p_Inp->MEErrorMetric[Q_PEL] != p_Inp->ModeDecisionMetric)
01351 {
01352 snprintf(errortext, ET_SIZE, "\nLast refinement level (QPel) distortion not the same as Mode decision distortion.\nPlease update MEDistortionQPel (%d) and/or MDDistortion(%d).", p_Inp->MEErrorMetric[Q_PEL], p_Inp->ModeDecisionMetric);
01353 error (errortext, 500);
01354 }
01355 }
01356
01357 if(p_Inp->Transform8x8Mode && p_Inp->sp_periodicity )
01358 {
01359 snprintf(errortext, ET_SIZE, "\nThe new 8x8 mode is not implemented for sp-frames.");
01360 error (errortext, 500);
01361 }
01362
01363 if(p_Inp->Transform8x8Mode && ( p_Inp->ProfileIDC<FREXT_HP && p_Inp->ProfileIDC!=FREXT_CAVLC444 ))
01364 {
01365 snprintf(errortext, ET_SIZE, "\nTransform8x8Mode may be used only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444);
01366 error (errortext, 500);
01367 }
01368
01369 if (p_Inp->DisableIntra4x4 == 1 && p_Inp->DisableIntra16x16 == 1 && p_Inp->EnableIPCM == 0 && p_Inp->Transform8x8Mode == 0)
01370 {
01371 snprintf(errortext, ET_SIZE, "\nAt least one intra prediction mode needs to be enabled.");
01372 error (errortext, 500);
01373 }
01374
01375 if(p_Inp->ScalingMatrixPresentFlag && ( p_Inp->ProfileIDC<FREXT_HP && p_Inp->ProfileIDC!=FREXT_CAVLC444 ))
01376 {
01377 snprintf(errortext, ET_SIZE, "\nScalingMatrixPresentFlag may be used only with ProfileIDC %d to %d.", FREXT_HP, FREXT_Hi444);
01378 error (errortext, 500);
01379 }
01380
01381 if(p_Inp->yuv_format==YUV422 && ( p_Inp->ProfileIDC < FREXT_Hi422 && p_Inp->ProfileIDC!=FREXT_CAVLC444 ))
01382 {
01383 snprintf(errortext, ET_SIZE, "\nFRExt Profile(YUV Format) Error!\nYUV422 can be used only with ProfileIDC %d or %d\n",FREXT_Hi422, FREXT_Hi444);
01384 error (errortext, 500);
01385 }
01386 if(p_Inp->yuv_format==YUV444 && ( p_Inp->ProfileIDC < FREXT_Hi444 && p_Inp->ProfileIDC!=FREXT_CAVLC444 ))
01387 {
01388 snprintf(errortext, ET_SIZE, "\nFRExt Profile(YUV Format) Error!\nYUV444 can be used only with ProfileIDC %d.\n",FREXT_Hi444);
01389 error (errortext, 500);
01390 }
01391
01392 if (p_Inp->NumberBFrames && ((p_Inp->BiPredMotionEstimation) && (p_Inp->search_range < p_Inp->BiPredMESearchRange)))
01393 {
01394 snprintf(errortext, ET_SIZE, "\nBiPredMESearchRange must be smaller or equal SearchRange.");
01395 error (errortext, 500);
01396 }
01397
01398 if (p_Inp->BiPredMotionEstimation)
01399 {
01400 p_Inp->BiPredMotionEstimation = 0;
01401 for (i = 0 ; i < 4; i++)
01402 p_Inp->BiPredMotionEstimation |= p_Inp->BiPredSearch[i];
01403 }
01404 else
01405 {
01406 for (i = 0 ; i < 4; i++)
01407 p_Inp->BiPredSearch[i] = 0;
01408 }
01409
01410
01411 if ( p_Inp->ChromaMEEnable && !(p_Inp->ChromaMCBuffer) )
01412 {
01413 snprintf(errortext, ET_SIZE, "\nChromaMCBuffer must be set to 1 if ChromaMEEnable is set.");
01414 error (errortext, 500);
01415 }
01416
01417 if ( p_Inp->ChromaMEEnable && p_Inp->yuv_format == YUV400)
01418 {
01419 fprintf(stderr, "Warning: ChromaMEEnable cannot be used with monochrome color format, disabling ChromaMEEnable.\n");
01420 p_Inp->ChromaMEEnable = 0;
01421 }
01422
01423 if ( (p_Inp->ChromaMCBuffer == 0) && (( p_Inp->yuv_format == YUV444) && (!p_Inp->separate_colour_plane_flag)) )
01424 {
01425 fprintf(stderr, "Warning: Enabling ChromaMCBuffer for 4:4:4 combined color coding.\n");
01426 p_Inp->ChromaMCBuffer = 1;
01427 }
01428
01429
01430 if (p_Inp->EnableOpenGOP)
01431 p_Inp->ReferenceReorder = 1;
01432
01433 if (p_Inp->SearchMode != EPZS)
01434 p_Inp->EPZSSubPelGrid = 0;
01435
01436 if (p_Inp->redundant_pic_flag)
01437 {
01438 if (p_Inp->PicInterlace || p_Inp->MbInterlace)
01439 {
01440 snprintf(errortext, ET_SIZE, "Redundant pictures cannot be used with interlaced tools.");
01441 error (errortext, 500);
01442 }
01443 if (p_Inp->RDPictureDecision)
01444 {
01445 snprintf(errortext, ET_SIZE, "Redundant pictures cannot be used with RDPictureDecision.");
01446 error (errortext, 500);
01447 }
01448 if (p_Inp->NumberBFrames)
01449 {
01450 snprintf(errortext, ET_SIZE, "Redundant pictures cannot be used with B frames.");
01451 error (errortext, 500);
01452 }
01453 if (p_Inp->PrimaryGOPLength < (1 << p_Inp->NumRedundantHierarchy))
01454 {
01455 snprintf(errortext, ET_SIZE, "PrimaryGOPLength must be equal or greater than 2^NumRedundantHierarchy.");
01456 error (errortext, 500);
01457 }
01458 if (p_Inp->num_ref_frames < p_Inp->PrimaryGOPLength)
01459 {
01460 snprintf(errortext, ET_SIZE, "NumberReferenceFrames must be greater than or equal to PrimaryGOPLength.");
01461 error (errortext, 500);
01462 }
01463 }
01464
01465 if (p_Inp->num_ref_frames == 1 && p_Inp->NumberBFrames)
01466 {
01467 fprintf( stderr, "\nWarning: B slices used but only one reference allocated within reference buffer.\n");
01468 fprintf( stderr, " Performance may be considerably compromised! \n");
01469 fprintf( stderr, " 2 or more references recommended for use with B slices.\n");
01470 }
01471 if ((p_Inp->HierarchicalCoding || p_Inp->BRefPictures) && p_Inp->NumberBFrames)
01472 {
01473 fprintf( stderr, "\nWarning: Hierarchical coding or Referenced B slices used.\n");
01474 fprintf( stderr, " Make sure that you have allocated enough references\n");
01475 fprintf( stderr, " in reference buffer to achieve best performance.\n");
01476 }
01477
01478 if (p_Inp->FastMDEnable == 0)
01479 {
01480 p_Inp->FastIntraMD = 0;
01481 p_Inp->FastIntra16x16 = 0;
01482 p_Inp->FastIntra4x4 = 0;
01483 p_Inp->FastIntra8x8 = 0;
01484 p_Inp->FastIntraChroma = 0;
01485 }
01486
01487
01488
01489 if (p_Inp->UseRDOQuant == 1)
01490 {
01491 if (p_Inp->rdopt == 0)
01492 {
01493 snprintf(errortext, ET_SIZE, "RDO Quantization not supported with low complexity RDO.");
01494 error (errortext, 500);
01495 }
01496
01497 if (p_Inp->MbInterlace != 0)
01498 {
01499 printf("RDO Quantization currently not supported with MBAFF. Option disabled.\n");
01500 p_Inp->UseRDOQuant = 0;
01501 p_Inp->RDOQ_QP_Num = 1;
01502 p_Inp->RDOQ_CP_MV = 0;
01503 p_Inp->RDOQ_CP_Mode = 0;
01504 }
01505 else
01506 {
01507 p_Inp->AdaptiveRounding = 0;
01508 printf("AdaptiveRounding is disabled when RDO Quantization is used\n");
01509 if (p_Inp->RDOQ_QP_Num < 2)
01510 {
01511 p_Inp->RDOQ_CP_MV = 0;
01512 p_Inp->RDOQ_CP_Mode = 0;
01513 }
01514 }
01515 }
01516 else
01517 {
01518 p_Inp->RDOQ_QP_Num = 1;
01519 p_Inp->RDOQ_CP_MV = 0;
01520 p_Inp->RDOQ_CP_Mode = 0;
01521 }
01522
01523 ProfileCheck(p_Inp);
01524 LevelCheck(p_Img, p_Inp);
01525 }
01526
01527 void PatchInputNoFrames(InputParameters *p_Inp)
01528 {
01529
01530
01531
01532
01533 p_Inp->no_frm_base = 1 + (p_Inp->no_frm_base - 1) * (p_Inp->NumFramesInELSubSeq + 1);
01534 }
01535