From 4c42f87adb78a2f2dc8765b6b607b3caad3de7fc Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 6 Oct 2021 14:28:58 +0200 Subject: Fix the tst_qmediaplayerbackend::seekPauseSeek autotest on gstreamer Avoid sending a video frame while we're in stopped state. This also gives us a more consistent cross-platform behavior where the other platforms also do not send any frames before going into paused. Pick-to: 6.2 Change-Id: Ifd0b0ad781f9a4feea3595847cc899b03078a747 Reviewed-by: Piotr Srebrny Reviewed-by: Lars Knoll --- src/multimedia/platform/gstreamer/common/qgstpipeline.cpp | 12 +++++++++--- src/multimedia/platform/gstreamer/common/qgstpipeline_p.h | 3 ++- .../platform/gstreamer/common/qgstreamermediaplayer.cpp | 9 +++++---- .../platform/gstreamer/common/qgstreamervideosink.cpp | 7 +++++++ .../platform/gstreamer/common/qgstreamervideosink_p.h | 1 + .../platform/gstreamer/common/qgstvideorenderersink.cpp | 12 ++++++++---- src/multimedia/platform/qplatformvideosink_p.h | 2 ++ 7 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp b/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp index 0f98e7d21..7a605b709 100644 --- a/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstpipeline.cpp @@ -62,7 +62,7 @@ public: QMutex filterMutex; QList syncFilters; QList busFilters; - QProperty inStoppedState; + bool inStoppedState = true; mutable qint64 m_position = 0; double m_rate = 1.; bool m_flushOnConfigChanges = false; @@ -237,10 +237,16 @@ QGstPipeline::~QGstPipeline() d->deref(); } -QProperty *QGstPipeline::inStoppedState() +bool QGstPipeline::inStoppedState() const { Q_ASSERT(d); - return &d->inStoppedState; + return d->inStoppedState; +} + +void QGstPipeline::setInStoppedState(bool stopped) +{ + Q_ASSERT(d); + d->inStoppedState = stopped; } void QGstPipeline::setFlushOnConfigChanges(bool flush) diff --git a/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h b/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h index 6ffaf33d6..133fb167b 100644 --- a/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstpipeline_p.h @@ -91,7 +91,8 @@ public: // QMediaPlayer is still in a stopped state, while we put the gstreamer pipeline into a // Paused state so that we can get the required metadata of the stream and also have a fast // transition to play. - QProperty *inStoppedState(); + bool inStoppedState() const; + void setInStoppedState(bool stopped); void setFlushOnConfigChanges(bool flush); diff --git a/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp b/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp index e3327a85a..6ebfb703b 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamermediaplayer.cpp @@ -205,7 +205,7 @@ void QGstreamerMediaPlayer::play() return; resetCurrentLoop(); - *playerPipeline.inStoppedState() = false; + playerPipeline.setInStoppedState(false); if (mediaStatus() == QMediaPlayer::EndOfMedia) { playerPipeline.setPosition(0); updatePosition(); @@ -233,8 +233,8 @@ void QGstreamerMediaPlayer::pause() return; positionUpdateTimer.stop(); - if (*playerPipeline.inStoppedState()) { - *playerPipeline.inStoppedState() = false; + if (playerPipeline.inStoppedState()) { + playerPipeline.setInStoppedState(false); playerPipeline.flush(); } int ret = playerPipeline.setState(GST_STATE_PAUSED); @@ -258,7 +258,7 @@ void QGstreamerMediaPlayer::stop() void QGstreamerMediaPlayer::stopOrEOS(bool eos) { positionUpdateTimer.stop(); - *playerPipeline.inStoppedState() = true; + playerPipeline.setInStoppedState(true); bool ret = playerPipeline.setStateSync(GST_STATE_PAUSED); if (!ret) qCDebug(qLcMediaPlayer) << "Unable to set the pipeline to the stopped state."; @@ -648,6 +648,7 @@ void QGstreamerMediaPlayer::setMedia(const QUrl &content, QIODevice *stream) decoder = QGstElement(); removeAllOutputs(); seekableChanged(false); + playerPipeline.setInStoppedState(true); if (m_duration != 0) { m_duration = 0; diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp index 0250fd3ef..516f61970 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp @@ -114,6 +114,13 @@ void QGstreamerVideoSink::setPipeline(QGstPipeline pipeline) gstPipeline = pipeline; } +bool QGstreamerVideoSink::inStoppedState() const +{ + if (gstPipeline.isNull()) + return true; + return gstPipeline.inStoppedState(); +} + void QGstreamerVideoSink::setRhi(QRhi *rhi) { if (rhi && rhi->backend() != QRhi::OpenGLES2) diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h b/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h index a049bc465..074dd5a0e 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h @@ -82,6 +82,7 @@ public: QGstElement subtitleSink() const { return gstSubtitleSink; } void setPipeline(QGstPipeline pipeline); + bool inStoppedState() const; GstContext *gstGlDisplayContext() const { return m_gstGlDisplayContext; } GstContext *gstGlLocalContext() const { return m_gstGlLocalContext; } diff --git a/src/multimedia/platform/gstreamer/common/qgstvideorenderersink.cpp b/src/multimedia/platform/gstreamer/common/qgstvideorenderersink.cpp index a74fa1b4b..2c15d71dc 100644 --- a/src/multimedia/platform/gstreamer/common/qgstvideorenderersink.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstvideorenderersink.cpp @@ -332,11 +332,15 @@ bool QGstVideoRenderer::handleEvent(QMutexLocker *locker) } } - QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, m_videoInfo, m_sink, m_format, memoryFormat); - QVideoFrame frame(videoBuffer, m_format); - QGstUtils::setFrameTimeStamps(&frame, buffer); + if (m_sink->inStoppedState()) { + m_sink->setVideoFrame(QVideoFrame()); + } else { + QGstVideoBuffer *videoBuffer = new QGstVideoBuffer(buffer, m_videoInfo, m_sink, m_format, memoryFormat); + QVideoFrame frame(videoBuffer, m_format); + QGstUtils::setFrameTimeStamps(&frame, buffer); - m_sink->setVideoFrame(frame); + m_sink->setVideoFrame(frame); + } gst_buffer_unref(buffer); diff --git a/src/multimedia/platform/qplatformvideosink_p.h b/src/multimedia/platform/qplatformvideosink_p.h index 95d1aa085..6b5769067 100644 --- a/src/multimedia/platform/qplatformvideosink_p.h +++ b/src/multimedia/platform/qplatformvideosink_p.h @@ -101,6 +101,8 @@ public: } void setVideoFrame(const QVideoFrame &frame) { setNativeSize(frame.size()); + if (frame == m_currentVideoFrame) + return; m_currentVideoFrame = frame; m_currentVideoFrame.setSubtitleText(subtitleText()); sink->videoFrameChanged(m_currentVideoFrame); -- cgit v1.2.3