[vlc-devel] [RFC 48/82] qt: add wayland video renderer
Rémi Denis-Courmont
remi at remlab.net
Fri Feb 1 14:32:14 CET 2019
This does not seem to bind to versions correctly. Also error handling seems missing.
Le 1 février 2019 15:01:52 GMT+02:00, Pierre Lamot <pierre at videolabs.io> a écrit :
>From: Alexandre Janniaux <alexandre.janniaux at gmail.com>
>
>---
> modules/gui/qt/Makefile.am | 9 +
> .../video_renderer/videorendererwayland.cpp | 154 ++++++++++++++++++
> .../video_renderer/videorendererwayland.hpp | 63 +++++++
> 3 files changed, 226 insertions(+)
>create mode 100644
>modules/gui/qt/components/video_renderer/videorendererwayland.cpp
>create mode 100644
>modules/gui/qt/components/video_renderer/videorendererwayland.hpp
>
>diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
>index 7d0132c6a1..e9cd3e61d4 100644
>--- a/modules/gui/qt/Makefile.am
>+++ b/modules/gui/qt/Makefile.am
>@@ -166,6 +166,11 @@ if HAVE_WIN32
> libqt_plugin_la_SOURCES += \
> gui/qt/main_interface_win32.cpp gui/qt/main_interface_win32.hpp
> endif
>+if HAVE_WAYLAND
>+libqt_plugin_la_SOURCES += \
>+ gui/qt/components/video_renderer/videorendererwayland.hpp \
>+ gui/qt/components/video_renderer/videorendererwayland.cpp
>+endif
>
> # Meta-object compilation
>
>@@ -260,6 +265,10 @@ if HAVE_WIN32
> nodist_libqt_plugin_la_SOURCES += gui/qt/main_interface_win32.moc.cpp
> endif
>
>+if HAVE_WAYLAND
>+nodist_libqt_plugin_la_SOURCES +=
>gui/qt/components/video_renderer/videorendererwayland.moc.cpp
>+endif
>+
> nodist_libqt_plugin_la_SOURCES += \
> gui/qt/ui/equalizer.h \
> gui/qt/ui/video_effects.h \
>diff --git
>a/modules/gui/qt/components/video_renderer/videorendererwayland.cpp
>b/modules/gui/qt/components/video_renderer/videorendererwayland.cpp
>new file mode 100644
>index 0000000000..120bb9a24c
>--- /dev/null
>+++ b/modules/gui/qt/components/video_renderer/videorendererwayland.cpp
>@@ -0,0 +1,154 @@
>+#include "videorendererwayland.hpp"
>+#include <QtQuick/QSGImageNode>
>+#include <QtQuick/QSGRectangleNode>
>+#include <QtQuick/QQuickWindow>
>+#include <vlc_vout_window.h>
>+#include "main_interface.hpp"
>+
>+#include QPNI_HEADER
>+#include <wayland-client.h>
>+#include <wayland-client-protocol.h>
>+
>+void VideoRendererWayland::registry_global( void *data, wl_registry
>*registry,
>+ uint32_t name, const char
>*intf,
>+ uint32_t version )
>+{
>+ VideoRendererWayland *renderer =
>static_cast<VideoRendererWayland*>( data );
>+
>+ if( !strcmp(intf, "wl_compositor") )
>+ renderer->m_compositor = static_cast<wl_compositor*>(
>+ wl_registry_bind( registry, name,
>+
>&wl_compositor_interface,
>+ version ));
>+
>+ else
>+ if( !strcmp(intf, "wl_subcompositor") )
>+ renderer->m_subcompositor = static_cast<wl_subcompositor*>(
>+ wl_registry_bind( registry, name,
>+
>&wl_subcompositor_interface,
>+ version ));
>+}
>+
>+void VideoRendererWayland::registry_global_remove( void *, wl_registry
>*, uint32_t )
>+{
>+ // nothing to do
>+}
>+
>+VideoRendererWayland::VideoRendererWayland( MainInterface* p_mi,
>QObject* parent )
>+ : VideoRenderer( parent )
>+ , m_mainInterface( p_mi )
>+{
>+ assert( m_mainInterface );
>+ m_surfaceProvider = new VideoSurfaceWayland( this, this );
>+}
>+
>+VideoRendererWayland::~VideoRendererWayland()
>+{
>+ if( m_subsurface )
>+ wl_subsurface_destroy( m_subsurface );
>+ if( m_surface )
>+ wl_surface_destroy( m_surface );
>+ if( m_compositor )
>+ wl_compositor_destroy( m_compositor );
>+ if( m_subcompositor )
>+ wl_subcompositor_destroy( m_subcompositor );
>+}
>+
>+void VideoRendererWayland::enableVideo(unsigned width, unsigned
>height, bool fullscreen)
>+{
>+ VideoRenderer::enableVideo(width, height, fullscreen);
>+ if (!m_hasVideo) //no window out has been set
>+ return;
>+
>+ m_voutWindow->type = VOUT_WINDOW_TYPE_WAYLAND;
>+
>+ QPlatformNativeInterface *qni = qApp->platformNativeInterface();
>+
>+ m_voutWindow->display.wl = static_cast<wl_display *>(
>+
>qni->nativeResourceForIntegration(QByteArrayLiteral("wl_display")));
>+
>+ const wl_registry_listener registry_cbs =
>+ {
>+ registry_global,
>+ registry_global_remove,
>+ };
>+
>+ wl_registry *registry = wl_display_get_registry(
>m_voutWindow->display.wl );
>+ wl_registry_add_listener( registry, ®istry_cbs, this );
>+ wl_display_roundtrip( m_voutWindow->display.wl );
>+ wl_registry_destroy( registry );
>+
>+ if( !m_compositor || !m_subcompositor )
>+ return; // TODO: what to do
>+
>+ QWindow *root_window = m_mainInterface->window()->windowHandle();
>+ wl_surface *root_surface = static_cast<wl_surface *>(
>+ qni->nativeResourceForWindow( QByteArrayLiteral("surface"),
>+ root_window ));
>+
>+ m_surface =
>+ m_voutWindow->handle.wl = wl_compositor_create_surface(
>m_compositor );
>+ m_subsurface = wl_subcompositor_get_subsurface( m_subcompositor,
>+
>m_voutWindow->handle.wl,
>+ root_surface );
>+
>+ wl_subsurface_place_below( m_subsurface, root_surface );
>+ wl_subsurface_set_desync( m_subsurface );
>+
>+ /* HACK: disable event input on surface, so that Qt don't try
>+ * to cast it's userdata */
>+ wl_region *region = wl_compositor_create_region( m_compositor );
>+ wl_region_add( region, 0, 0, 0, 0 );
>+ wl_surface_set_input_region( m_voutWindow->handle.wl, region );
>+ wl_region_destroy( region );
>+}
>+
>+
>+void VideoRendererWayland::disableVideo()
>+{
>+ VideoRenderer::disableVideo();
>+ if( m_subsurface )
>+ wl_subsurface_destroy( m_subsurface );
>+ if( m_surface )
>+ wl_surface_destroy( m_surface );
>+ if( m_subcompositor )
>+ wl_subcompositor_destroy( m_subcompositor );
>+ if( m_compositor )
>+ wl_compositor_destroy( m_compositor );
>+ m_subsurface = nullptr; m_surface = nullptr;
>+ m_compositor = nullptr; m_subcompositor = nullptr;
>+}
>+
>+VideoSurfaceProvider *VideoRendererWayland::getVideoSurfaceProvider()
>+{
>+ return m_surfaceProvider;
>+}
>+
>+VideoSurfaceWayland::VideoSurfaceWayland(VideoRendererWayland*
>renderer, QObject* parent)
>+ : VideoSurfaceProvider( parent )
>+ , m_renderer(renderer)
>+{
>+ connect(this, &VideoSurfaceWayland::mouseMoved, m_renderer,
>&VideoRenderer::onMouseMoved, Qt::QueuedConnection);
>+ connect(this, &VideoSurfaceWayland::mousePressed, m_renderer,
>&VideoRenderer::onMousePressed, Qt::QueuedConnection);
>+ connect(this, &VideoSurfaceWayland::mouseDblClicked, m_renderer,
>&VideoRenderer::onMouseDoubleClick, Qt::QueuedConnection);
>+ connect(this, &VideoSurfaceWayland::mouseReleased, m_renderer,
>&VideoRenderer::onMouseReleased, Qt::QueuedConnection);
>+
>+ connect(this, &VideoSurfaceWayland::surfaceSizeChanged,
>m_renderer, &VideoRenderer::onSurfaceSizeChanged);
>+
>+ connect(m_renderer, &VideoRendererWayland::updated, this,
>&VideoSurfaceWayland::update, Qt::QueuedConnection);
>+}
>+
>+QSGNode* VideoSurfaceWayland::updatePaintNode(QQuickItem* item,
>QSGNode* oldNode, QQuickItem::UpdatePaintNodeData*)
>+{
>+ QSGRectangleNode* node = static_cast<QSGRectangleNode*>(oldNode);
>+
>+ if (!node)
>+ {
>+ node = item->window()->createRectangleNode();
>+ node->setColor(Qt::transparent);
>+ }
>+ node->setRect(item->boundingRect());
>+
>+ return node;
>+}
>+
>diff --git
>a/modules/gui/qt/components/video_renderer/videorendererwayland.hpp
>b/modules/gui/qt/components/video_renderer/videorendererwayland.hpp
>new file mode 100644
>index 0000000000..c3c3462368
>--- /dev/null
>+++ b/modules/gui/qt/components/video_renderer/videorendererwayland.hpp
>@@ -0,0 +1,63 @@
>+#ifndef VLC_QT_VIDEORENDERERWL_HPP
>+#define VLC_QT_VIDEORENDERERWL_HPP
>+
>+#include <inttypes.h>
>+#include <QtQuick/QQuickItem>
>+#include <QMutex>
>+#include <QtQuick/QSGRectangleNode>
>+#include <components/qml_main_context.hpp>
>+#include "qt.hpp"
>+
>+#include "videorenderer.hpp"
>+
>+class MainInterface;
>+class VideoSurfaceWayland;
>+
>+struct wl_compositor;
>+struct wl_subcompositor;
>+struct wl_subsurface;
>+struct wl_registry;
>+
>+class VideoRendererWayland: public VideoRenderer
>+{
>+ Q_OBJECT
>+public:
>+ VideoRendererWayland(MainInterface* p_mi, QObject *parent =
>nullptr);
>+ ~VideoRendererWayland() override;
>+
>+ void enableVideo(unsigned int width, unsigned int height, bool
>fullscreen);
>+ void disableVideo();
>+
>+ VideoSurfaceProvider *getVideoSurfaceProvider() override;
>+
>+signals:
>+ void updated();
>+
>+private:
>+ /* wayland registry callbacks */
>+ static void registry_global( void *, wl_registry *, uint32_t,
>+ const char *, uint32_t );
>+ static void registry_global_remove( void *, wl_registry *,
>uint32_t );
>+
>+ MainInterface *m_mainInterface;
>+ VideoSurfaceWayland *m_surfaceProvider = nullptr;
>+ wl_compositor *m_compositor = nullptr;
>+ wl_subcompositor *m_subcompositor = nullptr;
>+ wl_subsurface *m_subsurface = nullptr;
>+ wl_surface *m_surface = nullptr;
>+};
>+
>+class VideoSurfaceWayland : public VideoSurfaceProvider
>+{
>+ Q_OBJECT
>+public:
>+ VideoSurfaceWayland(VideoRendererWayland* renderer, QObject*
>parent = nullptr);
>+
>+private:
>+ QSGNode *updatePaintNode(QQuickItem* item, QSGNode *,
>QQuickItem::UpdatePaintNodeData *) override;
>+
>+private:
>+ VideoRendererWayland* m_renderer = nullptr;
>+};
>+
>+#endif // VLC_QT_VIDEORENDERERWL_HPP
>--
>2.19.1
>
>_______________________________________________
>vlc-devel mailing list
>To unsubscribe or modify your subscription options:
>https://mailman.videolan.org/listinfo/vlc-devel
--
Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20190201/0170fc54/attachment.html>
More information about the vlc-devel
mailing list