rmpeg

A Rust media stack tested against FFmpeg.

Generated from local correctness and benchmark JSON at 2026-10-15T01:43:54Z.

GitHub

Phase 1

Upstream Sample Execution Progress

rmpeg currently gives 2557 of 2557 synced upstream sample files a clean execution row. All 2557 rows pass the current FFmpeg compatibility check.

100.0%
2557 runnable 2557 passed rows 0 failed comparisons 0 errors 0 skipped 2222 commands attempted 2557 upstream samples

Current Status

rmpeg's Phase 1 surface is measured as executable sample rows. The main progress bar tracks upstream execution coverage: every synced sample should produce a clean runnable, failing, or error row, and failed comparisons still count as runnable. Strict FFmpeg match status stays visible in the tables below. The current stack has 8/16/24/32-bit WAV, raw S16LE, AVI PCM, QuickTime/MP4 PCM, and FLAC decode/hash, H.264 video frame hashing, native GIF/PNG/APNG/PNM/BMP/DDS/FITS/SGI/DPX/PTX/TGA/Sun Raster/XBM/Alias PIX/BRender PIX image hashing, native lossy-audio execution rows, FLAC-backed filter/seek/remux rows, and broadening probe-level metadata across common audio, video, image, subtitle, game-media, and container formats.

AreaStatus
WAV/PCM metadata7/7 passing
WAV/PCM decode/hash7/7 passing
MP3 metadata1/1 passing
MP3 decode/hash0/1 passing
FLAC metadata1/1 passing
FLAC decode/hash1/1 passing
Ogg audio metadata2/2 passing
Ogg Vorbis decode/hash0/1 passing
Ogg Opus decode/hash0/1 passing
MP4/MOV metadata1/1 passing
H.264/AAC metadata1/1 passing
H.264/AAC decode/hash0/1 passing
Video decode/hash0/1 passing
Image decode/hash1/1 passing
Audio filters1/1 passing
Seeking1/1 passing
Resampling1/1 passing
Remuxing0/1 passing

Correctness

TestKindStatusDetails
probe mp4 h264_aac_mp4probe-jsonpassed
decode/hash mp4 h264_aac_mp4framemd5failedframe 0 differs: expected {'dts': 0, 'duration': 4096, 'hash': 'b6f473092c0aec4d6f0ccd58a6ec057d', 'pts': 0, 'size': 8192, 'stream_index': 0}, got {'stream_index': 0, 'dts': 0, 'pts': 0, 'duration': 4096, 'size': 8192, 'hash': 'd24e7e77d8f4aaa2ceb36d4109faa216'}
decode/video mp4 h264_aac_mp4framemd5failedframe 0 differs: expected {'dts': 0, 'duration': 1, 'hash': '135d9327e8efee810ff814a0fa94c2be', 'pts': 0, 'size': 4608, 'stream_index': 0}, got {'stream_index': 0, 'dts': 0, 'pts': 0, 'duration': 1, 'size': 4608, 'hash': 'b1e27aa018409de6bfd73f8afb883a65'}
probe wav mono_silence_8kprobe-jsonpassed
decode/hash wav mono_silence_8kframemd5passed
probe wav odd_chunksprobe-jsonpassed
decode/hash wav odd_chunksframemd5passed
probe wav pcm_u8probe-jsonpassed
decode/hash wav pcm_u8framemd5passed
probe wav short_100msprobe-jsonpassed
decode/hash wav short_100msframemd5passed
probe wav stereo_44k_sineprobe-jsonpassed
decode/hash wav stereo_44k_sineframemd5passed
probe wav tinyprobe-jsonpassed
decode/hash wav tinyframemd5passed
probe png tiny_rgbprobe-jsonpassed
decode/image png tiny_rgbframemd5passed
probe flac tone_flacprobe-jsonpassed
decode/hash flac tone_flacframemd5passed
probe mp3 tone_mp3probe-jsonpassed
decode/hash mp3 tone_mp3framemd5failedframe 0 differs: expected {'dts': 0, 'duration': 4096, 'hash': 'c3d03c27f66ac45b984601ce0054c181', 'pts': 0, 'size': 16384, 'stream_index': 0}, got {'stream_index': 0, 'dts': 0, 'pts': 0, 'duration': 4096, 'size': 16384, 'hash': 'f2dadeafd1769dddfca6012bf40789d1'}
probe ogg tone_opusprobe-jsonpassed
decode/hash ogg tone_opusframemd5failedframe 0 differs: expected {'dts': 0, 'duration': 4096, 'hash': 'b6a7bb743d3a16cd485adbf0c0e6d05e', 'pts': 0, 'size': 8192, 'stream_index': 0}, got {'stream_index': 0, 'dts': 0, 'pts': 0, 'duration': 4096, 'size': 8192, 'hash': 'f8b98b8751565cb2b51c7ea775662852'}
probe ogg tone_vorbisprobe-jsonpassed
decode/hash ogg tone_vorbisframemd5failedframe 0 differs: expected {'dts': 0, 'duration': 4096, 'hash': '1a38854ced1958e649cb508b9de97b95', 'pts': 0, 'size': 16384, 'stream_index': 0}, got {'stream_index': 0, 'dts': 0, 'pts': 0, 'duration': 4096, 'size': 16384, 'hash': '71c5f4bc97014e4ae7179e577d5624b0'}
probe wav truncated_riffprobe-jsonpassedboth ffprobe and rmpeg-probe rejected input
decode/hash wav truncated_riffframemd5passedboth ffmpeg and rmpeg rejected input
filter audio volume tone_flacfilterpassed
seek audio tone_flac 100msseekpassed
resample audio tone_flac 16000resamplepassed
remux flac tone_flac wavremuxfailedbinary output differs: expected 176478 bytes/f6d2b7eb7c3c55ebf9daf9c922457769, got 176478 bytes/2a6100628a324279dc14ad1f0ecddac6

FFmpeg Sample Corpus

This optional check syncs upstream FFmpeg FATE samples with FFmpeg's own make fate-rsync target, then probes every regular file with ffprobe and rmpeg-probe.

MetricValue
Generated2026-10-15T01:50:56Z
FFmpeg commit50740a1
ffprobe versionffprobe version n8.0.1 Copyright (c) 2007-2025 the FFmpeg developers
Samples directory/home/runner/work/rmpeg/rmpeg/.cache/ffmpeg/fate-suite
Total files checked2571
ffprobe accepted2236
rmpeg-probe accepted2222
Passed2545
Failed26
Errors0
Decode execution clean rows2557
Decode execution passed rows2557
Decode execution total rows2557
Decode commands attempted2222
Decode commands passed2222
Compatible no-command rows335
Decode clean failures0
Decode execution errors0
SampleStatusDetails
ac4/audio_id_2ch_2997fps.ac4failedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported or unrecognized media format
ac4/audio_id_514ch_25fps.mp4failedstream 0.codec_name: expected ac4, got unknown
ac4/audio_id_ims_25fps.tsfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: MPEG-TS stream has no DTS PES payload
ac4/sync-frames.tsfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: MPEG-TS stream has no DTS PES payload
audiomatch/tones_opus_48000_stereo.mkafailedstream 0.sample_rate: expected 48000, got 44100
citrix/citrix-mono-2bit-8000.wavfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: unsupported: WAV audio format 1024 is not PCM
citrix/citrix-stereo-2bit-8000.wavfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: unsupported: WAV audio format 1024 is not PCM
iamf/test_000096.iamffailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported observed IAMF layout
id3v2/lang_xxx.mp3failedstream 0.duration_seconds: expected 0.416, got 0.36
imm6/imm6.avifailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: AVI file has no supported streams
mov/mov-t35-cdsc-track.mp4failedstream 0.codec_name: expected av1, got unknown
mov/mov-t35-rndr-track.mp4failedstream 0.codec_name: expected av1, got unknown
mov/mpegh_layout16.mp4failedstream 0.codec_name: expected mpegh_3d_audio, got unknown
notchlc/alpha-blocks.movfailedstream 0.codec_name: expected notchlc, got unknown
notchlc/alpha-macroblocks.movfailedstream 0.codec_name: expected notchlc, got unknown
notchlc/alpha-ramp-500x300.movfailedstream 0.codec_name: expected notchlc, got unknown
notchlc/alpha-ramp.movfailedstream 0.codec_name: expected notchlc, got unknown
notchlc/chroma-alpha.movfailedstream 0.codec_name: expected notchlc, got unknown
pcm-dvda/pcm_dvda-96k24bit.aobfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported or unrecognized media format
rhetorex/rhetorex-mono-4bit-8000.wavfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: unsupported: WAV audio format 256 is not PCM
sub/aribcaption_clear.tsfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: MPEG-TS stream has no DTS PES payload
sub/aribcaption_ruby.tsfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: MPEG-TS stream has no DTS PES payload
truehd/spdifenc-branch-padding.thdfailedstream 0.channels: expected 2, got 6
vvc/frame-packing-reorder.vvcfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported or unrecognized media format
vvc/frame-packing-temporal.vvcfailedffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported or unrecognized media format
SampleSurfaceStatusDetails
No decode execution errors in the upstream corpus run.passed

Benchmarks

BenchmarkFFmpeg meanrmpeg meanRelativeStatus
probe tiny wav0.046923s0.000805srmpeg is 58.31x fastermeasured
probe tone mp30.046766s0.000827srmpeg is 56.58x fastermeasured
probe h264/aac mp40.051486s0.001031srmpeg is 49.94x fastermeasured
probe tone flac0.047997s0.000828srmpeg is 57.97x fastermeasured
probe tone opus0.048102s0.000855srmpeg is 56.29x fastermeasured
probe tone vorbis0.048396s0.000838srmpeg is 57.73x fastermeasured
framemd5 tiny wav0.050105s0.000962srmpeg is 52.10x fastermeasured

Supported Formats

Implemented test surfaces: RIFF/WAVE PCM, raw S16LE, AVI PCM, QuickTime/MP4 PCM, FLAC, MP3, AAC-in-MP4, Ogg Vorbis, Ogg Opus, H.264 video, GIF/PNG/APNG/PNM/BMP/DDS/FITS/SGI/DPX/PTX/TGA/Sun Raster/XBM/Alias PIX/BRender PIX images, audio filter, seek, resample, and FLAC-to-WAV remux compatibility checks all execute in the mirrored suite. Upstream GIF, APNG, observed AVI PCM, observed QuickTime/MP4 PCM, and 8/16/24/32-bit WAV rows decode natively and match FFmpeg for the synced fixtures. Passing support currently includes the mirrored probe, WAV/FLAC decode/hash, raw S16LE, AVI PCM, QuickTime/MP4 PCM, H.264, GIF/APNG, image, transform, and remux rows; MP3, AAC-in-MP4, Ogg Vorbis, Ogg Opus, and variable-size DPX rows execute through native attempts but are not bitexact yet.

Probe-level metadata is much broader and covers many observed FATE fixtures including MP3, FLAC, Ogg, MP4/MOV, Matroska/WebM, AVI, MPEG-TS, raw H.264/HEVC/VVC/MPEG video, FLV, RealMedia, ASF/WMA, Electronic Arts game media, Bink, Smacker, RoQ, Musepack, DSDIFF/DST, HEIF/HEIC/AVIF, subtitles, and many standalone image formats. Future independent codec and container work can improve strict hashes without changing the sample inventory or progress model.

Known Failures

Autoresearch Log

How To Reproduce

cargo xtask samples
cargo xtask reference
cargo xtask fate-mini
cargo xtask ffmpeg-samples
cargo xtask bench
cargo xtask site

Phase 2

Optimization

After the sample media set is working, Phase 2 will track which older FFmpeg codec paths rmpeg can beat on speed. The benchmark table already exists; this phase waits until compatibility is no longer the main blocker.