home *** CD-ROM | disk | FTP | other *** search
- /*
- * This is the main part
- */
-
- #include <intuition/screens.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
-
- #include "video.h"
- #include "proto.h"
- #include <sys/types.h>
- #include <signal.h>
-
- #include <proto/timer.h>
- #include <devices/timer.h>
-
- #define ASIO_REGARGS
- #include <clib/asyncio_protos.h>
-
- #include "util.h"
-
- #define HELP_TEXT "NOB\t- ignore and not display any B frames.\n\
- NOP\t- ignore and not display any P frames.\n\
- LOOP\t- makes the player loop back to the beginning after reaching the end.\n\
- EACHSTAT- causes statistics to be displayed after each frame.\n\
- \t Only valid when compiled with -DANALYSIS\n\
- NODISPLAY- dithers, but does not display, usually used for\n\
- \t testing and timing purposes.\n\
- QUIET\t- supresses printing of frame numbers, timing information,\n\
- \t and most error messages.\n\
- DITHER\t- selects from a variety of dither options.\n\
- \t The possible values are:\n\
- \t\tcolor\n\
- \t\thiresham\n\
- \t\tham6\n\
- \t\tcybergfx\n\
- \t\tcybergfxgray\n\
- \t\tgray\n\
- \t\tnone\n\
- PUBSCREEN- open window on selected \"deep\" public screen. Only valid\n\
- \t with DITHER cybergfx or cybergfxgray. Use with \"DEFAULT\" to open\n\
- \t on current default public screen.\n\
- MODEID\t- select modeid for screen to open and play on.\n\
- FRAMERATE- speed in frames per second. (0 - as fast as possible).\n\
- BUFFER\t- size of the io buffer (default - 65536).\n\
- FILE\t- filename of MPEG stream.\n"
-
- #define TEMPLATE "NOB/S,NOP/S,LOOP/S,EACHSTAT/S,ND=NODISPLAY/S,QUIET/S,DITHER/K,PS=PUBSCREEN/K,MODEID/K,FRAMERATE=FPS/K,BUFFER=BUF/K,FILE/A"
-
- #define OPT_NOB 0
- #define OPT_NOP 1
- #define OPT_LOOP 2
- #define OPT_EACHSTAT 3
- #define OPT_NODISPLAY 4
- #define OPT_QUIET 5
- #define OPT_DITHER 6
- #define OPT_PUBSCREEN 7
- #define OPT_MODEID 8
- #define OPT_FPS 9
- #define OPT_BUFFER 10
- #define OPT_FILE 11
- #define OPT_COUNT 12
-
-
- const char *dither_names = "ham6\1color\1hiresham\1ham6\1cybergfx\1cybergfxgray\1gray\1none";
- /* 01234 56789 1113151719 2123 2527293133 353739414345 474951 53
- got it? :) 10 12141618 202224 26283032 34363840424446 4850 525456
- */
-
- char animname[1024];
- char pubscreen_name[MAXPUBSCREENNAME + 1];
- char *pubname_ptr;
-
- /* Declaration of global variable to hold dither info. */
-
- int ditherType;
-
- /* size of the io buffer */
-
- int buf_length = 65536;
-
- /* Global file pointer to incoming data. */
- struct AsyncFile *input;
-
- /* End of File flag. */
- static int EOF_flag = 0;
-
- /* Loop flag. */
- int loopFlag = 0;
-
- /* Quiet flag. */
- int quietFlag = 0;
-
- /* Display image on screen? */
- int noDisplayFlag = 0;
-
- /* Setjmp/Longjmp env. */
- jmp_buf env;
-
- /* HAM6 rendering / HAM hires flag */
- extern int ham6, lores;
-
- /* modeid of CyberGraphX screen */
- unsigned long modeid = 0xffffffff;
-
- /* are we going to play on the Public Screen? */
- int cyber_pub = 0;
-
- /* Framerate, -1: specified in stream (default)
- 0: as fast as possible
- N (N>0): N frames/sec
- */
- int framerate = -1;
-
- /* these are for timer.device */
- struct Library *TimerBase;
- struct MsgPort *TimerMP; /* Message port pointer */
- struct timerequest *TimerIO; /* I/O structure pointer */
-
- /* Method of picture conversion */
- void (*DoDitherImage)(unsigned char *l, unsigned char *Cr, unsigned char *Cb,
- unsigned char *disp, int h, int w);
-
- static char version[]="$VER: aMiPEG 0.7 (compiled on " __DATE__ ", " __TIME__ ")\n";
-
- /*
- *--------------------------------------------------------------
- *
- * get_more_data --
- *
- * Called by correct_underflow in bit parsing utilities to
- * read in more data.
- *
- * Results:
- * Input buffer updated, buffer length updated.
- * Returns 1 if data read, 0 if EOF, -1 if error.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- int get_more_data(unsigned int *buf_start, int max_length, int *length_ptr, unsigned int **buf_ptr)
- {
-
- int length, num_read, request;
- unsigned char *buffer, *mark;
-
- if (EOF_flag) return 0;
-
- length = *length_ptr;
- buffer = (unsigned char *) *buf_ptr;
-
- if (length > 0) {
- memcpy((unsigned char *) buf_start, buffer, (length*4));
- mark = ((unsigned char *) (buf_start + length));
- }
- else {
- mark = (unsigned char *) buf_start;
- length = 0;
- }
-
- request = (max_length-length)*4;
-
- // num_read = fread( mark, 1, request, input);
- num_read = ReadAsync(input, mark, request);
-
- /* Paulo Villegas - 26/1/1993: Correction for 4-byte alignment */
- {
- int num_read_rounded;
- unsigned char *index;
-
- num_read_rounded = num_read & 0xfffffffc;
-
- /* this can happen only if num_read<request; i.e. end of file reached */
- if( num_read_rounded < num_read )
- {
- num_read_rounded+=4;
- /* fill in with zeros */
- for( index=mark+num_read; index<mark+num_read_rounded; *(index++)=0 );
- /* advance to the next 4-byte boundary */
- num_read = num_read_rounded;
- }
- }
-
- if (num_read < 0) {
- return -1;
- }
- else if (num_read == 0) {
- *buf_ptr = buf_start;
-
- /* Make 32 bits after end equal to 0 and 32
- bits after that equal to seq end code
- in order to prevent messy data from infinite
- recursion.
- */
-
- *(buf_start + length) = 0x0;
- *(buf_start + length+1) = SEQ_END_CODE;
-
- EOF_flag = 1;
- return 0;
- }
-
- num_read >>= 2;
-
- *buf_ptr = buf_start;
- *length_ptr = length + num_read;
-
- return 1;
- }
-
- /*
- *--------------------------------------------------------------
- *
- * int_handler --
- *
- * Handles Cntl-C interupts..
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
- void int_handler(int dummy)
- {
- if (!quietFlag) fprintf(stderr, "Interrupted!\n");
- if (curVidStream) DestroyVidStream(curVidStream);
-
- if(input)
- CloseAsync(input);
-
- exit(1);
- }
-
-
- /*
- *--------------------------------------------------------------
- *
- * init_timer --
- *
- * Prepare timer.device and IORequest for later use
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- void init_timer(void)
- {
- /* Create port for timer device communications */
- if(TimerMP = CreatePort(NULL, 0))
- /* Create message block for device IO */
- if(TimerIO = (struct timerequest *)CreateExtIO(TimerMP, sizeof(struct timerequest)))
-
- /* Open the timer device with UNIT_MICROHZ */
- if(!OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *)TimerIO, 0))
- {
- TimerBase = (struct Library *)TimerIO->tr_node.io_Device;
- TimerIO->tr_node.io_Command = TR_ADDREQUEST;
- return;
- }
- else
- fprintf(stderr, "Error: Can't open Timer.device\n");
- else
- fprintf(stderr, "Error: Can't create IO request\n");
- else
- fprintf(stderr, "Error: Can't create port\n");
-
- exit(1);
- }
- /*
- *--------------------------------------------------------------
- *
- * close_timer --
- *
- * Close timer.device, remove IORequest and message port
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- void close_timer(void)
- {
- if(TimerBase)
- CloseDevice((struct IORequest *)TimerIO); /* Close Timer device */
-
- if(TimerIO)
- DeleteExtIO((struct IORequest *)TimerIO);
-
- if(TimerMP)
- DeletePort(TimerMP);
- }
-
- /*
- *--------------------------------------------------------------
- *
- * main --
- *
- * Parses command line, starts decoding and displaying.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *--------------------------------------------------------------
- */
-
- void main(int argc, char **argv)
- {
- static VidStream *theStream;
- extern int lores;
- LONG opts[OPT_COUNT];
- struct RDArgs *rdargs;
-
- ditherType = FULL_COLOR_DITHER;
- noDisplayFlag = 0;
-
- memset(opts, 0, sizeof(opts));
-
- if(rdargs = (struct RDArgs *)AllocDosObject(DOS_RDARGS, NULL))
- {
- rdargs->RDA_ExtHelp = HELP_TEXT;
-
- if(rdargs = ReadArgs(TEMPLATE, opts, rdargs))
- {
- if(opts[OPT_NOP])
- TogglePFlag();
-
- if(opts[OPT_NOB])
- ToggleBFlag();
-
- if(opts[OPT_DITHER])
- {
- switch(strstr(dither_names, strlwr((char *)opts[OPT_DITHER])) - dither_names)
- {
- case 5: /* color */
- ditherType = FULL_COLOR_DITHER;
- break;
-
- case 11: /* hiresham */
- ditherType = FULL_COLOR_DITHER;
- lores = FALSE;
- break;
-
- case 0: /* ham6 */
- ditherType = FULL_COLOR_DITHER;
- ham6 = TRUE;
- break;
-
- case 25: /* cybergfx */
- ditherType = CYBERGFX_DITHER;
- break;
-
- case 34: /* cybergfxgray */
- ditherType = CYBERGFXGRAY_DITHER;
- break;
-
- case 42: /* gray */
- ditherType = GRAY_DITHER;
- break;
-
- case 52: /* none */
- ditherType = NO_DITHER;
- break;
-
- default:
- fprintf(stderr, "You should specify legal dither name after DITHER keyword.\n");
- FreeArgs(rdargs);
- exit(10);
- }
- }
-
- if(opts[OPT_EACHSTAT])
- #ifdef ANALYSIS
- showEachFlag = 1;
- #else
- {
- fprintf(stderr, "To use EACHSTAT, recompile with DEFINE ANALYSIS in CFLAGS\n");
- exit(1);
- }
- #endif
-
- if(opts[OPT_QUIET])
- quietFlag = 1;
-
- if(opts[OPT_LOOP])
- loopFlag = 1;
-
- if(opts[OPT_NODISPLAY])
- noDisplayFlag = 1;
-
- if(opts[OPT_PUBSCREEN])
- {
- if(!stricmp("default", (char *)opts[OPT_PUBSCREEN]))
- pubname_ptr = NULL;
- else
- {
- strcpy(pubscreen_name, (char *)opts[OPT_PUBSCREEN]);
- pubname_ptr = pubscreen_name;
- }
-
- cyber_pub = 1;
- }
-
- if(opts[OPT_MODEID])
- if(sscanf((char *)opts[OPT_MODEID], "%x", &modeid) != 1)
- {
- fprintf(stderr, "ModeID should be an hexadecimal value.\n");
- FreeArgs(rdargs);
- exit(10);
- }
-
- if(opts[OPT_FPS])
- if(sscanf((char *)opts[OPT_FPS], "%d", &framerate) != 1)
- {
- fprintf(stderr, "You should specify a number after FRAMERATE keyword.\n");
- FreeArgs(rdargs);
- exit(10);
- }
-
- if(opts[OPT_BUFFER])
- if(sscanf((char *)opts[OPT_BUFFER], "%d", &buf_length) != 1)
- {
- fprintf(stderr, "You should specify a number after BUFFER keyword.\n");
- FreeArgs(rdargs);
- exit(10);
- }
-
- if(opts[OPT_FILE])
- {
- // input = fopen((char *)opts[OPT_FILE], "r");
-
- input = OpenAsync((char *)opts[OPT_FILE], MODE_READ, buf_length);
-
- if(input == NULL)
- {
- fprintf(stderr, "Could not open file %s\n", (char *)opts[OPT_FILE]);
- FreeArgs(rdargs);
- exit(10);
- }
-
- strcpy(animname, (char *)opts[OPT_FILE]);
-
- signal(SIGINT, int_handler);
-
- init_tables();
-
- switch (ditherType)
- {
- case CYBERGFX_DITHER:
- InitColorDither();
- modeid = InitCyberGfxDisplay(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawCyberGfxImage;
- DoDitherImage = ColorDitherImage_RGB;
- break;
-
- case CYBERGFXGRAY_DITHER:
- InitColorDither();
- modeid = InitCyberGfxDisplay(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawCyberGfxImage;
- DoDitherImage = NoDitherImage;
- break;
-
- case GRAY_DITHER:
- InitColorDither();
- modeid = InitGrayDisplay(modeid);
- HAM8_draw = (void (*)(void *, int, int)) DrawGrayImage;
- DoDitherImage = NoDitherImage;
- break;
-
- case FULL_COLOR_DITHER:
- InitColorDither();
- InitColorDisplay();
- break;
-
- case NO_DITHER:
- HAM8_draw = (void (*)(void *, int, int)) NoDitherImage; // method casting ... argh!
- DoDitherImage = NoDitherImage;
- break;
- }
-
- init_timer();
-
- /*
- * The new restart handling has not been checked out very closely with changing
- * (non)intra scale matrices!
- */
-
- theStream = NewVidStream(buf_length);
-
- if (setjmp(env) != 0)
- {
- mpegInitVidRsrc(); /* fix bug in static first in mpegVidRsrc */
-
- // rewind(input);
- SeekAsync(input, 0, MODE_START);
-
- EOF_flag = 0;
- theStream->bit_offset = 0;
- theStream->buf_length = 0;
- theStream->buffer = NULL;
- totNumFrames = 0;
- #ifdef ANALYSIS
- init_stats();
- #endif
- }
-
- realTimeStart = ReadSysClock();
- while (mpegVidRsrc(0, theStream));
-
- CloseAsync(input);
- }
-
- FreeArgs(rdargs);
- }
- else
- {
- PrintFault(IoErr(), argv[0]);
- exit(10);
- }
-
- FreeDosObject(DOS_RDARGS, rdargs);
- }
- else
- {
- PrintFault(IoErr(), argv[0]);
- exit(10);
- }
- }
-
-
- /*
- * Dummy display method
- *
- */
- void NoDitherImage(unsigned char *l, unsigned char *Cr, unsigned char *Cb,
- unsigned char *disp, int h, int w)
- {}
-
-