diff options
Diffstat (limited to 'src/plugins/mediaservices')
4 files changed, 208 insertions, 67 deletions
diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp index 2d7aaa8..e646693 100644 --- a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.cpp @@ -59,6 +59,9 @@ QT_BEGIN_NAMESPACE QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *session, QObject *parent) : QMediaPlayerControl(parent) , m_session(session) + , m_state(QMediaPlayer::StoppedState) + , m_mediaStatus(QMediaPlayer::NoMedia) + , m_bufferProgress(-1) , m_stream(0) , m_fifoNotifier(0) , m_fifoCanWrite(false) @@ -77,11 +80,11 @@ QGstreamerPlayerControl::QGstreamerPlayerControl(QGstreamerPlayerSession *sessio connect(m_session, SIGNAL(volumeChanged(int)), this, SIGNAL(volumeChanged(int))); connect(m_session, SIGNAL(stateChanged(QMediaPlayer::State)), - this, SIGNAL(stateChanged(QMediaPlayer::State))); - connect(m_session, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), - this, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus))); + this, SLOT(updateState(QMediaPlayer::State))); connect(m_session,SIGNAL(bufferingProgressChanged(int)), - this, SIGNAL(bufferStatusChanged(int))); + this, SLOT(setBufferProgress(int))); + connect(m_session, SIGNAL(playbackFinished()), + this, SLOT(processEOS())); connect(m_session, SIGNAL(audioAvailableChanged(bool)), this, SIGNAL(audioAvailableChanged(bool))); connect(m_session, SIGNAL(videoAvailableChanged(bool)), @@ -114,17 +117,20 @@ qint64 QGstreamerPlayerControl::duration() const QMediaPlayer::State QGstreamerPlayerControl::state() const { - return m_session->state(); + return m_state; } QMediaPlayer::MediaStatus QGstreamerPlayerControl::mediaStatus() const { - return m_session->mediaStatus(); + return m_mediaStatus; } int QGstreamerPlayerControl::bufferStatus() const { - return 100; + if (m_bufferProgress == -1) { + return m_session->state() == QMediaPlayer::StoppedState ? 0 : 100; + } else + return m_bufferProgress; } int QGstreamerPlayerControl::volume() const @@ -169,23 +175,33 @@ void QGstreamerPlayerControl::setPosition(qint64 pos) void QGstreamerPlayerControl::play() { - m_session->play(); - - if (m_fifoFd[1] >= 0) { - m_fifoCanWrite = true; - - writeFifo(); + if (m_session->play()) { + if (m_state != QMediaPlayer::PlayingState) + emit stateChanged(m_state = QMediaPlayer::PlayingState); } } void QGstreamerPlayerControl::pause() { - m_session->pause(); + if (m_session->pause()) { + if (m_state != QMediaPlayer::PausedState) + emit stateChanged(m_state = QMediaPlayer::PausedState); + } } void QGstreamerPlayerControl::stop() { - m_session->stop(); + if (m_state != QMediaPlayer::StoppedState) { + m_session->pause(); + if (!m_session->seek(0)) { + m_bufferProgress = -1; + m_session->stop(); + m_session->pause(); + } + emit positionChanged(0); + if (m_state != QMediaPlayer::StoppedState) + emit stateChanged(m_state = QMediaPlayer::StoppedState); + } } void QGstreamerPlayerControl::setVolume(int volume) @@ -210,8 +226,15 @@ const QIODevice *QGstreamerPlayerControl::mediaStream() const void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice *stream) { + QMediaPlayer::State oldState = m_state; + m_state = QMediaPlayer::StoppedState; m_session->stop(); + if (m_bufferProgress != -1) { + m_bufferProgress = -1; + emit bufferStatusChanged(0); + } + if (m_stream) { closeFifo(); @@ -234,7 +257,25 @@ void QGstreamerPlayerControl::setMedia(const QMediaContent &content, QIODevice * m_session->load(url); + if (m_fifoFd[1] >= 0) { + m_fifoCanWrite = true; + + writeFifo(); + } + + if (!url.isEmpty()) { + if (m_mediaStatus != QMediaPlayer::LoadingMedia) + emit mediaStatusChanged(m_mediaStatus = QMediaPlayer::LoadingMedia); + m_session->pause(); + } else { + if (m_mediaStatus != QMediaPlayer::NoMedia) + emit mediaStatusChanged(m_mediaStatus = QMediaPlayer::NoMedia); + setBufferProgress(0); + } + emit mediaChanged(m_currentResource); + if (m_state != oldState) + emit stateChanged(m_state); } void QGstreamerPlayerControl::setVideoOutput(QObject *output) @@ -252,6 +293,68 @@ bool QGstreamerPlayerControl::isVideoAvailable() const return m_session->isVideoAvailable(); } +void QGstreamerPlayerControl::updateState(QMediaPlayer::State state) +{ + QMediaPlayer::MediaStatus oldStatus = m_mediaStatus; + + switch (state) { + case QMediaPlayer::StoppedState: + if (m_state != QMediaPlayer::StoppedState) + emit stateChanged(m_state = QMediaPlayer::StoppedState); + break; + + case QMediaPlayer::PlayingState: + case QMediaPlayer::PausedState: + if (m_state == QMediaPlayer::StoppedState) + m_mediaStatus = QMediaPlayer::LoadedMedia; + else { + if (m_bufferProgress == -1) + m_mediaStatus = QMediaPlayer::BufferedMedia; + } + break; + } + + if (m_mediaStatus != oldStatus) + emit mediaStatusChanged(m_mediaStatus); +} + +void QGstreamerPlayerControl::processEOS() +{ + m_mediaStatus = QMediaPlayer::EndOfMedia; + m_state = QMediaPlayer::StoppedState; + + emit stateChanged(m_state); + emit mediaStatusChanged(m_mediaStatus); +} + +void QGstreamerPlayerControl::setBufferProgress(int progress) +{ + if (m_bufferProgress == progress || m_mediaStatus == QMediaPlayer::NoMedia) + return; + + QMediaPlayer::MediaStatus oldStatus = m_mediaStatus; + + m_bufferProgress = progress; + + if (m_state == QMediaPlayer::StoppedState) { + m_mediaStatus = QMediaPlayer::LoadedMedia; + } else { + if (m_bufferProgress < 100) { + m_mediaStatus = QMediaPlayer::StalledMedia; + m_session->pause(); + } else { + m_mediaStatus = QMediaPlayer::BufferedMedia; + if (m_state == QMediaPlayer::PlayingState) + m_session->play(); + } + } + + if (m_mediaStatus != oldStatus) + emit mediaStatusChanged(m_mediaStatus); + + emit bufferStatusChanged(m_bufferProgress); +} + void QGstreamerPlayerControl::writeFifo() { if (m_fifoCanWrite) { diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.h b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.h index ae0f8b6..0c53945 100644 --- a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.h +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayercontrol.h @@ -107,11 +107,18 @@ private Q_SLOTS: void writeFifo(); void fifoReadyWrite(int socket); + void updateState(QMediaPlayer::State); + void processEOS(); + void setBufferProgress(int progress); + private: bool openFifo(); void closeFifo(); QGstreamerPlayerSession *m_session; + QMediaPlayer::State m_state; + QMediaPlayer::MediaStatus m_mediaStatus; + int m_bufferProgress; QMediaContent m_currentResource; QIODevice *m_stream; QSocketNotifier *m_fifoNotifier; diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.cpp b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.cpp index 600621e..392a7a8 100644 --- a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.cpp +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.cpp @@ -57,7 +57,6 @@ QT_BEGIN_NAMESPACE QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) :QObject(parent), m_state(QMediaPlayer::StoppedState), - m_mediaStatus(QMediaPlayer::UnknownMediaStatus), m_busHelper(0), m_playbin(0), m_nullVideoOutput(0), @@ -92,6 +91,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent) m_busHelper->installSyncEventFilter(this); m_nullVideoOutput = gst_element_factory_make("fakesink", NULL); + gst_object_ref(GST_OBJECT(m_nullVideoOutput)); g_object_set(G_OBJECT(m_playbin), "video-sink", m_nullVideoOutput, NULL); // Initial volume @@ -109,12 +109,14 @@ QGstreamerPlayerSession::~QGstreamerPlayerSession() delete m_busHelper; gst_object_unref(GST_OBJECT(m_bus)); gst_object_unref(GST_OBJECT(m_playbin)); + gst_object_unref(GST_OBJECT(m_nullVideoOutput)); } } void QGstreamerPlayerSession::load(const QUrl &url) { m_url = url; + if (m_playbin) { m_tags.clear(); emit tagsChanged(); @@ -259,26 +261,36 @@ bool QGstreamerPlayerSession::isSeekable() const return m_seekable; } -void QGstreamerPlayerSession::play() +bool QGstreamerPlayerSession::play() { if (m_playbin) { if (gst_element_set_state(m_playbin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { qWarning() << "GStreamer; Unable to play -" << m_url.toString(); - m_state = QMediaPlayer::StoppedState; - m_mediaStatus = QMediaPlayer::InvalidMedia; + m_state = QMediaPlayer::StoppedState; emit stateChanged(m_state); - emit mediaStatusChanged(m_mediaStatus); - emit error(int(QMediaPlayer::ResourceError), tr("Unable to play %1").arg(m_url.path())); - } + } else + return true; } + + return false; } -void QGstreamerPlayerSession::pause() +bool QGstreamerPlayerSession::pause() { - if (m_playbin) - gst_element_set_state(m_playbin, GST_STATE_PAUSED); + if (m_playbin) { + if (gst_element_set_state(m_playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) { + qWarning() << "GStreamer; Unable to play -" << m_url.toString(); + m_state = QMediaPlayer::StoppedState; + + emit stateChanged(m_state); + emit error(int(QMediaPlayer::ResourceError), tr("Unable to play %1").arg(m_url.path())); + } else + return true; + } + + return false; } void QGstreamerPlayerSession::stop() @@ -292,31 +304,45 @@ void QGstreamerPlayerSession::stop() } } -void QGstreamerPlayerSession::seek(qint64 ms) +bool QGstreamerPlayerSession::seek(qint64 ms) { if (m_playbin && m_state != QMediaPlayer::StoppedState) { gint64 position = (gint64)ms * 1000000; - gst_element_seek_simple(m_playbin, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, position); + return gst_element_seek_simple(m_playbin, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, position); } + + return false; } void QGstreamerPlayerSession::setVolume(int volume) { - m_volume = volume; - emit volumeChanged(m_volume); + if (m_volume != volume) { + m_volume = volume; - if (!m_muted && m_playbin) - g_object_set(G_OBJECT(m_playbin), "volume", m_volume/100.0, NULL); + if (m_playbin) { +#ifndef USE_PLAYBIN2 + if(!m_muted) +#endif + g_object_set(G_OBJECT(m_playbin), "volume", m_volume/100.0, NULL); + } + + emit volumeChanged(m_volume); + } } void QGstreamerPlayerSession::setMuted(bool muted) { - m_muted = muted; - - g_object_set(G_OBJECT(m_playbin), "volume", (m_muted ? 0 : m_volume/100.0), NULL); + if (m_muted != muted) { + m_muted = muted; - emit mutedStateChanged(m_muted); +#ifdef USE_PLAYBIN2 + g_object_set(G_OBJECT(m_playbin), "mute", m_muted, NULL); +#else + g_object_set(G_OBJECT(m_playbin), "volume", (m_muted ? 0 : m_volume/100.0), NULL); +#endif + emit mutedStateChanged(m_muted); + } } static void addTagToMap(const GstTagList *list, @@ -388,14 +414,6 @@ void QGstreamerPlayerSession::setSeekable(bool seekable) } } -void QGstreamerPlayerSession::setMediaStatus(QMediaPlayer::MediaStatus status) -{ - if (m_mediaStatus != status) { - m_mediaStatus = status; - emit mediaStatusChanged(status); - } -} - bool QGstreamerPlayerSession::processSyncMessage(const QGstreamerMessage &message) { GstMessage* gm = message.rawMessage(); @@ -440,9 +458,6 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message) if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) { switch (GST_MESSAGE_TYPE(gm)) { - case GST_MESSAGE_DURATION: - break; - case GST_MESSAGE_STATE_CHANGED: { GstState oldState; @@ -462,24 +477,19 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message) switch (newState) { case GST_STATE_VOID_PENDING: case GST_STATE_NULL: - setMediaStatus(QMediaPlayer::UnknownMediaStatus); setSeekable(false); if (m_state != QMediaPlayer::StoppedState) emit stateChanged(m_state = QMediaPlayer::StoppedState); break; case GST_STATE_READY: - setMediaStatus(QMediaPlayer::LoadedMedia); setSeekable(false); if (m_state != QMediaPlayer::StoppedState) emit stateChanged(m_state = QMediaPlayer::StoppedState); break; case GST_STATE_PAUSED: - //don't emit state changes for intermediate states - if (m_state != QMediaPlayer::PausedState && pending == GST_STATE_VOID_PENDING) + if (m_state != QMediaPlayer::PausedState) emit stateChanged(m_state = QMediaPlayer::PausedState); - setMediaStatus(QMediaPlayer::LoadedMedia); - //check for seekable if (oldState == GST_STATE_READY) { /* @@ -513,17 +523,13 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message) if (m_state != QMediaPlayer::PlayingState) emit stateChanged(m_state = QMediaPlayer::PlayingState); + break; } } break; case GST_MESSAGE_EOS: - if (m_state != QMediaPlayer::StoppedState) - emit stateChanged(m_state = QMediaPlayer::StoppedState); - - setMediaStatus(QMediaPlayer::EndOfMedia); - emit playbackFinished(); break; @@ -546,7 +552,11 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message) case GST_MESSAGE_INFO: break; case GST_MESSAGE_BUFFERING: - setMediaStatus(QMediaPlayer::BufferingMedia); + { + int progress = 0; + gst_message_parse_buffering(gm, &progress); + emit bufferingProgressChanged(progress); + } break; case GST_MESSAGE_STATE_DIRTY: case GST_MESSAGE_STEP_DONE: @@ -556,8 +566,32 @@ void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message) case GST_MESSAGE_STRUCTURE_CHANGE: case GST_MESSAGE_APPLICATION: case GST_MESSAGE_ELEMENT: + break; case GST_MESSAGE_SEGMENT_START: + { + const GstStructure *structure = gst_message_get_structure(gm); + qint64 position = g_value_get_int64(gst_structure_get_value(structure, "position")); + position /= 1000000; + m_lastPosition = position; + emit positionChanged(position); + } + break; case GST_MESSAGE_SEGMENT_DONE: + break; + case GST_MESSAGE_DURATION: + { + GstFormat format = GST_FORMAT_TIME; + gint64 duration = 0; + + if (gst_element_query_duration(m_playbin, &format, &duration)) { + int newDuration = duration / 1000000; + if (m_duration != newDuration) { + m_duration = newDuration; + emit durationChanged(m_duration); + } + } + } + break; case GST_MESSAGE_LATENCY: #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 13) case GST_MESSAGE_ASYNC_START: @@ -604,7 +638,7 @@ void QGstreamerPlayerSession::getStreamsInfo() haveAudio = audioStreamsCount > 0; haveVideo = videoStreamsCount > 0; - m_playbin2StreamOffset[QMediaStreamsControl::AudioStream] = 0; + /*m_playbin2StreamOffset[QMediaStreamsControl::AudioStream] = 0; m_playbin2StreamOffset[QMediaStreamsControl::VideoStream] = audioStreamsCount; m_playbin2StreamOffset[QMediaStreamsControl::SubPictureStream] = audioStreamsCount+videoStreamsCount; @@ -648,7 +682,9 @@ void QGstreamerPlayerSession::getStreamsInfo() } m_streamProperties.append(streamProperties); + } + */ #else enum { diff --git a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.h b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.h index d650ec7..edfec5b 100644 --- a/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.h +++ b/src/plugins/mediaservices/gstreamer/mediaplayer/qgstreamerplayersession.h @@ -71,7 +71,6 @@ public: QUrl url() const; QMediaPlayer::State state() const { return m_state; } - QMediaPlayer::MediaStatus mediaStatus() const { return m_mediaStatus; } qint64 duration() const; qint64 position() const; @@ -105,11 +104,11 @@ public: public slots: void load(const QUrl &url); - void play(); - void pause(); + bool play(); + bool pause(); void stop(); - void seek(qint64 pos); + bool seek(qint64 pos); void setVolume(int volume); void setMuted(bool muted); @@ -118,7 +117,6 @@ signals: void durationChanged(qint64 duration); void positionChanged(qint64 position); void stateChanged(QMediaPlayer::State state); - void mediaStatusChanged(QMediaPlayer::MediaStatus mediaStatus); void volumeChanged(int volume); void mutedStateChanged(bool muted); void audioAvailableChanged(bool audioAvailable); @@ -137,11 +135,8 @@ private slots: void setSeekable(bool); private: - void setMediaStatus(QMediaPlayer::MediaStatus); - QUrl m_url; QMediaPlayer::State m_state; - QMediaPlayer::MediaStatus m_mediaStatus; QGstreamerBusHelper* m_busHelper; GstElement* m_playbin; GstElement* m_nullVideoOutput; |