I built a custom FMV codec from scratch for the Mega-CD (known as the Sega CD outside Japan). It can play 320×224 fullscreen video at 30 FPS with 22.05 kHz audio, and it runs on unmodified hardware. The source code is available too. This was, of course, AI-agentic coding—thanks, 5-6.Sol and Fable.
Classic Sega CD FMV often means a small window, a low frame rate, and heavily compressed audio. I wanted to find out how far the original hardware could be pushed if I aimed for fullscreen 30 FPS. That simple question was the motivation.
The codec is called CAVC—short for Constraint-Aware Video Codec. It is designed around the constraints that matter on real hardware: the two 68000 CPUs across the Genesis/Mega Drive and Sega CD, the split RAM architecture, available DMA bandwidth, and the strict 150 KiB/s bandwidth limit of the 1× CD-ROM drive.
The best way to see the result is to watch it. I used the Sonic Jam opening as the main comparison and included a capture from real hardware.
What the Main Comparison Shows
The split-screen comparison plays four sources at once:
- CAVC playback in Genesis Plus GX, shown in the largest panel
- The source footage from the TrueMotion AVI included in the Sega Saturn version of Sonic Jam
- The original Sega CD version for comparison
- A real-hardware capture from an actual Japanese Mega Drive 2 and Mega-CD 2
The fourth panel is the one I cared about most. I did not want to stop at “it runs in an emulator”; I fed the same stream to real hardware and verified that it played back there as well. If that part failed, the whole project would have been a theoretical exercise.
The original Sonic Jam source video is 288×200.
CAVC Specifications
- Resolution: Up to 320×224 in H40 mode, filling the full active display area
- Frame rate: 30 FPS, with 15 FPS and 24 FPS also supported
- Audio: 22.05 kHz ADPCM
- Color: Dynamic palette switching during playback
- Target hardware: Unmodified Sega CD / Mega-CD hardware
Additional Footage
Beyond the main comparison, I prepared several other videos. Each one is embedded here so you can watch it without leaving the article.
Sonic Jam Opening — 288×200 at 30 FPS
For Sonic Jam, there is a detailed visual analysis and encoding breakdown, followed by a standalone Genesis Plus GX capture.
Bad Apple!! — 320×224 Fullscreen at 30 FPS
Bad Apple!! is played at 320×224 fullscreen and 30 FPS. These are the comparison, analysis, and standalone emulator videos.
Lunar: The Silver Star Opening — 320×224 Fullscreen at 24 FPS
CAVC can also take advantage of the Genesis VDP’s hardware scrolling. This is especially effective in scenes with sustained horizontal camera movement, such as the opening of Lunar: The Silver Star. Instead of redrawing the entire screen every frame, the codec can scroll the existing image with the VDP, reducing the amount of new visual data that must be transferred. The final fade-out is handled with palette fading instead of re-encoding the image for each brightness step.
Tears of Steel — 320×168 Live Action at 24 FPS
Live-action footage is especially challenging, but I think the result remains reasonably watchable.
Source Code
The encoder is written in Python, while the player that runs on the console is written in 68000 assembly. The repository also includes tools for generating analysis videos, so you can inspect the decisions being made as each image is assembled.
GitHub repository: akiyan/segacd-fmv-cavc
This is the English version of my original Japanese article. I also shared a shorter write-up on Reddit.
If you have any thoughts or questions, feel free to reach out to @akiyan.
