PU21 (HDR perceptual PSNR / SSIM)¶
PU21 (Perceptually Uniform encoding, 2021) is a full-reference HDR adapter: it maps absolute display luminance (cd/m², a.k.a. nits) through a contrast-sensitivity-fitted transfer curve so that the ordinary SDR metrics (PSNR, SSIM) become perceptually meaningful on HDR content. PSNR/SSIM computed directly on PQ code values or on linear HDR correlate poorly with perception above ~100 nit; PU21 closes that gap. It is the standard, peer-reviewed "transform-then-score" approach (Mantiuk & Azimi, QoMEX/PCS 2021) and the closest analog to the fork's CIEDE2000 / SSIMULACRA 2 extractors.
The pu21 extractor provides two features:
| Feature key | Meaning |
|---|---|
pu21_psnr | PSNR of the PU21-encoded luma planes (peak = 256, no SDR dB cap) |
pu21_ssim | Single-scale Gaussian SSIM of the PU21-encoded luma planes at data range L = 256 |
What it measures¶
For each frame, the luma (Y) plane of the reference and distorted pictures is:
- decoded from its PQ (SMPTE ST.2084) code value to absolute luminance in cd/m² (ST.2084 EOTF × 10000);
- clamped to the PU21 valid domain [0.005, 10000] cd/m²;
- PU21-encoded through the 7-coefficient transfer function (default
banding_glarevariant). The encoding is designed so 100 nit maps to ~256, mimicking an 8-bit SDR input to the downstream metric, and spans ~0..600.
PU-PSNR is then 10·log10(256² / MSE) over the encoded planes (peak = 256, no SDR cap — the 60/72/84/108 dB SDR table is inappropriate for the ~0..600 encoded domain; identical frames yield a large finite dB). PU-SSIM is a single-scale 11×11 Gaussian SSIM at data range L = 256 (C1 = (0.01·256)², C2 = (0.03·256)²).
All per-pixel math is performed in double precision.
Note on PU-SSIM. PU21 requires SSIM at data range L = 256. The fork's shared SSIM kernel (backing the
float_ssimfeature and the Netflix golden assertions) hardcodes L = 255 and is left byte-identical and untouched; PU21 ships its own self-contained L = 256 SSIM. PU-SSIM is therefore not bit-comparable to thefloat_ssimfeature.
Scope (RC)¶
- Luma only. Only the Y plane is encoded and scored (matches SSIM's luminance path; chroma encoding is a future scope decision).
- PQ input only. The
transferoption defaults topqand rejects any other value with-EINVAL. HLG (needs an OOTF peak-luminance assumption) and SDR-gamma (needs a display multiplier) input paths are deferred, consistent with the ΔE-ITP HDR-scope decision. - Full-range PQ assumed. The PQ decode normalises each code value by its bit-depth maximum (
2^bpc - 1, e.g./1023for 10-bit) — i.e. it assumes full-range ("PC range") code values. Limited-range ("video range") HDR10, where 10-bit luma spans 64–940 rather than 0–1023, would be mis-scaled: the decoded luminance is too low at the floor and clipped against the wrong ceiling, shifting the PU21 encoding. Norangeoption is offered because PU21 performs no YUV→RGB matrix decode — it operates directly on the integer luma plane — so a range flag would only gate this single normalisation constant. Feed full-range PQ luma; if your source is limited-range, expand it to full range before scoring. - Bit depths: 8 / 10 / 12 / 16-bit; HDR content is realistically 10/12-bit.
- No model assets. PU21 is a closed-form coefficient table — no ONNX/PKL.
Options¶
| Option | Type | Default | Values |
|---|---|---|---|
variant | string | banding_glare | banding, banding_glare, peaks, peaks_glare |
transfer | string | pq | pq (others rejected with -EINVAL in RC) |
The banding_glare variant is the canonical default recommended by the PU21 authors.
How to run PU21¶
PU21 expects PQ-encoded HDR YUV. Using the VMAF command line:
core/build/tools/vmaf \
--reference ref_pq.yuv \
--distorted dist_pq.yuv \
--width 3840 --height 2160 --pixel_format 420 --bitdepth 10 \
--no_prediction --feature pu21 --output /dev/stdout
Select a different variant via the option syntax:
Each frame yields pu21_psnr (dB) and pu21_ssim (0..1) values, pooled across frames by the framework. Higher PU-PSNR and PU-SSIM mean closer perceptual agreement; for near-identical HDR frames PU-PSNR > 60 dB is normal.
References¶
- Mantiuk & Azimi, "PU21: A novel perceptually uniform encoding for adapting existing quality metrics for HDR", QoMEX/PCS 2021 — https://ieeexplore.ieee.org/document/9477471/.
- Official reference implementation (encoder coefficients + formula + range): https://github.com/gfxdisp/pu21 (BSD 3-Clause, University of Cambridge 2021).
- SMPTE ST.2084 (PQ) — Perceptual Quantizer EOTF.
- Design decision: ADR-1111.