Files
effectcraft/crates/hevcenc
EthanSuquetandClaude Opus 5.5 0f583853ad Untrack crates/hevcenc/target (36 MB of build output) and ignore nested target/
Commit c9d5e733 (M13.4, hevcenc deblocking) committed 207 files under
crates/hevcenc/target/agent-codec-hevc/: an agent's CARGO_TARGET_DIR with
rlibs, rmetas, build-script outputs and .rustc_info.json (~36 MB). They
were tracked because .gitignore only ignored the root `/target`.

- git rm --cached the directory; nothing references it.
- .gitignore: `/target` -> `target/`, so a per-crate or per-agent target
  dir is ignored anywhere in the tree. No tracked file lives under a
  directory named `target`, so nothing else becomes ignored.

The blobs stay in history; this keeps them out of every new checkout and
stops the next agent run from committing more.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-06 15:02:20 -04:00
..
2026-10-03 05:21:39 -04:00

effectcraft-hevcenc

Clean-room, pure-Rust HEVC / H.265 encoder for EffectCraft's MP4 export (layer L0, std only, no unsafe, builds for wasm32-unknown-unknown).

What it produces

  • Profiles: Main (8-bit) and Main 10 (10-bit), 4:2:0, Main tier. general_level_idc is taken from the config or chosen as the lowest level whose MaxLumaPs, MaxLumaSr (and, in bitrate mode, MaxBR) fit (Table A.8).
  • Parameter sets: VPS, SPS (with VUI: BT.709 colour description, video_full_range_flag, timing info from the frame rate) and PPS, as raw NAL units (Encoder::parameter_sets) and as an hvcC record (ISO/IEC 14496-15 §8.3.3.1, lengthSizeMinusOne 3, complete VPS / SPS / PPS arrays, Encoder::hvcc).
  • Pictures: one slice per picture; IDR_N_LP every keyint pictures (1 = all intra, 0 = only the first), TRAIL_R P pictures otherwise, each referencing the previous picture (one short-term RPS in the SPS, num_ref_idx_l0_active 1, no reordering, pts = dts). Packets are length-prefixed (4-byte big-endian) NAL units without parameter sets.
  • Picture size: any even width / height; the coded size is padded to a multiple of 8 by edge replication and cropped with the conformance window. Odd sizes are rejected with Error::InvalidConfig (4:2:0 conformance-window offsets are in units of two luma samples).

Coding tools

  • 64x64 CTUs, coding units 64x64 .. 8x8 chosen by rate-distortion optimisation: every candidate is actually predicted, transformed, quantised and reconstructed, and its rate is measured with a CABAC bit estimator that evolves the same context states as the real coder. Split decisions compare the best unsplit candidate with the recursively coded children (early exit after a skip).
  • Intra: all 35 modes (SATD search on a coarse grid plus refinement and the MPMs), 2Nx2N at 8..32 and NxN (four 4x4 PUs) at 8x8, chroma in DM mode, MPM / remaining-mode coding, reference substitution, [1 2 1] and strong (32x32) smoothing, DC / angular boundary filters.
  • Inter (P): skip and merge (spatial candidates + zero candidates, MaxNumMergeCand 5) and AMVP with mvd coding; integer motion search (predictor starts + square pattern, steps 16..1) and half / quarter-sample refinement on pre-interpolated half-sample planes; the coded prediction uses the normative 8-tap / 4-tap interpolation filters and reference-picture edge clamping.
  • Transforms: DST-VII 4x4 (intra luma) and DCT 4..32 (inverse by even/odd decomposition, bit-identical to the matrix form), dead-zone quantisation (1/3 intra, 1/6 inter), flat scaling, sign data hiding, inferred transform splits only (max_transform_hierarchy_depth_* 0, so 64x64 CUs use four 32x32 TUs).
  • Entropy coding: CABAC (context initialisation by slice QP and init type, decision / bypass / terminate bins, flush), end_of_slice_segment_flag, byte alignment, emulation prevention.
  • In-loop filters: the deblocking filter is on (the encoder deblocks its own reconstruction, so references match the decoder); SAO is disabled.
  • Rate control: ConstantQp(qp) or Bitrate { kbps }, a per-picture QP from a bits-x-Qstep model per picture type (I pictures get roughly 4x the bits of a P picture) with a buffer that spreads over- and undershoot over the following pictures.

Not implemented: B pictures / reordering, multiple references, TMVP, AMP and other inter partition shapes, residual quadtree splits, transform skip, scaling lists, PCM, SAO, RDOQ, cu_qp_delta / adaptive quantisation, tiles / WPP / multiple slices, range extensions (4:2:2, 4:4:4, > 10 bits).

Measurements

On a shared, heavily loaded machine, opt-level 3: about 0.45 s of CPU per 1920x1080 picture (ffmpeg testsrc2, QP 22 / 32). On ffmpeg's mandelbrot 1080p source (8 pictures, IPPP, QP 32) the stream is about 12 % larger at about 0.2 dB lower mean PSNR-Y than x265 --preset medium at the same QP without psy tuning (110.5 kB / 42.3 dB vs 98.3 kB / 42.5 dB). The synthetic test image reaches 45.8 dB PSNR-Y at QP 22.

Tests

cargo test -p effectcraft-hevcenc:

  • every stream is decoded with the first-party filmcraft-hevc decoder and compared bit-exactly with the encoder's reconstruction (Encoder::last_reconstruction, hidden API);
  • when ffmpeg is on PATH, the Annex-B elementary stream is decoded with ffmpeg -v error -xerror (no stderr output allowed) and compared bit-exactly as well (skipped otherwise). ffmpeg is used only as an external test oracle;
  • covered: 8-bit and 10-bit, all-intra and IP, QP 0 noise (escape codes), QP 0..51, strong deblocking at high QP, sizes 8x8 .. 200x136 with cropping, POC wrap (300 pictures without IDR), bitrate mode within 2x of the target, hvcC layout;
  • bench_1080p (ignored) reports speed, size and PSNR on 1080p content generated by ffmpeg.

Specifications

  • ITU-T H.265 (V8, 08/2021) | ISO/IEC 23008-2, High efficiency video coding: 7 (syntax and semantics), 8.4 - 8.7 (intra / inter prediction, scaling and transforms, deblocking), 9.3 (CABAC, including the informative encoder description of 9.3.4), Annex A (profiles, tiers and levels), Annex E (VUI).
  • ISO/IEC 14496-15 (2019), §8.3.3.1 HEVCDecoderConfigurationRecord.

Implemented from the specification text. Constant tables (CABAC context layout and initValues, rangeTabLPS / transIdx, scan orders, the DCT / DST matrices, intra angles, interpolation filters, the chroma QP table, the deblocking beta / tC tables) and the decoder-side reconstruction arithmetic (intra reference substitution / filtering / prediction, fractional interpolation, deblocking) are mirrored from FilmCraft's first-party, spec-derived filmcraft-hevc decoder (same organisation, MIT OR Apache-2.0), so that encoder and decoder reconstruct identically. No third-party encoder or decoder source (x265, libde265, ffmpeg, HM, ...) was consulted.