ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/freemol/trunk/src/mpeg_encode/src/main.c
Revision: 73
Committed: Mon Dec 15 03:00:55 2008 UTC (12 years, 9 months ago) by wdelano
File size: 15772 byte(s)
Log Message:
Line File contents
1 /*===========================================================================*
2 * main.c *
3 * *
4 * Main procedure *
5 * *
6 * EXPORTED PROCEDURES: *
7 * main *
8 * *
9 *===========================================================================*/
10
11 /*
12 * Copyright (c) 1995 The Regents of the University of California.
13 * All rights reserved.
14 *
15 * Permission to use, copy, modify, and distribute this software and its
16 * documentation for any purpose, without fee, and without written agreement is
17 * hereby granted, provided that the above copyright notice and the following
18 * two paragraphs appear in all copies of this software.
19 *
20 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
21 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
22 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
23 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
28 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
29 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
30 */
31
32 /*
33 * $Header: /n/picasso/project/mpeg/mpeg_dist/mpeg_encode/RCS/main.c,v 1.25 1995/08/07 21:44:21 smoot Exp $
34 * $Log: main.c,v $
35 * Revision 1.25 1995/08/07 21:44:21 smoot
36 * renamed index -> idx; save the encoder's name; compute frame types ahead of time
37 *
38 * Revision 1.24 1995/06/21 18:25:57 smoot
39 * added binary write flag (DOS!)
40 *
41 * Revision 1.23 1995/05/16 06:25:28 smoot
42 * added TUNEing init and float-dct == float_dct
43 *
44 * Revision 1.22 1995/05/16 00:15:05 smoot
45 * fixed usage print
46 *
47 * Revision 1.21 1995/05/11 23:59:56 smoot
48 * *** empty log message ***
49 *
50 * Revision 1.20 1995/02/02 20:05:37 eyhung
51 * fixed smoot typo in 1.19
52 *
53 * Revision 1.19 1995/02/02 18:56:11 smoot
54 * ANSI-ified some prototypes
55 *
56 * Revision 1.18 1995/02/01 21:47:37 smoot
57 * cleanup
58 *
59 * Revision 1.17 1995/01/31 22:22:49 eyhung
60 * Fixed steve's typo and added float_dct to Usage()
61 *
62 * Revision 1.16 1995/01/31 21:44:08 smoot
63 * Added -float_dct option
64 *
65 * Revision 1.15 1995/01/31 01:19:39 eyhung
66 * removed -interactive
67 *
68 * Revision 1.14 1995/01/27 21:56:57 eyhung
69 * Deleted setting JMOVIE_TYPE to JPEG_TYPE since we need to know
70 * if we started with a JMOVIE for getting input files
71 *
72 * Revision 1.13 1995/01/19 23:50:06 eyhung
73 * Removed printing of output file to screen - done at end of encoding now.
74 *
75 * Revision 1.12 1995/01/19 23:08:41 eyhung
76 * Changed copyrights
77 *
78 * Revision 1.11 1995/01/17 08:25:44 eyhung
79 * added -interactive to Usage
80 *
81 * Revision 1.10 1995/01/17 08:24:53 eyhung
82 * Added -interactive option
83 *
84 * Revision 1.9 1995/01/16 08:04:10 eyhung
85 * More realQuiet stuff.
86 *
87 * Revision 1.8 1995/01/16 07:38:49 eyhung
88 * Added realquiet option
89 *
90 * Revision 1.7 1994/11/14 22:32:01 smoot
91 * Merged specifics and rate control
92 *
93 * Revision 1.6 1994/11/12 02:11:52 keving
94 * nothing
95 *
96 * Revision 1.5 1994/03/15 00:27:11 keving
97 * nothing
98 *
99 * Revision 1.4 1993/12/22 19:19:01 keving
100 * nothing
101 *
102 * Revision 1.3 1993/07/22 22:23:43 keving
103 * nothing
104 *
105 * Revision 1.2 1993/06/30 20:06:09 keving
106 * nothing
107 *
108 * Revision 1.1 1993/02/17 23:18:20 dwallach
109 * Initial revision
110 *
111 */
112
113
114 /*==============*
115 * HEADER FILES *
116 *==============*/
117
118 #include <assert.h>
119 #include "all.h"
120 #include "mtypes.h"
121 #include "mpeg.h"
122 #include "search.h"
123 #include "prototypes.h"
124 #include "param.h"
125 #include "parallel.h"
126 #include "readframe.h"
127 #include "combine.h"
128 #include "frames.h"
129 #include "jpeg.h"
130 #include "specifics.h"
131 #include "opts.h"
132 #include <time.h>
133
134 int main _ANSI_ARGS_((int argc, char **argv));
135
136 /*==================*
137 * STATIC VARIABLES *
138 *==================*/
139
140 static int frameStart = -1;
141 static int frameEnd;
142
143
144 /*==================*
145 * GLOBAL VARIABLES *
146 *==================*/
147
148 extern time_t IOtime;
149 int whichGOP = -1;
150 boolean childProcess = FALSE;
151 boolean ioServer = FALSE;
152 boolean outputServer = FALSE;
153 boolean decodeServer = FALSE;
154 int quietTime = 0;
155 boolean realQuiet = FALSE;
156 boolean frameSummary = TRUE;
157 boolean debugSockets = FALSE;
158 boolean debugMachines = FALSE;
159 boolean showBitRatePerFrame = FALSE;
160 boolean computeMVHist = FALSE;
161 int baseFormat;
162 extern boolean specificsOn;
163 extern FrameSpecList *fsl;
164 boolean pureDCT=FALSE;
165 char encoder_name[1024];
166
167 /*===============================*
168 * INTERNAL PROCEDURE prototypes *
169 *===============================*/
170
171 static void Usage _ANSI_ARGS_((void));
172 static void CompileTests _ANSI_ARGS_((void));
173
174
175 /*================================*
176 * External PROCEDURE prototypes *
177 *================================*/
178
179 void init_idctref _ANSI_ARGS_((void));
180 void init_fdct _ANSI_ARGS_((void));
181
182 /*=====================*
183 * EXPORTED PROCEDURES *
184 *=====================*/
185
186
187 /*===========================================================================*
188 *
189 * main
190 *
191 * see man page. run without arguments to see usage
192 *
193 * RETURNS: 0 if all is well; 1 on most if not all errors
194 *
195 *===========================================================================*/
196 int
197 main(argc, argv)
198 int argc;
199 char **argv;
200 {
201 FILE *ofp = NULL;
202 register int idx;
203 int function = ENCODE_FRAMES;
204 int portNumber = 0;
205 char *hostName = NULL;
206 int32 totalTime = -1;
207 int maxMachines = 0x7fffffff;
208 int outputFrames = 0;
209 time_t initTimeStart;
210 time_t framesTimeStart, framesTimeEnd;
211
212 strcpy(encoder_name, argv[0]);
213
214 CompileTests();
215
216 time(&initTimeStart);
217
218 /* WLD */
219 if ( argc == 0 ) {
220 Usage();
221 }
222 /* WLD END /
223
224 SetStatFileName("");
225
226 /* parse the arguments */
227 idx = 1;
228 while ( idx < argc-1 ) {
229 if ( argv[idx][0] != '-' ) {
230 Usage();
231 }
232
233 if ( strcmp(argv[idx], "-stat") == 0 ) {
234 if ( idx+1 < argc-1 ) {
235 SetStatFileName(argv[idx+1]);
236 idx += 2;
237 } else {
238 Usage();
239 }
240 } else if ( strcmp(argv[idx], "-gop") == 0 ) {
241 if ( (function != ENCODE_FRAMES) || (frameStart != -1) ) {
242 Usage();
243 }
244
245 if ( idx+1 < argc-1 ) {
246 whichGOP = atoi(argv[idx+1]);
247 idx += 2;
248 } else {
249 Usage();
250 }
251 } else if ( strcmp(argv[idx], "-frames") == 0 ) {
252 if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ) {
253 Usage();
254 }
255
256 if ( idx+2 < argc-1 ) {
257 frameStart = atoi(argv[idx+1]);
258 frameEnd = atoi(argv[idx+2]);
259
260 if ( (frameStart > frameEnd) || (frameStart < 0) ) {
261 fprintf(stderr, "ERROR: bad frame numbers!\n");
262 Usage();
263 }
264
265 idx += 3;
266 } else {
267 Usage();
268 }
269 } else if ( strcmp(argv[idx], "-combine_gops") == 0 ) {
270 if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ||
271 (frameStart != -1) ) {
272 Usage();
273 }
274
275 function = COMBINE_GOPS;
276 idx++;
277 } else if ( strcmp(argv[idx], "-combine_frames") == 0 ) {
278 if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ||
279 (frameStart != -1) ) {
280 Usage();
281 }
282
283 function = COMBINE_FRAMES;
284 idx++;
285 } else if ( strcmp(argv[idx], "-child") == 0 ) {
286 if ( idx+7 < argc-1 ) {
287 hostName = argv[idx+1];
288 portNumber = atoi(argv[idx+2]);
289 ioPortNumber = atoi(argv[idx+3]);
290 combinePortNumber = atoi(argv[idx+4]);
291 decodePortNumber = atoi(argv[idx+5]);
292 machineNumber = atoi(argv[idx+6]);
293 remoteIO = atoi(argv[idx+7]);
294
295 IOhostName = hostName;
296 } else {
297 Usage();
298 }
299
300 childProcess = TRUE;
301 idx += 8;
302 } else if ( strcmp(argv[idx], "-io_server") == 0 ) {
303 if ( idx+2 < argc-1 ) {
304 hostName = argv[idx+1];
305 portNumber = atoi(argv[idx+2]);
306 } else {
307 Usage();
308 }
309
310 ioServer = TRUE;
311 idx += 3;
312 } else if ( strcmp(argv[idx], "-output_server") == 0 ) {
313 if ( idx+3 < argc-1 ) {
314 hostName = argv[idx+1];
315 portNumber = atoi(argv[idx+2]);
316 outputFrames = atoi(argv[idx+3]);
317 } else {
318 Usage();
319 }
320
321 function = COMBINE_FRAMES;
322 outputServer = TRUE;
323 idx += 4;
324 } else if ( strcmp(argv[idx], "-decode_server") == 0 ) {
325 if ( idx+3 < argc-1 ) {
326 hostName = argv[idx+1];
327 portNumber = atoi(argv[idx+2]);
328 outputFrames = atoi(argv[idx+3]);
329 } else {
330 Usage();
331 }
332
333 function = COMBINE_FRAMES;
334 decodeServer = TRUE;
335 idx += 4;
336 } else if ( strcmp(argv[idx], "-nice") == 0 ) {
337 niceProcesses = TRUE;
338 idx++;
339 } else if ( strcmp(argv[idx], "-max_machines") == 0 ) {
340 if ( idx+1 < argc-1 ) {
341 maxMachines = atoi(argv[idx+1]);
342 } else {
343 Usage();
344 }
345
346 idx += 2;
347 } else if ( strcmp(argv[idx], "-quiet") == 0 ) {
348 if ( idx+1 < argc-1 ) {
349 quietTime = atoi(argv[idx+1]);
350 } else {
351 Usage();
352 }
353
354 idx += 2;
355 } else if ( strcmp(argv[idx], "-realquiet") == 0 ) {
356 realQuiet = TRUE;
357 idx++;
358 } else if (( strcmp(argv[idx], "-float_dct") == 0 ) ||
359 ( strcmp(argv[idx], "-float-dct") == 0 )) {
360 pureDCT = TRUE;
361 init_idctref();
362 init_fdct();
363 idx++;
364 } else if ( strcmp(argv[idx], "-no_frame_summary") == 0 ) {
365 if ( idx < argc-1 ) {
366 frameSummary = FALSE;
367 } else {
368 Usage();
369 }
370
371 idx++;
372 } else if ( strcmp(argv[idx], "-snr") == 0 ) {
373 printSNR = TRUE;
374 idx++;
375 } else if ( strcmp(argv[idx], "-mse") == 0 ) {
376 printSNR = printMSE = TRUE;
377 idx++;
378 } else if ( strcmp(argv[idx], "-debug_sockets") == 0 ) {
379 debugSockets = TRUE;
380 idx++;
381 } else if ( strcmp(argv[idx], "-debug_machines") == 0 ) {
382 debugMachines = TRUE;
383 idx++;
384 } else if ( strcmp(argv[idx], "-bit_rate_info") == 0 ) {
385 if ( idx+1 < argc-1 ) {
386 showBitRatePerFrame = TRUE;
387 SetBitRateFileName(argv[idx+1]);
388 idx += 2;
389 } else {
390 Usage();
391 }
392 } else if ( strcmp(argv[idx], "-mv_histogram") == 0 ) {
393 computeMVHist = TRUE;
394 idx++;
395 } else {
396 Usage();
397 }
398 }
399
400 { /* WLD */
401 char *pname = NULL;
402 if(argc>1) {
403 pname = argv[argc-1];
404 if(pname[0]=='-')
405 pname = NULL;
406 }
407 if ( ! ReadParamFile(pname, function) ) {
408 Usage();
409 }
410 /* WLD END */
411 }
412
413 /* Jim Boucher's stuff:
414 if we are using a movie format then break up into frames*/
415 if ( (!childProcess) && (baseFormat == JMOVIE_FILE_TYPE) ) {
416 JM2JPEG();
417 }
418
419 if ( printSNR || (referenceFrame == DECODED_FRAME) ) {
420 decodeRefFrames = TRUE;
421 }
422
423 numMachines = min(numMachines, maxMachines);
424
425 Tune_Init();
426 Frame_Init();
427
428 #ifdef BLEAH
429 time_t initTimeEnd;
430
431 time(&initTimeEnd);
432 fprintf(stdout, "INIT TIME: %d seconds\n",
433 initTimeEnd-initTimeStart);
434 fflush(stdout);
435 #endif
436
437 if (specificsOn) Specifics_Init();
438
439 ComputeFrameTable();
440
441 if ( ioServer ) {
442 StartIOServer(numInputFiles, hostName, portNumber);
443 return 0;
444 } else if ( outputServer ) {
445 StartCombineServer(outputFrames, outputFileName, hostName, portNumber);
446 return 0;
447 } else if ( decodeServer ) {
448 StartDecodeServer(outputFrames, outputFileName, hostName, portNumber);
449 return 0;
450 }
451
452 if ( (frameStart == -1) &&
453 ((numMachines == 0) || (function != ENCODE_FRAMES)) ) {
454 if ( (ofp = fopen(outputFileName, "wb")) == NULL ) {
455 fprintf(stderr, "ERROR: Could not open output file!\n");
456 exit(1);
457 }
458 }
459
460 if ( function == ENCODE_FRAMES ) {
461 if ( (numMachines == 0) || (frameStart != -1) ) {
462 time(&framesTimeStart);
463 totalTime = GenMPEGStream(whichGOP, frameStart, frameEnd,
464 customQtable, customNIQtable,
465 numInputFiles, ofp,
466 outputFileName);
467 time(&framesTimeEnd);
468 if ( childProcess && (! realQuiet) ) {
469 #ifdef BLEAH
470 fprintf(stdout, "SCHEDULE: MACHINE %d FRAMES %d-%d TIME %d-%d IOTIME %d\n",
471 machineNumber, frameStart, frameEnd,
472 framesTimeStart, framesTimeEnd,
473 IOtime);
474 #endif
475 fprintf(stdout, "%s: FRAMES %d-%d (%d seconds)\n",
476 getenv("HOST"), frameStart, frameEnd,
477 (int) (framesTimeEnd-framesTimeStart));
478 fflush(stdout);
479 }
480 } else {
481 /* check if parameter file has absolute path */
482 if ( (argv[argc-1][0] != '/') && (argv[argc-1][0] != '~') ) {
483 fprintf(stderr, "ERROR: For parallel execution, please use absolute path for parameter file!\n");
484 exit(1);
485 } else {
486 StartMasterServer(numInputFiles, argv[argc-1], outputFileName);
487 }
488 }
489 } else if ( function == COMBINE_GOPS ) {
490 GOPStoMPEG(numInputFiles, outputFileName, ofp);
491 } else if ( function == COMBINE_FRAMES ) {
492 FramesToMPEG(numInputFiles, outputFileName, ofp, FALSE);
493 }
494
495 if ( childProcess ) {
496 while ( NotifyMasterDone(hostName, portNumber, machineNumber,
497 totalTime,
498 &frameStart, &frameEnd) ) {
499 /* do more frames */
500 time(&framesTimeStart);
501 totalTime = GenMPEGStream(-1, frameStart, frameEnd,
502 customQtable, customNIQtable,
503 numInputFiles, NULL,
504 outputFileName);
505 time(&framesTimeEnd);
506
507 if (! realQuiet) {
508 #ifdef BLEAH
509 fprintf(stdout, "SCHEDULE: MACHINE %d FRAMES %d-%d TIME %d-%d IOTIME %d\n",
510 machineNumber, frameStart, frameEnd,
511 framesTimeStart, framesTimeEnd,
512 IOtime);
513 #endif
514 fprintf(stdout, "%s: FRAMES %d-%d (%d seconds)\n",
515 getenv("HOST"), frameStart, frameEnd,
516 (int) (framesTimeEnd-framesTimeStart));
517 fflush(stdout);
518 }
519
520 }
521 }
522
523 Frame_Exit();
524
525 return 0; /* all is well */
526 }
527
528
529 /*=====================*
530 * INTERNAL PROCEDURES *
531 *=====================*/
532
533 /*===========================================================================*
534 *
535 * Usage
536 *
537 * prints out usage for the program
538 *
539 * RETURNS: nothing
540 *
541 * SIDE EFFECTS: none
542 *
543 *===========================================================================*/
544 static void
545 Usage()
546 {
547 fprintf(stderr, "Usage: mpeg_encode [options] param_file\n");
548 fprintf(stderr, "Options:\n");
549 fprintf(stderr, "\t-stat stat_file: append stats to stat_file\n");
550 fprintf(stderr, "\t-quiet n: don't report remaining time for at least n seconds\n");
551 fprintf(stderr, "\t-realquiet: output nothing at all if successful\n");
552 fprintf(stderr, "\t-no_frame_summary: suppress frame summary lines\n");
553 fprintf(stderr, "\t-float_dct: use more accurate floating point DCT\n");
554 fprintf(stderr, "\t-gop gop_num: encode only the numbered GOP\n");
555 fprintf(stderr, "\t-combine_gops: combine GOP files instead of encode\n");
556 fprintf(stderr, "\t-frames first_frame last_frame: encode only the specified frames\n");
557 fprintf(stderr, "\t-combine_frames: combine frame files instead of encode\n");
558 fprintf(stderr, "\t-nice: run slave processes nicely\n");
559 fprintf(stderr, "\t-max_machines num_machines: use at most num_machines machines\n");
560 fprintf(stderr, "\t-snr: print signal-to-noise ratio\n");
561 fprintf(stderr, "\t-bit_rate_info rate_file: put bit rate in specified file\n");
562 fprintf(stderr, "\t-mv_histogram: show histograms of motion vectors\n");
563 exit(1);
564
565 /* extended usage (used by parallel code; shouldn't be called by user):
566 -child parallelHostName portNumber ioPortNumber combinePortNumber machineNumber remote
567 -io_server parallelHostName portNumber
568
569 (remote = 1 if need to use ioPortNumber)
570 */
571 }
572
573
574 static void
575 CompileTests()
576 {
577 assert(sizeof(uint8) == 1);
578 assert(sizeof(uint16) == 2);
579 assert(sizeof(uint32) == 4);
580 assert(sizeof(int8) == 1);
581 assert(sizeof(int16) == 2);
582 assert(sizeof(int32) == 4);
583
584 if ( (-8 >> 3) != -1 ) {
585 fprintf(stderr, "ERROR: Right shifts are NOT arithmetic!!!\n");
586 fprintf(stderr, "Change >> to multiplies by powers of 2\n");
587 exit(1);
588 }
589 }