summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVaL Doroshchuk <valentyn.doroshchuk@qt.io>2019-09-10 11:37:39 +0200
committerChristian Strømme <christian.stromme@qt.io>2019-10-01 08:12:01 +0000
commit9eef3390241f8c6e25c5ccc7b1baa25058146927 (patch)
tree323147313ce309856c4b2075a2057ca2dfae8546
parent163846dba1ef9171699b5203cf9bfbb91a609df0 (diff)
downloadqtmultimedia-9eef3390241f8c6e25c5ccc7b1baa25058146927.tar.gz
GStreamer: Recreate playbin after custom pipeline
Currently if custom pipeline is set, old playbin elements are destroyed. And if normal url is passed again after the custom pipeline, it is unable to play. Because no playbin elements exist anymore. Adding a fix to recreate playbin elements if "not a pipeline url" is passed. Fixes: QTBUG-78079 Change-Id: I8b3498c4660639f5d757b322a136846ee82fdc28 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
-rw-r--r--src/gsttools/qgstreamerplayersession.cpp90
-rw-r--r--src/gsttools/qgstreamerplayersession_p.h3
2 files changed, 64 insertions, 29 deletions
diff --git a/src/gsttools/qgstreamerplayersession.cpp b/src/gsttools/qgstreamerplayersession.cpp
index 1a74de574..c0998d7ae 100644
--- a/src/gsttools/qgstreamerplayersession.cpp
+++ b/src/gsttools/qgstreamerplayersession.cpp
@@ -113,6 +113,11 @@ static GstStaticCaps static_RawCaps = GST_STATIC_CAPS(DEFAULT_RAW_CAPS);
QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
: QObject(parent)
{
+ initPlaybin();
+}
+
+void QGstreamerPlayerSession::initPlaybin()
+{
m_playbin = gst_element_factory_make(QT_GSTREAMER_PLAYBIN_ELEMENT_NAME, NULL);
if (m_playbin) {
//GST_PLAY_FLAG_NATIVE_VIDEO omits configuration of ffmpegcolorspace and videoscale,
@@ -186,9 +191,7 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
if (m_playbin != 0) {
// Sort out messages
- m_bus = gst_element_get_bus(m_playbin);
- m_busHelper = new QGstreamerBusHelper(m_bus, this);
- m_busHelper->installMessageFilter(this);
+ setBus(gst_element_get_bus(m_playbin));
g_object_set(G_OBJECT(m_playbin), "video-sink", m_videoOutputBin, NULL);
@@ -224,16 +227,33 @@ QGstreamerPlayerSession::~QGstreamerPlayerSession()
removeAudioBufferProbe();
delete m_busHelper;
- gst_object_unref(GST_OBJECT(m_bus));
- if (m_playbin)
- gst_object_unref(GST_OBJECT(m_playbin));
- gst_object_unref(GST_OBJECT(m_pipeline));
+ m_busHelper = nullptr;
+ resetElements();
+ }
+}
+
+template <class T>
+static inline void resetGstObject(T *&obj, T *v = nullptr)
+{
+ if (obj)
+ gst_object_unref(GST_OBJECT(obj));
+
+ obj = v;
+}
+
+void QGstreamerPlayerSession::resetElements()
+{
+ setBus(nullptr);
+ resetGstObject(m_playbin);
+ resetGstObject(m_pipeline);
#if !GST_CHECK_VERSION(1,0,0)
- gst_object_unref(GST_OBJECT(m_colorSpace));
+ resetGstObject(m_colorSpace);
#endif
- gst_object_unref(GST_OBJECT(m_nullVideoSink));
- gst_object_unref(GST_OBJECT(m_videoOutputBin));
- }
+ resetGstObject(m_nullVideoSink);
+ resetGstObject(m_videoOutputBin);
+
+ m_volumeElement = nullptr;
+ m_videoIdentity = nullptr;
}
GstElement *QGstreamerPlayerSession::playbin() const
@@ -323,8 +343,14 @@ void QGstreamerPlayerSession::loadFromUri(const QNetworkRequest &request)
bool QGstreamerPlayerSession::parsePipeline()
{
- if (m_request.url().scheme() != QLatin1String("gst-pipeline"))
+ if (m_request.url().scheme() != QLatin1String("gst-pipeline")) {
+ if (!m_playbin) {
+ resetElements();
+ initPlaybin();
+ updateVideoRenderer();
+ }
return false;
+ }
// Set current surface to video sink before creating a pipeline.
auto renderer = qobject_cast<QVideoRendererControl *>(m_videoOutput);
@@ -371,25 +397,12 @@ bool QGstreamerPlayerSession::setPipeline(GstElement *pipeline)
if (!bus)
return false;
- gst_object_unref(GST_OBJECT(m_pipeline));
- m_pipeline = pipeline;
- gst_object_unref(GST_OBJECT(m_bus));
- m_bus = bus;
- m_busHelper->deleteLater();
- m_busHelper = new QGstreamerBusHelper(m_bus, this);
- m_busHelper->installMessageFilter(this);
-
- if (m_videoOutput)
- m_busHelper->installMessageFilter(m_videoOutput);
-
- if (m_playbin) {
+ if (m_playbin)
gst_element_set_state(m_playbin, GST_STATE_NULL);
- gst_object_unref(GST_OBJECT(m_playbin));
- }
- m_playbin = nullptr;
- m_volumeElement = nullptr;
- m_videoIdentity = nullptr;
+ resetElements();
+ setBus(bus);
+ m_pipeline = pipeline;
if (m_renderer) {
gst_foreach(gst_bin_iterate_sinks(GST_BIN(pipeline)),
@@ -419,6 +432,25 @@ bool QGstreamerPlayerSession::setPipeline(GstElement *pipeline)
return true;
}
+void QGstreamerPlayerSession::setBus(GstBus *bus)
+{
+ resetGstObject(m_bus, bus);
+
+ // It might still accept gst messages.
+ if (m_busHelper)
+ m_busHelper->deleteLater();
+ m_busHelper = nullptr;
+
+ if (!m_bus)
+ return;
+
+ m_busHelper = new QGstreamerBusHelper(m_bus, this);
+ m_busHelper->installMessageFilter(this);
+
+ if (m_videoOutput)
+ m_busHelper->installMessageFilter(m_videoOutput);
+}
+
qint64 QGstreamerPlayerSession::duration() const
{
return m_duration;
diff --git a/src/gsttools/qgstreamerplayersession_p.h b/src/gsttools/qgstreamerplayersession_p.h
index 69027eeb2..797229e69 100644
--- a/src/gsttools/qgstreamerplayersession_p.h
+++ b/src/gsttools/qgstreamerplayersession_p.h
@@ -210,6 +210,9 @@ private:
void resumeVideoProbes();
bool parsePipeline();
bool setPipeline(GstElement *pipeline);
+ void resetElements();
+ void initPlaybin();
+ void setBus(GstBus *bus);
QNetworkRequest m_request;
QMediaPlayer::State m_state = QMediaPlayer::StoppedState;