From 7941413f3fe1e03cd10377299c6a3171df4e2cf3 Mon Sep 17 00:00:00 2001 From: Dmytro Poplavskiy Date: Mon, 29 Aug 2011 16:09:04 +1000 Subject: Gst player backend: don't show the first frame when resuming playback. It's necessary to temporarily disable show-preroll-frame of video sink, load pipeline to paused state, seek to requested position, and after seeking is finished (position updated) playback is started with show-preroll-frame restored. Task-number: MOBILITY-3030 Reviewed-by: Jonas Rabbe Change-Id: Ide1e6d909dd53f670229c293bc6be496a54e8626 (cherry picked from commit 625cce87e28fc7b5ec8785824affb3129fd3607b) Reviewed-on: http://codereview.qt-project.org/5500 Reviewed-by: Qt Sanity Bot Reviewed-by: Jonas Rabbe --- .../mediaplayer/qgstreamerplayercontrol.cpp | 33 ++++++++++++++++++++-- .../mediaplayer/qgstreamerplayercontrol.h | 1 + .../mediaplayer/qgstreamerplayersession.cpp | 20 +++++++++++++ .../mediaplayer/qgstreamerplayersession.h | 4 +++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp index 84b0cff4b..619816313 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp @@ -79,7 +79,7 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio m_resources = new PlayerResourcePolicy(this); connect(m_session, SIGNAL(positionChanged(qint64)), - this, SIGNAL(positionChanged(qint64))); + this, SLOT(updatePosition(qint64))); connect(m_session, SIGNAL(durationChanged(qint64)), this, SIGNAL(durationChanged(qint64))); connect(m_session, SIGNAL(mutedStateChanged(bool)), @@ -195,9 +195,10 @@ void QGstreamerPlayerControl::setPosition(qint64 pos) if (m_session->isSeekable() && m_session->seek(pos)) { m_seekToStartPending = false; - m_pendingSeekPosition = -1; } else { m_pendingSeekPosition = pos; + //don't display the first video frame since it's not what user requested. + m_session->showPrerollFrames(false); } popAndNotifyState(); @@ -256,7 +257,11 @@ void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState) bool ok = false; - if (newState == QMediaPlayer::PlayingState) + //To prevent displaying the first video frame when playback is resumed + //the pipeline is paused instead of playing, seeked to requested position, + //and after seeking is finished (position updated) playback is restarted + //with show-preroll-frame enabled. + if (newState == QMediaPlayer::PlayingState && m_pendingSeekPosition == -1) ok = m_session->play(); else ok = m_session->pause(); @@ -335,6 +340,7 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice * m_state = QMediaPlayer::StoppedState; QMediaContent oldMedia = m_currentResource; m_pendingSeekPosition = -1; + m_session->showPrerollFrames(true); if (!content.isNull() || stream) { if (!m_resources->isRequested() && !m_resources->isGranted()) @@ -700,6 +706,8 @@ void QGstreamerPlayerControl::handleResourcesLost() qint64 pos = m_session->position(); m_session->stop(); m_pendingSeekPosition = pos; + //don't blink the first video frame after playback is restored + m_session->showPrerollFrames(false); if (oldState != QMediaPlayer::StoppedState ) m_state = QMediaPlayer::PausedState; @@ -746,3 +754,22 @@ void QGstreamerPlayerControl::popAndNotifyState() } } } + +void QGstreamerPlayerControl::updatePosition(qint64 pos) +{ +#ifdef DEBUG_PLAYBIN + qDebug() << Q_FUNC_INFO << pos/1000.0 << "pending:" << m_pendingSeekPosition/1000.0; +#endif + + if (m_pendingSeekPosition != -1) { + //seek request is complete, it's safe to resume playback + //with prerolled frame displayed + m_pendingSeekPosition = -1; + m_session->showPrerollFrames(true); + if (m_state == QMediaPlayer::PlayingState) { + m_session->play(); + } + } + + emit positionChanged(pos); +} diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h index 2c418f284..ea02c9766 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayercontrol.h @@ -118,6 +118,7 @@ private Q_SLOTS: void processEOS(); void setBufferProgress(int progress); void applyPendingSeek(bool isSeekable); + void updatePosition(qint64 pos); void handleInvalidMedia(); diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp index d3d582332..7fb5599c2 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.cpp @@ -103,6 +103,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) m_lastPosition(0), m_duration(-1), m_durationQueries(0), + m_displayPrerolledFrame(true), m_sourceType(UnknownSrc), m_everPlayed(false), m_isLiveSource(false) @@ -536,6 +537,11 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) linked = gst_element_link_many(m_videoIdentity, m_colorSpace, m_videoSink, NULL); } + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) { + gboolean value = m_displayPrerolledFrame; + g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, NULL); + } + switch (m_pendingState) { case QMediaPlayer::PausedState: gst_element_set_state(m_playbin, GST_STATE_PAUSED); @@ -1596,3 +1602,17 @@ void QGstreamerPlayerSession::processInvalidMedia(QMediaPlayer::Error errorCode, stop(); emit error(int(errorCode), errorString); } + +void QGstreamerPlayerSession::showPrerollFrames(bool enabled) +{ +#ifdef DEBUG_PLAYBIN + qDebug() << Q_FUNC_INFO << enabled; +#endif + if (enabled != m_displayPrerolledFrame && m_videoSink && + g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame") != 0) { + + gboolean value = enabled; + g_object_set(G_OBJECT(m_videoSink), "show-preroll-frame", value, NULL); + m_displayPrerolledFrame = enabled; + } +} diff --git a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h index 297754b93..e89c1521c 100644 --- a/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h +++ b/src/plugins/gstreamer/mediaplayer/qgstreamerplayersession.h @@ -131,6 +131,8 @@ public slots: void setVolume(int volume); void setMuted(bool muted); + void showPrerollFrames(bool enabled); + signals: void durationChanged(qint64 duration); void positionChanged(qint64 position); @@ -209,6 +211,8 @@ private: qint64 m_duration; int m_durationQueries; + bool m_displayPrerolledFrame; + enum SourceType { UnknownSrc, -- cgit v1.2.3