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