Skip to main content

rusty_h264_accel/
lib.rs

1//! SIMD acceleration for rusty_h264 — **portable Rust intrinsics**, with a shrinking
2//! remainder of vendored openh264 x86 assembly.
3//!
4//! This crate is deliberately **not** `#![forbid(unsafe_code)]`: it is the one place
5//! `unsafe` lives, behind safe wrappers, so the codec core stays `forbid(unsafe)`.
6//!
7//! ## Structure, and where it is going
8//!
9//! `docs/add_SIMD_rip_ASM.md` is ripping the assembly out kernel by kernel. Two things
10//! follow from that, and this file is arranged around them:
11//!
12//! * **`x86_asm`** holds everything still backed by openh264 NASM. It is gated on
13//!   `target_arch = "x86_64"` and shrinks with every phase of the campaign.
14//! * **Portable modules** (`chroma_mc`, …) hold Rust intrinsics with an x86-64 path, an
15//!   aarch64 NEON path, and a scalar reference that all three are tested bit-identical
16//!   against. These compile and run on **every** architecture.
17//!
18//! Until the campaign finishes, the crate is a mix. The whole crate used to be
19//! `#![cfg(target_arch = "x86_64")]` — compiled to nothing on ARM, which is why aarch64
20//! ran fully scalar. That gate now sits on the `x86_asm` module alone, so portable
21//! kernels reach ARM as they land.
22//!
23//! **Order matters: replace, then rip.** The vendored assembly measures ~1.94x on decode
24//! (paired, N=5, 34/35 reps above 1.0), so deleting a kernel before its portable
25//! replacement is bit-identical and no slower would ship a real regression.
26//!
27//! openh264 asm is BSD-2 licensed; attribution lives in `vendor/LICENSE.openh264`.
28#![allow(non_snake_case)]
29
30// --- portable: every architecture --------------------------------------------------
31mod chroma_mc;
32pub use chroma_mc::{mc_chroma_w4, mc_chroma_w8};
33mod deblock_simd;
34pub use deblock_simd::{
35    deblock_chroma_eq4_h, deblock_chroma_eq4_v, deblock_chroma_lt4_h, deblock_chroma_lt4_v,
36    deblock_luma_eq4_h, deblock_luma_eq4_v, deblock_luma_lt4_h, deblock_luma_lt4_v,
37};
38mod luma_mc;
39mod satd_sad;
40// Portable transform/quant. MEASURED SLOWER than the openh264 assembly on x86-64
41// (fast preset 1.253 against a 12.7% floor; quality 1.031, within floor), so x86-64
42// keeps the assembly and this serves every OTHER architecture — which previously had
43// no implementation at all. Reopen the x86 swap with SIMD intrinsics; the scalar
44// shape was not enough here, unlike the 4x4 kernels LLVM does vectorise well.
45mod transform_quant;
46#[cfg(not(target_arch = "x86_64"))]
47pub use transform_quant::{dct_four_t4, idct_four_t4_rec, quant_four_4x4};
48pub use satd_sad::{
49    sad_16x16, sad_16x8, sad_8x16, satd_16x16, satd_16x8, satd_4x4, satd_8x16, satd_8x8,
50};
51pub use luma_mc::{mc_centre, mc_hor20, mc_ver02, pixel_avg};
52
53// --- still assembly-backed: x86-64 only ---------------------------------------------
54#[cfg(target_arch = "x86_64")]
55mod x86_asm;
56#[cfg(target_arch = "x86_64")]
57pub use x86_asm::*;