From 2f8c02a2d39df551f8041b7acca2f1ac0f38f69d Mon Sep 17 00:00:00 2001 From: s8n Date: Fri, 8 May 2026 17:45:34 +0100 Subject: [PATCH] audit: rick-and-morty color/HDR diagnosis --- docs/21-rick-and-morty-color-audit.md | 482 ++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 docs/21-rick-and-morty-color-audit.md diff --git a/docs/21-rick-and-morty-color-audit.md b/docs/21-rick-and-morty-color-audit.md new file mode 100644 index 0000000..36ba6ec --- /dev/null +++ b/docs/21-rick-and-morty-color-audit.md @@ -0,0 +1,482 @@ +# 21 — Rick and Morty Color / HDR Audit (Read-Only) + +> Status: **read-only audit**, executed 2026-05-08 against +> `https://arrflix.s8n.ru` (Jellyfin 10.10.3 on nullstone). Scope: +> diagnose why **Rick and Morty looks "kind of gray / washed-out"** +> while other titles render normally. **No fixes applied. No state +> mutated. No transcode triggered.** +> +> Inputs: `ffprobe` via `docker exec jellyfin /usr/lib/jellyfin-ffmpeg/ffprobe` +> against on-disk media; Jellyfin REST `/Items/{id}/PlaybackInfo`, +> `/System/Configuration/encoding`, `/Branding/Configuration` (auth +> `X-Emby-Token: ${JELLYFIN_API_TOKEN}`); contrast probe against +> *The Mandalorian* as a known-good SDR title; review of `CustomCss` +> against the inventory in doc 14 §1b. + +--- + +## 1. Executive summary + +**Confirmed root cause:** the Rick and Morty release on disk is an +**HDR10 4K HEVC Main 10 (PQ / BT.2020) "AI Upscale"** of an originally +SDR animated show. Jellyfin classifies it as `VideoRange=HDR` +`VideoRangeType=HDR10` and forces the browser onto the **transcode +path** (`TranscodeReasons=ContainerNotSupported, AudioCodecNotSupported, +SubtitleCodecNotSupported` — every browser session triggers this). The +encoding config has **`EnableTonemapping=false` and +`HardwareAccelerationType=none`**, so ffmpeg software-decodes the +HDR10 source, then h264-encodes **without applying a tonemap**, then +the browser interprets the resulting BT.2020 PQ pixel data as plain +BT.709 SDR. That mis-interpretation is the textbook signature of the +washed-out grey look. + +**One-line remediation (lowest blast radius):** in +`/System/Configuration/encoding`, set `EnableTonemapping=true` (the +algorithm `bt2390` is already correctly selected) — this enables CPU +tonemap on the existing software pipeline; CSS, hardware, and source +files do not need to change. + +CSS / theme is **ruled out** as a cause — `CustomCss` contains zero +`grayscale(`, zero `saturate(`, zero `hue-rotate(` filters. + +--- + +## 2. ffprobe table — Rick and Morty (Season 01) + +All probes via `docker exec jellyfin /usr/lib/jellyfin-ffmpeg/ffprobe -v error -select_streams v:0 …`. + +| File | Codec | Profile | Pix fmt | color_space | color_transfer | color_primaries | range | W×H | Bitrate | Size | HDR side-data | +|---|---|---|---|---|---|---|---|---|---|---|---| +| S01E01 — Pilot | hevc | Main 10 | yuv420p10le | bt2020nc | **smpte2084** (PQ) | bt2020 | pc | 3840×2160 | 8.13 Mbit/s | 1.34 GB | **none** (no MasteringDisplay / CLL block) | +| S01E05 — Meeseeks and Destroy | hevc | Main 10 | yuv420p10le | bt2020nc | **smpte2084** | bt2020 | pc | 3840×2160 | 7.97 Mbit/s | 1.26 GB | not present | +| S01E08 — Rixty Minutes | hevc | Main 10 | yuv420p10le | bt2020nc | **smpte2084** | (BT.2020) | (pc) | 3840×2160 | n/a | 1.34 GB | not present | +| S01E11 — Ricksy Business | hevc | Main 10 | yuv420p10le | bt2020nc | **smpte2084** | bt2020 | pc | 3840×2160 | 8.86 Mbit/s | 1.49 GB | not present | + +**Reading:** + +- `color_transfer=smpte2084` (a.k.a. ST 2084 / PQ) is the **HDR10 + transfer function**. All R&M S01 episodes ship with HDR10 tagging. +- `color_primaries=bt2020` + `color_space=bt2020nc` are the BT.2020 + wide-gamut primaries (the HDR colour space). +- `pix_fmt=yuv420p10le` = 10-bit-per-component, 4:2:0 chroma sub- + sampling. Required for HDR10 content. +- `color_range=pc` = full-range (0–1023 for 10-bit) rather than the + TV-range (64–940) usually expected. **This is unusual** — most HDR10 + Blu-ray / streaming sources are TV-range. PC-range mis-interpreted + as TV-range is itself a contrast/saturation hit, layered on top of + the HDR-as-SDR hit. +- **No HDR side-data** (`MasteringDisplayMetadata`, + `ContentLightLevelMetadata`) is present in any episode — the source + declares HDR10 but ships without the static-metadata blocks that a + proper HDR display or tonemapper would consume. This is a + fingerprint of a **fake HDR10** AI upscale (the file's own embedded + title is `"Rick and Morty - S01E01 - Pilot - 2160p HDR Ai Upscale -Mesc"`). +- 4K x 24 fps x ~8 Mbit/s × 1320 s = file size matches container + declaration, no surprises in muxing. +- The poster art / show landing page itself is rendered by the SPA + from JF's image cache (PNG / JPEG, sRGB) — those are not affected by + HDR. Only the **video element** is washed-out. + +### 2a. Comparison vs. The Mandalorian (known-good SDR) + +| File | Codec | Profile | Pix fmt | color_space | color_transfer | W×H | Bitrate | +|---|---|---|---|---|---|---|---| +| Mandalorian S01E01 | hevc | Main 10 | yuv420p10le | **bt709** | **bt709** | 1920×804 | 6.69 Mbit/s | +| Mandalorian S02E01 | hevc | Main 10 | yuv420p10le | **bt709** | **bt709** | (1920×…) | n/a | +| Mandalorian S03E01 | hevc | Main 10 | yuv420p10le | **bt709** | **bt709** | 1920×804 | 6.72 Mbit/s | + +**Reading:** Mandalorian is **plain SDR BT.709** (the same colour space +the browser's `