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