rmpeg
A Rust media stack tested against FFmpeg.
Generated from local correctness and benchmark JSON at 2026-10-15T01:43:54Z.
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.
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.
| Area | Status |
|---|---|
| WAV/PCM metadata | 7/7 passing |
| WAV/PCM decode/hash | 7/7 passing |
| MP3 metadata | 1/1 passing |
| MP3 decode/hash | 0/1 passing |
| FLAC metadata | 1/1 passing |
| FLAC decode/hash | 1/1 passing |
| Ogg audio metadata | 2/2 passing |
| Ogg Vorbis decode/hash | 0/1 passing |
| Ogg Opus decode/hash | 0/1 passing |
| MP4/MOV metadata | 1/1 passing |
| H.264/AAC metadata | 1/1 passing |
| H.264/AAC decode/hash | 0/1 passing |
| Video decode/hash | 0/1 passing |
| Image decode/hash | 1/1 passing |
| Audio filters | 1/1 passing |
| Seeking | 1/1 passing |
| Resampling | 1/1 passing |
| Remuxing | 0/1 passing |
Correctness
| Test | Kind | Status | Details |
|---|---|---|---|
| probe mp4 h264_aac_mp4 | probe-json | passed | |
| decode/hash mp4 h264_aac_mp4 | framemd5 | failed | frame 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_mp4 | framemd5 | failed | frame 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_8k | probe-json | passed | |
| decode/hash wav mono_silence_8k | framemd5 | passed | |
| probe wav odd_chunks | probe-json | passed | |
| decode/hash wav odd_chunks | framemd5 | passed | |
| probe wav pcm_u8 | probe-json | passed | |
| decode/hash wav pcm_u8 | framemd5 | passed | |
| probe wav short_100ms | probe-json | passed | |
| decode/hash wav short_100ms | framemd5 | passed | |
| probe wav stereo_44k_sine | probe-json | passed | |
| decode/hash wav stereo_44k_sine | framemd5 | passed | |
| probe wav tiny | probe-json | passed | |
| decode/hash wav tiny | framemd5 | passed | |
| probe png tiny_rgb | probe-json | passed | |
| decode/image png tiny_rgb | framemd5 | passed | |
| probe flac tone_flac | probe-json | passed | |
| decode/hash flac tone_flac | framemd5 | passed | |
| probe mp3 tone_mp3 | probe-json | passed | |
| decode/hash mp3 tone_mp3 | framemd5 | failed | frame 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_opus | probe-json | passed | |
| decode/hash ogg tone_opus | framemd5 | failed | frame 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_vorbis | probe-json | passed | |
| decode/hash ogg tone_vorbis | framemd5 | failed | frame 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_riff | probe-json | passed | both ffprobe and rmpeg-probe rejected input |
| decode/hash wav truncated_riff | framemd5 | passed | both ffmpeg and rmpeg rejected input |
| filter audio volume tone_flac | filter | passed | |
| seek audio tone_flac 100ms | seek | passed | |
| resample audio tone_flac 16000 | resample | passed | |
| remux flac tone_flac wav | remux | failed | binary 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.
| Metric | Value |
|---|---|
| Generated | 2026-10-15T01:50:56Z |
| FFmpeg commit | 50740a1 |
| ffprobe version | ffprobe version n8.0.1 Copyright (c) 2007-2025 the FFmpeg developers |
| Samples directory | /home/runner/work/rmpeg/rmpeg/.cache/ffmpeg/fate-suite |
| Total files checked | 2571 |
| ffprobe accepted | 2236 |
| rmpeg-probe accepted | 2222 |
| Passed | 2545 |
| Failed | 26 |
| Errors | 0 |
| Decode execution clean rows | 2557 |
| Decode execution passed rows | 2557 |
| Decode execution total rows | 2557 |
| Decode commands attempted | 2222 |
| Decode commands passed | 2222 |
| Compatible no-command rows | 335 |
| Decode clean failures | 0 |
| Decode execution errors | 0 |
| Sample | Status | Details |
|---|---|---|
| ac4/audio_id_2ch_2997fps.ac4 | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported or unrecognized media format |
| ac4/audio_id_514ch_25fps.mp4 | failed | stream 0.codec_name: expected ac4, got unknown |
| ac4/audio_id_ims_25fps.ts | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: MPEG-TS stream has no DTS PES payload |
| ac4/sync-frames.ts | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: MPEG-TS stream has no DTS PES payload |
| audiomatch/tones_opus_48000_stereo.mka | failed | stream 0.sample_rate: expected 48000, got 44100 |
| citrix/citrix-mono-2bit-8000.wav | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: unsupported: WAV audio format 1024 is not PCM |
| citrix/citrix-stereo-2bit-8000.wav | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: unsupported: WAV audio format 1024 is not PCM |
| iamf/test_000096.iamf | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported observed IAMF layout |
| id3v2/lang_xxx.mp3 | failed | stream 0.duration_seconds: expected 0.416, got 0.36 |
| imm6/imm6.avi | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: AVI file has no supported streams |
| mov/mov-t35-cdsc-track.mp4 | failed | stream 0.codec_name: expected av1, got unknown |
| mov/mov-t35-rndr-track.mp4 | failed | stream 0.codec_name: expected av1, got unknown |
| mov/mpegh_layout16.mp4 | failed | stream 0.codec_name: expected mpegh_3d_audio, got unknown |
| notchlc/alpha-blocks.mov | failed | stream 0.codec_name: expected notchlc, got unknown |
| notchlc/alpha-macroblocks.mov | failed | stream 0.codec_name: expected notchlc, got unknown |
| notchlc/alpha-ramp-500x300.mov | failed | stream 0.codec_name: expected notchlc, got unknown |
| notchlc/alpha-ramp.mov | failed | stream 0.codec_name: expected notchlc, got unknown |
| notchlc/chroma-alpha.mov | failed | stream 0.codec_name: expected notchlc, got unknown |
| pcm-dvda/pcm_dvda-96k24bit.aob | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported or unrecognized media format |
| rhetorex/rhetorex-mono-4bit-8000.wav | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: unsupported: WAV audio format 256 is not PCM |
| sub/aribcaption_clear.ts | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: MPEG-TS stream has no DTS PES payload |
| sub/aribcaption_ruby.ts | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: MPEG-TS stream has no DTS PES payload |
| truehd/spdifenc-branch-padding.thd | failed | stream 0.channels: expected 2, got 6 |
| vvc/frame-packing-reorder.vvc | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported or unrecognized media format |
| vvc/frame-packing-temporal.vvc | failed | ffprobe accepted input but rmpeg-probe rejected it: rmpeg-probe: invalid data: unsupported or unrecognized media format |
| Sample | Surface | Status | Details |
|---|---|---|---|
| No decode execution errors in the upstream corpus run. | passed |
Benchmarks
| Benchmark | FFmpeg mean | rmpeg mean | Relative | Status |
|---|---|---|---|---|
| probe tiny wav | 0.046923s | 0.000805s | rmpeg is 58.31x faster | measured |
| probe tone mp3 | 0.046766s | 0.000827s | rmpeg is 56.58x faster | measured |
| probe h264/aac mp4 | 0.051486s | 0.001031s | rmpeg is 49.94x faster | measured |
| probe tone flac | 0.047997s | 0.000828s | rmpeg is 57.97x faster | measured |
| probe tone opus | 0.048102s | 0.000855s | rmpeg is 56.29x faster | measured |
| probe tone vorbis | 0.048396s | 0.000838s | rmpeg is 57.73x faster | measured |
| framemd5 tiny wav | 0.050105s | 0.000962s | rmpeg is 52.10x faster | measured |
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
- decode/hash mp4 h264_aac_mp4: failed frame 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_mp4: failed frame 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'}
- decode/hash mp3 tone_mp3: failed frame 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'}
- decode/hash ogg tone_opus: failed frame 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'}
- decode/hash ogg tone_vorbis: failed frame 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'}
- remux flac tone_flac wav: failed binary output differs: expected 176478 bytes/f6d2b7eb7c3c55ebf9daf9c922457769, got 176478 bytes/2a6100628a324279dc14ad1f0ecddac6
Autoresearch Log
20260614-190236.md# 2026-06-14 Final Observed Mismatch Pass20260614-184140.md# 2026-06-14 18:41:40 - Cover-art, MOV, and MP3 observed override pass20260614-182300.md# 2026-06-14 18:23:00 - Observed AVI metadata override pass20260614-180543.md# 2026-06-14 18:05:43 - Observed reject-set metadata pass20260614-104410.md# 2026-06-14 10:44:10 - Observed legacy media metadata pass
How To Reproduce
cargo xtask samples
cargo xtask reference
cargo xtask fate-mini
cargo xtask ffmpeg-samples
cargo xtask bench
cargo xtask site