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 [[https://ext.3dodev.com/3DO/Toolkit_1.5/Streaming/2p1/Examples/|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. * Video Processing Guide: [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/tktfldr/vidfldr/01VID.html|tktfldr/vidfldr/01VID.html]] * Generating and converting data: [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs/tktfldr/dsgfldr/2dsgc.html|tktfldr/dsgfldr/2dsgc.html]] * 3DO DataStreamer Programmer's Guide: [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs//tktfldr/dsgfldr/0dsgfrst.html|tktfldr/dsgfldr/0dsgfrst.html]] * 3DO DataStreamer Tool manpages: [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs//tktfldr/dsrfldr/dsr3frst.html|tktfldr/dsrfldr/dsr3frst.html]] ===== 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 [[http://3dodev.com/software/sdks#prebuilt_qemu_macos_9_vm|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: [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs//tktfldr/dsgfldr/2dsgc.html|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 === - Open ''scratch:myvideo.mov'' in **Quicktime** - File> Export - Export: Movie to AVI - Options> Settings: - Apple Cinepak - Depth: Millions of Colors - Quality: Best - Fames per second: 8, 10, 12, 15, 20, 25, 30 (other values appear to crash movietostream) - Key frame every: 2x or 3x the target framerate is a good starting point - 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. - 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**. - Open ''scratch:myvideo.aiff'' in **Quicktime** - File> Export - Export: Sound to AIFF - Options: - Compressor: None - Rate: 22.050 kHz (or whichever makes most sense, see above) - Size: 16 bit - Use: Stereo - Open **SoundHack 3DO** and select ''scratch:myvideo.aiff'' - File> Save a Copy… - File Type: Audio IFC - Format: 8 Bit 2:1 3DO SDXC (or 4 Bit 4:1 ADPCM as suggested in SDK docs) - 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: [[https://ext.3dodev.com/3DO/Portfolio_2.5/OnLineDoc/DevDocs//tktfldr/dsrfldr/dsr4frst.html|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 ===== 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: ===== * {{:media:isos:3do_bad_apple.iso|Touhou - Bad Apple!!}} * {{:media:isos:lontv.iso|Lon.TV Channel Trailer}}