[vlc-devel] [RFC 44/82] qt: provide base implementation video sink to render video output within the interface

Rémi Denis-Courmont remi at remlab.net
Fri Feb 1 14:47:12 CET 2019


Video sink and video renderer are other names (arguably better) for vout display.

Reusing them for window is confusing imo.

Le 1 février 2019 15:01:48 GMT+02:00, Pierre Lamot <pierre at videolabs.io> a écrit :
>VideoSurface provide a QQuickItem which can be embed within a QML scene
>to
>  represent the video node.
>
>VideoSurfaceProvider is the actual implementation of the VideoSurface
>which will
>  be selected at runtime
>
>VideoRenderer implement a video sink which will be in charge of
>rendering the video
>---
> modules/gui/qt/Makefile.am                    |   6 +
> .../video_renderer/videorenderer.cpp          |  63 +++++++
> .../video_renderer/videorenderer.hpp          |  37 ++++
> .../video_renderer/videosurface.cpp           | 170 ++++++++++++++++++
> .../video_renderer/videosurface.hpp           | 102 +++++++++++
> 5 files changed, 378 insertions(+)
>create mode 100644
>modules/gui/qt/components/video_renderer/videorenderer.cpp
>create mode 100644
>modules/gui/qt/components/video_renderer/videorenderer.hpp
>create mode 100644
>modules/gui/qt/components/video_renderer/videosurface.cpp
>create mode 100644
>modules/gui/qt/components/video_renderer/videosurface.hpp
>
>diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
>index d48aa0c1e2..c061c8a2bd 100644
>--- a/modules/gui/qt/Makefile.am
>+++ b/modules/gui/qt/Makefile.am
>@@ -98,6 +98,10 @@ libqt_plugin_la_SOURCES = \
> 	gui/qt/components/controller.cpp gui/qt/components/controller.hpp \
> 	gui/qt/components/controller_widget.cpp \
> 	gui/qt/components/controller_widget.hpp \
>+	gui/qt/components/video_renderer/videosurface.cpp \
>+	gui/qt/components/video_renderer/videosurface.hpp \
>+	gui/qt/components/video_renderer/videorenderer.cpp \
>+	gui/qt/components/video_renderer/videorenderer.hpp \
> 	gui/qt/components/custom_menus.cpp \
> 	gui/qt/components/custom_menus.hpp \
> 	gui/qt/components/epg/EPGChannels.cpp \
>@@ -216,6 +220,8 @@ nodist_libqt_plugin_la_SOURCES = \
> 	gui/qt/components/controller.moc.cpp \
> 	gui/qt/components/controller_widget.moc.cpp \
> 	gui/qt/components/custom_menus.moc.cpp \
>+	gui/qt/components/video_renderer/videosurface.moc.cpp \
>+	gui/qt/components/video_renderer/videorenderer.moc.cpp \
> 	gui/qt/components/epg/EPGChannels.moc.cpp \
> 	gui/qt/components/epg/EPGProgram.moc.cpp \
> 	gui/qt/components/epg/EPGRuler.moc.cpp \
>diff --git a/modules/gui/qt/components/video_renderer/videorenderer.cpp
>b/modules/gui/qt/components/video_renderer/videorenderer.cpp
>new file mode 100644
>index 0000000000..09150f372d
>--- /dev/null
>+++ b/modules/gui/qt/components/video_renderer/videorenderer.cpp
>@@ -0,0 +1,63 @@
>+#include "videorenderer.hpp"
>+
>+VideoRenderer::VideoRenderer(QObject* parent)
>+    : QObject(parent)
>+{
>+}
>+
>+void VideoRenderer::setupVoutWindow(vout_window_t* window)
>+{
>+    QMutexLocker lock(&m_voutlock);
>+    m_voutWindow = window;
>+    m_hasVideo = false;
>+}
>+
>+void VideoRenderer::enableVideo(unsigned /*width*/, unsigned
>/*height*/, bool /*fullscreen*/)
>+{
>+    QMutexLocker lock(&m_voutlock);
>+    if (m_voutWindow)
>+        m_hasVideo = true;
>+}
>+
>+void VideoRenderer::disableVideo()
>+{
>+    QMutexLocker lock(&m_voutlock);
>+    if (m_voutWindow)
>+        m_hasVideo = false;
>+}
>+
>+void VideoRenderer::onMousePressed(int vlcButton)
>+{
>+    QMutexLocker lock(&m_voutlock);
>+    if (m_hasVideo)
>+        vout_window_ReportMousePressed(m_voutWindow, vlcButton);
>+}
>+
>+void VideoRenderer::onMouseReleased(int vlcButton)
>+{
>+    QMutexLocker lock(&m_voutlock);
>+    if (m_hasVideo)
>+        vout_window_ReportMouseReleased(m_voutWindow, vlcButton);
>+}
>+
>+void VideoRenderer::onMouseDoubleClick(int vlcButton)
>+{
>+    QMutexLocker lock(&m_voutlock);
>+    if (m_hasVideo)
>+        vout_window_ReportMouseDoubleClick(m_voutWindow, vlcButton);
>+}
>+
>+void VideoRenderer::onMouseMoved(float x, float y)
>+{
>+    QMutexLocker lock(&m_voutlock);
>+    if (m_hasVideo)
>+        vout_window_ReportMouseMoved(m_voutWindow, x, y);
>+}
>+
>+void VideoRenderer::onSurfaceSizeChanged(QSizeF size)
>+{
>+
>+    QMutexLocker lock(&m_voutlock);
>+    if (m_hasVideo)
>+        vout_window_ReportSize(m_voutWindow, size.width(),
>size.height());
>+}
>diff --git a/modules/gui/qt/components/video_renderer/videorenderer.hpp
>b/modules/gui/qt/components/video_renderer/videorenderer.hpp
>new file mode 100644
>index 0000000000..98e3ea26c2
>--- /dev/null
>+++ b/modules/gui/qt/components/video_renderer/videorenderer.hpp
>@@ -0,0 +1,37 @@
>+#ifndef VIDEORENDERER_HPP
>+#define VIDEORENDERER_HPP
>+
>+#include <QObject>
>+#include <QMutex>
>+#include "qt.hpp"
>+#include "vlc_vout_window.h"
>+#include "videosurface.hpp"
>+
>+class VideoRenderer : public QObject
>+{
>+    Q_OBJECT
>+public:
>+    VideoRenderer(QObject* parent = nullptr);
>+    virtual ~VideoRenderer() {}
>+
>+    virtual void setupVoutWindow(vout_window_t* window);
>+    virtual void enableVideo(unsigned width, unsigned height, bool
>fullscreen);
>+    virtual void disableVideo();
>+
>+    virtual VideoSurfaceProvider* getVideoSurfaceProvider() = 0;
>+
>+public slots:
>+    void onMousePressed( int vlcButton );
>+    void onMouseReleased( int vlcButton );
>+    void onMouseDoubleClick( int vlcButton );
>+    void onMouseMoved( float x, float y );
>+    void onSurfaceSizeChanged(QSizeF size);
>+
>+protected:
>+    QMutex m_voutlock;
>+    vout_window_t* m_voutWindow = nullptr;
>+    bool m_hasVideo = false;
>+
>+};
>+
>+#endif // VIDEORENDERER_HPP
>diff --git a/modules/gui/qt/components/video_renderer/videosurface.cpp
>b/modules/gui/qt/components/video_renderer/videosurface.cpp
>new file mode 100644
>index 0000000000..39b453c3c1
>--- /dev/null
>+++ b/modules/gui/qt/components/video_renderer/videosurface.cpp
>@@ -0,0 +1,170 @@
>+/*****************************************************************************
>+ * Copyright (C) 2019 VLC authors and VideoLAN
>+ *
>+ * This program is free software; you can redistribute it and/or
>modify
>+ * it under the terms of the GNU General Public License as published
>by
>+ * the Free Software Foundation; either version 2 of the License, or
>+ * (at your option) any later version.
>+ *
>+ * This program is distributed in the hope that it will be useful,
>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>+ * GNU General Public License for more details.
>+ *
>+ * You should have received a copy of the GNU General Public License
>+ * along with this program; if not, write to the Free Software
>+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
>02110-1301, USA.
>+
>*****************************************************************************/
>+#include "videosurface.hpp"
>+#include "main_interface.hpp"
>+
>+
>+VideoSurfaceProvider::VideoSurfaceProvider(QObject* parent)
>+    : QObject(parent)
>+{
>+}
>+
>+VideoSurface::VideoSurface(QQuickItem* parent)
>+    : QQuickItem(parent)
>+{
>+    setAcceptHoverEvents(true);
>+    setAcceptedMouseButtons(Qt::AllButtons);
>+    setFlag(ItemAcceptsInputMethod, true);
>+    setFlag(ItemHasContents, true);
>+
>+    connect(this, &QQuickItem::widthChanged, this,
>&VideoSurface::onSurfaceSizeChanged);
>+    connect(this, &QQuickItem::heightChanged, this,
>&VideoSurface::onSurfaceSizeChanged);
>+}
>+
>+QmlMainContext*VideoSurface::getCtx()
>+{
>+    return m_mainCtx;
>+}
>+
>+void VideoSurface::setCtx(QmlMainContext* mainctx)
>+{
>+    m_mainCtx = mainctx;
>+    emit ctxChanged(mainctx);
>+}
>+
>+QSize VideoSurface::getSourceSize() const
>+{
>+    return m_sourceSize;
>+}
>+
>+int VideoSurface::qtMouseButton2VLC( Qt::MouseButton qtButton )
>+{
>+    switch( qtButton )
>+    {
>+        case Qt::LeftButton:
>+            return 0;
>+        case Qt::RightButton:
>+            return 2;
>+        case Qt::MiddleButton:
>+            return 1;
>+        default:
>+            return -1;
>+    }
>+}
>+
>+void VideoSurface::mousePressEvent(QMouseEvent* event)
>+{
>+    int vlc_button = qtMouseButton2VLC( event->button() );
>+    if( vlc_button >= 0 )
>+    {
>+        emit mousePressed(vlc_button);
>+        event->accept();
>+    }
>+    else
>+        event->ignore();
>+}
>+
>+void VideoSurface::mouseReleaseEvent(QMouseEvent* event)
>+{
>+    int vlc_button = qtMouseButton2VLC( event->button() );
>+    if( vlc_button >= 0 )
>+    {
>+        emit mouseReleased(vlc_button);
>+        event->accept();
>+    }
>+    else
>+        event->ignore();
>+}
>+
>+void VideoSurface::mouseMoveEvent(QMouseEvent* event)
>+{
>+    QPointF current_pos = event->localPos();
>+    emit mouseMoved(current_pos.x() , current_pos.y());
>+    event->accept();
>+}
>+
>+void VideoSurface::hoverMoveEvent(QHoverEvent* event)
>+{
>+    QPointF current_pos = event->posF();
>+    if (current_pos != m_oldHoverPos)
>+    {
>+        float scaleW = m_sourceSize.width() / width();
>+        float scaleH = m_sourceSize.height() / height();
>+        emit mouseMoved(current_pos.x() * scaleW, current_pos.y() *
>scaleH);
>+        m_oldHoverPos = current_pos;
>+    }
>+    event->accept();
>+}
>+
>+void VideoSurface::mouseDoubleClickEvent(QMouseEvent* event)
>+{
>+    int vlc_button = qtMouseButton2VLC( event->button() );
>+    if( vlc_button >= 0 )
>+    {
>+        emit mouseDblClicked(vlc_button);
>+        event->accept();
>+    }
>+    else
>+        event->ignore();
>+}
>+
>+Qt::CursorShape VideoSurface::getCursorShape() const
>+{
>+    return cursor().shape();
>+}
>+
>+void VideoSurface::setCursorShape(Qt::CursorShape shape)
>+{
>+    setCursor(shape);
>+}
>+
>+QSGNode*VideoSurface::updatePaintNode(QSGNode* node,
>QQuickItem::UpdatePaintNodeData* nodeData)
>+{
>+    if (m_provider == nullptr) {
>+        if (m_mainCtx == nullptr)
>+            return nullptr;
>+        m_provider = 
>m_mainCtx->getMainInterface()->getVideoSurfaceProvider();
>+        if (!m_provider)
>+            return nullptr;
>+
>+        //forward signal to the provider
>+        connect(this, &VideoSurface::mouseMoved, m_provider,
>&VideoSurfaceProvider::mouseMoved);
>+        connect(this, &VideoSurface::mousePressed, m_provider,
>&VideoSurfaceProvider::mousePressed);
>+        connect(this, &VideoSurface::mouseDblClicked, m_provider,
>&VideoSurfaceProvider::mouseDblClicked);
>+        connect(this, &VideoSurface::mouseReleased, m_provider,
>&VideoSurfaceProvider::mouseReleased);
>+
>+        connect(this, &VideoSurface::surfaceSizeChanged, m_provider,
>&VideoSurfaceProvider::surfaceSizeChanged);
>+
>+        connect(m_provider, &VideoSurfaceProvider::update, this,
>&VideoSurface::update);
>+        connect(m_provider, &VideoSurfaceProvider::sourceSizeChanged,
>this, &VideoSurface::onSourceSizeChanged);
>+    }
>+    return m_provider->updatePaintNode(this, node, nodeData);
>+}
>+
>+void VideoSurface::onSourceSizeChanged(QSize newSize)
>+{
>+    if (newSize != m_sourceSize) {
>+        m_sourceSize = newSize;
>+        emit sourceSizeChanged(m_sourceSize);
>+    }
>+}
>+
>+void VideoSurface::onSurfaceSizeChanged()
>+{
>+    emit surfaceSizeChanged(size());
>+}
>diff --git a/modules/gui/qt/components/video_renderer/videosurface.hpp
>b/modules/gui/qt/components/video_renderer/videosurface.hpp
>new file mode 100644
>index 0000000000..41cb257a0a
>--- /dev/null
>+++ b/modules/gui/qt/components/video_renderer/videosurface.hpp
>@@ -0,0 +1,102 @@
>+/*****************************************************************************
>+ * Copyright (C) 2019 VLC authors and VideoLAN
>+ *
>+ * This program is free software; you can redistribute it and/or
>modify
>+ * it under the terms of the GNU General Public License as published
>by
>+ * the Free Software Foundation; either version 2 of the License, or
>+ * (at your option) any later version.
>+ *
>+ * This program is distributed in the hope that it will be useful,
>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>+ * GNU General Public License for more details.
>+ *
>+ * You should have received a copy of the GNU General Public License
>+ * along with this program; if not, write to the Free Software
>+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
>02110-1301, USA.
>+
>*****************************************************************************/
>+#ifndef VIDEOSURFACE_HPP
>+#define VIDEOSURFACE_HPP
>+
>+#include <QtQuick/QQuickItem>
>+#include <QCursor>
>+#include <components/qml_main_context.hpp>
>+#include "qt.hpp"
>+
>+class VideoSurfaceProvider : public QObject
>+{
>+    Q_OBJECT
>+public:
>+    VideoSurfaceProvider(QObject* parent);
>+    virtual ~VideoSurfaceProvider() {}
>+    virtual QSGNode* updatePaintNode(QQuickItem* item, QSGNode*
>oldNode, QQuickItem::UpdatePaintNodeData*) = 0;
>+
>+signals:
>+    void ctxChanged(QmlMainContext*);
>+    void sourceSizeChanged(QSize);
>+
>+    void surfaceSizeChanged(QSizeF);
>+
>+    void mousePressed( int vlcButton );
>+    void mouseReleased( int vlcButton );
>+    void mouseDblClicked( int vlcButton );
>+    void mouseMoved( float x, float y );
>+
>+    void update();
>+};
>+
>+
>+class VideoSurface : public QQuickItem
>+{
>+    Q_OBJECT
>+    Q_PROPERTY(QmlMainContext* ctx READ getCtx WRITE setCtx NOTIFY
>ctxChanged)
>+    Q_PROPERTY(QSize sourceSize READ getSourceSize NOTIFY
>sourceSizeChanged)
>+    Q_PROPERTY(Qt::CursorShape cursorShape READ getCursorShape WRITE
>setCursorShape RESET unsetCursor)
>+
>+public:
>+    VideoSurface( QQuickItem* parent = nullptr );
>+
>+    QmlMainContext* getCtx();
>+    void setCtx(QmlMainContext* mainctx);
>+
>+    QSize getSourceSize() const;
>+
>+protected:
>+    int qtMouseButton2VLC( Qt::MouseButton qtButton );
>+
>+    virtual void mousePressEvent(QMouseEvent *event) override;
>+    virtual void mouseReleaseEvent(QMouseEvent *event) override;
>+    virtual void mouseMoveEvent(QMouseEvent *event) override;
>+    virtual void hoverMoveEvent(QHoverEvent *event) override;
>+    virtual void mouseDoubleClickEvent(QMouseEvent *event) override;
>+
>+    Qt::CursorShape getCursorShape() const;
>+    void setCursorShape(Qt::CursorShape);
>+
>+    virtual QSGNode* updatePaintNode(QSGNode *,
>QQuickItem::UpdatePaintNodeData *) override;
>+
>+signals:
>+    void ctxChanged(QmlMainContext*);
>+    void sourceSizeChanged(QSize);
>+    void surfaceSizeChanged(QSizeF);
>+
>+    void mousePressed( int vlcButton );
>+    void mouseReleased( int vlcButton );
>+    void mouseDblClicked( int vlcButton );
>+    void mouseMoved( float x, float y );
>+
>+private slots:
>+    void onSourceSizeChanged(QSize);
>+    void onSurfaceSizeChanged();
>+
>+private:
>+    QmlMainContext* m_mainCtx = nullptr;
>+
>+    bool m_sourceSizeChanged = false;
>+    QSize m_sourceSize;
>+    QPointF m_oldHoverPos;
>+
>+    VideoSurfaceProvider* m_provider = nullptr;
>+};
>+
>+#endif // VIDEOSURFACE_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/10b5124a/attachment.html>


More information about the vlc-devel mailing list