home *** CD-ROM | disk | FTP | other *** search
- /* ******************* Easy_MPEG Version 1.04 *********************** */
- /* ******************* Scott A. Tribbey *********************** */
- /* ******************* March 3,1995 *********************** */
-
- /* Painless MPEG! Yup this should make it easy for anybody */
- /* to create their own MPEG movies */
-
- /* AREXX script for making MPEG-1 video streams using */
- /* the Berkley University MPEG-1 encoder for the Amiga */
- /* This macro will create the MPEG-1 stream from 24bit frames */
- /* that have been or are being created by a ray tracer or */
- /* other graphics output program */
-
- /* The program uses the MPEG-1 encoder to create individual GOPS */
- /* or 'Groups Of Pictures' as another application produces the frames */
- /* In this way, hard drive space is conserved, as everytime the */
- /* number of produced frames available is enough to encode a GOP */
- /* the frames will be converted to a GOP and deleted */
- /* This allows for very large animations to be constructed on a */
- /* system with only modest hard drive space */
-
- /* TRACE('results') */
-
-
-
-
- IF ARG() = 1 THEN
- DO
-
- IF EXISTS( 'MPEG.settings' ) THEN
- DO
- Call ReadParams()
- GOPS_COMPLETE = 0 /* Just here to initialize variable */
- END
- ELSE
- Call InitGlobals()
-
- PARSE ARG FrameName StFrame EndFrame Xdim Ydim OutFile FrmDelay DelOldFrms .
-
- IF FrameName == '?' THEN
- DO
- SAY 'Usage: rx Easy_MPEG Base_Frame_Name Start End Xdim Ydim '
- SAY ' OutFileName Delay DelOldFrames'
- SAY
- SAY 'Example: rx Make_MPEG dh0:IFF/Frame. 0000 0030 352 240 Movie 30 YES'
- SAY ' creates Movie.mpg from:'
- SAY ' dh0:IFF/Frame.0000 through dh0:IFF/Frame.0030'
- SAY ' resolution is 352 by 240, directory scan every 30 sec.'
- SAY ' original IFF files will be deleted'
- SAY
- EXIT /* Quit here */
- END
-
- Call GetFileInDir()
- Call GetFrameName()
- Call CalcGOPS()
-
- END
- ELSE
- DO
-
- IF EXISTS( 'MPEG.settings' ) THEN
- DO
- Call ReadParams()
- Call GetFileInDir()
- Call CalcGOPS()
- GOPS_COMPLETE = 0 /* Just here to initialize variable */
- Call Stats()
- Call RunHost()
- END
- ELSE
- DO
- Call InitGlobals()
- Call CalcGOPS()
- Call Stats()
- Call RunHost()
- END
-
- END
-
- /* Save Parameters in the MPEG.settings file for future reference in case this session
- gets interrupted */
-
- Call SaveParams()
-
- /* This first section is where the program checks to see if any of */
- /* the work is already done. If any GOP's have been produced, then */
- /* the program starts from where it was last interrupted */
-
- Error = 0
-
- DO I = 0 to TOT_GOPS - 1 UNTIL Error = 1
- IF ~ EXISTS(InputDir || OutFile || '.mpg' || '.gop.' || I)
- THEN Error = 1
- END
-
- GOPS_COMPLETE = I
-
-
- Call Stats()
-
- Call WriteParamFile()
-
-
- /* change HOST address to AmigaDOS and set a decent size stack */
-
- ADDRESS ('COMMAND')
- 'Stack 30000'
-
-
- /* Wait for and create individual GOPS as frames are available */
- /* This will run forever if it never gets all the appropriate frames */
- /* Pressing CTRL-C here will break the program */
-
- /* Main loop where frames are scanned for */
-
- DO UNTIL GOPS_COMPLETE == TOT_GOPS
-
- SAY 'Waiting for Frames for GOP 'GOPS_COMPLETE
- SAY '***** PRESS CTRL-C TO ABORT *****'
-
-
- LastGOPFrm = StFrame + (GOPS_COMPLETE * GOP_SIZE) + GOP_SIZE
-
- IF LastGOPFrm > EndFrame THEN
- LastGOPFrm = EndFrame
-
- /* Create ZERO padded frame number for file name */
- FrmNumber = RIGHT(LastGOPFrm,LENGTH(StFrame),0)
-
- SAY 'Waiting for' FrameName || FrmNumber
- SAY ''
-
- IF EXISTS( InputDir || FrameName || FrmNumber ) THEN
- DO
-
- /* Check if this is the last frame of the animation */
- /* if it is, then we must check it by using the OPEN() */
- /* function to see if it is complete */
- /* if it isn't then we BREAK out of this DO segment and */
- /* wait again */
-
- IF FrmNumber == EndFrame THEN
- IF OPEN( TESTF , InputDir || FrameName || FrmNumber ) THEN
- DO
- BOGUS = CLOSE( TESTF )
- IF ((TOT_FRAMES // GOP_SIZE) > 0) & ,
- (GOPS_COMPLETE = TOT_GOPS - 1) THEN
- DO
- GOP_SIZE = TOT_FRAMES // GOP_SIZE
- LastGOPFrm = LastGOPFrm + 1
- END
- ELSE IF ((TOT_FRAMES // GOP_SIZE) == 0) & ,
- (GOPS_COMPLETE = TOT_GOPS - 1) THEN
- LastGOPFrm = LastGOPFrm + 1
- END
- ELSE
- BREAK
-
-
-
- /* First turn IFF-24 frames into .PPM files */
- /* and delete the original IFF-24 frames if requested */
-
- DO x = (LastGOPFrm - GOP_SIZE) to (LastGOPFrm - 1)
- FrmNumber = RIGHT( x ,LENGTH(StFrame),0)
- SAY 'Converting Frame'FrmNumber'to PPM format'
-
- RC = 0
- '24toPPM >NIL:' InputDir || FrameName || FrmNumber ,
- InputDir || FrameName || FrmNumber || '.ppm'
-
- /* Check to see if 24toppm failed due to wrong number */
- /* of bitplanes and use ilbmtoppm instead */
-
- IF RC == 20 THEN
- 'ILBMtoPPM <'InputDir || FrameName || FrmNumber ,
- '>'||InputDir || FrameName || FrmNumber || '.ppm'
-
- IF DelOldFrms == 'YES' THEN
- 'delete' InputDir || FrameName || FrmNumber
- END
-
- 'mpeg_encode -gop' GOPS_COMPLETE OutFile||'.param'
-
- GOPS_COMPLETE = GOPS_COMPLETE + 1
-
- /* Now Delete the PPM files */
-
- DO x = (LastGOPFrm - GOP_SIZE) to (LastGOPFrm - 1)
- FrmNumber = RIGHT( x ,LENGTH(StFrame),0)
- 'delete' InputDir || FrameName || FrmNumber || '.ppm'
- END
-
- Call Stats()
-
- END
-
-
- IF GOPS_COMPLETE == TOT_GOPS THEN
- BREAK
-
- /* Put in a frame search delay so as not to absorb processor time */
-
- Call delay( FrmDelay * 50 )
-
- /* ADDRESS COMMAND 'wait' FrmDelay THIS USED TOO MUCH CPU TIME */
-
- END
-
-
-
-
- /* Now that all graphic files are done generating */
- /* combine all the GOPS into an MPEG file */
-
-
- /* Here is where we give the final command to mpeg_encode */
- /* which then combines the GOP's into a full MPEG-1 file */
-
-
- 'mpeg_encode -combine_gops' OutFile||'.param'
-
- /* Now Delete the GOPS and we're done! */
- DO I = 0 to (TOT_GOPS - 1)
- 'delete' InputDir || OutFile || '.mpg' || '.gop.' || I
- END
-
-
- SAY '------------------------------'
- SAY ' Processing Complete!'
- SAY '------------------------------'
-
- SAY
-
-
- /* Here is where the last little OK window pops up */
- /* if you don't like that, then just comment the following */
- /* line out of the program */
-
- Call Request(300,100,"Processing Complete",,"OK",,)
-
- EXIT
-
-
-
-
- /* ================================================================== */
- /* This is where the functions are defined */
- /* ================================================================== */
-
-
- /* This separates the FrameName and InputDir from the input string */
-
- GetFrameName:
-
- IF LASTPOS('/' , FrameName ) > 0 THEN
- DO
- FileInDir = LEFT( FrameName, LASTPOS('/' , FrameName )-1 )
- InputDir = LEFT( FrameName, LASTPOS('/' , FrameName ) )
- FrameName = SUBSTR( FrameName, LASTPOS('/' , FrameName )+1 )
- END
- ELSE
- InputDir = ''
-
- RETURN 0
-
-
-
- GetFileInDir:
-
- IF LASTPOS('/' , InputDir ) > 0 THEN
- FileInDir = LEFT( InputDir, LASTPOS('/' , InputDir )-1 )
- ELSE
- FileInDir = ''
-
- RETURN 0
-
-
-
- /* This initializes the global variables in case there */
- /* is no MPEG.settings file to read them from */
-
- InitGlobals:
-
- FrameName = 'Pic.'
- StFrame = '0000'
- EndFrame = '0030'
- Xdim = 160
- Ydim = 120
- InputDir = 'input/'
- FileInDir = 'input'
- PATTERN = 'IPBP'
- IQScale = 2
- PQScale = 4
- BQScale = 6
- FrmDelay = 60
- DelOldFrms = 'YES'
- OutFile = 'Movie'
-
- GOPS_COMPLETE = 0
-
- RETURN 0
-
-
-
- /* This prints the Status to the CON: window */
-
- Stats:
- SAY '' /* This is a clear screen character */
- SAY 'Easy_MPEG Scott Tribbey 1995 All rights reserved'
- SAY 'MPEG Stream Status'
- SAY '--------------------------------------------------'
- SAY 'Start Frame :' FrameName || StFrame
- SAY 'End Frame :' FrameName || EndFrame
- SAY 'Frame Width :' Xdim
- SAY 'Frame Height :' Ydim
- SAY 'Input Dir. :' InputDir
- SAY 'Encode Patt. :' PATTERN
- SAY 'IQScale :' IQScale
- SAY 'PQScale :' PQScale
- SAY 'BQScale :' BQScale
- SAY 'GOP_SIZE :' GOP_SIZE
- SAY 'Total Frames :' TOT_FRAMES
- SAY 'Dir. Scan :' FrmDelay 'sec.'
- SAY 'Del Old Frms :' DelOldFrms
- SAY 'Total GOPS :' TOT_GOPS
- SAY 'OutFile Name :' OutFile || '.mpg'
- SAY '--------------------------------------------------'
- SAY 'GOPS Complete:' GOPS_COMPLETE '(' (GOPS_COMPLETE / TOT_GOPS * 100) '% )'
- SAY '--------------------------------------------------'
- SAY
- SAY
-
- RETURN 0
-
-
- /* Store current MPEG parameters in MPEG.settings file */
-
- SaveParams:
-
- OPEN( SETFILE,'MPEG.settings', 'W' )
-
- WRITELN( SETFILE , FrameName )
- WRITELN( SETFILE , InputDir )
- WRITELN( SETFILE , StFrame )
- WRITELN( SETFILE , EndFrame )
- WRITELN( SETFILE , Xdim )
- WRITELN( SETFILE , Ydim )
- WRITELN( SETFILE , OutFile )
- WRITELN( SETFILE , FrmDelay )
- WRITELN( SETFILE , DelOldFrms )
- WRITELN( SETFILE , IQScale )
- WRITELN( SETFILE , PQScale )
- WRITELN( SETFILE , BQScale )
- WRITELN( SETFILE , PATTERN )
-
- CLOSE( SETFILE )
-
- RETURN 0
-
-
- /* Read MPEG parameters from MPEG.settings file */
-
- ReadParams:
-
- OPEN( SETFILE,'MPEG.settings', 'R' )
-
- FrameName = READLN( SETFILE )
- InputDir = READLN( SETFILE )
- StFrame = READLN( SETFILE )
- EndFrame = READLN( SETFILE )
- Xdim = READLN( SETFILE )
- Ydim = READLN( SETFILE )
- OutFile = READLN( SETFILE )
- FrmDelay = READLN( SETFILE )
- DelOldFrms = READLN( SETFILE )
- IQScale = READLN( SETFILE )
- PQScale = READLN( SETFILE )
- BQScale = READLN( SETFILE )
- PATTERN = READLN( SETFILE )
-
- CLOSE( SETFILE )
-
-
- RETURN 0
-
-
-
- /* Setup some MPEG parameters and calc. the number of GOPS */
- /* Calculate a reasonable GOP size ( at least 3 frames ) */
-
- CalcGOPS:
-
- GOP_SIZE = LENGTH(PATTERN)
-
- I = 0
-
- DO I = I + 1 UNTIL GOP_SIZE >= 0
- GOP_SIZE = I * LENGTH(PATTERN)
-
- END
-
-
- IF EndFrame <= StFrame
- THEN DO
- EndFrame = StFrame + 1
- Call Request(300,100,"You need more frames than that!",,"OK",,)
- END
-
- TOT_FRAMES = EndFrame - StFrame + 1
- TOT_GOPS = TRUNC( TOT_FRAMES / GOP_SIZE )
-
- IF TOT_FRAMES // GOP_SIZE ~= 0 THEN
- TOT_GOPS = TOT_GOPS + 1
-
-
- IF TOT_GOPS == 0
- THEN
- DO
- Call Request(300,100,"You need more frames than that!",,"OK",,)
- /* SAY
- SAY ' Hey you''ll need more frames than that!!!'
- SAY
- EXIT */
- END
-
- RETURN 0
-
-
-
-
- /* This function creates the .param file which contains the operational */
- /* parameters for the mpeg_encode program */
-
- WriteParamFile:
-
- SAY 'Compiling mpeg_encode Parameter File...'
- SAY
-
- OPEN( PARMFILE, Outfile || '.param', 'W' )
-
- WRITELN( PARMFILE , '# This parameter file created by Easy_MPEG.rexx' )
- WRITELN( PARMFILE , '# An Arexx program by Scott Tribbey 1995' )
-
- WRITELN( PARMFILE , '' )
- WRITELN( PARMFILE , '' )
- WRITELN( PARMFILE , 'PATTERN ' || PATTERN )
- WRITELN( PARMFILE , 'OUTPUT ' || InputDir || OutFile || '.mpg' )
- WRITELN( PARMFILE , '' )
- WRITELN( PARMFILE , 'BASE_FILE_FORMAT PPM' )
- WRITELN( PARMFILE , 'GOP_SIZE ' GOP_SIZE )
- WRITELN( PARMFILE , 'SLICES_PER_FRAME 1 ' )
- WRITELN( PARMFILE , '' )
- WRITELN( PARMFILE , 'PIXEL HALF' )
- WRITELN( PARMFILE , 'RANGE 10' )
- WRITELN( PARMFILE , 'PSEARCH_ALG LOGARITHMIC' )
- WRITELN( PARMFILE , 'BSEARCH_ALG CROSS2' )
- WRITELN( PARMFILE , 'IQSCALE 'IQScale )
- WRITELN( PARMFILE , 'PQSCALE 'PQScale )
- WRITELN( PARMFILE , 'BQSCALE 'BQScale )
- WRITELN( PARMFILE , '' )
- WRITELN( PARMFILE , 'REFERENCE_FRAME ORIGINAL' )
- WRITELN( PARMFILE , 'FORCE_ENCODE_LAST_FRAME' )
- WRITELN( PARMFILE , '' )
- WRITELN( PARMFILE , 'YUV_SIZE '||Xdim||'x'||Ydim )
- WRITELN( PARMFILE , 'INPUT_DIR '||FileInDir )
- WRITELN( PARMFILE , 'INPUT' )
- WRITELN( PARMFILE , FrameName || '*' || '.ppm ' '[' || ,
- StFrame || '-' || EndFrame || ']')
- WRITELN( PARMFILE , 'END_INPUT' )
- WRITELN( PARMFILE , 'INPUT_CONVERT *' )
-
- CLOSE( PARMFILE )
-
- RETURN 0
-
-
-
- RunHost:
-
- if ~show('l', "rexxarplib.library") then do
- check = addlib('rexxarplib.library',0,-30,0)
- end
-
- if ~show('l', "rexxsupportlib.library") then do
- check = addlib('rexxsupport.library',0,-30,0)
- end
-
- ADDRESS COMMAND
-
- /* The following command is the only way to use the createhost() */
- /* function without locking up the script */
-
- Call OPENPORT(MPEGPORT)
-
- 'Run ' 'SYS:Rexxc/rx ''Call createhost(MPEGHOST, MPEGPORT,)'''
-
- Call delay(100) /* delay to allow the host to get set up */
-
- idcmp = 'CLOSEWINDOW+GADGETDOWN+GADGETUP'
- flags = 'WINDOWCLOSE+WINDOWDRAG+WINDOWDEPTH'
- call OpenWindow(MPEGHOST, 50, 50, 340, 200, idcmp, flags, "Easy_MPEG 1.04 Scott Tribbey 1995")
-
- call SetAPen(MPEGHOST,1)
-
- /* Now Add the gadgets */
-
- call AddGadget(MPEGHOST,120 ,15 ,00 ,FrameName ,"%l STRING %d %g",200 )
- call AddGadget(MPEGHOST,120 ,30 ,01 ,InputDir ,"%l STRING %d %g",200 )
- call AddGadget(MPEGHOST,120 ,45 ,02 ,StFrame ,"%l STRING %d %g",100 )
- call AddGadget(MPEGHOST,120 ,60 ,03 ,EndFrame ,"%l STRING %d %g",100 )
- call AddGadget(MPEGHOST,135 ,75 ,04 ,Xdim ,"%l STRING %d %g",40 )
- call AddGadget(MPEGHOST,205 ,75 ,05 ,Ydim ,"%l STRING %d %g",40 )
- call AddGadget(MPEGHOST,120 ,120 ,06 ,OutFile ,"%l STRING %d %g",200 )
- call AddGadget(MPEGHOST,120 ,135 ,07 ,FrmDelay ,"%l STRING %d %g",40 )
- call AddGadget(MPEGHOST,120 ,150 ,08,"Del. Old Frames" ,"%l STRING %d")
- call AddGadget(MPEGHOST,252 ,170 ,09,"Start\Scanning" ,"%l STRING %d")
- call AddGadget(MPEGHOST,120 ,170 ,10,"Quit\Program" ,"QUIT")
- call AddGadget(MPEGHOST,244 ,45 ,11,"File\Requester" ,"%l STRING %d")
- call AddGadget(MPEGHOST,135 ,90 ,12,IQScale ,"%l STRING %d %g",40 )
- call AddGadget(MPEGHOST,205 ,90 ,13,PQScale ,"%l STRING %d %g",40 )
- call AddGadget(MPEGHOST,275 ,90 ,14,BQScale ,"%l STRING %d %g",40 )
- call AddGadget(MPEGHOST,120 ,105 ,15,PATTERN ,"%l STRING %d %g",200 )
-
-
- /* Now Add the gadget labels */
-
- call Move(MPEGHOST,10,22)
- call Text(MPEGHOST," Frame Name:")
- call Move(MPEGHOST,10,37)
- call Text(MPEGHOST," Input Dir:")
- call Move(MPEGHOST,10,52)
- call Text(MPEGHOST," Start Frame:")
- call Move(MPEGHOST,10,67)
- call Text(MPEGHOST," End Frame:")
- call Move(MPEGHOST,10,82)
- call Text(MPEGHOST," Resolution: X")
- call Move(MPEGHOST,190,82)
- call Text(MPEGHOST,"Y")
-
- call Move(MPEGHOST,10,97)
- call Text(MPEGHOST,"Quant. Scale: I")
- call Move(MPEGHOST,190,97)
- call Text(MPEGHOST,"P")
- call Move(MPEGHOST,260,97)
- call Text(MPEGHOST,"B")
- call Move(MPEGHOST,10,112)
- call Text(MPEGHOST,"Frm. Pattern:")
-
- call Move(MPEGHOST,10,127)
- call Text(MPEGHOST," Out File:")
- call Move(MPEGHOST,10,142)
- call Text(MPEGHOST," Dir. Scan:")
- call Move(MPEGHOST,170,142)
- call Text(MPEGHOST,"Sec.")
-
- CALL MessageLoop()
-
- call Exit(MPEGHOST)
-
- Call CLOSEPORT(MPEGPORT)
-
- IF QUIT = 1 THEN EXIT(0)
-
-
- RETURN 0
-
-
-
-
-
- MessageLoop:
-
-
- /* MAIN message loop */
-
- keep_going=1
- DO WHILE keep_going=1
-
-
- /* Wait for at least one message to arrive */
-
- t=WAITPKT(MPEGPORT)
-
- /* process *ALL* the messages waiting at this port */
-
- DO ff=1
- p=GETPKT(MPEGPORT)
-
-
- /* p=NULL means not more messages at this port.
- This is the *ONLY* time you should leave this loop! */
-
- IF p='0000 0000'x THEN LEAVE ff /* message port empty */
-
- /* get the message from the the port packet */
-
- command=GETARG(p)
-
-
- /* REPLY() as soon as you can, as soon as you are through extracting
- data from the packet with GETARG() */
-
- t=REPLY(p,0)
-
-
- /* Ignore any messages received after the CLOSEWINDOW */
-
- IF keep_going=0 THEN ITERATE ff
-
-
-
- /* now we can see what the message contains, and act on it */
-
- PARSE VAR command arg1' 'arg2' 'arg3' 'arg4' '
- SELECT
- WHEN arg1='CLOSEWINDOW' | arg1 = 'QUIT' THEN
- DO
- keep_going=0
- QUIT = 1
- END
-
- WHEN arg1='GADGETUP' THEN
- DO
- SELECT
- WHEN arg2='STRING' THEN
- DO
- SELECT
- WHEN arg3 = 0 THEN FrameName = arg4
- WHEN arg3 = 1 THEN
- DO
- InputDir = arg4
- Call GetFileInDir()
- END
-
- WHEN arg3 = 2 THEN StFrame = arg4
- WHEN arg3 = 3 THEN EndFrame = arg4
- WHEN arg3 = 4 THEN Xdim = arg4
- WHEN arg3 = 5 THEN Ydim = arg4
- WHEN arg3 = 6 THEN OutFile = arg4
- WHEN arg3 = 7 THEN FrmDelay = arg4
-
- WHEN arg3 = 8 THEN
- IF DelOldFrms = 'YES' THEN
- DelOldFrms = 'NO'
- ELSE
- DelOldFrms = 'YES'
-
- WHEN arg3 = 9 THEN keep_going=0
- WHEN arg3 = 10 THEN FrmDelay = arg4
-
-
- WHEN arg3 = 11 THEN Call GetBaseFile()
- WHEN arg3 = 12 THEN IQScale = arg4
- WHEN arg3 = 13 THEN PQScale = arg4
- WHEN arg3 = 14 THEN BQScale = arg4
- WHEN arg3 = 15 THEN PATTERN = arg4
-
- OTHERWISE
- END
- Call CalcGOPS()
- Call Stats()
- END
-
- OTHERWISE
- END
-
- END
-
-
- OTHERWISE DO
-
- SAY 'arg1 'arg1
- SAY 'arg2 'arg2
- SAY 'arg3 'arg3
-
- END
-
- END
-
- END
- END
-
-
- RETURN 0
-
-
- /* This is where we use the ARP file requester to get the Base Filename */
-
- GetBaseFile:
-
- FileName = GetFile(100,100,FileInDir,,,)
-
- IF FileName ~= '' THEN
- DO
- FrameName = FileName
- Call GetFrameName()
-
- call RemoveGadget(MPEGHOST,00)
- call RemoveGadget(MPEGHOST,01)
-
- call AddGadget(MPEGHOST,120 ,15 ,00 ,FrameName ,"%l STRING %d %g",200 )
- call AddGadget(MPEGHOST,120 ,30 ,01 ,InputDir ,"%l STRING %d %g",200 )
- END
-
- RETURN 0
-