Input Script

The XDC encoder uses input scripts to create video files. These scripts contain some mandatory directives such as the framerate of the input and where the audio file is, as well as the list of frame files that make up the video.  Here’s an example of what a script looks like:

# sample TRON sequence
screenmode=1
sourcefps=23.976
waveinput=d:\xdc\sources\tron\tron.wav
d:\xdc\sources\tron\tr_00000.bmp
d:\xdc\sources\tron\tr_00001.bmp
d:\xdc\sources\tron\tr_00002.bmp
d:\xdc\sources\tron\tr_00003.bmp
d:\xdc\sources\tron\tr_00004.bmp
d:\xdc\sources\tron\tr_00005.bmp
d:\xdc\sources\tron\tr_00006.bmp
# ...etc.

Line-by-line explanation:

  1. Starts with a comment
  2. Defines the CGA screen mode this video is formatted for
  3. Defines the framerate of the source video
  4. Defines the location of the audio file for this video
  5. Ends with the complete list of video frames to include, in order

Other directives can be added (full list below), and you can also insert directives at multiple points in the script which is useful for handling multiple sections of the video differently.

When creating a script, it’s best to get the list of frames in the script first, then add directives at the top of the script later.  Putting a list of all frames into a script is usually easy:

DOS or Windows: dir /b *.bmp > tron.scr
UNIX: ls *.bmp > tron.scr

This dumps a bare listing of filenames only into “tron.scr”.  As long as the script is in the same directory as the bitmap files, this works fine; or, you can perform search-and-replace with a text editor to put the full path back into every line as shown in the example script above.

As of this writing, the encoder implementation is in 16-bit DOS, so all filenames must adhere to 8.3 standards.  See FAQs for background on why this is.

Mandatory Directives

These directives must be in every script, included before the frame list:

  • SCREENMODE: The screen mode to encode for.  Values are 1 for CGA composite color output, 2 for 640×200 B&W mode, and 3 for Tandy 160×200 mode.  Example: “screenmode=1”.
  • SOURCEFPS: The original source framerate of the video.  Values can be integer or floating point.  This directive must be first in the script, as subsequent directives use values derived from it. Examples: “sourcefps=29.97”, “sourcefps=24”, etc.
  • WAVEINPUT: Points to an 8-bit PCM (uncompressed) mono .wav file containing audio for the video.

It is also probably a good idea to specify these first three directives in this order.

Optional Directives

The XDC encoder has default values that stress image quality over size, which means it can create extremely large files if the picture content is constantly changing at high framerates.  Use of additional directives to control this is highly encouraged; at a bare minimum, you should know your target’s I/O maximum transfer rate and use MAXDISKRATE to set it, to ensure you’re not creating files that you can’t play without stuttering, or files that are so big they don’t fit on your hard disk.

Bitrate control

  • MAXDISKRATE: Specifies the maximum bitrate in KB.  This is useful for ensuring your video will not exceed the capability of your disk subsystem.  Possible values can be something like 150 for a 1X CDROM, 90 for an MFM drive, 160 for an XTIDE adapter, etc.  Example:  “maxdiskrate=150”.

Visual Quality

  • FRAMEINTEGRITY: Specifies the percentage of how much changed data is encoded before XDC considers the frame “done” and loads a new frame.  Value is an integer anywhere from 0 to 100.  A value of 0 will preserve motion at the expense of picture detail, and 100 will preserve picture detail at the expense of motion.  Default value is 75, which works well for most sources and doesn’t have to be changed unless you’re unhappy with the resulting picture quality.
  • SHAVEPIXELS: If enabled, single-pixel changes are discarded.  This can lower the size of the video and stabilize areas of the picture, but can also create onscreen “trails” as moving picture areas are not erased correctly.  To deal with “trails”, a full keyframe is encoded once every second.  Values are ON or OFF; default is OFF.
  • SHAVEDELTAS: Similar to SHAVEPIXELS, but stronger.  If enabled, two-byte changes or smaller are discarded.  Values are ON or OFF; default is OFF.
  • CHEATING: If enabled, will encode every other line as blank.  This reduces horizontal resolution and overall “dims” the resulting picture, but gives the encoder more bits to work with.  Values are ON or OFF; default is OFF.

Debugging

  • DEBUG: Sets the level of output in the log file produced by the encoder.  Default is 1; can be set from 0 to 3 where higher values increase verbosity.
  • OVERRIDEBYTEPOOL: Forces the number of opcode bytes to be used to encode each video frame.  For debugging purposes only.  Values can range from 32 to 10000.
  • OVERRIDECYCLES: Increases the number of playback cycles per frame to the encoder.  For debugging purposes only, as misuse of this will create videos that have stuttering playback.  Only allowable values are “MAX” (set to the full maximum available in a single CGA screen refresh) and “COMPLETE” (set to the full number of cycles it takes to perform a REP MOVSW of 16384 bytes).

Miscellaneous

  • COMBINEDELTAS: Can be used to turn off one of the encoder optimization phases, which will generally result in a 20% encoding speedup at the expense of 20% larger/less efficient files.  Values are ON or OFF.
  • PAUSE: Will pause the encoder at that line in the script and wait for the user to hit a key to continue.

Difficult sources

If you feed XDC source material where every single area of the screen is changing (ie. an action movie, a panning camera, etc.), you may find that the encoder has to drop frames to make everything fit within available bandwidth.  The obvious fix is to increase the bandwidth you’re willing to give the encoder by increasing your MAXDISKRATE value.  If you can’t do this (ie. it would exceed the capabilities of your transport medium), then try turning on SHAVEPIXELS to reduce encoder workload.  If that doesn’t help, you can step it up by turning on SHAVEDELTAS.  If the end result still doesn’t look good (ie. framerate is too slow, or the video is “smeary”), then use 160×100 input files or turn on CHEATING to cut the data you’re giving to the encoder in half.

If the resulting video looks mostly ok but has too many motion artifacts (ie. you see “smearing” or “trails” in the encoded video), set FRAMEINTEGRITY to 100.  This will lower the effective framerate, but each frame that does display will display completely.  Conversely, if you want to preserve motion and don’t care how much it smears, set FRAMEINTEGRITY to 0.

Example Scenarios

Color movies that play off of a 1X CDROM (this requires the movie to be broken up into parts no longer than 40 minutes each, due to the 65535-frame limit of XDV files, and also to fit two parts nicely onto a single 700MB/80-minute CDROM):

screenmode=1
sourcefps=23.976
maxdiskrate=150
frameintegrity=67

 

Stupid encoder tricks

If you omit the WAVEINPUT= line in the script, the encoder will not create a video file, but rather dump each encoded frame to an individual file with an extension of .xdc.  This is useful for examining the code produced for a specific frame, ie.:

D:\AC\RAWFRAME\BA>debug ba3317.xdc
-u
0856:0100 1E            PUSH    DS
0856:0101 0E            PUSH    CS
0856:0102 1F            POP     DS
0856:0103 BE6909        MOV     SI,0969
0856:0106 B800B8        MOV     AX,B800
0856:0109 8EC0          MOV     ES,AX
0856:010B B500          MOV     CH,00
0856:010D FC            CLD
0856:010E BF631A        MOV     DI,1A63
0856:0111 B130          MOV     CL,30
0856:0113 B0FF          MOV     AL,FF
0856:0115 F3            REPZ
0856:0116 AA            STOSB
0856:0117 BFB31A        MOV     DI,1AB3
0856:011A B130          MOV     CL,30
0856:011C F3            REPZ
0856:011D AA            STOSB

Another use for this is displaying full-screen pictures in your own programming projects: Just set the video mode, preserve any registers you need preserved, then CALL the XDC encoder output data.  (To ensure one single frame gets completely created for use this way, set frameintegrity=100 and overridebytepool=10000.)