Site Tools


tutorials:trapexit:creating_3do_compatible_fmv

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

  • Non-integer frame rates crash movietostream / movietostream_shuttle
  • The 3DO SDK's Cinepak decoder or the Data Streaming library is sensitive to non-Apple Cinepak encoded videos. It will crash.
  • There is an A/V sync drift. The drift is not large but after a minute or two of play it is noticeable. This appears to have always been a problem. Probably due to how sync is managed. There are 239.67391304 audio ticks per second but some tooling uses 240 ticks per second without any adjustment for the error. This sync issue however is not present in 3DO Video releases like Woody Woodpecker.
  • There appears to be an issue with Quicktime 6.0.3 with regard to framerates. If the target framerate is the same as the source video framerate the video gets jittery. If you leave the target framerate is left blank or “best” it will speed up the framerate slightly. 30fps will become 31.25fps. Earlier versions of QT need to be tested to see if they too have this issue.

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:

  • CD quality stereo requires 176 KB/s.
  • The lowest quality sound currently offered(22 K Mono 4:1) is acceptable for voice in most cases.
  • Most music can use 22 K 16-bit stereo 2:1 compressed (44KB/s data rate). High frequencies are attenuated, but not usually too much.
  • Most audio sounds better at 2:1 compression than at 4:1. 22 KB 2:1 sounds better than 44 KB 4:1-and they have the same data 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:

  • enableaudiomask: stereo = 0x3 and mono = 0x1
  • file: The last value is a start time offset in audio ticks. There are 240 audio ticks per second. You can set an offset to help with desync but it will still de-sync over time.
  • preloadinstrument: change to SA_22K_16B_M_SDX2 for mono or just leave it out and let the system handle it.

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

  • There appears to be a demuxer in FFMPEG for 3DO stream files but in my limited testing I've been unable to get it to work. If it is functional there is no documentation and that should be addressed.
  • create a 3DO stream muxer
  • create an AIFC encoder
  • address the apparent incompatibilities with the Cinepak encoder and the Quicktime output to make it compatible with 3DO tooling

General

  • Investigate porting sndsquash, movietostream, sftostream, and/or weaver to Linux and Windows. Though adding to FFMPEG would be preferable.
  • Investigate the A/V sync issues. Likely something to do with the audio tick rate.
  • Compare Shuttle Player from examples with Woody Woodpecker releases. They use a modified version of Shuttle player but do not exibit the AV drift the example does. Trying to use a movietostream_shuttle encoded video with the Woody Woodpecker title does not work nor does the reverse. Something about the stream file is incompatible between the two players.
  • Investigate older versions of Quicktime to see if encoding to the same framerate as the source also has problems.

Examples:

tutorials/trapexit/creating_3do_compatible_fmv.txt · Last modified: 2022/10/02 19:48 by trapexit