Table of Contents

This is a tutorial for creating 3DO “stream” files which are compatible with the PlayMovie app found in some games (such as Doom) or NuPlayer found in the streaming examples. Substituting movietostream with movietostream_shuttle will create a stream compatible with ShuttlePlayer. See the Streaming examples for more details.

General Details

Like other platforms at the time the 3DO's typical video codec was Cinepak. Audio generally is 8 or 16bit signed big endian PCM which can be compressed (AIFF or AIFC).

The 3DO SDK provides a number of tools to enable converting to Cinepak, compress audio, and then mux into the “stream” format used by the standard data streaming library. You can, and should, check out the original docs for more details.

Notes

Step 0: Preparation

You will need a MacOS 3DO development environment. You can find a system PPC QEMU image here.

This guide expects 3DO Toolkit 1.5, 3DO Portfolio 2.5, MPW, and Quicktime Pro 6.0.3 (+ MPEG4/Divx codecs) installed.

The file we'll be processing is myvideo.mkv and within MacOS exists on a drive labeled scratch as in the QEMU image linked above.

Step 1: Transcode for Quicktime

Video

We first need to take our source video and convert it into something Quicktime will be able to process. Given the age of Quicktime 6.0.3 used in MacOS9 the best and most recent codec available to us is MPEG-4 Part 2 (Divx). This will give the smallest and best quality to later convert to Cinepak. Alternatively we could use qtrle which is lossless but the file will be huge there doesn't appear to be a significance difference in encode time or quality between them. The overall compression is very slightly better when using a qtrle source but visually appears the same.

While FFMPEG does have a Cinepak encoder it is 1) extremely slow. 2) Causes the 3DO tool movietostream to crash.

The vaguedenoiser and fps filters can be removed but the denoiser can help compression and clarity when encoding to Cinepak and the framerate change may be necessary to work around the fps issue mentioned above. The scaler will maximize the resolution depending on the aspect ratio. The max being 320×240. If you are targeting a CRT then 304×228 or 288×216 are recommended resolutions given the overscan.

$ ffmpeg \
    -i "myvideo.mkv" \
    -vf "vaguedenoiser,scale='if(gt(a,320/240),320,-1)':'if(gt(a,320/240),-1,240)':force_original_aspect_ratio=decrease,fps=30000/1001" \
    -c:v mpeg4 \
    -qscale:v 0 \
    -an \
    -sn \
    -y \
    "file:myvideo.mov"

Audio

For audio we can convert directly to AIFF which could be used without further encoding but most likely you'll want to compress it to save space. That special compressed format, AIFC, is not supported by FFMPEG so we'll handle that in the next step.

From the docs: tktfldr/dsgfldr/2dsgc.html

Sample audio at 44 kHz and convert it to lower sample rates as appropriate. Deciding on the optimal compression may require some experimentation. Here's some information to help you decide on compression rate:

Stereo

$ ffmpeg \
  -i myvideo.mkv \
  -vn \
  -c:a pcm_s16be \
  -ar 22050 \
  -ac 2 \
  -sn \
  "file:myvideo.aiff"

Mono

$ ffmpeg \
 -i myvideo.mkv \
 -vn \
 -c:a pcm_s16be \
 -ar 22050 \
 -ac 1 \
 -sn \
 "file:myvideo.aiff"

Step 2: Transcode for 3DO

Transfer myvideo.mov and myvideo.aiff to the MacOS system. There are a number of ways to do this but an easy way is to use an FTP or HTTP server on the host system and use NetFiller or Classzilla to copy the files to the scratch drive.

Video

Quicktime

  1. Open scratch:myvideo.mov in Quicktime
  2. File> Export
  3. Export: Movie to AVI
  4. Options> Settings:
    1. Apple Cinepak
    2. Depth: Millions of Colors
    3. Quality: Best
    4. Fames per second: 8, 10, 12, 15, 20, 25, 30 (other values appear to crash movietostream)
    5. Key frame every: 2x or 3x the target framerate is a good starting point
    6. Limit data rate to: 120 KBytes/sec. Just need to ensure the total stream data rate is below ~280KBps. QT's limiter doesn't work great so you might need to move the value down to keep it at a reasonable rate. 100-120KBps at 30FPS and 90 frames per keyframe is about right generally. You'll have to play with the values.
    7. OK, OK, Save (as scratch:myvideo.cvid)

MovieCompress

MovieCompress is a tool provided with the 3DO SDK. It's not clear if the tool is buggy generally or not toally compatible with OS9 but the output seems to crash movietostream. More testing is needed.

Audio

If you've already selected the sample rate, channels, etc. when using FFMPEG skip to 5.

  1. Open scratch:myvideo.aiff in Quicktime
  2. File> Export
  3. Export: Sound to AIFF
  4. Options:
    1. Compressor: None
    2. Rate: 22.050 kHz (or whichever makes most sense, see above)
    3. Size: 16 bit
    4. Use: Stereo
  5. Open SoundHack 3DO and select scratch:myvideo.aiff
  6. File> Save a Copy…
    1. File Type: Audio IFC
    2. Format: 8 Bit 2:1 3DO SDXC (or 4 Bit 4:1 ADPCM as suggested in SDK docs)
    3. OK, Save (as scratch:myvideo.aifc)

Step 3: Convert to Stream

Run these commands within MPW Shell. The keypad enter key is required to execute command or click on the MPW Shell button in the top left of the MPW Shell window.

Video

movietostream -b 65536 -o scratch:myvideo.film scratch:myvideo.avi

Audio

sftostream -o scratch:myvideo.saudio -i scratch:myvideo.aifc

Step 4: Weave

Annoyingly the Weave program requires a separate file to work rather than using command line arguments. Here is a generic script that should work for exclusive video/audio streaming (where an app isn't also doing other things). Open SimpleText or similar text editor and create a plain text file with the content below.

You can read more about Weave script commands at: tktfldr/dsrfldr/dsr4frst.html

weaver.script

writestreamheader
writemarkertable
streamblocksize 98304
mediablocksize 2048
streambuffers 6
streamerdeltapri 6
dataacqdeltapri 8
preloadinstrument SA_22K_16B_S_SDX2
audioclockchan 0
enableaudiomask 0x3
subscriber FILM 10
subscriber SNDS 7
subscriber CTRL 11
streamstarttime 0
file scratch:myvideo.saudio 0 0
file scratch:myvideo.film 1 0

Notes:

Once the script is saved (let's call it weaver.script) we can now “weave” the stream files (myvideo.film and myvideo.saudio) together.

weaver -o scratch:myvideo.stream <scratch:weaver.script

Usage

Coming

Will be creating a simple project that enables building 3DO ISOs dedicated to playing video clips.

Future Work

FFmpeg

General

Examples: