[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt: use libatomic

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Sun Feb 16 11:54:22 UTC 2025



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


Commits:
55bbcaf9 by Fatih Uzunoglu at 2025-02-16T11:39:28+00:00
qt: use libatomic

- - - - -
389a1999 by Fatih Uzunoglu at 2025-02-16T11:39:28+00:00
qt: use sampling instead of event based approach to update high resolution time widget

Currently, if Qt's event loop is not fast enough to consume the high resolution events,
the events may backlog.

- - - - -


7 changed files:

- configure.ac
- modules/gui/qt/Makefile.am
- modules/gui/qt/meson.build
- modules/gui/qt/player/player_controller.cpp
- modules/gui/qt/player/player_controller.hpp
- modules/gui/qt/player/player_controller_p.hpp
- modules/gui/qt/player/qml/controlbarcontrols/HighResolutionTimeWidget.qml


Changes:

=====================================
configure.ac
=====================================
@@ -996,6 +996,13 @@ AS_IF([test "${SYS}" != "mingw32"], [
 ])
 AC_SUBST([LIBRT])
 
+dnl Check for libatomic
+have_libatomic="no"
+VLC_SAVE_FLAGS
+AC_SEARCH_LIBS([__atomic_load], [atomic], [have_libatomic="yes"])
+VLC_RESTORE_FLAGS
+AM_CONDITIONAL([HAVE_LIBATOMIC], [test "${have_libatomic}" = "yes"])
+
 dnl  Check for clock_* functions, needs to be done here,
 dnl  after the -lrt check
 AC_REPLACE_FUNCS([clock_gettime clock_nanosleep clock_getres])


=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -51,6 +51,10 @@ libqt_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS_qt) \
 
 libqt_plugin_la_CXXFLAGS = $(AM_CXXFLAGS) $(QT_CFLAGS) $(CXXFLAGS_qt) -fPIC
 libqt_plugin_la_LIBADD = $(vlc_qt_libs)
+if HAVE_LIBATOMIC
+libqt_plugin_la_CXXFLAGS += -DQT_HAS_LIBATOMIC
+libqt_plugin_la_LIBADD += -latomic
+endif
 libqt_plugin_la_LDFLAGS = $(AM_LDFLAGS) $(QT_LDFLAGS)
 if HAVE_DARWIN
 libqt_plugin_la_LDFLAGS += -Wl,-framework,Cocoa


=====================================
modules/gui/qt/meson.build
=====================================
@@ -924,6 +924,12 @@ if qt6_dep.found()
         qt_rcc_extra_arguments += '-compress-algo=zlib'
     endif
 
+    libatomic = cc.find_library('atomic', required: false)
+    if libatomic.found()
+        qt_extra_deps += cc.find_library('atomic', required: false)
+        qt_extra_flags += '-DQT_HAS_LIBATOMIC'
+    endif
+
     prog_python = find_program('python3')
     modules_qrc = []
     foreach module : qml_modules


=====================================
modules/gui/qt/player/player_controller.cpp
=====================================
@@ -38,6 +38,10 @@
 #include <QDir>
 #include <QSignalMapper>
 #include <QThreadPool>
+#ifndef QT_HAS_LIBATOMIC
+#include <QReadLocker>
+#include <QWriteLocker>
+#endif
 
 #include <cassert>
 
@@ -1009,16 +1013,10 @@ static void on_player_timer_smpte_update(const struct vlc_player_timer_smpte_tim
                                          void *data)
 {
     PlayerControllerPrivate* that = static_cast<PlayerControllerPrivate *>(data);
-
-    that->callAsync([that, tc_copy = *tc](){
-        that->m_highResolutionTime = QString::asprintf("%02u:%02u:%02u%c%02u",
-                                                       tc_copy.hours,
-                                                       tc_copy.minutes,
-                                                       tc_copy.seconds,
-                                                       tc_copy.drop_frame ? '.' : ':',
-                                                       tc_copy.frames);
-        emit that->q_func()->highResolutionTimeChanged(that->m_highResolutionTime);
-    });
+#ifndef QT_HAS_LIBATOMIC
+    QWriteLocker lock(&that->m_highResolutionTimeLock);
+#endif
+    that->m_highResolutionTime = *tc;
 }
 
 
@@ -1953,6 +1951,39 @@ void PlayerController::snapshot()
     }
 }
 
+QString PlayerController::highResolutionTime() const
+{
+    Q_D(const PlayerController);
+
+    // Sample:
+    vlc_player_timer_smpte_timecode sample;
+    {
+#ifndef QT_HAS_LIBATOMIC
+        QReadLocker lock(&d->m_highResolutionTimeLock);
+#endif
+        sample = d->m_highResolutionTime;
+    }
+
+    const vlc_player_timer_smpte_timecode& lastSample = d->m_highResolutionTimeSample.first;
+
+    if (sample.frames == lastSample.frames &&
+        sample.frame_resolution == lastSample.frame_resolution &&
+        sample.seconds == lastSample.seconds &&
+        sample.minutes == lastSample.minutes &&
+        sample.hours == lastSample.hours &&
+        sample.drop_frame == lastSample.drop_frame)
+        return d->m_highResolutionTimeSample.second;
+
+    d->m_highResolutionTimeSample.second = QString::asprintf("%02u:%02u:%02u%c%02u",
+                                                             sample.hours,
+                                                             sample.minutes,
+                                                             sample.seconds,
+                                                             sample.drop_frame ? '.' : ':',
+                                                             sample.frames);
+    d->m_highResolutionTimeSample.first = std::move(sample);
+
+    return d->m_highResolutionTimeSample.second;
+}
 
 //OTHER
 
@@ -2137,7 +2168,4 @@ PRIMITIVETYPE_GETTER(QString, getAlbum, m_album)
 PRIMITIVETYPE_GETTER(QUrl, getArtwork, m_artwork)
 PRIMITIVETYPE_GETTER(QUrl, getUrl, m_url)
 
-// High resolution time fed by SMPTE timer
-PRIMITIVETYPE_GETTER(QString, highResolutionTime, m_highResolutionTime)
-
 #undef PRIMITIVETYPE_GETTER


=====================================
modules/gui/qt/player/player_controller.hpp
=====================================
@@ -196,7 +196,7 @@ public:
     Q_PROPERTY(RendererManager* rendererManager READ getRendererManager CONSTANT FINAL)
 
     // High resolution time fed by SMPTE Timer
-    Q_PROPERTY(QString highResolutionTime READ highResolutionTime NOTIFY highResolutionTimeChanged FINAL)
+    Q_PROPERTY(QString highResolutionTime READ highResolutionTime FINAL)
 
     /* exposed actions */
 public slots:


=====================================
modules/gui/qt/player/player_controller_p.hpp
=====================================
@@ -29,6 +29,11 @@
 #include <QTimer>
 #include <QUrl>
 
+#ifndef QT_HAS_LIBATOMIC
+#warning "libatomic is not available. Read write lock is going to be used instead."
+#include <QReadWriteLock>
+#endif
+
 typedef struct vlc_preparser_t vlc_preparser_t;
 
 class PlayerControllerPrivate {
@@ -95,7 +100,14 @@ public:
     double       m_position = 0.f;
     VLCTick      m_length= 0;
 
-    QString m_highResolutionTime { "00:00:00:00" };
+#if QT_HAS_LIBATOMIC
+    std::atomic<vlc_player_timer_smpte_timecode> m_highResolutionTime;
+#else
+    vlc_player_timer_smpte_timecode m_highResolutionTime;
+    mutable QReadWriteLock m_highResolutionTimeLock;
+#endif
+    mutable QPair<vlc_player_timer_smpte_timecode, QString> m_highResolutionTimeSample;
+
     unsigned m_smpteTimerRequestCount = 0;
 
     SharedInputItem    m_currentItem;


=====================================
modules/gui/qt/player/qml/controlbarcontrols/HighResolutionTimeWidget.qml
=====================================
@@ -17,6 +17,7 @@
  *****************************************************************************/
 
 import QtQuick
+import QtQuick.Window
 import QtQuick.Controls
 
 
@@ -37,7 +38,7 @@ Control {
     Keys.onPressed: (event) => Navigation.defaultKeyAction(event)
 
     Accessible.role: Accessible.Indicator
-    Accessible.name:  paintOnly ? "00:00:00:00" : Player.highResolutionTime
+    Accessible.name: contentItem.text
 
     function _adjustSMPTETimer(add) {
         if (typeof toolbarEditor !== "undefined") // FIXME: Can't use paintOnly because it is set later
@@ -73,16 +74,46 @@ Control {
         implicitHeight: smpteTimecodeMetrics.height
         implicitWidth: smpteTimecodeMetrics.width
 
+        property alias text: label.text
+
         Widgets.MenuLabel {
             id: label
             anchors.fill: parent
 
-            text: paintOnly ? "00:00:00:00" : Player.highResolutionTime
+            text: paintOnly ? "00:00:00:00" : timeText
             color: theme.fg.primary
 
             horizontalAlignment: Text.AlignHCenter
 
             Accessible.ignored: true
+
+            property string timeText
+
+            Connections {
+                target: label.Window.window
+                enabled: label.visible
+
+                function onAfterAnimating() {
+                    // Sampling point
+                    // Emitted from the GUI thread
+
+                    // Constantly update the label, so that the window
+                    // prepares new frames as we don't know when the
+                    // timecode changes. This is similar to animations:
+                    label.update()
+
+                    if (label.timeText === Player.highResolutionTime)
+                        return
+
+                    label.timeText = Player.highResolutionTime
+
+                    // Text would like polishing after text change.
+                    // We need this because `afterAnimating()` is
+                    // signalled after the items are polished:
+                    if (label.ensurePolished)
+                        label.ensurePolished()
+                }
+            }
         }
 
         TextMetrics {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4f3aac42bcdf0da26cbbb21207a608bf205592df...389a1999412fc2a3fd6b5065de6c7e9681a87bb0

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4f3aac42bcdf0da26cbbb21207a608bf205592df...389a1999412fc2a3fd6b5065de6c7e9681a87bb0
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