[vlc-commits] [Git][videolan/vlc][master] qt: enforce synchronization in video surface when vout becomes available

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Sat Aug 16 14:04:42 UTC 2025



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
eec0b959 by Fatih Uzunoglu at 2025-08-16T13:21:26+00:00
qt: enforce synchronization in video surface when vout becomes available

This is because even when there is video surface provider bound, without
vout the forwarded requests are not respected in the provider.

Granted, one can argue that it should be the provider's responsibility to
store to forwarded properties from the surface item, and apply them as
soon as vout is available. However, that would be really debatable, because
the availability of vout is public in the provider.

- - - - -


2 changed files:

- modules/gui/qt/maininterface/videosurface.cpp
- modules/gui/qt/maininterface/videosurface.hpp


Changes:

=====================================
modules/gui/qt/maininterface/videosurface.cpp
=====================================
@@ -250,7 +250,7 @@ void VideoSurface::synchronize()
         position = renderPosition();
     }
 
-    if (m_oldRenderSize != size || m_dprDirty)
+    if (m_allDirty || m_dprDirty || m_oldRenderSize != size)
     {
         if (!size.isEmpty())
         {
@@ -259,7 +259,7 @@ void VideoSurface::synchronize()
         }
     }
 
-    if (m_oldRenderPosition != position || m_dprDirty)
+    if (m_allDirty || m_dprDirty || m_oldRenderPosition != position)
     {
         if (position.x() >= 0.0 && position.y() >= 0.0)
         {
@@ -268,11 +268,13 @@ void VideoSurface::synchronize()
         }
     }
 
-    if (m_dprDirty)
+    if (m_allDirty || m_dprDirty)
     {
         emit surfaceScaleChanged(m_dpr);
         m_dprDirty = false;
     }
+
+    m_allDirty = false;
 }
 
 void VideoSurface::itemChange(ItemChange change, const ItemChangeData &value)
@@ -312,6 +314,17 @@ void VideoSurface::setVideoSurfaceProvider(VideoSurfaceProvider *newVideoSurface
         connect(this, &VideoSurface::surfacePositionChanged, m_provider, &VideoSurfaceProvider::surfacePositionChanged, Qt::DirectConnection);
         connect(this, &VideoSurface::surfaceScaleChanged, m_provider, &VideoSurfaceProvider::surfaceScaleChanged, Qt::DirectConnection);
 
+        // With auto connection, this should be queued if the signal was emitted from vout thread,
+        // so that the slot is executed in item's thread:
+        connect(m_provider, &VideoSurfaceProvider::videoEnabledChanged, this, [this](bool enabled) {
+            if (enabled)
+            {
+                m_videoEnabledChanged = true;
+                if (flags().testFlag(ItemHasContents)) // "Only items which specify QQuickItem::ItemHasContents are allowed to call QQuickItem::update()."
+                    update();
+            }
+        });
+
         connect(&m_wheelEventConverter, &WheelToVLCConverter::vlcWheelKey, m_provider, &VideoSurfaceProvider::onMouseWheeled);
 
         setFlag(ItemHasContents, true);
@@ -366,5 +379,11 @@ QSGNode *VideoSurface::updatePaintNode(QSGNode *node, UpdatePaintNodeData *data)
         m_dprChanged = false;
     }
 
+    if (m_videoEnabledChanged)
+    {
+        m_allDirty = true;
+        m_videoEnabledChanged = false;
+    }
+
     return ViewBlockingRectangle::updatePaintNode(node, data);
 }


=====================================
modules/gui/qt/maininterface/videosurface.hpp
=====================================
@@ -133,20 +133,22 @@ private:
     QPointer<QQuickWindow> m_oldWindow;
     QMetaObject::Connection m_synchConnection;
 
-    // This is updated and read from different threads, but during synchronization stage so explicit synchronization
+    // These are updated and read from different threads, but during synchronization stage so explicit synchronization
     // such as atomic boolean or locking is not necessary:
     bool m_dprChanged = false; // itemChange() <-> updatePaintNode() (different threads, but GUI thread is blocked)
+    bool m_videoEnabledChanged = false; // we need to enforce a full fledged synchronization in this case
 
     // These are updated and read from either the item/GUI thread or the render thread:
     QSizeF m_oldRenderSize;
     QPointF m_oldRenderPosition {-1., -1.};
 
-    // m_dpr and m_dprDirty are updated in render thread when the GUI thread is blocked (updatePaintNode()).
-    // m_dprDirty may be updated in GUI thread when threaded updates is not possible. Since m_dprDirty can
+    // m_dpr, m_dprDirty and m_allDirty are updated in render thread when the GUI thread is blocked (updatePaintNode()).
+    // m_dprDirty and m_allDirty may be updated in GUI thread when threaded updates is not possible. Since they can
     // not be updated both in render thread and GUI thread concurrently (as GUI thread is blocked during
     // updatePaintNode() call), data synchronization should not be necessary:
     qreal m_dpr = 1.0;
-    bool m_dprDirty = false;
+    bool m_dprDirty = false; // causes synchronizing dpr-related properties
+    bool m_allDirty = false; // causes synchronizing everything
 };
 
 #endif // VIDEOSURFACE_HPP



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/eec0b959dbb34715c887d20f02d4d415c3da6b3c

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/eec0b959dbb34715c887d20f02d4d415c3da6b3c
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list