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