[vlc-commits] [Git][videolan/vlc][master] 2 commits: qt: do not take snapshots from the UI thread

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Tue Oct 4 17:15:46 UTC 2022



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
1aa5ca65 by Romain Vimont at 2022-10-04T15:28:11+00:00
qt: do not take snapshots from the UI thread

Snapshots are performed via a call to:

    var_TriggerCallback("video-snapshot")

causing its callback (SnapshotCallback) to be called synchronously,
executing the following steps:
 - wait for the vout thread to actually capture the (next) frame;
 - encode the picture to PNG;
 - write the result to disk (I/O).

Since var_TriggerCallback("video-snapshot") is called from the UI
thread, all these blocking actions are also performed on the UI thread.

Move the call to a separate thread.

- - - - -
b3ccc7b0 by Romain Vimont at 2022-10-04T15:28:11+00:00
hotkeys: do not take snapshots from the UI thread

Snapshots are performed via a call to:

    var_TriggerCallback("video-snapshot")

causing its callback (SnapshotCallback) to be called synchronously,
executing the following steps:
 - wait for the vout thread to actually capture the (next) frame;
 - encode the picture to PNG;
 - write the result to disk (I/O).

Since var_TriggerCallback("video-snapshot") is called from the UI
thread, all these blocking actions are also performed on the UI thread.

Move the call to a separate thread.

- - - - -


2 changed files:

- modules/control/hotkeys.c
- modules/gui/qt/player/player_controller.cpp


Changes:

=====================================
modules/control/hotkeys.c
=====================================
@@ -37,6 +37,7 @@
 #include <vlc_playlist.h>
 #include <vlc_actions.h>
 #include <vlc_spu.h>
+#include <vlc_executor.h>
 #include "math.h"
 
 struct intf_sys_t
@@ -56,6 +57,8 @@ struct intf_sys_t
         vlc_tick_t subtitle_time;
     } subsync;
     enum vlc_vout_order spu_channel_order;
+
+    vlc_executor_t *executor;
 };
 
 static void handle_action(intf_thread_t *, vlc_action_id_t);
@@ -758,6 +761,42 @@ PLAYER_ACTION_HANDLER(Aout)
     }
 }
 
+struct snapshot_task
+{
+    struct vlc_runnable runnable;
+    vout_thread_t *vout;
+};
+
+static void RunSnapshot(void *userdata)
+{
+    struct snapshot_task *task = userdata;
+
+    var_TriggerCallback(task->vout, "video-snapshot");
+
+    vout_Release(task->vout);
+    free(task);
+}
+
+static void TakeSnapshotAsync(struct intf_sys_t *sys, vlc_player_t *player)
+{
+    if (!sys->executor)
+    {
+        /* Create the executor only on the first request */
+        sys->executor = vlc_executor_New(1);
+        if (!sys->executor)
+            return;
+    }
+
+    struct snapshot_task *task = malloc(sizeof(*task));
+    if (!task)
+        return;
+
+    task->vout = vlc_player_vout_Hold(player);
+    task->runnable.run = RunSnapshot;
+    task->runnable.userdata = task;
+    vlc_executor_Submit(sys->executor, &task->runnable);
+}
+
 PLAYER_ACTION_HANDLER(Vouts)
 {
     VLC_UNUSED(intf);
@@ -770,7 +809,7 @@ PLAYER_ACTION_HANDLER(Vouts)
             vlc_player_vout_SetFullscreen(player, false);
             break;
         case ACTIONID_SNAPSHOT:
-            vlc_player_vout_Snapshot(player);
+            TakeSnapshotAsync(intf->p_sys, player);
             break;
         case ACTIONID_WALLPAPER:
             vlc_player_vout_ToggleWallpaperMode(player);
@@ -1283,6 +1322,9 @@ Open(vlc_object_t *this)
         return VLC_EGENERIC;
     }
     var_AddCallback(vlc_object_instance(intf), "key-action", ActionCallback, intf);
+
+    sys->executor = NULL;
+
     intf->p_sys = sys;
     return VLC_SUCCESS;
 }
@@ -1302,6 +1344,13 @@ Close(vlc_object_t *this)
     vlc_player_Unlock(player);
 
     var_DelCallback(vlc_object_instance(intf), "key-action", ActionCallback, intf);
+
+    if (sys->executor)
+    {
+        vlc_executor_WaitIdle(sys->executor);
+        vlc_executor_Delete(sys->executor);
+    }
+
     free(sys);
 }
 


=====================================
modules/gui/qt/player/player_controller.cpp
=====================================
@@ -35,6 +35,7 @@
 #include <QFile>
 #include <QDir>
 #include <QSignalMapper>
+#include <QThreadPool>
 
 #include <assert.h>
 
@@ -1791,7 +1792,22 @@ void PlayerController::snapshot()
 {
     VoutPtr vout = getVout();
     if (vout)
-        var_TriggerCallback(vout.get(), "video-snapshot");
+    {
+        /* Passing a lambda directly would require Qt 5.15:
+         * <https://doc.qt.io/qt-5/qthreadpool.html#start-1>
+         */
+        struct SnapshotTask : public QRunnable
+        {
+            VoutPtr vout;
+            SnapshotTask(VoutPtr vout) : vout(std::move(vout)) {}
+            void run() override
+            {
+                var_TriggerCallback(vout.get(), "video-snapshot");
+            }
+        };
+
+        QThreadPool::globalInstance()->start(new SnapshotTask(std::move(vout)));
+    }
 }
 
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e2a10a5cd339ded73b3501cb40e976a34437fa67...b3ccc7b027764b853ff775291769a805226578aa

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e2a10a5cd339ded73b3501cb40e976a34437fa67...b3ccc7b027764b853ff775291769a805226578aa
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