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