summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gsttools/qgstreamerplayersession.cpp87
-rw-r--r--src/gsttools/qgstreamervideooverlay.cpp47
-rw-r--r--src/gsttools/qgstreamervideorenderer.cpp46
-rw-r--r--src/gsttools/qgstreamervideowidget.cpp5
-rw-r--r--src/gsttools/qgstvideorenderersink.cpp23
-rw-r--r--src/multimedia/gsttools_headers/qgstreamerplayersession_p.h7
-rw-r--r--src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h1
-rw-r--r--src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h3
-rw-r--r--src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h1
-rw-r--r--src/multimedia/gsttools_headers/qgstreamervideowidget_p.h1
-rw-r--r--src/multimedia/gsttools_headers/qgstvideorenderersink_p.h3
11 files changed, 160 insertions, 64 deletions
diff --git a/src/gsttools/qgstreamerplayersession.cpp b/src/gsttools/qgstreamerplayersession.cpp
index 8ee099590..adf27e4a0 100644
--- a/src/gsttools/qgstreamerplayersession.cpp
+++ b/src/gsttools/qgstreamerplayersession.cpp
@@ -114,7 +114,6 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
m_state(QMediaPlayer::StoppedState),
m_pendingState(QMediaPlayer::StoppedState),
m_busHelper(0),
- m_playbin(0),
m_videoSink(0),
#if !GST_CHECK_VERSION(1,0,0)
m_usingColorspaceElement(false),
@@ -241,12 +240,15 @@ QGstreamerPlayerSession::QGstreamerPlayerSession(QObject *parent)
#if QT_CONFIG(gstreamer_app)
g_signal_connect(G_OBJECT(m_playbin), "deep-notify::source", G_CALLBACK(configureAppSrcElement), this);
#endif
+
+ m_pipeline = m_playbin;
+ gst_object_ref(GST_OBJECT(m_pipeline));
}
}
QGstreamerPlayerSession::~QGstreamerPlayerSession()
{
- if (m_playbin) {
+ if (m_pipeline) {
stop();
removeVideoBufferProbe();
@@ -254,7 +256,9 @@ QGstreamerPlayerSession::~QGstreamerPlayerSession()
delete m_busHelper;
gst_object_unref(GST_OBJECT(m_bus));
- gst_object_unref(GST_OBJECT(m_playbin));
+ if (m_playbin)
+ gst_object_unref(GST_OBJECT(m_playbin));
+ gst_object_unref(GST_OBJECT(m_pipeline));
#if !GST_CHECK_VERSION(1,0,0)
gst_object_unref(GST_OBJECT(m_colorSpace));
#endif
@@ -268,6 +272,33 @@ GstElement *QGstreamerPlayerSession::playbin() const
return m_playbin;
}
+void QGstreamerPlayerSession::setPipeline(GstElement *pipeline)
+{
+ GstBus *bus = pipeline ? gst_element_get_bus(pipeline) : nullptr;
+ if (!bus)
+ return;
+
+ gst_object_unref(GST_OBJECT(m_pipeline));
+ m_pipeline = pipeline;
+ gst_object_unref(GST_OBJECT(m_bus));
+ m_bus = bus;
+ delete m_busHelper;
+ m_busHelper = new QGstreamerBusHelper(m_bus, this);
+ m_busHelper->installMessageFilter(this);
+
+ if (m_videoOutput)
+ m_busHelper->installMessageFilter(m_videoOutput);
+
+ 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;
+}
+
#if QT_CONFIG(gstreamer_app)
void QGstreamerPlayerSession::configureAppSrcElement(GObject* object, GObject *orig, GParamSpec *pspec, QGstreamerPlayerSession* self)
{
@@ -357,7 +388,7 @@ qint64 QGstreamerPlayerSession::position() const
{
gint64 position = 0;
- if (m_playbin && qt_gst_element_query_position(m_playbin, GST_FORMAT_TIME, &position))
+ if (m_pipeline && qt_gst_element_query_position(m_pipeline, GST_FORMAT_TIME, &position))
m_lastPosition = position / 1000000;
return m_lastPosition;
}
@@ -374,8 +405,8 @@ void QGstreamerPlayerSession::setPlaybackRate(qreal rate)
#endif
if (!qFuzzyCompare(m_playbackRate, rate)) {
m_playbackRate = rate;
- if (m_playbin && m_seekable) {
- gst_element_seek(m_playbin, rate, GST_FORMAT_TIME,
+ if (m_pipeline && m_seekable) {
+ gst_element_seek(m_pipeline, rate, GST_FORMAT_TIME,
GstSeekFlags(GST_SEEK_FLAG_FLUSH),
GST_SEEK_TYPE_NONE,0,
GST_SEEK_TYPE_NONE,0 );
@@ -396,7 +427,7 @@ QMediaTimeRange QGstreamerPlayerSession::availablePlaybackRanges() const
//with GST_FORMAT_PERCENT media is treated as encoded with constant bitrate.
GstQuery* query = gst_query_new_buffering(GST_FORMAT_PERCENT);
- if (!gst_element_query(m_playbin, query)) {
+ if (!gst_element_query(m_pipeline, query)) {
gst_query_unref(query);
return ranges;
}
@@ -551,6 +582,14 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
m_renderer = renderer;
+ // If custom pipeline is considered to use video sink from the renderer
+ // need to create the pipeline when the renderer is ready.
+ emit rendererChanged();
+
+ // No sense to continue if custom pipeline requested.
+ if (!m_playbin)
+ return;
+
#ifdef DEBUG_VO_BIN_DUMP
gst_debug_bin_to_dot_file_with_ts(GST_BIN(m_playbin),
GstDebugGraphDetails(GST_DEBUG_GRAPH_SHOW_ALL /* GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS | GST_DEBUG_GRAPH_SHOW_STATES*/),
@@ -684,7 +723,7 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
void QGstreamerPlayerSession::finishVideoOutputChange()
{
- if (!m_pendingVideoSink)
+ if (!m_playbin || !m_pendingVideoSink)
return;
#ifdef DEBUG_PLAYBIN
@@ -889,9 +928,9 @@ bool QGstreamerPlayerSession::play()
#endif
m_everPlayed = false;
- if (m_playbin) {
+ if (m_pipeline) {
m_pendingState = QMediaPlayer::PlayingState;
- if (gst_element_set_state(m_playbin, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
+ if (gst_element_set_state(m_pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
qWarning() << "GStreamer; Unable to play -" << m_request.url().toString();
m_pendingState = m_state = QMediaPlayer::StoppedState;
emit stateChanged(m_state);
@@ -909,12 +948,12 @@ bool QGstreamerPlayerSession::pause()
#ifdef DEBUG_PLAYBIN
qDebug() << Q_FUNC_INFO;
#endif
- if (m_playbin) {
+ if (m_pipeline) {
m_pendingState = QMediaPlayer::PausedState;
if (m_pendingVideoSink != 0)
return true;
- if (gst_element_set_state(m_playbin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
+ if (gst_element_set_state(m_pipeline, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
qWarning() << "GStreamer; Unable to pause -" << m_request.url().toString();
m_pendingState = m_state = QMediaPlayer::StoppedState;
emit stateChanged(m_state);
@@ -933,13 +972,13 @@ void QGstreamerPlayerSession::stop()
qDebug() << Q_FUNC_INFO;
#endif
m_everPlayed = false;
- if (m_playbin) {
+ if (m_pipeline) {
if (m_renderer)
m_renderer->stopRenderer();
flushVideoProbes();
- gst_element_set_state(m_playbin, GST_STATE_NULL);
+ gst_element_set_state(m_pipeline, GST_STATE_NULL);
m_lastPosition = 0;
QMediaPlayer::State oldState = m_state;
@@ -960,10 +999,10 @@ bool QGstreamerPlayerSession::seek(qint64 ms)
qDebug() << Q_FUNC_INFO << ms;
#endif
//seek locks when the video output sink is changing and pad is blocked
- if (m_playbin && !m_pendingVideoSink && m_state != QMediaPlayer::StoppedState && m_seekable) {
+ if (m_pipeline && !m_pendingVideoSink && m_state != QMediaPlayer::StoppedState && m_seekable) {
ms = qMax(ms,qint64(0));
gint64 position = ms * 1000000;
- bool isSeeking = gst_element_seek(m_playbin,
+ bool isSeeking = gst_element_seek(m_pipeline,
m_playbackRate,
GST_FORMAT_TIME,
GstSeekFlags(GST_SEEK_FLAG_FLUSH),
@@ -1061,7 +1100,7 @@ bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message
}
bool handlePlaybin2 = false;
- if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) {
+ if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_pipeline)) {
switch (GST_MESSAGE_TYPE(gm)) {
case GST_MESSAGE_STATE_CHANGED:
{
@@ -1217,7 +1256,7 @@ bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message
case GST_MESSAGE_ASYNC_DONE:
{
gint64 position = 0;
- if (qt_gst_element_query_position(m_playbin, GST_FORMAT_TIME, &position)) {
+ if (qt_gst_element_query_position(m_pipeline, GST_FORMAT_TIME, &position)) {
position /= 1000000;
m_lastPosition = position;
emit positionChanged(position);
@@ -1317,6 +1356,9 @@ bool QGstreamerPlayerSession::processBusMessage(const QGstreamerMessage &message
void QGstreamerPlayerSession::getStreamsInfo()
{
+ if (!m_playbin)
+ return;
+
QList< QMap<QString,QVariant> > oldProperties = m_streamProperties;
QList<QMediaStreamsControl::StreamType> oldTypes = m_streamTypes;
QMap<QMediaStreamsControl::StreamType, int> oldOffset = m_playbin2StreamOffset;
@@ -1408,6 +1450,9 @@ void QGstreamerPlayerSession::getStreamsInfo()
void QGstreamerPlayerSession::updateVideoResolutionTag()
{
+ if (!m_videoIdentity)
+ return;
+
#ifdef DEBUG_PLAYBIN
qDebug() << Q_FUNC_INFO;
#endif
@@ -1457,7 +1502,7 @@ void QGstreamerPlayerSession::updateDuration()
gint64 gstDuration = 0;
int duration = -1;
- if (m_playbin && qt_gst_element_query_duration(m_playbin, GST_FORMAT_TIME, &gstDuration))
+ if (m_pipeline && qt_gst_element_query_duration(m_pipeline, GST_FORMAT_TIME, &gstDuration))
duration = gstDuration / 1000000;
if (m_duration != duration) {
@@ -1469,7 +1514,7 @@ void QGstreamerPlayerSession::updateDuration()
if (m_duration > 0) {
m_durationQueries = 0;
GstQuery *query = gst_query_new_seeking(GST_FORMAT_TIME);
- if (gst_element_query(m_playbin, query))
+ if (gst_element_query(m_pipeline, query))
gst_query_parse_seeking(query, 0, &seekable, 0, 0);
gst_query_unref(query);
}
@@ -1802,7 +1847,7 @@ void QGstreamerPlayerSession::endOfMediaReset()
m_renderer->stopRenderer();
flushVideoProbes();
- gst_element_set_state(m_playbin, GST_STATE_NULL);
+ gst_element_set_state(m_pipeline, GST_STATE_NULL);
QMediaPlayer::State oldState = m_state;
m_pendingState = m_state = QMediaPlayer::StoppedState;
diff --git a/src/gsttools/qgstreamervideooverlay.cpp b/src/gsttools/qgstreamervideooverlay.cpp
index de4f255d5..1f3e28549 100644
--- a/src/gsttools/qgstreamervideooverlay.cpp
+++ b/src/gsttools/qgstreamervideooverlay.cpp
@@ -379,27 +379,13 @@ QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent, const QByteArray
: QObject(parent)
, QGstreamerBufferProbe(QGstreamerBufferProbe::ProbeCaps)
{
+ GstElement *sink = nullptr;
if (!elementName.isEmpty())
- m_videoSink = gst_element_factory_make(elementName.constData(), NULL);
+ sink = gst_element_factory_make(elementName.constData(), NULL);
else
- m_videoSink = findBestVideoSink();
+ sink = findBestVideoSink();
- if (m_videoSink) {
- qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership
-
- GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
- addProbeToPad(pad);
- gst_object_unref(GST_OBJECT(pad));
-
- QString sinkName(QLatin1String(GST_OBJECT_NAME(m_videoSink)));
- bool isVaapi = sinkName.startsWith(QLatin1String("vaapisink"));
- m_sinkProperties = isVaapi ? new QVaapiSinkProperties(m_videoSink) : new QXVImageSinkProperties(m_videoSink);
-
- if (m_sinkProperties->hasShowPrerollFrame()) {
- g_signal_connect(m_videoSink, "notify::show-preroll-frame",
- G_CALLBACK(showPrerollFrameChanged), this);
- }
- }
+ setVideoSink(sink);
}
QGstreamerVideoOverlay::~QGstreamerVideoOverlay()
@@ -418,6 +404,31 @@ GstElement *QGstreamerVideoOverlay::videoSink() const
return m_videoSink;
}
+void QGstreamerVideoOverlay::setVideoSink(GstElement *sink)
+{
+ if (!sink)
+ return;
+
+ if (m_videoSink)
+ gst_object_unref(GST_OBJECT(m_videoSink));
+
+ m_videoSink = sink;
+ qt_gst_object_ref_sink(GST_OBJECT(m_videoSink));
+
+ GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink");
+ addProbeToPad(pad);
+ gst_object_unref(GST_OBJECT(pad));
+
+ QString sinkName(QLatin1String(GST_OBJECT_NAME(sink)));
+ bool isVaapi = sinkName.startsWith(QLatin1String("vaapisink"));
+ delete m_sinkProperties;
+ m_sinkProperties = isVaapi ? new QVaapiSinkProperties(sink) : new QXVImageSinkProperties(sink);
+
+ if (m_sinkProperties->hasShowPrerollFrame())
+ g_signal_connect(m_videoSink, "notify::show-preroll-frame",
+ G_CALLBACK(showPrerollFrameChanged), this);
+}
+
QSize QGstreamerVideoOverlay::nativeVideoSize() const
{
return m_nativeVideoSize;
diff --git a/src/gsttools/qgstreamervideorenderer.cpp b/src/gsttools/qgstreamervideorenderer.cpp
index 412257739..1b5cc8caf 100644
--- a/src/gsttools/qgstreamervideorenderer.cpp
+++ b/src/gsttools/qgstreamervideorenderer.cpp
@@ -45,25 +45,44 @@
#include <gst/gst.h>
+static inline void resetSink(GstElement *&element, GstElement *v = nullptr)
+{
+ if (element)
+ gst_object_unref(GST_OBJECT(element));
+
+ if (v)
+ qt_gst_object_ref_sink(GST_OBJECT(v));
+
+ element = v;
+}
+
QGstreamerVideoRenderer::QGstreamerVideoRenderer(QObject *parent)
- :QVideoRendererControl(parent),m_videoSink(0), m_surface(0)
+ : QVideoRendererControl(parent)
{
}
QGstreamerVideoRenderer::~QGstreamerVideoRenderer()
{
- if (m_videoSink)
- gst_object_unref(GST_OBJECT(m_videoSink));
+ resetSink(m_videoSink);
+}
+
+void QGstreamerVideoRenderer::setVideoSink(GstElement *sink)
+{
+ if (!sink)
+ return;
+
+ resetSink(m_videoSink, sink);
+ emit sinkChanged();
}
GstElement *QGstreamerVideoRenderer::videoSink()
{
if (!m_videoSink && m_surface) {
- m_videoSink = QVideoSurfaceGstSink::createSink(m_surface);
- qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership
+ auto sink = reinterpret_cast<GstElement *>(QVideoSurfaceGstSink::createSink(m_surface));
+ resetSink(m_videoSink, sink);
}
- return reinterpret_cast<GstElement*>(m_videoSink);
+ return m_videoSink;
}
void QGstreamerVideoRenderer::stopRenderer()
@@ -80,11 +99,7 @@ QAbstractVideoSurface *QGstreamerVideoRenderer::surface() const
void QGstreamerVideoRenderer::setSurface(QAbstractVideoSurface *surface)
{
if (m_surface != surface) {
- //qDebug() << Q_FUNC_INFO << surface;
- if (m_videoSink)
- gst_object_unref(GST_OBJECT(m_videoSink));
-
- m_videoSink = 0;
+ resetSink(m_videoSink);
if (m_surface) {
disconnect(m_surface.data(), SIGNAL(supportedFormatsChanged()),
@@ -98,6 +113,7 @@ void QGstreamerVideoRenderer::setSurface(QAbstractVideoSurface *surface)
if (m_surface) {
connect(m_surface.data(), SIGNAL(supportedFormatsChanged()),
this, SLOT(handleFormatChange()));
+ QGstVideoRendererSink::setSurface(m_surface);
}
if (wasReady != isReady())
@@ -109,11 +125,5 @@ void QGstreamerVideoRenderer::setSurface(QAbstractVideoSurface *surface)
void QGstreamerVideoRenderer::handleFormatChange()
{
- //qDebug() << "Supported formats list has changed, reload video output";
-
- if (m_videoSink)
- gst_object_unref(GST_OBJECT(m_videoSink));
-
- m_videoSink = 0;
- emit sinkChanged();
+ setVideoSink(nullptr);
}
diff --git a/src/gsttools/qgstreamervideowidget.cpp b/src/gsttools/qgstreamervideowidget.cpp
index 792df4243..633f39fa2 100644
--- a/src/gsttools/qgstreamervideowidget.cpp
+++ b/src/gsttools/qgstreamervideowidget.cpp
@@ -135,6 +135,11 @@ GstElement *QGstreamerVideoWidgetControl::videoSink()
return m_videoOverlay.videoSink();
}
+void QGstreamerVideoWidgetControl::setVideoSink(GstElement *sink)
+{
+ m_videoOverlay.setVideoSink(sink);
+}
+
void QGstreamerVideoWidgetControl::onOverlayActiveChanged()
{
updateWidgetAttributes();
diff --git a/src/gsttools/qgstvideorenderersink.cpp b/src/gsttools/qgstvideorenderersink.cpp
index 4c73c26a3..09fdd42a6 100644
--- a/src/gsttools/qgstvideorenderersink.cpp
+++ b/src/gsttools/qgstvideorenderersink.cpp
@@ -394,21 +394,27 @@ void QVideoSurfaceGstDelegate::updateSupportedFormats()
}
static GstVideoSinkClass *sink_parent_class;
+static QAbstractVideoSurface *current_surface;
#define VO_SINK(s) QGstVideoRendererSink *sink(reinterpret_cast<QGstVideoRendererSink *>(s))
QGstVideoRendererSink *QGstVideoRendererSink::createSink(QAbstractVideoSurface *surface)
{
+ setSurface(surface);
QGstVideoRendererSink *sink = reinterpret_cast<QGstVideoRendererSink *>(
g_object_new(QGstVideoRendererSink::get_type(), 0));
- sink->delegate = new QVideoSurfaceGstDelegate(surface);
-
g_signal_connect(G_OBJECT(sink), "notify::show-preroll-frame", G_CALLBACK(handleShowPrerollChange), sink);
return sink;
}
+void QGstVideoRendererSink::setSurface(QAbstractVideoSurface *surface)
+{
+ current_surface = surface;
+ get_type();
+}
+
GType QGstVideoRendererSink::get_type()
{
static GType type = 0;
@@ -430,6 +436,10 @@ GType QGstVideoRendererSink::get_type()
type = g_type_register_static(
GST_TYPE_VIDEO_SINK, "QGstVideoRendererSink", &info, GTypeFlags(0));
+
+ // Register the sink type to be used in custom piplines.
+ // When surface is ready the sink can be used.
+ gst_element_register(nullptr, "qtvideosink", GST_RANK_PRIMARY, type);
}
return type;
@@ -453,6 +463,11 @@ void QGstVideoRendererSink::class_init(gpointer g_class, gpointer class_data)
GstElementClass *element_class = reinterpret_cast<GstElementClass *>(g_class);
element_class->change_state = QGstVideoRendererSink::change_state;
+ gst_element_class_set_metadata(element_class,
+ "Qt built-in video renderer sink",
+ "Sink/Video",
+ "Qt default built-in video renderer sink",
+ "The Qt Company");
GObjectClass *object_class = reinterpret_cast<GObjectClass *>(g_class);
object_class->finalize = QGstVideoRendererSink::finalize;
@@ -476,8 +491,8 @@ void QGstVideoRendererSink::instance_init(GTypeInstance *instance, gpointer g_cl
VO_SINK(instance);
Q_UNUSED(g_class);
-
- sink->delegate = 0;
+ sink->delegate = new QVideoSurfaceGstDelegate(current_surface);
+ sink->delegate->moveToThread(current_surface->thread());
}
void QGstVideoRendererSink::finalize(GObject *object)
diff --git a/src/multimedia/gsttools_headers/qgstreamerplayersession_p.h b/src/multimedia/gsttools_headers/qgstreamerplayersession_p.h
index 81c385600..447b9816a 100644
--- a/src/multimedia/gsttools_headers/qgstreamerplayersession_p.h
+++ b/src/multimedia/gsttools_headers/qgstreamerplayersession_p.h
@@ -94,6 +94,8 @@ public:
virtual ~QGstreamerPlayerSession();
GstElement *playbin() const;
+ void setPipeline(GstElement *pipeline);
+ GstElement *pipeline() const { return m_pipeline; }
QGstreamerBusHelper *bus() const { return m_busHelper; }
QNetworkRequest request() const;
@@ -110,6 +112,7 @@ public:
bool isAudioAvailable() const;
void setVideoRenderer(QObject *renderer);
+ QGstreamerVideoRendererInterface *renderer() const { return m_renderer; }
bool isVideoAvailable() const;
bool isSeekable() const;
@@ -174,6 +177,7 @@ signals:
void error(int error, const QString &errorString);
void invalidMedia();
void playbackRateChanged(qreal);
+ void rendererChanged();
private slots:
void getStreamsInfo();
@@ -209,7 +213,8 @@ private:
QMediaPlayer::State m_state;
QMediaPlayer::State m_pendingState;
QGstreamerBusHelper* m_busHelper;
- GstElement* m_playbin;
+ GstElement *m_playbin = nullptr; // Can be null
+ GstElement *m_pipeline = nullptr; // Never null
GstElement* m_videoSink;
diff --git a/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h b/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h
index 4228f0fd0..f2ca8a23b 100644
--- a/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h
+++ b/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h
@@ -72,6 +72,7 @@ public:
virtual ~QGstreamerVideoOverlay();
GstElement *videoSink() const;
+ void setVideoSink(GstElement *);
QSize nativeVideoSize() const;
void setWindowHandle(WId id);
diff --git a/src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h b/src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h
index 2f0b80d45..d87bfcb8f 100644
--- a/src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h
+++ b/src/multimedia/gsttools_headers/qgstreamervideorenderer_p.h
@@ -72,6 +72,7 @@ public:
void setSurface(QAbstractVideoSurface *surface) override;
GstElement *videoSink() override;
+ void setVideoSink(GstElement *) override;
void stopRenderer() override;
bool isReady() const override { return m_surface != 0; }
@@ -84,7 +85,7 @@ private slots:
void handleFormatChange();
private:
- QVideoSurfaceGstSink *m_videoSink;
+ GstElement *m_videoSink = nullptr;
QPointer<QAbstractVideoSurface> m_surface;
};
diff --git a/src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h b/src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h
index 0d172167b..231c843db 100644
--- a/src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h
+++ b/src/multimedia/gsttools_headers/qgstreamervideorendererinterface_p.h
@@ -62,6 +62,7 @@ class QGstreamerVideoRendererInterface
public:
virtual ~QGstreamerVideoRendererInterface();
virtual GstElement *videoSink() = 0;
+ virtual void setVideoSink(GstElement *) {};
//stopRenderer() is called when the renderer element is stopped.
//it can be reimplemented when video renderer can't detect
diff --git a/src/multimedia/gsttools_headers/qgstreamervideowidget_p.h b/src/multimedia/gsttools_headers/qgstreamervideowidget_p.h
index 3e3240725..1ddb738df 100644
--- a/src/multimedia/gsttools_headers/qgstreamervideowidget_p.h
+++ b/src/multimedia/gsttools_headers/qgstreamervideowidget_p.h
@@ -75,6 +75,7 @@ public:
virtual ~QGstreamerVideoWidgetControl();
GstElement *videoSink() override;
+ void setVideoSink(GstElement *) override;
QWidget *videoWidget() override;
diff --git a/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h b/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
index 3971c959d..d2417a7c9 100644
--- a/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
+++ b/src/multimedia/gsttools_headers/qgstvideorenderersink_p.h
@@ -138,12 +138,13 @@ private:
bool m_flush;
};
-class QGstVideoRendererSink
+class Q_GSTTOOLS_EXPORT QGstVideoRendererSink
{
public:
GstVideoSink parent;
static QGstVideoRendererSink *createSink(QAbstractVideoSurface *surface);
+ static void setSurface(QAbstractVideoSurface *surface);
private:
static GType get_type();