1From acd6206d7925ba626c36ed254e5db932ad571cdd Mon Sep 17 00:00:00 2001
2From: Jeffy Chen <jeffy.chen@rock-chips.com>
3Date: Tue, 30 Mar 2021 06:32:34 +0800
4Subject: [PATCH 14/17] HACK: gstreamer: Support LastFrame flush mode
5
6Hold last frame for VideoOutput.LastFrame.
7
8Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
9---
10 src/gsttools/qgstreamerplayersession.cpp        | 17 +++++++++++++++++
11 src/gsttools/qgstreamervideooverlay.cpp         |  4 ++++
12 src/gsttools/qgstreamervideooverlay_p.h         |  5 +++++
13 src/gsttools/qgstreamervideowindow.cpp          | 10 ++++++++++
14 src/gsttools/qgstreamervideowindow_p.h          |  3 +++
15 src/multimedia/controls/qvideowindowcontrol.h   |  3 +++
16 .../qdeclarativevideooutput.cpp                 |  4 ++++
17 .../qdeclarativevideooutput_backend_p.h         |  2 ++
18 .../qdeclarativevideooutput_p.h                 |  6 +++---
19 .../qdeclarativevideooutput_window.cpp          |  9 +++++++++
20 .../qdeclarativevideooutput_window_p.h          |  2 ++
21 11 files changed, 62 insertions(+), 3 deletions(-)
22
23diff --git a/src/gsttools/qgstreamerplayersession.cpp b/src/gsttools/qgstreamerplayersession.cpp
24index cc0681b..b0a37f8 100755
25--- a/src/gsttools/qgstreamerplayersession.cpp
26+++ b/src/gsttools/qgstreamerplayersession.cpp
27@@ -63,6 +63,8 @@
28 #include <qvideorenderercontrol.h>
29 #include <QUrlQuery>
30
31+#include <qvideowindowcontrol.h>
32+
33 //#define DEBUG_PLAYBIN
34
35 QT_BEGIN_NAMESPACE
36@@ -1959,6 +1961,21 @@ void QGstreamerPlayerSession::removeProbe(QGstreamerAudioProbeControl* probe)
37 // and setSeekable() values.
38 void QGstreamerPlayerSession::endOfMediaReset()
39 {
40+    auto window = qobject_cast<QVideoWindowControl *>(m_videoOutput);
41+    if (window) {
42+        switch (window->flushMode()) {
43+        case Qt::LastFrame:
44+            pause();
45+            return;
46+        case Qt::FirstFrame:
47+            qWarning()<<"FirstFrame flush mode not supported";
48+            seek(0);
49+            break;
50+        default:
51+            break;
52+        }
53+    }
54+
55     if (m_renderer)
56         m_renderer->stopRenderer();
57
58diff --git a/src/gsttools/qgstreamervideooverlay.cpp b/src/gsttools/qgstreamervideooverlay.cpp
59index 837fe92..2a8a8e8 100644
60--- a/src/gsttools/qgstreamervideooverlay.cpp
61+++ b/src/gsttools/qgstreamervideooverlay.cpp
62@@ -711,6 +711,10 @@ void QGstreamerVideoOverlay::updateIsActive()
63
64     bool newIsActive = (state == GST_STATE_PLAYING || (state == GST_STATE_PAUSED && showPreroll));
65
66+    // HACK: Pretend active when pausing to hold video frame
67+    if (m_flushMode != Qt::EmptyFrame)
68+        newIsActive |= m_isActive && state == GST_STATE_PAUSED;
69+
70     if (newIsActive != m_isActive) {
71         m_isActive = newIsActive;
72         emit activeChanged();
73diff --git a/src/gsttools/qgstreamervideooverlay_p.h b/src/gsttools/qgstreamervideooverlay_p.h
74index 32b3d93..5628862 100644
75--- a/src/gsttools/qgstreamervideooverlay_p.h
76+++ b/src/gsttools/qgstreamervideooverlay_p.h
77@@ -100,6 +100,9 @@ public:
78     bool processSyncMessage(const QGstreamerMessage &message) override;
79     bool processBusMessage(const QGstreamerMessage &message) override;
80
81+    Qt::FlushMode flushMode() const { return m_flushMode; };
82+    void setFlushMode(Qt::FlushMode mode) { m_flushMode = mode; };
83+
84 Q_SIGNALS:
85     void nativeVideoSizeChanged();
86     void activeChanged();
87@@ -121,6 +124,8 @@ private:
88     QGstreamerSinkProperties *m_sinkProperties = nullptr;
89     WId m_windowId = 0;
90     QRect m_rect;
91+
92+    Qt::FlushMode m_flushMode = Qt::EmptyFrame;
93 };
94
95 QT_END_NAMESPACE
96diff --git a/src/gsttools/qgstreamervideowindow.cpp b/src/gsttools/qgstreamervideowindow.cpp
97index e7e3c50..f813b79 100644
98--- a/src/gsttools/qgstreamervideowindow.cpp
99+++ b/src/gsttools/qgstreamervideowindow.cpp
100@@ -177,3 +177,13 @@ QSize QGstreamerVideoWindow::nativeSize() const
101 {
102     return m_videoOverlay.nativeVideoSize();
103 }
104+
105+Qt::FlushMode QGstreamerVideoWindow::flushMode() const
106+{
107+    return m_videoOverlay.flushMode();
108+}
109+
110+void QGstreamerVideoWindow::setFlushMode(Qt::FlushMode mode)
111+{
112+    m_videoOverlay.setFlushMode(mode);
113+}
114diff --git a/src/gsttools/qgstreamervideowindow_p.h b/src/gsttools/qgstreamervideowindow_p.h
115index a0ed859..b46e580 100644
116--- a/src/gsttools/qgstreamervideowindow_p.h
117+++ b/src/gsttools/qgstreamervideowindow_p.h
118@@ -110,6 +110,9 @@ public:
119     bool processBusMessage(const QGstreamerMessage &message) override;
120     bool isReady() const override { return m_windowId != 0; }
121
122+    Qt::FlushMode flushMode() const override;
123+    void setFlushMode(Qt::FlushMode mode) override;
124+
125 signals:
126     void sinkChanged();
127     void readyChanged(bool);
128diff --git a/src/multimedia/controls/qvideowindowcontrol.h b/src/multimedia/controls/qvideowindowcontrol.h
129index 510a299..cb22c7b 100644
130--- a/src/multimedia/controls/qvideowindowcontrol.h
131+++ b/src/multimedia/controls/qvideowindowcontrol.h
132@@ -85,6 +85,9 @@ public:
133     virtual int saturation() const = 0;
134     virtual void setSaturation(int saturation) = 0;
135
136+    virtual Qt::FlushMode flushMode() const = 0;
137+    virtual void setFlushMode(Qt::FlushMode mode) = 0;
138+
139 Q_SIGNALS:
140     void fullScreenChanged(bool fullScreen);
141     void brightnessChanged(int brightness);
142diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
143index d2f735b..ae23b65 100644
144--- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
145+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp
146@@ -921,7 +921,11 @@ void QDeclarativeVideoOutput::setFlushMode(FlushMode mode)
147         return;
148
149     m_flushMode = mode;
150+
151     emit flushModeChanged();
152+
153+    if (m_backend)
154+        m_backend->updateFlushMode();
155 }
156
157 QT_END_NAMESPACE
158diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_backend_p.h b/src/qtmultimediaquicktools/qdeclarativevideooutput_backend_p.h
159index da99b38..677853b 100644
160--- a/src/qtmultimediaquicktools/qdeclarativevideooutput_backend_p.h
161+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_backend_p.h
162@@ -94,6 +94,8 @@ public:
163     virtual void releaseResources() { }
164     virtual void invalidateSceneGraph() { }
165
166+    virtual void updateFlushMode() { };
167+
168 protected:
169     QDeclarativeVideoOutput *q;
170     QPointer<QMediaService> m_service;
171diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h b/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h
172index d14731c..010e08c 100644
173--- a/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h
174+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h
175@@ -89,9 +89,9 @@ public:
176
177     enum FlushMode
178     {
179-        EmptyFrame,
180-        FirstFrame,
181-        LastFrame
182+        EmptyFrame = Qt::EmptyFrame,
183+        FirstFrame = Qt::FirstFrame,
184+        LastFrame = Qt::LastFrame
185     };
186
187     enum FillMode
188diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_window.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput_window.cpp
189index bae29e1..c7204a3 100644
190--- a/src/qtmultimediaquicktools/qdeclarativevideooutput_window.cpp
191+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_window.cpp
192@@ -57,6 +57,12 @@ QDeclarativeVideoWindowBackend::~QDeclarativeVideoWindowBackend()
193     releaseControl();
194 }
195
196+void QDeclarativeVideoWindowBackend::updateFlushMode()
197+{
198+    if (m_videoWindowControl)
199+        m_videoWindowControl->setFlushMode((Qt::FlushMode)q->flushMode());
200+}
201+
202 bool QDeclarativeVideoWindowBackend::init(QMediaService *service)
203 {
204     if (QMediaControl *control = service->requestControl(QVideoWindowControl_iid)) {
205@@ -66,6 +72,9 @@ bool QDeclarativeVideoWindowBackend::init(QMediaService *service)
206             m_service = service;
207             QObject::connect(m_videoWindowControl.data(), SIGNAL(nativeSizeChanged()),
208                              q, SLOT(_q_updateNativeSize()));
209+
210+            updateFlushMode();
211+
212             return true;
213         }
214     }
215diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_window_p.h b/src/qtmultimediaquicktools/qdeclarativevideooutput_window_p.h
216index eb1814b..b8990c8 100644
217--- a/src/qtmultimediaquicktools/qdeclarativevideooutput_window_p.h
218+++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_window_p.h
219@@ -73,6 +73,8 @@ public:
220     QAbstractVideoSurface *videoSurface() const override;
221     QRectF adjustedViewport() const override;
222
223+    void updateFlushMode() override;
224+
225 private:
226     QPointer<QVideoWindowControl> m_videoWindowControl;
227     bool m_visible;
228--
2292.20.1
230
231