mirror of
https://github.com/Screenly/Anthias.git
synced 2026-06-10 17:18:43 -04:00
* fix(viewer): aspect-fit, gapless looping, and 30fps cap for pi1/2/3 video Fixes the issue #2987 regressions on the Qt5 linuxfb boards by moving playback from a bash gst-launch relaunch loop into a small in-process GStreamer helper (anthias_viewer/gst_fbdev_player.py): - Portrait/4:3 videos no longer stretch to the framebuffer: a CAPS-event pad probe reads the decoder's native dims + PAR and pins aspect-fit caps (pixel-aspect-ratio=1/1) on the capsfilter, so the bcm2835 ISP scales aspect-correct and fbdevsink centers the frame. The previous fb-sized forced caps parked the distortion in a PAR that fbdevsink ignores (reproduced on-device: 1080x1920 -> 3840x2160 par 81/256). - Clips no longer freeze/cut at loop boundaries: playbin about-to-finish re-queues the same URI for a gapless loop instead of rebuilding the whole pipeline per iteration (0.4-1.7 s per loop measured on a Pi 4, several seconds on a Pi 3, all eaten out of the fixed slot duration). Flush-seek on EOS and NULL->PLAYING restart remain as fallbacks. - 50/60 fps sources drop to an even 30 fps cadence up front (videorate drop-only) instead of juddering on irregular late-frame drops; the decode->ISP->memcpy chain sustains ~40 fps at 1080p on a Pi 3. - The framebuffer is zeroed at startup so letterbox borders are black rather than remnants of the previous asset. - The helper runs by path (not -m) so the package __init__ (Django settings, redis, D-Bus) never imports in the child; validated e2e on the armhf image: negotiation, rotation, looping, SIGTERM exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): address review feedback on the fbdev player helper - Correct the module docstring: the helper is executed by file path, not -m (the package __init__ must not import in the child) - Fail fast with a clear log line when the GStreamer python bindings are missing instead of crashing with a traceback - Clear the framebuffer in scanline-sized chunks so a 4K console doesn't peak a ~33 MB allocation on a 512 MB board Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): degrade to silent video when the audio branch fails Integrated testbed run surfaced a wholesale-failure mode the relaunch loop also had: a broken audio branch killed the video with it. Two real-world triggers: the ALSA card is absent (HDMI audio disabled in config.txt -> no vc4hdmi), and an undecodable audio codec (AC3 - a52dec lives in plugins-ugly, not shipped). Retry once with GST_PLAY_FLAG_AUDIO cleared on both the synchronous start failure (alsasink can't reach READY) and the first async pipeline error; a genuine video error recurs on the retry and still exits non-zero. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): read the visible fb resolution via FBIOGET_VSCREENINFO Integrated testbed run surfaced a divergence the sysfs read hides: sysfs virtual_size reports xres_virtual/yres_virtual, which can be larger than the scanned-out mode (panning / double-buffer configs — observed live: visible 1920x1080, virtual 3840x2160). fbdevsink centers/crops against varinfo.xres/yres, so scaling to the virtual size paints mostly off-screen. Query the same ioctl fbdevsink uses; keep the sysfs read (and the 1080p default) as fallbacks for hosts without fb access. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): swap the audio sink for fakesink on the video-only retry Clearing GST_PLAY_FLAG_AUDIO is not sufficient: an element set on the audio-sink property remains a playsink child and is still state-synced with the pipeline, so a failing alsasink failed the retry too (observed live on the testbed). Replace it with a fakesink when degrading to silent video. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): pre-flight the ALSA device and rebuild on audio failure The integrated testbed run showed two things the previous in-place retry missed: - a playbin whose sink activation failed does not reliably restart after NULL: the video-only retry failed instantly on the reused element with no further GStreamer error; - alsasink opens the PCM on NULL->READY, so a missing card is detectable synchronously before it can poison playbin's whole sink activation. So: pre-flight the device with a standalone alsasink and only wire the audio branch when it opens; on any pipeline error with audio enabled (e.g. an undecodable AC3 track mid-preroll), tear down and rebuild a fresh video-only playbin instead of restarting the errored one. Genuine video errors recur on the rebuilt pipeline and still exit non-zero. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): satisfy mypy on the gi-typed returns Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Documentation
This page has moved to https://anthias.screenly.io/docs/.
The Anthias documentation now lives at https://anthias.screenly.io/docs/.