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 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 #include <assert.h>
00131 #include "all.h"
00132 #include "mtypes.h"
00133 #include "mpeg.h"
00134 #include "search.h"
00135 #include "prototypes.h"
00136 #include "param.h"
00137 #include "parallel.h"
00138 #include "readframe.h"
00139 #include "combine.h"
00140 #include "frames.h"
00141 #include "jpeg.h"
00142 #include "specifics.h"
00143 #include "opts.h"
00144 #include <time.h>
00145 
00146 int     main _ANSI_ARGS_((int argc, char **argv));
00147 
00148 
00149 
00150 
00151 
00152 static int      frameStart = -1;
00153 static int      frameEnd;
00154 
00155 
00156 
00157 
00158 
00159 
00160 extern time_t IOtime;
00161 int     whichGOP = -1;
00162 boolean childProcess = FALSE;
00163 boolean ioServer = FALSE;
00164 boolean outputServer = FALSE;
00165 boolean decodeServer = FALSE;
00166 int     quietTime = 0;
00167 boolean realQuiet = FALSE;
00168 boolean frameSummary = TRUE;
00169 boolean debugSockets = FALSE;
00170 boolean debugMachines = FALSE;
00171 boolean showBitRatePerFrame = FALSE;
00172 boolean computeMVHist = FALSE;
00173 int     baseFormat;
00174 extern  boolean specificsOn;
00175 extern  FrameSpecList *fsl;
00176 boolean pureDCT=FALSE;
00177 char    encoder_name[1024];
00178 
00179 
00180 
00181 
00182 
00183 static void Usage _ANSI_ARGS_((void));
00184 static void CompileTests _ANSI_ARGS_((void));
00185 
00186 
00187 
00188 
00189 
00190 
00191 void init_idctref _ANSI_ARGS_((void));
00192 void init_fdct _ANSI_ARGS_((void));
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 int
00209 main(argc, argv)
00210     int argc;
00211     char **argv;
00212 {
00213     FILE *ofp = NULL;
00214     register int idx;
00215     int     function = ENCODE_FRAMES;
00216     int     portNumber = 0;
00217     char    *hostName = NULL;
00218     int32   totalTime = -1;
00219     int     maxMachines = 0x7fffffff;
00220     int     outputFrames = 0;
00221     time_t  initTimeStart;
00222     time_t  framesTimeStart, framesTimeEnd;
00223 
00224     strcpy(encoder_name, argv[0]);
00225 
00226     CompileTests();
00227 
00228     time(&initTimeStart);
00229 
00230     if ( argc == 1 ) {
00231         Usage();
00232     }
00233 
00234     SetStatFileName("");
00235 
00236     
00237     idx = 1;
00238     while ( idx < argc-1 ) {
00239         if ( argv[idx][0] != '-' ) {
00240             Usage();
00241         }
00242 
00243         if ( strcmp(argv[idx], "-stat") == 0 ) {
00244             if ( idx+1 < argc-1 ) {
00245                 SetStatFileName(argv[idx+1]);
00246                 idx += 2;
00247             } else {
00248                 Usage();
00249             }
00250         } else if ( strcmp(argv[idx], "-gop") == 0 ) {
00251             if ( (function != ENCODE_FRAMES) || (frameStart != -1) ) {
00252                 Usage();
00253             }
00254 
00255             if ( idx+1 < argc-1 ) {
00256                 whichGOP = atoi(argv[idx+1]);
00257                 idx += 2;
00258             } else {
00259                 Usage();
00260             }
00261         } else if ( strcmp(argv[idx], "-frames") == 0 ) {
00262             if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ) {
00263                 Usage();
00264             }
00265 
00266             if ( idx+2 < argc-1 ) {
00267                 frameStart = atoi(argv[idx+1]);
00268                 frameEnd = atoi(argv[idx+2]);
00269 
00270                 if ( (frameStart > frameEnd) || (frameStart < 0) ) {
00271                     fprintf(stderr, "ERROR:  bad frame numbers!\n");
00272                     Usage();
00273                 }
00274 
00275                 idx += 3;
00276             } else {
00277                 Usage();
00278             }
00279         } else if ( strcmp(argv[idx], "-combine_gops") == 0 ) {
00280             if ( (function != ENCODE_FRAMES) || (whichGOP != -1) || 
00281                  (frameStart != -1) ) {
00282                 Usage();
00283             }
00284 
00285             function = COMBINE_GOPS;
00286             idx++;
00287         } else if ( strcmp(argv[idx], "-combine_frames") == 0 ) {
00288             if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ||
00289                  (frameStart != -1) ) {
00290                 Usage();
00291             }
00292 
00293             function = COMBINE_FRAMES;
00294             idx++;
00295         } else if ( strcmp(argv[idx], "-child") == 0 ) {
00296             if ( idx+7 < argc-1 ) {
00297                 hostName = argv[idx+1];
00298                 portNumber = atoi(argv[idx+2]);
00299                 ioPortNumber = atoi(argv[idx+3]);
00300                 combinePortNumber = atoi(argv[idx+4]);
00301                 decodePortNumber = atoi(argv[idx+5]);
00302                 machineNumber = atoi(argv[idx+6]);
00303                 remoteIO = atoi(argv[idx+7]);
00304 
00305                 IOhostName = hostName;
00306             } else {
00307                 Usage();
00308             }
00309 
00310             childProcess = TRUE;
00311             idx += 8;
00312         } else if ( strcmp(argv[idx], "-io_server") == 0 ) {
00313             if ( idx+2 < argc-1 ) {
00314                 hostName = argv[idx+1];
00315                 portNumber = atoi(argv[idx+2]);
00316             } else {
00317                 Usage();
00318             }
00319 
00320             ioServer = TRUE;
00321             idx += 3;
00322         } else if ( strcmp(argv[idx], "-output_server") == 0 ) {
00323             if ( idx+3 < argc-1 ) {
00324                 hostName = argv[idx+1];
00325                 portNumber = atoi(argv[idx+2]);
00326                 outputFrames = atoi(argv[idx+3]);
00327             } else {
00328                 Usage();
00329             }
00330 
00331             function = COMBINE_FRAMES;
00332             outputServer = TRUE;
00333             idx += 4;
00334         } else if ( strcmp(argv[idx], "-decode_server") == 0 ) {
00335             if ( idx+3 < argc-1 ) {
00336                 hostName = argv[idx+1];
00337                 portNumber = atoi(argv[idx+2]);
00338                 outputFrames = atoi(argv[idx+3]);
00339             } else {
00340                 Usage();
00341             }
00342 
00343             function = COMBINE_FRAMES;
00344             decodeServer = TRUE;
00345             idx += 4;
00346         } else if ( strcmp(argv[idx], "-nice") == 0 ) {
00347             niceProcesses = TRUE;
00348             idx++;
00349         } else if ( strcmp(argv[idx], "-max_machines") == 0 ) {
00350             if ( idx+1 < argc-1 ) {
00351                 maxMachines = atoi(argv[idx+1]);
00352             } else {
00353                 Usage();
00354             }
00355 
00356             idx += 2;
00357         } else if ( strcmp(argv[idx], "-quiet") == 0 ) {
00358             if ( idx+1 < argc-1 ) {
00359                 quietTime = atoi(argv[idx+1]);
00360             } else {
00361                 Usage();
00362             }
00363 
00364             idx += 2;
00365         } else if ( strcmp(argv[idx], "-realquiet") == 0 ) {
00366             realQuiet = TRUE;
00367             idx++;
00368         } else if (( strcmp(argv[idx], "-float_dct") == 0 ) ||
00369                    ( strcmp(argv[idx], "-float-dct") == 0 )) {
00370             pureDCT = TRUE;
00371             init_idctref();
00372             init_fdct();
00373             idx++;
00374         } else if ( strcmp(argv[idx], "-no_frame_summary") == 0 ) {
00375             if ( idx < argc-1 ) {
00376                 frameSummary = FALSE;
00377             } else {
00378                 Usage();
00379             }
00380 
00381             idx++;
00382         } else if ( strcmp(argv[idx], "-snr") == 0 ) {
00383             printSNR = TRUE;
00384             idx++;
00385         } else if ( strcmp(argv[idx], "-mse") == 0 ) {
00386             printSNR =  printMSE = TRUE;
00387             idx++;
00388         } else if ( strcmp(argv[idx], "-debug_sockets") == 0 ) {
00389             debugSockets = TRUE;
00390             idx++;
00391         } else if ( strcmp(argv[idx], "-debug_machines") == 0 ) {
00392             debugMachines = TRUE;
00393             idx++;
00394         } else if ( strcmp(argv[idx], "-bit_rate_info") == 0 ) {
00395             if ( idx+1 < argc-1 ) {
00396                 showBitRatePerFrame = TRUE;
00397                 SetBitRateFileName(argv[idx+1]);
00398                 idx += 2;
00399             } else {
00400                 Usage();
00401             }
00402         } else if ( strcmp(argv[idx], "-mv_histogram") == 0 ) {
00403             computeMVHist = TRUE;
00404             idx++;
00405         } else {
00406             Usage();
00407         }
00408     }
00409 
00410     if ( ! ReadParamFile(argv[argc-1], function) ) {
00411         Usage();
00412     }
00413 
00414     
00415 
00416     if ( (!childProcess) && (baseFormat == JMOVIE_FILE_TYPE) ) {
00417          JM2JPEG();
00418     }
00419 
00420     if ( printSNR || (referenceFrame == DECODED_FRAME) ) {
00421         decodeRefFrames = TRUE;
00422     }
00423 
00424     numMachines = min(numMachines, maxMachines);
00425 
00426     Tune_Init();
00427     Frame_Init();
00428 
00429 #ifdef BLEAH
00430     time_t  initTimeEnd;
00431 
00432     time(&initTimeEnd);
00433     fprintf(stdout, "INIT TIME:  %d seconds\n",
00434             initTimeEnd-initTimeStart);
00435     fflush(stdout);
00436 #endif
00437 
00438     if (specificsOn) Specifics_Init();
00439 
00440     ComputeFrameTable();
00441 
00442     if ( ioServer ) {
00443         StartIOServer(numInputFiles, hostName, portNumber);
00444         return 0;
00445     } else if ( outputServer ) {
00446         StartCombineServer(outputFrames, outputFileName, hostName, portNumber);
00447         return 0;
00448     } else if ( decodeServer ) {
00449         StartDecodeServer(outputFrames, outputFileName, hostName, portNumber);
00450         return 0;
00451     }
00452 
00453     if ( (frameStart == -1) &&
00454          ((numMachines == 0) || (function != ENCODE_FRAMES)) ) {
00455         if ( (ofp = fopen(outputFileName, "wb")) == NULL ) {
00456             fprintf(stderr, "ERROR:  Could not open output file!\n");
00457             exit(1);
00458         }
00459     }
00460 
00461     if ( function == ENCODE_FRAMES ) {
00462         if ( (numMachines == 0) || (frameStart != -1) ) {
00463             time(&framesTimeStart);
00464             totalTime = GenMPEGStream(whichGOP, frameStart, frameEnd,
00465                                       customQtable, customNIQtable,
00466                                       numInputFiles, ofp,
00467                                       outputFileName);
00468             time(&framesTimeEnd);
00469             if ( childProcess && (! realQuiet) ) {
00470 #ifdef BLEAH
00471                 fprintf(stdout, "SCHEDULE:  MACHINE %d FRAMES %d-%d TIME %d-%d IOTIME %d\n",
00472                         machineNumber, frameStart, frameEnd,
00473                         framesTimeStart, framesTimeEnd,
00474                         IOtime);
00475 #endif
00476                 fprintf(stdout, "%s:  FRAMES %d-%d (%d seconds)\n",
00477                         getenv("HOST"), frameStart, frameEnd,
00478                         (int) (framesTimeEnd-framesTimeStart));
00479                 fflush(stdout);
00480             }
00481         } else {
00482             
00483             if ( (argv[argc-1][0] != '/') && (argv[argc-1][0] != '~') ) {
00484                 fprintf(stderr, "ERROR:  For parallel execution, please use absolute path for parameter file!\n");
00485                 exit(1);
00486             } else {
00487                 StartMasterServer(numInputFiles, argv[argc-1], outputFileName);
00488             }
00489         }
00490     } else if ( function == COMBINE_GOPS ) {
00491         GOPStoMPEG(numInputFiles, outputFileName, ofp);
00492     } else if ( function == COMBINE_FRAMES ) {
00493         FramesToMPEG(numInputFiles, outputFileName, ofp, FALSE);
00494     }
00495 
00496     if ( childProcess ) {
00497         while ( NotifyMasterDone(hostName, portNumber, machineNumber,
00498                                  totalTime,
00499                                  &frameStart, &frameEnd) ) {
00500             
00501             time(&framesTimeStart);
00502             totalTime = GenMPEGStream(-1, frameStart, frameEnd,
00503                                       customQtable, customNIQtable,
00504                                       numInputFiles, NULL,
00505                                       outputFileName);
00506             time(&framesTimeEnd);
00507 
00508             if (! realQuiet) {
00509 #ifdef BLEAH
00510                 fprintf(stdout, "SCHEDULE:  MACHINE %d FRAMES %d-%d TIME %d-%d IOTIME %d\n",
00511                         machineNumber, frameStart, frameEnd,
00512                         framesTimeStart, framesTimeEnd,
00513                         IOtime);
00514 #endif
00515                 fprintf(stdout, "%s:  FRAMES %d-%d (%d seconds)\n",
00516                         getenv("HOST"), frameStart, frameEnd,
00517                         (int) (framesTimeEnd-framesTimeStart));
00518             fflush(stdout);
00519             }
00520 
00521         }
00522     }
00523 
00524     Frame_Exit();
00525 
00526     return 0;   
00527 }
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 
00539 
00540 
00541 
00542 
00543 
00544 
00545 static void
00546 Usage()
00547 {
00548     fprintf(stderr, "Usage:  mpeg_encode [options] param_file\n");
00549     fprintf(stderr, "Options:\n");
00550     fprintf(stderr, "\t-stat stat_file:  append stats to stat_file\n");
00551     fprintf(stderr, "\t-quiet n:  don't report remaining time for at least n seconds\n");
00552     fprintf(stderr, "\t-realquiet:  output nothing at all if successful\n");
00553     fprintf(stderr, "\t-no_frame_summary:  suppress frame summary lines\n");
00554     fprintf(stderr, "\t-float_dct:  use more accurate floating point DCT\n");
00555     fprintf(stderr, "\t-gop gop_num:  encode only the numbered GOP\n");
00556     fprintf(stderr, "\t-combine_gops:  combine GOP files instead of encode\n");
00557     fprintf(stderr, "\t-frames first_frame last_frame:  encode only the specified frames\n");
00558     fprintf(stderr, "\t-combine_frames:  combine frame files instead of encode\n");
00559     fprintf(stderr, "\t-nice:  run slave processes nicely\n");
00560     fprintf(stderr, "\t-max_machines num_machines:  use at most num_machines machines\n");
00561     fprintf(stderr, "\t-snr:  print signal-to-noise ratio\n");
00562     fprintf(stderr, "\t-bit_rate_info rate_file:  put bit rate in specified file\n");
00563     fprintf(stderr, "\t-mv_histogram:  show histograms of motion vectors\n");
00564     exit(1);
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 }
00573 
00574 
00575 static void
00576 CompileTests()
00577 {
00578     assert(sizeof(uint8) == 1);
00579     assert(sizeof(uint16) == 2);
00580     assert(sizeof(uint32) == 4);
00581     assert(sizeof(int8) == 1);
00582     assert(sizeof(int16) == 2);
00583     assert(sizeof(int32) == 4);
00584 
00585     if ( (-8 >> 3) != -1 ) {
00586         fprintf(stderr, "ERROR:  Right shifts are NOT arithmetic!!!\n");
00587         fprintf(stderr, "Change >> to multiplies by powers of 2\n");
00588         exit(1);
00589     }
00590 }