[vlc-commits] [Git][videolan/vlc][master] 3 commits: libvlc: allow user to report mouse events when using libvlc_video_set_output_callbacks
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Wed Jun 14 07:18:01 UTC 2023
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
60078ca9 by Pierre Lamot at 2023-06-14T07:01:11+00:00
libvlc: allow user to report mouse events when using libvlc_video_set_output_callbacks
when using libvlc_video_set_output_callbacks, VLC has no native surface to
intercept mouse events (unlike libvlc_media_player_set_xwindow/xid/...). This
patch allows user to send these events manually to VLC. This is useful when
dealing with interactive medias (DVD menus).
- - - - -
2ed25097 by Pierre Lamot at 2023-06-14T07:01:11+00:00
doc: d3d11_player: implement mouse support
- - - - -
04ea9e05 by Pierre Lamot at 2023-06-14T07:01:11+00:00
doc: QtGL: implement window resize and mouse callbacks
- - - - -
7 changed files:
- doc/libvlc/QtGL/qtvlcwidget.cpp
- doc/libvlc/QtGL/qtvlcwidget.h
- doc/libvlc/d3d11_player.cpp
- doc/libvlc/d3d9_player.c
- include/vlc/libvlc_media_player.h
- lib/media_player.c
- modules/video_output/wextern.c
Changes:
=====================================
doc/libvlc/QtGL/qtvlcwidget.cpp
=====================================
@@ -61,6 +61,67 @@ public:
return mBuffers[m_idx_display].get();
}
+ void onResize(QSize size)
+ {
+ QMutexLocker lock(&m_cb_lock);
+ m_windowSize = size;
+ if (!report_size_change)
+ return;
+ report_size_change(reportOpaque, size.width(), size.height());
+ }
+
+ void onMouseMove(QPoint pos)
+ {
+ QMutexLocker lock(&m_cb_lock);
+ if (!report_mouse_move)
+ return;
+ report_mouse_move(reportOpaque, pos.x(), pos.y());
+ }
+
+ void onMousePress(Qt::MouseButton button)
+ {
+ QMutexLocker lock(&m_cb_lock);
+ if (!report_mouse_press)
+ return;
+ bool ok;
+ auto vlcButton = qtToVlcMouseButton(button, &ok);
+ if (!ok)
+ return;
+ report_mouse_press(reportOpaque, vlcButton);
+ }
+
+ void onMouseRelease(Qt::MouseButton button)
+ {
+ QMutexLocker lock(&m_cb_lock);
+ if (!report_mouse_release)
+ return;
+ bool ok;
+ auto vlcButton = qtToVlcMouseButton(button, &ok);
+ if (!ok)
+ return;
+ report_mouse_release(reportOpaque, vlcButton);
+ }
+
+ static void setReportCallbacks(void* data,
+ libvlc_video_output_resize_cb report_size_change,
+ libvlc_video_output_mouse_move_cb report_mouse_move,
+ libvlc_video_output_mouse_press_cb report_mouse_press,
+ libvlc_video_output_mouse_release_cb report_mouse_release,
+ void* reportOpaque)
+ {
+ VLCVideo* that = static_cast<VLCVideo*>(data);
+ QMutexLocker lock(&that->m_cb_lock);
+ that->reportOpaque = reportOpaque;
+ that->report_size_change = report_size_change;
+ that->report_mouse_move = report_mouse_move;
+ that->report_mouse_press = report_mouse_press;
+ that->report_mouse_release = report_mouse_release;
+
+ //report initial window size
+ if (report_size_change && that->m_windowSize.isValid())
+ report_size_change(that->reportOpaque, that->m_windowSize.width(), that->m_windowSize.height());
+ }
+
/// this callback will create the surfaces and FBO used by VLC to perform its rendering
static bool resizeRenderTextures(void* data, const libvlc_video_render_cfg_t *cfg,
libvlc_video_output_cfg_t *render_cfg)
@@ -159,6 +220,24 @@ public:
}
private:
+ libvlc_video_output_mouse_button_t qtToVlcMouseButton(Qt::MouseButton button, bool* ok)
+ {
+ assert(ok != nullptr);
+ *ok = true;
+ switch (button)
+ {
+ case Qt::LeftButton:
+ return libvlc_video_output_mouse_button_left;
+ case Qt::RightButton:
+ return libvlc_video_output_mouse_button_right;
+ case Qt::MiddleButton:
+ return libvlc_video_output_mouse_button_middle;
+ default:
+ *ok = false;
+ return libvlc_video_output_mouse_button_left;
+ }
+ }
+
QtVLCWidget *mWidget;
QOpenGLContext *mContext;
QOffscreenSurface *mSurface;
@@ -173,6 +252,16 @@ private:
size_t m_idx_swap = 1;
size_t m_idx_display = 2;
bool m_updated = false;
+
+ QSize m_windowSize;
+
+ QMutex m_cb_lock;
+ void* reportOpaque = nullptr;
+ libvlc_video_output_resize_cb report_size_change = nullptr;
+ libvlc_video_output_mouse_move_cb report_mouse_move = nullptr;
+ libvlc_video_output_mouse_press_cb report_mouse_press = nullptr;
+ libvlc_video_output_mouse_release_cb report_mouse_release = nullptr;
+
};
@@ -181,6 +270,8 @@ QtVLCWidget::QtVLCWidget(QWidget *parent)
vertexBuffer(QOpenGLBuffer::VertexBuffer),
vertexIndexBuffer(QOpenGLBuffer::IndexBuffer)
{
+ setMouseTracking(true);
+
// --transparent causes the clear color to be transparent. Therefore, on systems that
// support it, the widget will become transparent apart from the logo.
@@ -209,7 +300,7 @@ bool QtVLCWidget::playMedia(const char* url)
// Define the opengl rendering callbacks
libvlc_video_set_output_callbacks(m_mp,
mVLC->isOpenGLES() ? libvlc_video_engine_gles2 : libvlc_video_engine_opengl,
- VLCVideo::setup, VLCVideo::cleanup, nullptr, VLCVideo::resizeRenderTextures, VLCVideo::swap,
+ VLCVideo::setup, VLCVideo::cleanup, VLCVideo::setReportCallbacks, VLCVideo::resizeRenderTextures, VLCVideo::swap,
VLCVideo::make_current, VLCVideo::get_proc_address, nullptr, nullptr,
mVLC.get());
@@ -371,7 +462,23 @@ void QtVLCWidget::paintGL()
void QtVLCWidget::resizeGL(int w, int h)
{
- Q_UNUSED(w);
- Q_UNUSED(h);
- /* TODO */
+ mVLC->onResize(QSize(w, h));
+}
+
+void QtVLCWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ QOpenGLWidget::mouseMoveEvent(event);
+ mVLC->onMouseMove(event->pos());
+}
+
+void QtVLCWidget::mousePressEvent(QMouseEvent *event)
+{
+ QOpenGLWidget::mousePressEvent(event);
+ mVLC->onMousePress(event->button());
+}
+
+void QtVLCWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+ QOpenGLWidget::mouseReleaseEvent(event);
+ mVLC->onMouseRelease(event->button());
}
=====================================
doc/libvlc/QtGL/qtvlcwidget.h
=====================================
@@ -31,6 +31,10 @@ protected:
void paintGL() override;
void resizeGL(int width, int height) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+
private:
QOpenGLVertexArrayObject m_vao;
std::unique_ptr<QOpenGLShaderProgram> m_program;
=====================================
doc/libvlc/d3d11_player.cpp
=====================================
@@ -11,6 +11,7 @@
*/
#include <windows.h>
+#include <windowsx.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <cassert>
@@ -81,6 +82,9 @@ struct render_context
unsigned width, height;
} client_area;
libvlc_video_output_resize_cb ReportSize;
+ libvlc_video_output_mouse_move_cb MouseMove;
+ libvlc_video_output_mouse_press_cb MousePress;
+ libvlc_video_output_mouse_release_cb MouseRelease;
void *ReportOpaque;
};
@@ -498,13 +502,19 @@ static void CleanupDevice_cb( void *opaque )
}
// receive the libvlc callback to call when we want to change the libvlc output size
-static void SetResize_cb( void *opaque,
+static void SetReport_cb( void *opaque,
libvlc_video_output_resize_cb report_size_change,
+ libvlc_video_output_mouse_move_cb report_mouse_move,
+ libvlc_video_output_mouse_press_cb report_mouse_press,
+ libvlc_video_output_mouse_release_cb report_mouse_release,
void *report_opaque )
{
struct render_context *ctx = static_cast<struct render_context *>( opaque );
AcquireSRWLockExclusive(&ctx->sizeLock);
ctx->ReportSize = report_size_change;
+ ctx->MouseMove = report_mouse_move;
+ ctx->MousePress = report_mouse_press;
+ ctx->MouseRelease = report_mouse_release;
ctx->ReportOpaque = report_opaque;
if (ctx->ReportSize != nullptr)
@@ -515,6 +525,25 @@ static void SetResize_cb( void *opaque,
ReleaseSRWLockExclusive(&ctx->sizeLock);
}
+static libvlc_video_output_mouse_button_t windowsButtonToVLC(UINT message)
+{
+ switch (message)
+ {
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDOWN:
+ return libvlc_video_output_mouse_button_left;
+ case WM_MBUTTONUP:
+ case WM_MBUTTONDOWN:
+ return libvlc_video_output_mouse_button_middle;
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDOWN:
+ return libvlc_video_output_mouse_button_right;
+ default:
+ //should not happen
+ return libvlc_video_output_mouse_button_right;
+ }
+}
+
static const char *AspectRatio = NULL;
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
@@ -572,6 +601,42 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
}
break;
+ case WM_MOUSEMOVE:
+ {
+ int mouseX = int(GET_X_LPARAM(lParam) - ctx->client_area.width * (BORDER_LEFT + 1)/2.0f);
+ int mouseY = int(GET_Y_LPARAM(lParam) - ctx->client_area.width * (1 - BORDER_TOP) / 2.0f);
+
+ AcquireSRWLockExclusive(&ctx->sizeLock);
+ if (ctx->MouseMove != nullptr)
+ ctx->MouseMove(ctx->ReportOpaque, mouseX, mouseY);
+ ReleaseSRWLockExclusive(&ctx->sizeLock);
+ }
+ break;
+
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_LBUTTONDOWN:
+ {
+ auto button = windowsButtonToVLC(message);
+ AcquireSRWLockExclusive(&ctx->sizeLock);
+ if (ctx->MousePress != nullptr)
+ ctx->MousePress(ctx->ReportOpaque, button);
+ ReleaseSRWLockExclusive(&ctx->sizeLock);
+ }
+ break;
+
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ case WM_LBUTTONUP:
+ {
+ auto button = windowsButtonToVLC(message);
+ AcquireSRWLockExclusive(&ctx->sizeLock);
+ if (ctx->MouseRelease != nullptr)
+ ctx->MouseRelease(ctx->ReportOpaque, button);
+ ReleaseSRWLockExclusive(&ctx->sizeLock);
+ }
+ break;
+
case WM_DESTROY:
PostQuitMessage(0);
return 0;
@@ -681,7 +746,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
/* Tell VLC to render into our D3D11 environment */
libvlc_video_set_output_callbacks( Context.p_mp, libvlc_video_engine_d3d11,
- SetupDevice_cb, CleanupDevice_cb, SetResize_cb,
+ SetupDevice_cb, CleanupDevice_cb, SetReport_cb,
UpdateOutput_cb, Swap_cb, StartRendering_cb,
nullptr, nullptr, SelectPlane_cb,
&Context );
=====================================
doc/libvlc/d3d9_player.c
=====================================
@@ -222,9 +222,12 @@ static void CleanupDevice_cb( void *opaque )
}
}
-static void SetResize_cb( void *opaque,
- libvlc_video_output_resize_cb report_size_change,
- void *report_opaque )
+static void SetReport_cb( void *opaque,
+ libvlc_video_output_resize_cb report_size_change,
+ libvlc_video_output_mouse_move_cb report_mouse_move,
+ libvlc_video_output_mouse_press_cb report_mouse_press,
+ libvlc_video_output_mouse_release_cb report_mouse_release,
+ void *report_opaque )
{
struct render_context *ctx = opaque;
EnterCriticalSection(&ctx->sizeLock);
@@ -416,7 +419,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
/* Tell VLC to render into our D3D9 environment */
libvlc_video_set_output_callbacks( Context.p_mp, libvlc_video_engine_d3d9,
- SetupDevice_cb, CleanupDevice_cb, SetResize_cb,
+ SetupDevice_cb, CleanupDevice_cb, SetReport_cb,
UpdateOutput_cb, Swap_cb, StartRendering_cb,
NULL, NULL, NULL,
&Context );
=====================================
include/vlc/libvlc_media_player.h
=====================================
@@ -717,32 +717,92 @@ typedef enum libvlc_video_engine_t {
/** Callback type that can be called to request a render size changes.
- *
- * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_resize_cb.
- *
- * \param report_opaque parameter passed to \ref libvlc_video_output_set_resize_cb. [IN]
+ *
+ * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
+ *
+ * \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
* \param width new rendering width requested. [IN]
* \param height new rendering height requested. [IN]
*/
typedef void( *libvlc_video_output_resize_cb )( void *report_opaque, unsigned width, unsigned height );
+/**
+ * Enumeration of the different mouse buttons that can be reported for user interaction
+ * can be passed to \ref libvlc_video_output_mouse_press_cb and \ref libvlc_video_output_mouse_release_cb.
+ */
+typedef enum libvlc_video_output_mouse_button_t {
+ libvlc_video_output_mouse_button_left = 0,
+ libvlc_video_output_mouse_button_middle = 1,
+ libvlc_video_output_mouse_button_right = 2
+} libvlc_video_output_mouse_button_t;
+
+
+/** Callback type that can be called to notify the mouse position when hovering the render surface.
+ *
+ * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
+ *
+ * The position (0,0) denotes the top left corner, bottom right corner position
+ * is (width,height) as reported by \ref libvlc_video_output_resize_cb.
+ *
+ * \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
+ * \param x horizontal mouse positon in \ref libvlc_video_output_resize_cb coordinates. [IN]
+ * \param y vertical mouse positon in \ref libvlc_video_output_resize_cb coordinates. [IN]
+ */
+typedef void (*libvlc_video_output_mouse_move_cb)(void *opaque, int x, int y);
+
+/** Callback type that can be called to notify when a mouse button is pressed in the rendering surface.
+ *
+ * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
+ *
+ * The button event will be reported at the last position provided by \ref libvlc_video_output_mouse_move_cb
+ *
+ * \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
+ * \param button represent the button pressed, see \ref libvlc_video_output_mouse_button_t for available buttons. [IN]
+ */
+typedef void (*libvlc_video_output_mouse_press_cb)(void *opaque, libvlc_video_output_mouse_button_t button);
+
+/** Callback type that can be called to notify when a mouse button is released in the rendering surface.
+ *
+ * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
+ *
+ * The button event will be reported at the last position provided by \ref libvlc_video_output_mouse_move_cb.
+ *
+ * \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
+ * \param button represent the button released, see \ref libvlc_video_output_mouse_button_t for available buttons. [IN]
+ */
+typedef void (*libvlc_video_output_mouse_release_cb)(void *opaque, libvlc_video_output_mouse_button_t button);
+
/** Set the callback to call when the host app resizes the rendering area.
*
* This allows text rendering and aspect ratio to be handled properly when the host
- * rendering size changes.
+ * rendering size changes and to provide mouse.
*
* It may be called before the \ref libvlc_video_output_setup_cb callback.
*
+ * \warning These callbacks cannot be called concurently, the caller is responsible for serialization
+ *
* \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
* \param[in] report_size_change callback which must be called when the host size changes.
* The callback is valid until another call to \ref libvlc_video_output_set_resize_cb
* is done. This may be called from any thread.
+ * \param[in] report_mouse_move callback which must be called when the mouse position change on the video surface.
+ * The coordinates are relative to the size reported through the report_size_change.
+ * This may be called from any thread.
+ * \param[in] report_mouse_pressed callback which must be called when a mouse button is pressed on the video surface,
+ * The position of the event is the last position reported by the report_mouse_move callback. This may be
+ * called from any thread.
+ * \param[in] report_mouse_released callback which must be called when a mouse button is released on the video surface,
+ * The position of the event is the last position reported by the report_mouse_move callback. This may be
+ * called from any thread.
* \param[in] report_opaque private pointer to pass to the \ref report_size_change callback.
*/
-typedef void( *libvlc_video_output_set_resize_cb )( void *opaque,
- libvlc_video_output_resize_cb report_size_change,
- void *report_opaque );
+typedef void( *libvlc_video_output_set_window_cb )( void *opaque,
+ libvlc_video_output_resize_cb report_size_change,
+ libvlc_video_output_mouse_move_cb report_mouse_move,
+ libvlc_video_output_mouse_press_cb report_mouse_pressed,
+ libvlc_video_output_mouse_release_cb report_mouse_released,
+ void *report_opaque );
/** Tell the host the rendering for the given plane is about to start
*
@@ -801,7 +861,7 @@ bool libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
libvlc_video_engine_t engine,
libvlc_video_output_setup_cb setup_cb,
libvlc_video_output_cleanup_cb cleanup_cb,
- libvlc_video_output_set_resize_cb resize_cb,
+ libvlc_video_output_set_window_cb window_cb,
libvlc_video_update_output_cb update_output_cb,
libvlc_video_swap_cb swap_cb,
libvlc_video_makeCurrent_cb makeCurrent_cb,
=====================================
lib/media_player.c
=====================================
@@ -634,7 +634,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
var_Create( mp, "vout-cb-opaque", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-setup", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-cleanup", VLC_VAR_ADDRESS );
- var_Create( mp, "vout-cb-resize-cb", VLC_VAR_ADDRESS );
+ var_Create( mp, "vout-cb-window-cb", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-update-output", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-swap", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-get-proc-address", VLC_VAR_ADDRESS );
@@ -1062,7 +1062,7 @@ bool libvlc_video_set_output_callbacks(libvlc_media_player_t *mp,
libvlc_video_engine_t engine,
libvlc_video_output_setup_cb setup_cb,
libvlc_video_output_cleanup_cb cleanup_cb,
- libvlc_video_output_set_resize_cb resize_cb,
+ libvlc_video_output_set_window_cb set_window_cb,
libvlc_video_update_output_cb update_output_cb,
libvlc_video_swap_cb swap_cb,
libvlc_video_makeCurrent_cb makeCurrent_cb,
@@ -1108,7 +1108,7 @@ bool libvlc_video_set_output_callbacks(libvlc_media_player_t *mp,
var_SetAddress( mp, "vout-cb-opaque", opaque );
var_SetAddress( mp, "vout-cb-setup", setup_cb );
var_SetAddress( mp, "vout-cb-cleanup", cleanup_cb );
- var_SetAddress( mp, "vout-cb-resize-cb", resize_cb );
+ var_SetAddress( mp, "vout-cb-window-cb", set_window_cb );
var_SetAddress( mp, "vout-cb-update-output", update_output_cb );
var_SetAddress( mp, "vout-cb-swap", swap_cb );
var_SetAddress( mp, "vout-cb-get-proc-address", getProcAddress_cb );
=====================================
modules/video_output/wextern.c
=====================================
@@ -48,7 +48,7 @@ vlc_module_end()
typedef struct {
void *opaque;
- libvlc_video_output_set_resize_cb setResizeCb;
+ libvlc_video_output_set_window_cb setWindowCb;
} wextern_t;
static void WindowResize(void *opaque, unsigned width, unsigned height)
@@ -57,13 +57,34 @@ static void WindowResize(void *opaque, unsigned width, unsigned height)
vlc_window_ReportSize(window, width, height);
}
+static void WindowMouseMoved(void *opaque, int x, int y)
+{
+ vlc_window_t *window = opaque;
+ vlc_window_ReportMouseMoved(window, x, y);
+}
+
+static void WindowMousePress(void *opaque, libvlc_video_output_mouse_button_t button)
+{
+ vlc_window_t *window = opaque;
+ vlc_window_ReportMousePressed(window, button);
+}
+
+static void WindowMouseRelease(void *opaque, libvlc_video_output_mouse_button_t button)
+{
+ vlc_window_t *window = opaque;
+ vlc_window_ReportMouseReleased(window, button);
+}
+
static int Enable(struct vlc_window *wnd, const vlc_window_cfg_t *wcfg)
{
wextern_t *sys = wnd->sys;
- if ( sys->setResizeCb != NULL )
+ if ( sys->setWindowCb != NULL )
/* bypass the size handling as the window doesn't handle the size */
- sys->setResizeCb( sys->opaque, WindowResize, wnd );
+ sys->setWindowCb( sys->opaque,
+ WindowResize,
+ WindowMouseMoved, WindowMousePress, WindowMouseRelease,
+ wnd );
(void) wcfg;
return VLC_SUCCESS;
@@ -73,8 +94,8 @@ static void Disable(struct vlc_window *wnd)
{
wextern_t *sys = wnd->sys;
- if ( sys->setResizeCb != NULL )
- sys->setResizeCb( sys->opaque, NULL, NULL );
+ if ( sys->setWindowCb != NULL )
+ sys->setWindowCb( sys->opaque, NULL, NULL, NULL, NULL, NULL );
}
static const struct vlc_window_operations ops = {
@@ -89,11 +110,13 @@ static int Open(vlc_window_t *wnd)
wextern_t *sys = vlc_obj_malloc(VLC_OBJECT(wnd), sizeof(*sys));
if (unlikely(sys==NULL))
return VLC_ENOMEM;
+
sys->opaque = var_InheritAddress( wnd, "vout-cb-opaque" );
- sys->setResizeCb = var_InheritAddress( wnd, "vout-cb-resize-cb" );
+ sys->setWindowCb = var_InheritAddress( wnd, "vout-cb-window-cb" );
wnd->sys = sys;
wnd->type = VLC_WINDOW_TYPE_DUMMY;
wnd->ops = &ops;
+ wnd->info.has_double_click = false;
return VLC_SUCCESS;
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/df6ab0815338f6fbfda971e95cd6e3a9c626f91c...04ea9e055ee25c20fd2e5e02154fc2e18c19ad3e
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/df6ab0815338f6fbfda971e95cd6e3a9c626f91c...04ea9e055ee25c20fd2e5e02154fc2e18c19ad3e
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