Field notes/Mediarusty_h265performance

rusty_h265 0.7.0: Nine Decoder Veins and a Mixed FFmpeg Result

rusty_h265 0.7.0 cut decoder instructions 26 to 37 percent on three inputs and decodes 1.37x to 1.50x faster than 0.6, while ordinary 8-bit inter still trails FFmpeg.

Signed by M·
Painted stone bakery at dawn where a silhouetted baker slides a full tray of loaves into a glowing brick oven, small lights strung over a window onto green hills
What changed in the rusty_h265 0.7.0 HEVC decoder?

rusty_h265 0.7.0 is an instruction-count campaign on the pure-Rust HEVC decoder. The repository reports 34.0, 36.7 and 26.3 percent fewer callgrind instructions on three inputs and 1.37x to 1.50x paired wall-clock gains over 0.6, with each change gated on 147 of 147 bit-exact JCT-VC streams.

rusty_h265 0.7.0 is the first measured performance campaign on the pure-Rust HEVC decoder, and it ships as a tagged release: commit c01a7b2b, crates.io 0.7.0 on 7 November 2026. The campaign commit is ea495319, merged as rusty_h265#10. The paired baseline in that README is the 0.6 decoder. Those ratios were measured before the integration commit and were not retaken on it.

The result in one breath: 34.0, 36.7 and 26.3 percent fewer instructions on three inputs, 1.37x to 1.50x paired wall-clock gains against 0.6, every step bit-exact on the JCT-VC suite, and a single-thread comparison against FFmpeg 8.1.2 that is honestly mixed. rusty_h265 0.7.0 wins one input class, ties two, and trails ordinary 8-bit inter.

This is not the introduction. The role and constellation of the decoder are in the rusty_h265 field note, and the safety argument against C stacks is Pure Rust Alternative for HEVC C stacks. This note is the engineering ledger. Every number is repository-reported. This article reran nothing.

Scope: decoder only. Main, Main 10 and Main Still Picture, 4:2:0, 8 and 10 bit, written from the ITU-T H.265 specification. No encoder, no H.264, no AV1.

What the rusty_h265 0.7.0 counts say

Instruction counts are callgrind Ir (Valgrind manual) on the shipping configuration, rusty_alloc plus AVX2, native under WSL. Same-binary reruns move about 20K on a 5G count, so a vein that removes millions is far outside the noise.

  • 20 s 720p x265 inter: 25.162 G to 16.614 G, down 34.0 percent.
  • all-intra ipred_x24: 42.237 G to 26.733 G, down 36.7 percent.
  • dblk_heavy: 5.251 G to 3.869 G, down 26.3 percent.

rusty_h265 0.7.0 wall clock comes from tools/bench/codec-bench.ps1: pinned core, High priority, self-reported decode time, ABBA ordering, both arms under rusty_alloc, on an i7-14650HX. Against the 0.6 build:

  • x265 20 s 720p30: 1.37x, 11/11 pairs.
  • JCT-VC 720p, 60 frames: 1.39x, 11/11 pairs.
  • ipred_x24: 1.50x, 11/11 pairs.

The plan also records 1.296x, 1.358x, 1.233x and 1.291x on its 8-bit, 10-bit, dblk_heavy and wp_x10 set, at 20 or 21 of 21 pairs. Two published tables disagree on the candidate's absolute milliseconds for the x265 clip, so the ratios are the verdict and the milliseconds are not averaged. The campaign section names WSL but not the CPU or rustc version for the counts.

The nine veins in rusty_h265 0.7.0

The rusty_h265 0.7.0 ledger is docs/plans/rusty_hevc_kernels.md, from the instruction-count campaign section. Each vein was kept on two conditions: callgrind went down, and the decoder stayed bit-exact.

SAO and inverse transform as whole-block kernels in rusty_h265

Sample adaptive offset now runs one kernel for a whole CTB when all eight neighbors are usable. The kernel is in sao.rs. The inverse transform became one kernel per block size, with dequantization folded into the coefficient write rather than a separate pass (itx.rs). The ring at slice and tile borders still takes the scalar SAO path.

Deblocking and intra decided once

Deblocking boundary strength is derived while parsing, then the filter walk skips runs of zero strength instead of visiting every edge. Intra prediction answers neighbor availability once per block and copies spans, rather than asking again for each sample position. Both are the same idea: decide once, then do bulk work. The ledger prices each vein separately; this note does not attribute a share of any total to one vein.

Motion compensation and one packed record

Motion compensation folds the uni- and bi-prediction store into the last interpolation pass, so the store happens during that pass rather than as a separate step. The several per-4x4 maps became one packed record filled once per coding unit. The glue changes are small and add up: isa() inlined, a narrower horizontal tail, and NAL unescaping a word at a time. Pictures with transquant bypass or PCM loop-filter-disabled samples stay on the scalar loops.

What rusty_h265 0.7.0 does not claim

A campaign note is only useful if it says where the speed stops. rusty_h265 0.7.0 has three clear edges, and each one belongs next to the headline whenever rusty_h265 0.7.0 is quoted.

The FFmpeg ratios for rusty_h265, unrounded

Against FFmpeg 8.1.2 native hevc with -threads 1, same machine, same method:

  • x265 clip and ipred_x24: 0.82x, 15/15 pairs. Slower.
  • 8-bit set: 0.80x. Slower.
  • 10-bit and dblk_heavy: parity.
  • wp_x10 weighted prediction: 1.37x, 20/21 pairs, z = 4.15. Faster.

The crate README's own table reads 0.82x, 0.86x and 0.82x on its three clips. FFmpeg measured against itself reads 0.95x on this harness, which the README treats as the noise floor. This is a single-thread comparison. FFmpeg's frame threading is not in it. Do not compress this into "faster than FFmpeg".

Left on the bench: PGO and x86-64-v3

Two build-level wins were counted and not shipped. Profile-guided optimization, as described in the rustc PGO guide, cut 8.0 percent of inter and 13.5 percent of intra instructions. The plan calls that an upper bound because the training streams are the test streams. A -C target-cpu=x86-64-v3 build cut 3.4 and 4.5 percent. An SAO border-line save and write-on-decode motion maps were priced and also left out. None of these are in the rusty_h265 0.7.0 numbers.

rusty_h265 0.7.0 is on remade_ffmpeg_rs main

The codec crate 0.7.0 is the same published release. At 10:37 AM MST on 7 November 2026, remade_ffmpeg_rs#98 merged. main is ee52ed9b and pins rusty_h265 and rusty_h265-accel at 0.7.0. The version bump before that merge is e1fb63d. The mixed speed sentence is on main's readme. Those ratios stay the campaign measurements against the 0.6 decoder and FFmpeg 8.1.2. They were not retaken on the merge commit, and this note does not claim a new tool binary.

At 10:40 AM MST, ci, portfolio-check, and release-plz on that merge commit were still running. Pre-merge MP3 and AAC cargo-vet jobs reported rusty_alloc 2.4.0 missing safe-to-run. That is a supply-chain note on those audio crates, not an HEVC decode failure. The Learn field note is remade_ffmpeg_rs.

The correctness gate stated by that PR and the campaign commit is 147/147 JCT-VC HEVC_v1 streams bit-exact and 6,183/6,183 picture-hash SEI messages, the suite described by ITU-T H.265.1. That is conformance on a fixed suite, not a fuzzing result. Repo landings: rusty_h265 and remade_ffmpeg_rs. The cluster map is Media, and the allocator both arms ran under is rusty_alloc.

FAQ

Quick answers for builders evaluating this technology.

Is rusty_h265 0.7.0 faster than the FFmpeg HEVC decoder?

Mixed. Against FFmpeg 8.1.2 with one thread, the repository reports 1.37x on the weighted-prediction stream wp_x10, about 0.80x to 0.86x on ordinary 8-bit inter clips, and parity on 10-bit and deblocking-heavy inputs. Frame threading is outside the comparison.

Which rusty_h265 optimizations were counted but not shipped?

Profile-guided optimization (8.0 percent fewer inter and 13.5 percent fewer intra instructions, an upper bound because it trained on the test streams), a target-cpu=x86-64-v3 build (3.4 and 4.5 percent), an SAO border-line save, and write-on-decode motion maps.

Does remade_ffmpeg_rs main build rusty_h265 0.7.0 yet?

Yes, as of 10:37 AM MST on 7 November 2026. Pull request 98 merged as ee52ed9b, and main pins rusty_h265 and rusty_h265-accel 0.7.0. The mixed speed ratios were not retimed on that commit. At 10:40 AM MST, ci, portfolio-check, and release-plz were still running.

How were the rusty_h265 0.7.0 instruction counts taken?

callgrind Ir on the shipping configuration with rusty_alloc and AVX2, built natively under WSL. Same-binary reruns differ by about 20,000 instructions on a five-billion count. The campaign section does not name the CPU or rustc version.

Why quote ratios instead of milliseconds for rusty_h265 0.7.0?

The crate README and the plan print different absolute times for the new build on the same x265 clip, 1,461 ms in one table and 1,539 ms in the other. The paired ratios against a named baseline are the documented verdicts.