ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/freemol/trunk/src/mpeg_encode/src/main.c
Revision: 22
Committed: Mon Jul 7 22:16:37 2008 UTC (11 years ago) by wdelano
File size: 15557 byte(s)
Log Message:
initial checkin of mpeg_encode source
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 if ( argc == 1 ) {
219 Usage();
220 }
221
222 SetStatFileName("");
223
224 /* parse the arguments */
225 idx = 1;
226 while ( idx < argc-1 ) {
227 if ( argv[idx][0] != '-' ) {
228 Usage();
229 }
230
231 if ( strcmp(argv[idx], "-stat") == 0 ) {
232 if ( idx+1 < argc-1 ) {
233 SetStatFileName(argv[idx+1]);
234 idx += 2;
235 } else {
236 Usage();
237 }
238 } else if ( strcmp(argv[idx], "-gop") == 0 ) {
239 if ( (function != ENCODE_FRAMES) || (frameStart != -1) ) {
240 Usage();
241 }
242
243 if ( idx+1 < argc-1 ) {
244 whichGOP = atoi(argv[idx+1]);
245 idx += 2;
246 } else {
247 Usage();
248 }
249 } else if ( strcmp(argv[idx], "-frames") == 0 ) {
250 if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ) {
251 Usage();
252 }
253
254 if ( idx+2 < argc-1 ) {
255 frameStart = atoi(argv[idx+1]);
256 frameEnd = atoi(argv[idx+2]);
257
258 if ( (frameStart > frameEnd) || (frameStart < 0) ) {
259 fprintf(stderr, "ERROR: bad frame numbers!\n");
260 Usage();
261 }
262
263 idx += 3;
264 } else {
265 Usage();
266 }
267 } else if ( strcmp(argv[idx], "-combine_gops") == 0 ) {
268 if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ||
269 (frameStart != -1) ) {
270 Usage();
271 }
272
273 function = COMBINE_GOPS;
274 idx++;
275 } else if ( strcmp(argv[idx], "-combine_frames") == 0 ) {
276 if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ||
277 (frameStart != -1) ) {
278 Usage();
279 }
280
281 function = COMBINE_FRAMES;
282 idx++;
283 } else if ( strcmp(argv[idx], "-child") == 0 ) {
284 if ( idx+7 < argc-1 ) {
285 hostName = argv[idx+1];
286 portNumber = atoi(argv[idx+2]);
287 ioPortNumber = atoi(argv[idx+3]);
288 combinePortNumber = atoi(argv[idx+4]);
289 decodePortNumber = atoi(argv[idx+5]);
290 machineNumber = atoi(argv[idx+6]);
291 remoteIO = atoi(argv[idx+7]);
292
293 IOhostName = hostName;
294 } else {
295 Usage();
296 }
297
298 childProcess = TRUE;
299 idx += 8;
300 } else if ( strcmp(argv[idx], "-io_server") == 0 ) {
301 if ( idx+2 < argc-1 ) {
302 hostName = argv[idx+1];
303 portNumber = atoi(argv[idx+2]);
304 } else {
305 Usage();
306 }
307
308 ioServer = TRUE;
309 idx += 3;
310 } else if ( strcmp(argv[idx], "-output_server") == 0 ) {
311 if ( idx+3 < argc-1 ) {
312 hostName = argv[idx+1];
313 portNumber = atoi(argv[idx+2]);
314 outputFrames = atoi(argv[idx+3]);
315 } else {
316 Usage();
317 }
318
319 function = COMBINE_FRAMES;
320 outputServer = TRUE;
321 idx += 4;
322 } else if ( strcmp(argv[idx], "-decode_server") == 0 ) {
323 if ( idx+3 < argc-1 ) {
324 hostName = argv[idx+1];
325 portNumber = atoi(argv[idx+2]);
326 outputFrames = atoi(argv[idx+3]);
327 } else {
328 Usage();
329 }
330
331 function = COMBINE_FRAMES;
332 decodeServer = TRUE;
333 idx += 4;
334 } else if ( strcmp(argv[idx], "-nice") == 0 ) {
335 niceProcesses = TRUE;
336 idx++;
337 } else if ( strcmp(argv[idx], "-max_machines") == 0 ) {
338 if ( idx+1 < argc-1 ) {
339 maxMachines = atoi(argv[idx+1]);
340 } else {
341 Usage();
342 }
343
344 idx += 2;
345 } else if ( strcmp(argv[idx], "-quiet") == 0 ) {
346 if ( idx+1 < argc-1 ) {
347 quietTime = atoi(argv[idx+1]);
348 } else {
349 Usage();
350 }
351
352 idx += 2;
353 } else if ( strcmp(argv[idx], "-realquiet") == 0 ) {
354 realQuiet = TRUE;
355 idx++;
356 } else if (( strcmp(argv[idx], "-float_dct") == 0 ) ||
357 ( strcmp(argv[idx], "-float-dct") == 0 )) {
358 pureDCT = TRUE;
359 init_idctref();
360 init_fdct();
361 idx++;
362 } else if ( strcmp(argv[idx], "-no_frame_summary") == 0 ) {
363 if ( idx < argc-1 ) {
364 frameSummary = FALSE;
365 } else {
366 Usage();
367 }
368
369 idx++;
370 } else if ( strcmp(argv[idx], "-snr") == 0 ) {
371 printSNR = TRUE;
372 idx++;
373 } else if ( strcmp(argv[idx], "-mse") == 0 ) {
374 printSNR = printMSE = TRUE;
375 idx++;
376 } else if ( strcmp(argv[idx], "-debug_sockets") == 0 ) {
377 debugSockets = TRUE;
378 idx++;
379 } else if ( strcmp(argv[idx], "-debug_machines") == 0 ) {
380 debugMachines = TRUE;
381 idx++;
382 } else if ( strcmp(argv[idx], "-bit_rate_info") == 0 ) {
383 if ( idx+1 < argc-1 ) {
384 showBitRatePerFrame = TRUE;
385 SetBitRateFileName(argv[idx+1]);
386 idx += 2;
387 } else {
388 Usage();
389 }
390 } else if ( strcmp(argv[idx], "-mv_histogram") == 0 ) {
391 computeMVHist = TRUE;
392 idx++;
393 } else {
394 Usage();
395 }
396 }
397
398 if ( ! ReadParamFile(argv[argc-1], function) ) {
399 Usage();
400 }
401
402 /* Jim Boucher's stuff:
403 if we are using a movie format then break up into frames*/
404 if ( (!childProcess) && (baseFormat == JMOVIE_FILE_TYPE) ) {
405 JM2JPEG();
406 }
407
408 if ( printSNR || (referenceFrame == DECODED_FRAME) ) {
409 decodeRefFrames = TRUE;
410 }
411
412 numMachines = min(numMachines, maxMachines);
413
414 Tune_Init();
415 Frame_Init();
416
417 #ifdef BLEAH
418 time_t initTimeEnd;
419
420 time(&initTimeEnd);
421 fprintf(stdout, "INIT TIME: %d seconds\n",
422 initTimeEnd-initTimeStart);
423 fflush(stdout);
424 #endif
425
426 if (specificsOn) Specifics_Init();
427
428 ComputeFrameTable();
429
430 if ( ioServer ) {
431 StartIOServer(numInputFiles, hostName, portNumber);
432 return 0;
433 } else if ( outputServer ) {
434 StartCombineServer(outputFrames, outputFileName, hostName, portNumber);
435 return 0;
436 } else if ( decodeServer ) {
437 StartDecodeServer(outputFrames, outputFileName, hostName, portNumber);
438 return 0;
439 }
440
441 if ( (frameStart == -1) &&
442 ((numMachines == 0) || (function != ENCODE_FRAMES)) ) {
443 if ( (ofp = fopen(outputFileName, "wb")) == NULL ) {
444 fprintf(stderr, "ERROR: Could not open output file!\n");
445 exit(1);
446 }
447 }
448
449 if ( function == ENCODE_FRAMES ) {
450 if ( (numMachines == 0) || (frameStart != -1) ) {
451 time(&framesTimeStart);
452 totalTime = GenMPEGStream(whichGOP, frameStart, frameEnd,
453 customQtable, customNIQtable,
454 numInputFiles, ofp,
455 outputFileName);
456 time(&framesTimeEnd);
457 if ( childProcess && (! realQuiet) ) {
458 #ifdef BLEAH
459 fprintf(stdout, "SCHEDULE: MACHINE %d FRAMES %d-%d TIME %d-%d IOTIME %d\n",
460 machineNumber, frameStart, frameEnd,
461 framesTimeStart, framesTimeEnd,
462 IOtime);
463 #endif
464 fprintf(stdout, "%s: FRAMES %d-%d (%d seconds)\n",
465 getenv("HOST"), frameStart, frameEnd,
466 (int) (framesTimeEnd-framesTimeStart));
467 fflush(stdout);
468 }
469 } else {
470 /* check if parameter file has absolute path */
471 if ( (argv[argc-1][0] != '/') && (argv[argc-1][0] != '~') ) {
472 fprintf(stderr, "ERROR: For parallel execution, please use absolute path for parameter file!\n");
473 exit(1);
474 } else {
475 StartMasterServer(numInputFiles, argv[argc-1], outputFileName);
476 }
477 }
478 } else if ( function == COMBINE_GOPS ) {
479 GOPStoMPEG(numInputFiles, outputFileName, ofp);
480 } else if ( function == COMBINE_FRAMES ) {
481 FramesToMPEG(numInputFiles, outputFileName, ofp, FALSE);
482 }
483
484 if ( childProcess ) {
485 while ( NotifyMasterDone(hostName, portNumber, machineNumber,
486 totalTime,
487 &frameStart, &frameEnd) ) {
488 /* do more frames */
489 time(&framesTimeStart);
490 totalTime = GenMPEGStream(-1, frameStart, frameEnd,
491 customQtable, customNIQtable,
492 numInputFiles, NULL,
493 outputFileName);
494 time(&framesTimeEnd);
495
496 if (! realQuiet) {
497 #ifdef BLEAH
498 fprintf(stdout, "SCHEDULE: MACHINE %d FRAMES %d-%d TIME %d-%d IOTIME %d\n",
499 machineNumber, frameStart, frameEnd,
500 framesTimeStart, framesTimeEnd,
501 IOtime);
502 #endif
503 fprintf(stdout, "%s: FRAMES %d-%d (%d seconds)\n",
504 getenv("HOST"), frameStart, frameEnd,
505 (int) (framesTimeEnd-framesTimeStart));
506 fflush(stdout);
507 }
508
509 }
510 }
511
512 Frame_Exit();
513
514 return 0; /* all is well */
515 }
516
517
518 /*=====================*
519 * INTERNAL PROCEDURES *
520 *=====================*/
521
522 /*===========================================================================*
523 *
524 * Usage
525 *
526 * prints out usage for the program
527 *
528 * RETURNS: nothing
529 *
530 * SIDE EFFECTS: none
531 *
532 *===========================================================================*/
533 static void
534 Usage()
535 {
536 fprintf(stderr, "Usage: mpeg_encode [options] param_file\n");
537 fprintf(stderr, "Options:\n");
538 fprintf(stderr, "\t-stat stat_file: append stats to stat_file\n");
539 fprintf(stderr, "\t-quiet n: don't report remaining time for at least n seconds\n");
540 fprintf(stderr, "\t-realquiet: output nothing at all if successful\n");
541 fprintf(stderr, "\t-no_frame_summary: suppress frame summary lines\n");
542 fprintf(stderr, "\t-float_dct: use more accurate floating point DCT\n");
543 fprintf(stderr, "\t-gop gop_num: encode only the numbered GOP\n");
544 fprintf(stderr, "\t-combine_gops: combine GOP files instead of encode\n");
545 fprintf(stderr, "\t-frames first_frame last_frame: encode only the specified frames\n");
546 fprintf(stderr, "\t-combine_frames: combine frame files instead of encode\n");
547 fprintf(stderr, "\t-nice: run slave processes nicely\n");
548 fprintf(stderr, "\t-max_machines num_machines: use at most num_machines machines\n");
549 fprintf(stderr, "\t-snr: print signal-to-noise ratio\n");
550 fprintf(stderr, "\t-bit_rate_info rate_file: put bit rate in specified file\n");
551 fprintf(stderr, "\t-mv_histogram: show histograms of motion vectors\n");
552 exit(1);
553
554 /* extended usage (used by parallel code; shouldn't be called by user):
555 -child parallelHostName portNumber ioPortNumber combinePortNumber machineNumber remote
556 -io_server parallelHostName portNumber
557
558 (remote = 1 if need to use ioPortNumber)
559 */
560 }
561
562
563 static void
564 CompileTests()
565 {
566 assert(sizeof(uint8) == 1);
567 assert(sizeof(uint16) == 2);
568 assert(sizeof(uint32) == 4);
569 assert(sizeof(int8) == 1);
570 assert(sizeof(int16) == 2);
571 assert(sizeof(int32) == 4);
572
573 if ( (-8 >> 3) != -1 ) {
574 fprintf(stderr, "ERROR: Right shifts are NOT arithmetic!!!\n");
575 fprintf(stderr, "Change >> to multiplies by powers of 2\n");
576 exit(1);
577 }
578 }