_ABOVE REAL-TIME TRAINING AND THE HYPER-TIME ALGORITHM_ by Dutch Guckenberger, Liz Guckenberger, Frank Luongo, Kay Stanney, Jose Sepulveda Listing One { /* ***************************************************************** ** ECC INTERNATIONAL CORPORATION ***************************************************************** ** %BEGIN_HEADER ** %NAME: play.c ** %PURPOSE: Above Real-Time Modified Version of VIGS ** %DEPENDENCIES: ** ----- ** DEVELOPMENT ENVIRONMENT ** COMPILER: Pascal ** OPERATING SYSTEM: DOS ** COMPUTER: PC ** COMPILATION INSTRUCTIONS: uses Borland MAKE. Type 'make' ** TARGET ENVIRONMENT ** CPU: 8086 ** HARDWARE NAME: VIGS ** OPERATING SYSTEM: n/a ** MACHINE DEPENDENCIES: n/a ** %CHANGE HISTORY: ** REV: 3.0 DATE: 08-07-91 PROGRAMMER: Frank Luongo ** DESCRIPTION: Added Above Real-Time Modifications per Hyper-Time Algorithm ** %END_HEADER ***************************************************************** */ } ..... Procedure Play; {code for Hitachi laserdisc driver} const PLAY_1 = 37; PLAY_2 = 102; STEP = 36; begin Case mode_number of 1{1X} : { a 30Hz flag is set in the interrupt handler} if v30flg then begin if frame_cnt = 1 then begin {wait for Tx ready} while ((inport($3fd) and $20) <> $20 ) do {since loop time of program is considerably less than 30 ms we use the play command for 1X instead of the step command.} outport($3f8,PLAY_1); {only send play command once so not to reset frame_cnt} frame_cnt := frame_cnt + 1; end; {increment frame number variable to sync with videodisc player} frame_num := frame_num + 1; end; 2:{2X} begin if frame_cnt = 1 then begin {wait for Tx ready} while ((inport($3fd) and $20) <> $20 ) do {since loop time of program is less than 16 ms we use play command for 2X instead of the step command.} outport($3f8,PLAY_2); {we only send the play command once so we do not need to reset frame_cnt} frame_cnt := frame_cnt + 1; end; {increment the frame number variable every 60 Hz to maintain sync with the videodisc player} frame_num := frame_num + 1; end; 3:{1.33X} begin {keep track of the number of 60Hz passes} frame_cnt := frame_cnt + 1; {issue step command and inc frame_num every 2 out of 3 60 Hz passes} if frame_cnt < 4 then begin {wait for Tx ready} while ((inport($3fd) and $20) <> $20 ) do; {send the step command out the serial port} outport($3f8,STEP); {increment the frame variable to maintain sync} frame_num := frame_num + 1; end else {reset frame count} frame_cnt := 1; end; end; 4:{1.6X} begin {keep track of the number of 60Hz passes} frame_cnt := frame_cnt + 1; {issue step command and inc frame_num every 4 out of 5 60 Hz passes} if frame_cnt < 6 then begin {wait for Tx ready} while ((inport($3fd) and $20) <> $20 ) do; {send the step command out the serial port} outport($3f8,STEP); {increment the frame variable to maintain sync} frame_num := frame_num + 1; end else {reset frame count} frame_cnt := 1; end; end; 5:{0.5X} begin {keep track of the number of 60Hz passes} frame_cnt := frame_cnt + 1; {issue step command and inc frame_num every 1 out of 4 60 Hz passes} if frame_cnt > 3 then begin {wait for Tx ready} while ((inport($3fd) and $20) <> $20 ) do; {send the step command out the serial port} outport($3f8,STEP); {increment the frame variable to maintain sync} frame_num := frame_num + 1; end else {reset frame count} frame_cnt := 1; end; end; end;{case} end; Listing Two //***************************************************************** // ECC INTERNATIONAL CORPORATION //***************************************************************** // %BEGIN_HEADER // %NAME: artt_dos.c // %PURPOSE: Above Real Time Video Demonstration: // Demonstration of Above Real-Time MPEG Playback on Sigma Design's // ReelMagic Board. Modified Sigma Design example code for demonostration. // Note: If compliling with compilers that do not use Borland's BGI (like Visual C++), be sure to comment out the indicated lines // This example demonstrates how to get the position in the appropriate // time format and how to vary the playback speed buffers. // At the dos prompt, type "artt_dos " // Use up and down keys to change the speed, escape to exit // Note : link it with FMPFCTS.OBJ. Use bat file Dutch.bat to load fmpdrv // and play nfl file and unload driver // %DEPENDENCIES: // Important: Ensure fmpdrv.exe TSR is running prior to executing program. // FMPFCTS.OBJ // // // // // "types.h" // "fmpdrv.h" // "fmpmacs.h" // "fmpfcts.h" // DEVELOPMENT ENVIRONMENT // COMPILER: Turbo C or Visual C++ // OPERATING SYSTEM: DOS // COMPUTER: PC // COMPILATION INSTRUCTIONS: uses Borland MAKE. Type 'make' // TARGET ENVIRONMENT // CPU: 486 // HARDWARE NAME: PC with MPEG Playback // OPERATING SYSTEM: n/a // MACHINE DEPENDENCIES: n/a // %CHANGE HISTORY: // REV: 1.0 DATE: 06-07-94 Software Engineer: Dutch Guckenberger // DESCRIPTION: Header installation splayer.c modifications // DATE: 07-03-94 Software Engineer: Dutch Guckenberger // DESCRIPTION: Modified Sigma Design's Example code provided by Dennis // Gutridge to compile and run on MicroSoft's Visual C++. Key // was turning off audio prior to ARTT replay. // %END_HEADER // // ***************************************************************************/ #include #include #include #include #include "types.h" #include "fmpdrv.h" #include "fmpmacs.h" #include "fmpfcts.h" #define KEY_UP -72 #define KEY_DOWN -80 #define KEY_ESC 27 #define SPEED_DIV 50 #define SPEED_MIN 1 #define SPEED_MAX 200 #define SPEED_STEP 1 // Error function - Writes Msg and stop the program void Error(char *Msg,int ExitCode) { fprintf(stderr,Msg); exit(ExitCode); } void main(int argc,char *argv[]) { BYTE hStream; BOOL Done=FALSE; BOOL NewSpeed=TRUE; int Speed=SPEED_DIV; int ch; DWORD d; if (argc<2) Error("Specify a file to play.\n",1); // Locate the driver if (!FindDriver()) Error("Driver not found.\n",2); // Re-init the driver FMPInit(); // Open the file hStream=FMPOpen(FMPF_FILE,(DWORD)(LPSTR)argv[1]); // if hStream is null, the file has not been properly opened if (!hStream) { Error("Error while opening the file.\n",3); } // has the file been recognized ? if (FMPGet(hStream,FMPI_STM_TYPE)==FMPF_UNKNOWN) { FMPClose(hStream); Error("The file format is unknown.\n",4); } // set the destination window FMPSet(hStream,FMPI_VID_DEST_SIZE,MAKEDWORD(352,240)); FMPSet(hStream,FMPI_VID_DEST_POS ,MAKEDWORD((704-352)/2,(400-240)/2)); // set the time format to frames FMPSet(hStream,FMPI_STM_TIME_FMT,FMPF_FRAMES); // if it's a system stream, let's unselect the audio channels // because speed variation will not work properly with audio . if (FMPGet(hStream,FMPI_STM_TYPE)==FMPF_GROUP) { int i; BYTE aStream; BYTE n=FMPGet(hStream,FMPI_GRP_NB); for (i=1;i<=n;i++) { aStream=FMPCommand(FMP_GROUP,hStream,FMPF_GET|FMPF_INDEX,i); if (FMPGet(aStream,FMPI_STM_TYPE)==FMPF_AUDIO) FMPCommand(FMP_GROUP,hStream,FMPF_UNSELECT,aStream); } } // Following line commented out for Visual C++ Version // clrscr(); printf("Use up and down arrows to change the speed. Escape to quit\n"); printf("Frame :\nTime :\nSpeed Ratio :"); // Play the file FMPPlay(hStream,FMPF_END_REPEAT,0); while (!Done) { // Following line commented out for Visual C++ Version // gotoxy(13,2); FMPSet(hStream,FMPI_STM_TIME_FMT,FMPF_FRAMES); d=FMPGet(hStream,FMPI_STM_POSITION); if (d!=(DWORD)-1) printf("%7lu",d); // Following line commented out for Visual C++ Version // gotoxy(9,3); FMPSet(hStream,FMPI_STM_TIME_FMT,FMPF_HMSF); d=FMPGet(hStream,FMPI_STM_POSITION); if (d!=(DWORD)-1) printf("%02d:%02d:%02d %02d",HIBYTE(HIWORD(d)), LOBYTE(HIWORD(d)), HIBYTE(LOWORD(d)),LOBYTE(LOWORD(d))); // Following line altered for Visual C++ Version if (kbhit()) { ch=getch(); if (!ch) ch=-getch(); switch (ch) { case KEY_UP : Speed+=SPEED_STEP;NewSpeed=TRUE;break; case KEY_DOWN : Speed-=SPEED_STEP;NewSpeed=TRUE;break; case KEY_ESC : Done=TRUE;break; } } if (NewSpeed) { Speed=max(SPEED_MIN,min(SPEED_MAX,Speed)); FMPSet(hStream,FMPI_STM_SPEED,MAKEDWORD(Speed,SPEED_DIV)); // Following line commented out for Visual C++ Version // gotoxy(15,4); printf("%.2f\n",Speed/(float)SPEED_DIV); NewSpeed=FALSE; } } // close the stream FMPClose(hStream); } Example 1: initialization() { ... /* initialize ARTT variables */ current_artt_rate = 1.0; old_artt_rate = 1.0; } main_loop() { ... /* get the artt-rate if input from user, otherwise lookup list */ .... /* if artt_rate is different from last pass change rate */ if (current_artt_rate != old_artt_rate ) { alter_time_rate(current_artt_rate); old_artt_rate = current_artt_rate; } .... } Example 2: (a) 60seconds/ARTTConstant=ARTTScenarioTime (b) TotalAvailableFrames/ARTTScenarioTime (c) 60Seconds/1.33=45Seconds (d) 1800frames/45seconds=40fps Example 3: HTA skipped frame pseudocode */ Initialization of HTA_Skip */ HTA_Skip_mode =1 /* User Input */ User Select mode 1=1.0, 2 =2.0, 3=1.33, 4=1.6, 5=0.5, 6=3.0 /* Error Check User Input */ If (error_check(mode) == TRUE) then {symbol 183 \f "Symbol" \s 10 \h} Report error {symbol 183 \f "Symbol" \s 10 \h} Re-prompt for input {symbol 183 \f "Symbol" \s 10 \h} Offer quit option Case mode 1: play 1.0x @ 30 fps (skip every other 60 Hz pass) 2: play 2.0x @ 60 fps, increment 3: play 1.33x @ step every 2 out of 3 60 Hz passes 4: play 1.6x @ step every 4 out of 5 60 Hz passes 5: play 0.5x @ step once every 4 60 Hz passes 6: play 3.0x @ step 3 times every 2 60 Hz passes /*for Videodisc updates */