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 <qt_sanity_bot@ovi.com>
Reviewed-by: Jonas Rabbe <jonas.rabbe@nokia.com>
This commit is contained in:
Dmytro Poplavskiy
2011-08-29 16:09:04 +10:00
committed by Qt by Nokia
parent a328dab2e3
commit 7941413f3f
4 changed files with 55 additions and 3 deletions

View File

@@ -79,7 +79,7 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio
m_resources = new PlayerResourcePolicy(this); m_resources = new PlayerResourcePolicy(this);
connect(m_session, SIGNAL(positionChanged(qint64)), connect(m_session, SIGNAL(positionChanged(qint64)),
this, SIGNAL(positionChanged(qint64))); this, SLOT(updatePosition(qint64)));
connect(m_session, SIGNAL(durationChanged(qint64)), connect(m_session, SIGNAL(durationChanged(qint64)),
this, SIGNAL(durationChanged(qint64))); this, SIGNAL(durationChanged(qint64)));
connect(m_session, SIGNAL(mutedStateChanged(bool)), connect(m_session, SIGNAL(mutedStateChanged(bool)),
@@ -195,9 +195,10 @@ void QGstreamerPlayerControl::setPosition(qint64 pos)
if (m_session->isSeekable() && m_session->seek(pos)) { if (m_session->isSeekable() && m_session->seek(pos)) {
m_seekToStartPending = false; m_seekToStartPending = false;
m_pendingSeekPosition = -1;
} else { } else {
m_pendingSeekPosition = pos; m_pendingSeekPosition = pos;
//don't display the first video frame since it's not what user requested.
m_session->showPrerollFrames(false);
} }
popAndNotifyState(); popAndNotifyState();
@@ -256,7 +257,11 @@ void QGstreamerPlayerControl::playOrPause(QMediaPlayer::State newState)
bool ok = false; 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(); ok = m_session->play();
else else
ok = m_session->pause(); ok = m_session->pause();
@@ -335,6 +340,7 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *
m_state = QMediaPlayer::StoppedState; m_state = QMediaPlayer::StoppedState;
QMediaContent oldMedia = m_currentResource; QMediaContent oldMedia = m_currentResource;
m_pendingSeekPosition = -1; m_pendingSeekPosition = -1;
m_session->showPrerollFrames(true);
if (!content.isNull() || stream) { if (!content.isNull() || stream) {
if (!m_resources->isRequested() && !m_resources->isGranted()) if (!m_resources->isRequested() && !m_resources->isGranted())
@@ -700,6 +706,8 @@ void QGstreamerPlayerControl::handleResourcesLost()
qint64 pos = m_session->position(); qint64 pos = m_session->position();
m_session->stop(); m_session->stop();
m_pendingSeekPosition = pos; m_pendingSeekPosition = pos;
//don't blink the first video frame after playback is restored
m_session->showPrerollFrames(false);
if (oldState != QMediaPlayer::StoppedState ) if (oldState != QMediaPlayer::StoppedState )
m_state = QMediaPlayer::PausedState; 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);
}

View File

@@ -118,6 +118,7 @@ private Q_SLOTS:
void processEOS(); void processEOS();
void setBufferProgress(int progress); void setBufferProgress(int progress);
void applyPendingSeek(bool isSeekable); void applyPendingSeek(bool isSeekable);
void updatePosition(qint64 pos);
void handleInvalidMedia(); void handleInvalidMedia();

View File

@@ -103,6 +103,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
m_lastPosition(0), m_lastPosition(0),
m_duration(-1), m_duration(-1),
m_durationQueries(0), m_durationQueries(0),
m_displayPrerolledFrame(true),
m_sourceType(UnknownSrc), m_sourceType(UnknownSrc),
m_everPlayed(false), m_everPlayed(false),
m_isLiveSource(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); 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) { switch (m_pendingState) {
case QMediaPlayer::PausedState: case QMediaPlayer::PausedState:
gst_element_set_state(m_playbin, GST_STATE_PAUSED); gst_element_set_state(m_playbin, GST_STATE_PAUSED);
@@ -1596,3 +1602,17 @@ void QGstreamerPlayerSession::processInvalidMedia(QMediaPlayer::Error errorCode,
stop(); stop();
emit error(int(errorCode), errorString); 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;
}
}

View File

@@ -131,6 +131,8 @@ public slots:
void setVolume(int volume); void setVolume(int volume);
void setMuted(bool muted); void setMuted(bool muted);
void showPrerollFrames(bool enabled);
signals: signals:
void durationChanged(qint64 duration); void durationChanged(qint64 duration);
void positionChanged(qint64 position); void positionChanged(qint64 position);
@@ -209,6 +211,8 @@ private:
qint64 m_duration; qint64 m_duration;
int m_durationQueries; int m_durationQueries;
bool m_displayPrerolledFrame;
enum SourceType enum SourceType
{ {
UnknownSrc, UnknownSrc,