File indexing completed on 2024-05-12 05:53:13

0001 /*
0002  * Copyright 2020 Tomaz Cananbrava <tcanabrava@kde.org>
0003  *
0004  * This program is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU General Public License as
0006  * published by the Free Software Foundation; either version 2 of
0007  * the License or (at your option) version 3 or any later version
0008  * accepted by the membership of KDE e.V. (or its successor approved
0009  * by the membership of KDE e.V.), which shall act as a proxy
0010  * defined in Section 14 of version 3 of the license.
0011  *
0012  * This program is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015  * GNU General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU General Public License
0018  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0019  */
0020 
0021 #pragma once
0022 
0023 #include <QQuickItem>
0024 
0025 class GStreamerIntegration;
0026 
0027 /* This is a fake surface that controls the video.
0028  *
0029  * Because of the way that OpenGL works, and because how GStreamer
0030  * is created, we need to play / pause the pipeline in the rendering
0031  * thread, that means that this element is the actual responsible
0032  * of starting the video. Other classes can request the video to start,
0033  * but never directly.
0034  *
0035  * The 'VideoItem' element is a GstGlVideoItem, that's the real paint surface.
0036  * This class plug things together and controls playing / pausing / screenshooting, etc.
0037  */
0038 class VideoSurface : public QQuickItem
0039 {
0040     Q_OBJECT
0041     Q_PROPERTY(GStreamerIntegration *videoReceiver WRITE setVideoReceiver READ videoReceiver NOTIFY videoReceiverChanged)
0042     Q_PROPERTY(bool playing WRITE setPlaying READ playing NOTIFY playingChanged)
0043 
0044 public:
0045     VideoSurface(QQuickItem *parent = nullptr);
0046     virtual ~VideoSurface();
0047 
0048     /* This is the Video Receiver, that controls the creation of the pipeline and a few other helper functions */
0049     GStreamerIntegration *videoReceiver() const;
0050     Q_SLOT void setVideoReceiver(GStreamerIntegration *videoReceiver);
0051     Q_SIGNAL void videoReceiverChanged(GStreamerIntegration *videoReceiver);
0052 
0053     bool playing() const;
0054     Q_SLOT void setPlaying(bool value);
0055     Q_SIGNAL void playingChanged(bool value);
0056 
0057     /* This method sets the pipeline state to playing as soon as Qt allows it */
0058     Q_INVOKABLE void startVideo();
0059     Q_INVOKABLE void pauseVideo();
0060 
0061     /* update paint node usually is a method that should trigger a painting on the OpenGL surface
0062     in our case, it's where we set the gstreamer pipeline state to playing / stop / pause.
0063     */
0064     QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *) override;
0065 
0066 private:
0067     /**
0068      * @brief Create GST Video widget
0069      *
0070      */
0071     void createVideoItem();
0072 
0073     QQuickItem *_videoItem;
0074     GStreamerIntegration *_videoReceiver;
0075     bool _shouldStartVideo;
0076     bool _shouldPauseVideo;
0077     bool _playing;
0078 };