/*===========================================================================*
* main.c *
* *
* Main procedure *
* *
* EXPORTED PROCEDURES: *
* main *
* *
*===========================================================================*/
/*
* Copyright (c) 1995 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
* $Header: /share/cvs/AFNI/src/mpeg_encodedir/main.c,v 1.4 2004/04/02 15:12:40 rwcox Exp $
* $Log: main.c,v $
* Revision 1.4 2004/04/02 15:12:40 rwcox
* Cput
*
* Revision 1.3 2003/12/23 13:50:08 rwcox
* Cput
*
* Revision 1.2 2003/12/03 14:46:14 rwcox
* Cput
*
* Revision 1.1 2001/12/17 16:11:54 rwcox
* Cadd
*
* Revision 1.25 1995/08/07 21:44:21 smoot
* renamed index -> idx; save the encoder's name; compute frame types ahead of time
*
* Revision 1.24 1995/06/21 18:25:57 smoot
* added binary write flag (DOS!)
*
* Revision 1.23 1995/05/16 06:25:28 smoot
* added TUNEing init and float-dct == float_dct
*
* Revision 1.22 1995/05/16 00:15:05 smoot
* fixed usage print
*
* Revision 1.21 1995/05/11 23:59:56 smoot
* *** empty log message ***
*
* Revision 1.20 1995/02/02 20:05:37 eyhung
* fixed smoot typo in 1.19
*
* Revision 1.19 1995/02/02 18:56:11 smoot
* ANSI-ified some prototypes
*
* Revision 1.18 1995/02/01 21:47:37 smoot
* cleanup
*
* Revision 1.17 1995/01/31 22:22:49 eyhung
* Fixed steve's typo and added float_dct to Usage()
*
* Revision 1.16 1995/01/31 21:44:08 smoot
* Added -float_dct option
*
* Revision 1.15 1995/01/31 01:19:39 eyhung
* removed -interactive
*
* Revision 1.14 1995/01/27 21:56:57 eyhung
* Deleted setting JMOVIE_TYPE to JPEG_TYPE since we need to know
* if we started with a JMOVIE for getting input files
*
* Revision 1.13 1995/01/19 23:50:06 eyhung
* Removed printing of output file to screen - done at end of encoding now.
*
* Revision 1.12 1995/01/19 23:08:41 eyhung
* Changed copyrights
*
* Revision 1.11 1995/01/17 08:25:44 eyhung
* added -interactive to Usage
*
* Revision 1.10 1995/01/17 08:24:53 eyhung
* Added -interactive option
*
* Revision 1.9 1995/01/16 08:04:10 eyhung
* More realQuiet stuff.
*
* Revision 1.8 1995/01/16 07:38:49 eyhung
* Added realquiet option
*
* Revision 1.7 1994/11/14 22:32:01 smoot
* Merged specifics and rate control
*
* Revision 1.6 1994/11/12 02:11:52 keving
* nothing
*
* Revision 1.5 1994/03/15 00:27:11 keving
* nothing
*
* Revision 1.4 1993/12/22 19:19:01 keving
* nothing
*
* Revision 1.3 1993/07/22 22:23:43 keving
* nothing
*
* Revision 1.2 1993/06/30 20:06:09 keving
* nothing
*
* Revision 1.1 1993/02/17 23:18:20 dwallach
* Initial revision
*
*/
/*==============*
* HEADER FILES *
*==============*/
#include <assert.h>
#include "all.h"
#include "mtypes.h"
#include "mpeg.h"
#include "search.h"
#include "prototypes.h"
#include "param.h"
#include "parallel.h"
#include "readframe.h"
#include "combine.h"
#include "frames.h"
#include "jpeg.h"
#include "specifics.h"
#include "opts.h"
#include <time.h>
int main _ANSI_ARGS_((int argc, char **argv));
/*==================*
* STATIC VARIABLES *
*==================*/
static int frameStart = -1;
static int frameEnd;
/*==================*
* GLOBAL VARIABLES *
*==================*/
extern time_t IOtime;
int whichGOP = -1;
boolean childProcess = FALSE;
boolean ioServer = FALSE;
boolean outputServer = FALSE;
boolean decodeServer = FALSE;
int quietTime = 0;
boolean realQuiet = FALSE;
boolean frameSummary = TRUE;
boolean debugSockets = FALSE;
boolean debugMachines = FALSE;
boolean showBitRatePerFrame = FALSE;
boolean computeMVHist = FALSE;
int baseFormat;
extern boolean specificsOn;
extern FrameSpecList *fsl;
boolean pureDCT=FALSE;
char encoder_name[1024];
/*===============================*
* INTERNAL PROCEDURE prototypes *
*===============================*/
static void Usage _ANSI_ARGS_((void));
static void CompileTests _ANSI_ARGS_((void));
/*================================*
* External PROCEDURE prototypes *
*================================*/
void init_idctref _ANSI_ARGS_((void));
void init_fdct _ANSI_ARGS_((void));
/*=====================*
* EXPORTED PROCEDURES *
*=====================*/
/*===========================================================================*
*
* main
*
* see man page. run without arguments to see usage
*
* RETURNS: 0 if all is well; 1 on most if not all errors
*
*===========================================================================*/
int
main(argc, argv)
int argc;
char **argv;
{
FILE *ofp = NULL;
register int idx;
int function = ENCODE_FRAMES;
int portNumber = 0;
char *hostName = NULL;
int32 totalTime = -1;
int maxMachines = 0x7fffffff;
int outputFrames = 0;
time_t initTimeStart;
time_t framesTimeStart, framesTimeEnd;
strcpy(encoder_name, argv[0]);
CompileTests();
time(&initTimeStart);
if ( argc == 1 ) {
Usage();
}
SetStatFileName("");
/* parse the arguments */
idx = 1;
while ( idx < argc-1 ) {
if ( argv[idx][0] != '-' ) {
Usage();
}
if ( strcmp(argv[idx], "-stat") == 0 ) {
if ( idx+1 < argc-1 ) {
SetStatFileName(argv[idx+1]);
idx += 2;
} else {
Usage();
}
} else if ( strcmp(argv[idx], "-gop") == 0 ) {
if ( (function != ENCODE_FRAMES) || (frameStart != -1) ) {
Usage();
}
if ( idx+1 < argc-1 ) {
whichGOP = atoi(argv[idx+1]);
idx += 2;
} else {
Usage();
}
} else if ( strcmp(argv[idx], "-frames") == 0 ) {
if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ) {
Usage();
}
if ( idx+2 < argc-1 ) {
frameStart = atoi(argv[idx+1]);
frameEnd = atoi(argv[idx+2]);
if ( (frameStart > frameEnd) || (frameStart < 0) ) {
fprintf(stderr, "ERROR: bad frame numbers!\n");
Usage();
}
idx += 3;
} else {
Usage();
}
} else if ( strcmp(argv[idx], "-combine_gops") == 0 ) {
if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ||
(frameStart != -1) ) {
Usage();
}
function = COMBINE_GOPS;
idx++;
} else if ( strcmp(argv[idx], "-combine_frames") == 0 ) {
if ( (function != ENCODE_FRAMES) || (whichGOP != -1) ||
(frameStart != -1) ) {
Usage();
}
function = COMBINE_FRAMES;
idx++;
} else if ( strcmp(argv[idx], "-child") == 0 ) {
if ( idx+7 < argc-1 ) {
hostName = argv[idx+1];
portNumber = atoi(argv[idx+2]);
ioPortNumber = atoi(argv[idx+3]);
combinePortNumber = atoi(argv[idx+4]);
decodePortNumber = atoi(argv[idx+5]);
machineNumber = atoi(argv[idx+6]);
remoteIO = atoi(argv[idx+7]);
IOhostName = hostName;
} else {
Usage();
}
childProcess = TRUE;
idx += 8;
} else if ( strcmp(argv[idx], "-io_server") == 0 ) {
if ( idx+2 < argc-1 ) {
hostName = argv[idx+1];
portNumber = atoi(argv[idx+2]);
} else {
Usage();
}
ioServer = TRUE;
idx += 3;
} else if ( strcmp(argv[idx], "-output_server") == 0 ) {
if ( idx+3 < argc-1 ) {
hostName = argv[idx+1];
portNumber = atoi(argv[idx+2]);
outputFrames = atoi(argv[idx+3]);
} else {
Usage();
}
function = COMBINE_FRAMES;
outputServer = TRUE;
idx += 4;
} else if ( strcmp(argv[idx], "-decode_server") == 0 ) {
if ( idx+3 < argc-1 ) {
hostName = argv[idx+1];
portNumber = atoi(argv[idx+2]);
outputFrames = atoi(argv[idx+3]);
} else {
Usage();
}
function = COMBINE_FRAMES;
decodeServer = TRUE;
idx += 4;
} else if ( strcmp(argv[idx], "-nice") == 0 ) {
niceProcesses = TRUE;
idx++;
} else if ( strcmp(argv[idx], "-max_machines") == 0 ) {
if ( idx+1 < argc-1 ) {
maxMachines = atoi(argv[idx+1]);
} else {
Usage();
}
idx += 2;
} else if ( strcmp(argv[idx], "-quiet") == 0 ) {
if ( idx+1 < argc-1 ) {
quietTime = atoi(argv[idx+1]);
} else {
Usage();
}
idx += 2;
} else if ( strcmp(argv[idx], "-realquiet") == 0 ) {
realQuiet = TRUE;
idx++;
} else if (( strcmp(argv[idx], "-float_dct") == 0 ) ||
( strcmp(argv[idx], "-float-dct") == 0 )) {
pureDCT = TRUE;
init_idctref();
init_fdct();
idx++;
} else if ( strcmp(argv[idx], "-no_frame_summary") == 0 ) {
if ( idx < argc-1 ) {
frameSummary = FALSE;
} else {
Usage();
}
idx++;
} else if ( strcmp(argv[idx], "-snr") == 0 ) {
printSNR = TRUE;
idx++;
} else if ( strcmp(argv[idx], "-mse") == 0 ) {
printSNR = printMSE = TRUE;
idx++;
} else if ( strcmp(argv[idx], "-debug_sockets") == 0 ) {
debugSockets = TRUE;
idx++;
} else if ( strcmp(argv[idx], "-debug_machines") == 0 ) {
debugMachines = TRUE;
idx++;
} else if ( strcmp(argv[idx], "-bit_rate_info") == 0 ) {
if ( idx+1 < argc-1 ) {
showBitRatePerFrame = TRUE;
SetBitRateFileName(argv[idx+1]);
idx += 2;
} else {
Usage();
}
} else if ( strcmp(argv[idx], "-mv_histogram") == 0 ) {
computeMVHist = TRUE;
idx++;
} else {
Usage();
}
}
if ( ! ReadParamFile(argv[argc-1], function) ) {
Usage();
}
/* Jim Boucher's stuff:
if we are using a movie format then break up into frames*/
if ( (!childProcess) && (baseFormat == JMOVIE_FILE_TYPE) ) {
JM2JPEG();
}
if ( printSNR || (referenceFrame == DECODED_FRAME) ) {
decodeRefFrames = TRUE;
}
numMachines = min(numMachines, maxMachines);
Tune_Init();
Frame_Init();
#ifdef BLEAH
time_t initTimeEnd;
time(&initTimeEnd);
fprintf(stdout, "INIT TIME: %d seconds\n",
initTimeEnd-initTimeStart);
fflush(stdout);
#endif
if (specificsOn) Specifics_Init();
ComputeFrameTable();
if ( ioServer ) {
StartIOServer(numInputFiles, hostName, portNumber);
return 0;
} else if ( outputServer ) {
StartCombineServer(outputFrames, outputFileName, hostName, portNumber);
return 0;
} else if ( decodeServer ) {
StartDecodeServer(outputFrames, outputFileName, hostName, portNumber);
return 0;
}
if ( (frameStart == -1) &&
((numMachines == 0) || (function != ENCODE_FRAMES)) ) {
if ( (ofp = fopen(outputFileName, "wb")) == NULL ) {
fprintf(stderr, "ERROR: Could not open output file!\n");
exit(1);
}
}
if ( function == ENCODE_FRAMES ) {
if ( (numMachines == 0) || (frameStart != -1) ) {
time(&framesTimeStart);
totalTime = GenMPEGStream(whichGOP, frameStart, frameEnd,
customQtable, customNIQtable,
numInputFiles, ofp,
outputFileName);
time(&framesTimeEnd);
if ( childProcess && (! realQuiet) ) {
#ifdef BLEAH
fprintf(stdout, "SCHEDULE: MACHINE %d FRAMES %d-%d TIME %d-%d IOTIME %d\n",
machineNumber, frameStart, frameEnd,
framesTimeStart, framesTimeEnd,
IOtime);
#endif
fprintf(stdout, "%s: FRAMES %d-%d (%d seconds)\n",
getenv("HOST"), frameStart, frameEnd,
(int) (framesTimeEnd-framesTimeStart));
fflush(stdout);
}
} else {
/* check if parameter file has absolute path */
if ( (argv[argc-1][0] != '/') && (argv[argc-1][0] != '~') ) {
fprintf(stderr, "ERROR: For parallel execution, please use absolute path for parameter file!\n");
exit(1);
} else {
StartMasterServer(numInputFiles, argv[argc-1], outputFileName);
}
}
} else if ( function == COMBINE_GOPS ) {
GOPStoMPEG(numInputFiles, outputFileName, ofp);
} else if ( function == COMBINE_FRAMES ) {
FramesToMPEG(numInputFiles, outputFileName, ofp, FALSE);
}
if ( childProcess ) {
while ( NotifyMasterDone(hostName, portNumber, machineNumber,
totalTime,
&frameStart, &frameEnd) ) {
/* do more frames */
time(&framesTimeStart);
totalTime = GenMPEGStream(-1, frameStart, frameEnd,
customQtable, customNIQtable,
numInputFiles, NULL,
outputFileName);
time(&framesTimeEnd);
if (! realQuiet) {
#ifdef BLEAH
fprintf(stdout, "SCHEDULE: MACHINE %d FRAMES %d-%d TIME %d-%d IOTIME %d\n",
machineNumber, frameStart, frameEnd,
framesTimeStart, framesTimeEnd,
IOtime);
#endif
fprintf(stdout, "%s: FRAMES %d-%d (%d seconds)\n",
getenv("HOST"), frameStart, frameEnd,
(int) (framesTimeEnd-framesTimeStart));
fflush(stdout);
}
}
}
Frame_Exit();
return 0; /* all is well */
}
/*=====================*
* INTERNAL PROCEDURES *
*=====================*/
/*===========================================================================*
*
* Usage
*
* prints out usage for the program
*
* RETURNS: nothing
*
* SIDE EFFECTS: none
*
*===========================================================================*/
static void
Usage()
{
fprintf(stderr, "Usage: mpeg_encode [options] param_file\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, "\t-stat stat_file: append stats to stat_file\n");
fprintf(stderr, "\t-quiet n: don't report remaining time for at least n seconds\n");
fprintf(stderr, "\t-realquiet: output nothing at all if successful\n");
fprintf(stderr, "\t-no_frame_summary: suppress frame summary lines\n");
fprintf(stderr, "\t-float_dct: use more accurate floating point DCT\n");
fprintf(stderr, "\t-gop gop_num: encode only the numbered GOP\n");
fprintf(stderr, "\t-combine_gops: combine GOP files instead of encode\n");
fprintf(stderr, "\t-frames first_frame last_frame: encode only the specified frames\n");
fprintf(stderr, "\t-combine_frames: combine frame files instead of encode\n");
fprintf(stderr, "\t-nice: run slave processes nicely\n");
fprintf(stderr, "\t-max_machines num_machines: use at most num_machines machines\n");
fprintf(stderr, "\t-snr: print signal-to-noise ratio\n");
fprintf(stderr, "\t-bit_rate_info rate_file: put bit rate in specified file\n");
fprintf(stderr, "\t-mv_histogram: show histograms of motion vectors\n");
exit(1);
/* extended usage (used by parallel code; shouldn't be called by user):
-child parallelHostName portNumber ioPortNumber combinePortNumber machineNumber remote
-io_server parallelHostName portNumber
(remote = 1 if need to use ioPortNumber)
*/
}
static void
CompileTests()
{
assert(sizeof(uint8) == 1);
assert(sizeof(uint16) == 2);
assert(sizeof(uint32) == 4);
assert(sizeof(int8) == 1);
assert(sizeof(int16) == 2);
assert(sizeof(int32) == 4);
if ( (-8 >> 3) != -1 ) {
fprintf(stderr, "ERROR: Right shifts are NOT arithmetic!!!\n");
fprintf(stderr, "Change >> to multiplies by powers of 2\n");
exit(1);
}
}
syntax highlighted by Code2HTML, v. 0.9.1