fix: bias yt-dlp format_sort toward board's HW-decoded codec (Pi 5 HEVC)#3093
fix: bias yt-dlp format_sort toward board's HW-decoded codec (Pi 5 HEVC)#3093TekScene wants to merge 6 commits into
Conversation
…enly#3092) On Pi 5 (HEVC-only hardware decode), download_youtube_asset was requesting H.264 via a hardcoded format_sort preference. The download succeeded, but normalize_video_asset then rejected the asset with "Video codec 'h264' is not hardware-decoded on this device. Supported: hevc." The capability detection already existed — it just wasn't consulted before the download. Fix: call _hw_decoded_codecs() before building ydl_opts and set the leading format_sort entry to the board's preferred codec. HEVC-only boards (Pi 5) now request vcodec:hevc; all others keep vcodec:h264. Unknown boards fall back to h264 so the download still proceeds. Adds four tests covering Pi 5 (HEVC), Pi 4 (H.264 preferred when both supported), Pi 3 (H.264 only), and unrecognised board (h264 fallback). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pi 5's BCM2712 has no H.264 hardware decoder; the Cortex-A76 cores software-decode 1080p H.264 without frame drops. However YouTube rarely serves HEVC, so the previous HEVC-only codec gate on Pi 5 rejected every YouTube download regardless of format_sort preference. - processing.py: add h264 to pi5's accepted codec set alongside hevc - celery_tasks.py: simplify format_sort to prefer hevc on any board that has it (yt-dlp falls back to h264 on YouTube anyway) - test_processing.py: replace pi5+h264-rejection tests with pi3+hevc-rejection tests (mocked ffprobe, no ffmpeg needed); add new test asserting h264 IS accepted on pi5 via software decode - test_celery_tasks.py: update pi4 test to expect hevc preference Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add test_video_unsupported_codec_still_rejected_on_pi5 to verify that
codecs outside Pi 5's accepted set (VP9, AV1, …) still raise
UnsupportedVideoCodecError even after h264 was added as a software-
decode fallback. Restores the removed-behavior coverage flagged by the
code review for that path.
Also restore _ffmpeg_reencode_recipe / _handbrake_steps to prefer h264
when it's in the accepted set (faster to encode; both codecs are
hardware-decoded on Pi 4 where the set is {h264, hevc}). Update the
docstrings to reflect the current logic.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous comment said "HEVC-only boards (Pi 5) must not receive an H.264 stream", which was true before this PR but is now wrong: Pi 5 accepts H.264 via Cortex-A76 software decode since YouTube rarely serves HEVC. Update the comment to accurately describe the current behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On-device test report — physical Pi 5Tested both halves of this PR on a physical Pi 5 ( 1. Playback: does Pi 5 actually play SW-decoded 1080p H.264 smoothly? ✅The viewer image is unchanged by this PR, so I measured presented frame rate directly via the kernel
Both present at the 30 fps source cadence — SW-decoded H.264 is just as smooth as HW-decoded HEVC, at a higher but far-from-saturating CPU cost (~14% of total CPU). The "no frame drops on Cortex-A76" claim in the PR description holds on real hardware. (The old ~11 fps Pi 5 presentation bottleneck was fixed in #2975, which is already in the shipping viewer image.) 2. Gate change: clean before/after ✅Patched the two hunks into the celery container and ran the real
3. Live YouTube download — blocked by environment, not the PR
|
|
@TekScene Thank you for the contribution but please fix the linter error. |
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add _PREFERRED_DOWNLOAD_VCODEC dict and preferred_download_vcodec() in processing.py alongside _HW_DECODE_VIDEO_CODECS, so per-board download preferences live with the rest of the codec definitions rather than as ad-hoc logic in celery_tasks.py. Pi 5 keeps its HEVC preference (hardware decode path). Pi 4, x86, Rock Pi 4 and all other boards revert to H.264 — it is their primary hardware path and more widely available on YouTube. x86 HEVC via VAAPI is known-broken (black screen), so narrowing the HEVC bias to Pi 5 only closes that risk. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Good catch. The original implementation biased all HEVC-capable boards (Pi 4, x86, Rock Pi 4) toward HEVC in The updated approach introduces
A dedicated test ( |



Summary
Fixes #3092.
On Pi 5,
download_youtube_assetused a hardcodedvcodec:h264format_sort preference. yt-dlp downloaded H.264 (the only codec YouTube typically serves), which then failed at thenormalize_video_assetcodec gate:Two root causes fixed:
1. yt-dlp format selection (
celery_tasks.py): Call_hw_decoded_codecs()before buildingydl_optsand prefer HEVC informat_sortwhenever the board supports it. If YouTube ever serves an HEVC stream, it'll be picked automatically. When it doesn't (the common case), yt-dlp falls back to H.264.2. Pi 5 codec gate too strict (
processing.py): Pi 5's BCM2712 has no H.264 hardware decoder, but its Cortex-A76 cores software-decode 1080p H.264 without frame drops. YouTube rarely serves HEVC, so the previous HEVC-only gate rejected every YouTube download. H.264 is now accepted on Pi 5 alongside HEVC. On-device transcoding was explicitly ruled out — a prior attempt wedged a Pi 4's Celery worker for 99 minutes on a single H.264→HEVC pass.Changes:
src/anthias_server/celery_tasks.py: prefer HEVC in format_sort on any board that has it; fall back to H.264src/anthias_server/processing.py: addh264to Pi 5's accepted codec settests/test_celery_tasks.py: 4 new tests for per-board format_sort selection; Pi 4 test updated (now prefers HEVC when available)tests/test_processing.py: replace Pi 5+H.264 rejection tests (no longer valid) with Pi 3+HEVC rejection tests using mocked ffprobe; add new test asserting H.264 is accepted on Pi 5Test plan
pytest tests/test_celery_tasks.py -k "format"passes (4 new tests)pytest tests/test_celery_tasks.pyfully greenpytest tests/test_processing.pyfully green🤖 Generated with Claude Code