docs(plex): the transcode comments say the CPU-decode route

This commit is contained in:
2026-11-07 21:48:39 +01:00
parent 4ed07388e8
commit a6f1a26658
2 changed files with 20 additions and 17 deletions
+11 -9
View File
@@ -4,9 +4,10 @@ Playback is from the LOCAL physical file. Browser-compatible files (playable="di
raw with HTTP range requests. Everything else that is h264 video (playable="remux") is remuxed on
the fly to HLS with **video stream-copy** (cheap, I/O-bound — no video re-encode) and audio to AAC
when needed. Non-h264 video (playable="transcode": HEVC/VP9/AV1/MPEG-2/XviD…) needs a full re-encode
to H.264: on the prod host that runs on the Intel iGPU via VAAPI (`h264_vaapi`, near-zero CPU), with
software libx264 as the automatic fallback where the render node is absent or the source codec isn't
hardware-decodable. Same HLS session/seek machinery either way — only the video encoder differs.
to H.264: on the prod host that is encoded on the Intel iGPU via VAAPI (`h264_vaapi`) — decoded there
too when it can, else decoded on the CPU and uploaded (VC-1, XviD, DivX) — with software libx264 as
the fallback where the render node is absent, for a source neither GPU route takes (AV1, 10-bit SDR),
and when a GPU session produces nothing. Same HLS session/seek machinery either way.
Seek model (Jellyfin-style): one ffmpeg session per item, started at a given offset via `-ss`
(fast keyframe seek). A seek beyond the generated region restarts the session at the new offset,
@@ -501,16 +502,17 @@ def _want_hw(db: DbSession, item: PlexItem, transcode: bool, src: Path) -> bool:
return _select_encode(db, item, transcode, src)[0]
# CPU-nice increment for the SOFTWARE transcode child. The Plex ffmpeg is a Popen in the long-lived API
# process (which must NOT itself be niced), so — unlike the download worker's _deprioritize (run once in
# its own main()) — we lower priority per-child via preexec_fn in the fork. The GPU path needs none of
# this. Reuses the download child's nice default so all co-located re-encoders share one handicap.
# CPU-nice increment for a transcode child that works the CPU: a software encode, or a CPU decode
# feeding the GPU encoder. The Plex ffmpeg is a Popen in the long-lived API process (which must NOT
# itself be niced), so — unlike the download worker's _deprioritize (run once in its own main()) — we
# lower priority per-child via preexec_fn in the fork. The full-GPU path needs none of this. Reuses
# the download child's nice default so all co-located re-encoders share one handicap.
_SW_TRANSCODE_NICE = settings.download_child_nice
def _sw_child_preexec() -> None:
"""Runs in the forked child (POSIX) before exec: renice this software-transcode ffmpeg down so it
can't starve the co-located API / Postgres / playback. Best-effort — a failed renice must not fail
"""Runs in the forked child (POSIX) before exec: renice this CPU-bound transcode ffmpeg down so
it can't starve the co-located API / Postgres / playback. Best-effort — a failed renice must not fail
playback."""
try:
os.nice(_SW_TRANSCODE_NICE)