Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Multimedia
  4. Seamless video-to-video transition with v4l2h264dec + waylandsink on Pi3 (Debian Trixie) — frozen frame between clips
Qt 6.11 is out! See what's new in the release blog

Seamless video-to-video transition with v4l2h264dec + waylandsink on Pi3 (Debian Trixie) — frozen frame between clips

Scheduled Pinned Locked Moved Unsolved Qt Multimedia
gstreamerwaylandsinkraspberryqtquickv4l2
2 Posts 2 Posters 261 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    The Qt Mayssa
    wrote last edited by
    #1
    Platform: Raspberry Pi 3B, Debian Trixie, Qt 5.15, GStreamer 1.24, Wayland compositor, v4l2h264dec

    Why we built a custom GStreamer item instead of using Qt Multimedia's Video element

    Before describing the transition problem itself, I want to explain why we're not using Qt Multimedia's Video QML element, since that's the obvious first question.

    Qt Multimedia's GStreamer backend does use v4l2h264dec — we confirmed this with GST_DEBUG=3. That's not the issue. The issue is what happens at EOS on this specific platform.

    On Pi3 / kernel 6.6, when GST_EVENT_EOS reaches the V4L2 sink, it triggers a known memory leak in the Pi's V4L2 driver at end-of-playback. For a digital signage player looping content 24/7, this CMA (Contiguous Memory Allocator) leak accumulates until V4L2 buffer allocation fails:

    v4l2h264dec: Failed to allocate output buffers — Cannot allocate memory
    

    The workaround is to intercept and drop GST_EVENT_EOS via a pad probe on the sink pad, before it reaches the driver. End-of-video is detected via GST_MESSAGE_EOS on the bus (which is still emitted normally).

    Qt Multimedia's Video element doesn't expose any hook to install a pad probe at this level. This is why we built GstVideoItemV2, a custom QQuickItem that drives the pipeline directly with the raw GStreamer C API.

    Our pipeline:

    filesrc → qtdemux → h264parse → v4l2h264dec → queue → waylandsink
                                                                 ↑
                                                   pad probe: drop GST_EVENT_EOS
    

    Note on Qt6:

    migrating to Qt6 is not on our roadmap today, but if Qt6 Multimedia's GStreamer backend exposes pad-probe-level hooks, or if newer kernels have fixed this V4L2 EOS leak, it would be a strong argument to prioritize the upgrade. Any feedback on Qt6 + Pi3 + Wayland experience is welcome.
    The problem: ~13–80ms frozen frame at every video transition
    In a playlist zone, our player pre-builds the next video's pipeline while the current video is still playing (buildPipeline() runs on a separate dedicated worker thread). When video 1 ends:

    Video 1:  PLAYING ──────────────────────── STATE_NULL (~9ms, holds v4l2 lock)
    Video 2:     buildPipeline (11ms, no lock) ──────── waits lock ── set_state(PLAYING)
    Screen:   video 1 last frame ─────────────────────── FROZEN ─────── video 2 starts
    

    The freeze is not a black screen — it's video 1's last frame held by the Wayland compositor while video 2's waylandsink hasn't rendered its first frame yet.

    Loop works fine: when the same video loops (seek to 0), we reuse the same pipeline and the same waylandsink — no teardown, no lock, no freeze. The problem is strictly video1 → video2.

    Why we can't keep waylandsink alive between videos
    Reusing waylandsink across different source files (to avoid teardown) causes additional CMA exhaustion after ~10–15 cycles on this kernel. The V4L2 decoder's DMA buffers are tied to the sink's Wayland buffer pool and aren't released until STATE_NULL. We must destroy and recreate the full pipeline on every transition.

    One hardware decoder, one at a time
    The Pi3 has one V4L2 H.264 decoder instance (/dev/video10). We serialize access with a static QMutex that gates both the STATE_NULL release (video 1's worker thread) and the set_state(PLAYING) acquisition (video 2's worker thread).

    Current mitigation: worker thread pre-warming
    Each GstVideoItemV2 runs all GStreamer ops on a dedicated QThread worker. On Pi3 ARMv7 @ 1.4 GHz, pthread_create → kernel stack allocation → first event loop dispatch takes ~40–50ms. We pre-create the next video's QQuickItem (and its worker thread) during playback of the current video. Best-case gap: ~13ms. Still perceptible.

    Questions

    Atomic waylandsink handover: is there a GStreamer pattern to swap the source decoded into a single persistent sink without going through STATE_NULL — on a system where the sink can't be kept alive across sources due to CMA constraints?
    input-selector: has anyone used it upstream of a shared sink with two independent decoder chains on Pi3 / kernel 6.6, managing the CMA budget?
    kmssink + DRM atomic flip: viable on Pi3 + Trixie to bypass compositor buffering and hide the handover gap?
    STATE_PAUSED vs STATE_NULL: does PAUSED release V4L2 CMA buffers on this kernel? If it holds the hardware open (preventing dual-open) but releases CMA, we could keep a warm pipeline.
    Qt6 Multimedia: does it handle the V4L2 EOS CMA leak differently on Pi3/Wayland? Any first-hand experience?
    Thanks in advance for any pointers.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote last edited by
      #2

      Hi,

      I can only answer on the last part: Qt6 Multimedia module currently uses ffmpeg as backend on all platform except for embedded Linux which might be your case. I suggest you take a look at GStreamer chapter in the Qt Multimedia documentation. There might be stuff in there that could be of interest.

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt
      • Unsolved