[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