summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-02 03:01:36 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-02 03:01:37 +0100
commit8ca9765dabfd27d7c511e21e6862b24e46c2bf40 (patch)
tree58656a3b756c8f0581a9ca3161052b007f7096da /src
parentc877776c354a625373e1dc0f38ac4918da9a056f (diff)
parentdee506f70536dd10f3e00c42f685ead9283433b9 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'src')
-rw-r--r--src/gsttools/qgstreamerplayersession.cpp88
-rw-r--r--src/gsttools/qgstreamerplayersession_p.h3
-rw-r--r--src/plugins/android/src/common/qandroidvideooutput.cpp21
-rw-r--r--src/plugins/android/src/common/qandroidvideooutput.h4
-rw-r--r--src/qtmultimediaquicktools/qsgvideonode_yuv.cpp4
-rw-r--r--src/qtmultimediaquicktools/shaders/uyvyvideo.frag1
-rw-r--r--src/qtmultimediaquicktools/shaders/uyvyvideo_core.frag3
-rw-r--r--src/qtmultimediaquicktools/shaders/yuyvvideo.frag3
-rw-r--r--src/qtmultimediaquicktools/shaders/yuyvvideo_core.frag3
9 files changed, 86 insertions, 44 deletions
diff --git a/src/gsttools/qgstreamerplayersession.cpp b/src/gsttools/qgstreamerplayersession.cpp
index 485556275..bd402fb3c 100644
--- a/src/gsttools/qgstreamerplayersession.cpp
+++ b/src/gsttools/qgstreamerplayersession.cpp
@@ -272,33 +272,6 @@ 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)
{
@@ -364,6 +337,22 @@ void QGstreamerPlayerSession::loadFromUri(const QNetworkRequest &request)
}
#endif
+ if (m_request.url().scheme() == QLatin1String("gst-pipeline")) {
+ QString url = m_request.url().toString(QUrl::RemoveScheme);
+ QString pipeline = QUrl::fromPercentEncoding(url.toLatin1().constData());
+ GError *err = nullptr;
+ GstElement *element = gst_parse_launch(pipeline.toLatin1().constData(), &err);
+ if (err) {
+ auto errstr = QLatin1String(err->message);
+ qWarning() << "Error:" << pipeline << ":" << errstr;
+ emit error(QMediaPlayer::FormatError, errstr);
+ g_clear_error(&err);
+ }
+
+ setPipeline(element);
+ return;
+ }
+
if (m_playbin) {
m_tags.clear();
emit tagsChanged();
@@ -379,6 +368,48 @@ void QGstreamerPlayerSession::loadFromUri(const QNetworkRequest &request)
}
}
+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 (m_renderer) {
+ auto it = gst_bin_iterate_sinks(GST_BIN(pipeline));
+ GValue data = { 0, 0 };
+ while (gst_iterator_next (it, &data) == GST_ITERATOR_OK) {
+ auto child = static_cast<GstElement*>(g_value_get_object(&data));
+ if (QLatin1String(GST_OBJECT_NAME(child)) == QLatin1String("qtvideosink")) {
+ m_renderer->setVideoSink(child);
+ break;
+ }
+ }
+ gst_iterator_free(it);
+ }
+
+ emit pipelineChanged();
+}
+
qint64 QGstreamerPlayerSession::duration() const
{
return m_duration;
@@ -581,9 +612,6 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput)
QGstreamerVideoRendererInterface* renderer = qobject_cast<QGstreamerVideoRendererInterface*>(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.
diff --git a/src/gsttools/qgstreamerplayersession_p.h b/src/gsttools/qgstreamerplayersession_p.h
index 447b9816a..b613793c4 100644
--- a/src/gsttools/qgstreamerplayersession_p.h
+++ b/src/gsttools/qgstreamerplayersession_p.h
@@ -94,7 +94,6 @@ public:
virtual ~QGstreamerPlayerSession();
GstElement *playbin() const;
- void setPipeline(GstElement *pipeline);
GstElement *pipeline() const { return m_pipeline; }
QGstreamerBusHelper *bus() const { return m_busHelper; }
@@ -178,6 +177,7 @@ signals:
void invalidMedia();
void playbackRateChanged(qreal);
void rendererChanged();
+ void pipelineChanged();
private slots:
void getStreamsInfo();
@@ -208,6 +208,7 @@ private:
void addAudioBufferProbe();
void flushVideoProbes();
void resumeVideoProbes();
+ void setPipeline(GstElement *pipeline);
QNetworkRequest m_request;
QMediaPlayer::State m_state;
diff --git a/src/plugins/android/src/common/qandroidvideooutput.cpp b/src/plugins/android/src/common/qandroidvideooutput.cpp
index eeaf70982..083ceff24 100644
--- a/src/plugins/android/src/common/qandroidvideooutput.cpp
+++ b/src/plugins/android/src/common/qandroidvideooutput.cpp
@@ -82,6 +82,10 @@ void OpenGLResourcesDeleter::deleteShaderProgramHelper(void *prog)
delete reinterpret_cast<QOpenGLShaderProgram *>(prog);
}
+void OpenGLResourcesDeleter::deleteThisHelper()
+{
+ delete this;
+}
class AndroidTextureVideoBuffer : public QAbstractVideoBuffer
{
@@ -170,6 +174,7 @@ QAndroidTextureVideoOutput::QAndroidTextureVideoOutput(QObject *parent)
, m_externalTex(0)
, m_fbo(0)
, m_program(0)
+ , m_glDeleter(0)
, m_surfaceTextureCanAttachToContext(QtAndroidPrivate::androidSdkVersion() >= 16)
{
@@ -179,11 +184,11 @@ QAndroidTextureVideoOutput::~QAndroidTextureVideoOutput()
{
clearSurfaceTexture();
- if (!m_glDeleter.isNull()) { // Make sure all of these are deleted on the render thread.
+ if (m_glDeleter) { // Make sure all of these are deleted on the render thread.
m_glDeleter->deleteFbo(m_fbo);
m_glDeleter->deleteShaderProgram(m_program);
m_glDeleter->deleteTexture(m_externalTex);
- m_glDeleter->deleteLater();
+ m_glDeleter->deleteThis();
}
}
@@ -231,7 +236,8 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture()
// for the GL render thread to call us back to do it.
if (QOpenGLContext::currentContext()) {
glGenTextures(1, &m_externalTex);
- m_glDeleter.reset(new OpenGLResourcesDeleter);
+ if (!m_glDeleter)
+ m_glDeleter = new OpenGLResourcesDeleter;
} else if (!m_externalTex) {
return false;
}
@@ -246,7 +252,7 @@ bool QAndroidTextureVideoOutput::initSurfaceTexture()
} else {
delete m_surfaceTexture;
m_surfaceTexture = 0;
- if (!m_glDeleter.isNull())
+ if (m_glDeleter)
m_glDeleter->deleteTexture(m_externalTex);
m_externalTex = 0;
}
@@ -267,7 +273,7 @@ void QAndroidTextureVideoOutput::clearSurfaceTexture()
// only if detachFromGLContext() called (API level >= 16), so we'll do it manually,
// on the render thread.
if (m_surfaceTextureCanAttachToContext) {
- if (!m_glDeleter.isNull())
+ if (m_glDeleter)
m_glDeleter->deleteTexture(m_externalTex);
m_externalTex = 0;
}
@@ -401,7 +407,7 @@ void QAndroidTextureVideoOutput::createGLResources()
Q_ASSERT(QOpenGLContext::currentContext() != NULL);
if (!m_glDeleter)
- m_glDeleter.reset(new OpenGLResourcesDeleter);
+ m_glDeleter = new OpenGLResourcesDeleter;
if (m_surfaceTextureCanAttachToContext && !m_externalTex) {
m_surfaceTexture->detachFromGLContext();
@@ -451,7 +457,8 @@ void QAndroidTextureVideoOutput::customEvent(QEvent *e)
// This is running in the render thread (OpenGL enabled)
if (!m_surfaceTextureCanAttachToContext && !m_externalTex) {
glGenTextures(1, &m_externalTex);
- m_glDeleter.reset(new OpenGLResourcesDeleter); // We'll use this to cleanup GL resources in the correct thread
+ if (!m_glDeleter) // We'll use this to cleanup GL resources in the correct thread
+ m_glDeleter = new OpenGLResourcesDeleter;
emit readyChanged(true);
}
}
diff --git a/src/plugins/android/src/common/qandroidvideooutput.h b/src/plugins/android/src/common/qandroidvideooutput.h
index 62a936881..2a35247e9 100644
--- a/src/plugins/android/src/common/qandroidvideooutput.h
+++ b/src/plugins/android/src/common/qandroidvideooutput.h
@@ -81,11 +81,13 @@ public:
void deleteTexture(quint32 id) { QMetaObject::invokeMethod(this, "deleteTextureHelper", Qt::AutoConnection, Q_ARG(quint32, id)); }
void deleteFbo(QOpenGLFramebufferObject *fbo) { QMetaObject::invokeMethod(this, "deleteFboHelper", Qt::AutoConnection, Q_ARG(void *, fbo)); }
void deleteShaderProgram(QOpenGLShaderProgram *prog) { QMetaObject::invokeMethod(this, "deleteShaderProgramHelper", Qt::AutoConnection, Q_ARG(void *, prog)); }
+ void deleteThis() { QMetaObject::invokeMethod(this, "deleteThisHelper"); }
private:
Q_INVOKABLE void deleteTextureHelper(quint32 id);
Q_INVOKABLE void deleteFboHelper(void *fbo);
Q_INVOKABLE void deleteShaderProgramHelper(void *prog);
+ Q_INVOKABLE void deleteThisHelper();
};
class QAndroidTextureVideoOutput : public QAndroidVideoOutput
@@ -126,7 +128,7 @@ private:
quint32 m_externalTex;
QOpenGLFramebufferObject *m_fbo;
QOpenGLShaderProgram *m_program;
- QScopedPointer<OpenGLResourcesDeleter, QScopedPointerDeleteLater> m_glDeleter;
+ OpenGLResourcesDeleter *m_glDeleter;
bool m_surfaceTextureCanAttachToContext;
diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
index 43cd5a2b2..8e4ea01a1 100644
--- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
+++ b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp
@@ -388,8 +388,8 @@ void QSGVideoMaterial_YUV::bind()
// In YUYV texture the UV plane appears with the 1/2 of image and Y width.
m_planeWidth[1] = fw / 2;
functions->glActiveTexture(GL_TEXTURE1);
- // Either r,b (YUYV) or g,a (UYVY) values are used as source of YV.
- // Additionally Y and V are set per 2 pixels hence only 1/2 of image with is used.
+ // Either r,b (YUYV) or g,a (UYVY) values are used as source of UV.
+ // Additionally U and V are set per 2 pixels hence only 1/2 of image width is used.
// Interpreting this properly in shaders allows to not copy or not make conditionals inside shaders,
// only interpretation of data changes.
bindTexture(m_textureIds[1], m_planeWidth[1], m_frame.height(), m_frame.bits(), GL_RGBA);
diff --git a/src/qtmultimediaquicktools/shaders/uyvyvideo.frag b/src/qtmultimediaquicktools/shaders/uyvyvideo.frag
index 5c62441c2..244464e73 100644
--- a/src/qtmultimediaquicktools/shaders/uyvyvideo.frag
+++ b/src/qtmultimediaquicktools/shaders/uyvyvideo.frag
@@ -1,3 +1,4 @@
+// Reference: qgsvideonode_yuv.cpp:387 to 398
uniform sampler2D yTexture; // Y component passed as GL_LUMINANCE_ALPHA, in uyvy Y = a
uniform sampler2D uvTexture; // UV component passed as RGBA macropixel, in uyvy U = r, V = b
uniform mediump mat4 colorMatrix;
diff --git a/src/qtmultimediaquicktools/shaders/uyvyvideo_core.frag b/src/qtmultimediaquicktools/shaders/uyvyvideo_core.frag
index 75c7de5a6..b151a7c7f 100644
--- a/src/qtmultimediaquicktools/shaders/uyvyvideo_core.frag
+++ b/src/qtmultimediaquicktools/shaders/uyvyvideo_core.frag
@@ -1,5 +1,6 @@
#version 150 core
-uniform sampler2D yTexture; // Y component passed as GL_LUMINANCE_ALPHA, in uyvy Y = a
+// Reference: qgsvideonode_yuv.cpp:387 to 398
+uniform sampler2D yTexture; // Y component passed as GL_RG, in uyvy Y = a
uniform sampler2D uvTexture; // UV component passed as RGBA macropixel, in uyvy U = r, V = b
uniform mat4 colorMatrix;
uniform float opacity;
diff --git a/src/qtmultimediaquicktools/shaders/yuyvvideo.frag b/src/qtmultimediaquicktools/shaders/yuyvvideo.frag
index 5ce8b7366..c2ad65b78 100644
--- a/src/qtmultimediaquicktools/shaders/yuyvvideo.frag
+++ b/src/qtmultimediaquicktools/shaders/yuyvvideo.frag
@@ -1,5 +1,6 @@
+// Reference: qgsvideonode_yuv.cpp:387 to 398
uniform sampler2D yTexture; // Y component passed as GL_LUMINANCE_ALPHA, in yuyv Y = r
-uniform sampler2D uvTexture; // UV component passed as RGBA macropixel, in uyvy U = g, V = a
+uniform sampler2D uvTexture; // UV component passed as RGBA macropixel, in yuyv U = g, V = a
uniform mediump mat4 colorMatrix;
uniform lowp float opacity;
varying highp vec2 qt_TexCoord;
diff --git a/src/qtmultimediaquicktools/shaders/yuyvvideo_core.frag b/src/qtmultimediaquicktools/shaders/yuyvvideo_core.frag
index 010c4a5f2..a30d7818a 100644
--- a/src/qtmultimediaquicktools/shaders/yuyvvideo_core.frag
+++ b/src/qtmultimediaquicktools/shaders/yuyvvideo_core.frag
@@ -1,5 +1,6 @@
#version 150 core
-uniform sampler2D yTexture; // Y component passed as GL_LUMINANCE_ALPHA, in yuyv Y = r
+// Reference: qgsvideonode_yuv.cpp:387 to 398
+uniform sampler2D yTexture; // Y component passed as GL_RG, in yuyv Y = r
uniform sampler2D uvTexture; // UV component passed as RGBA macropixel, in uyvy U = g, V = a
uniform mat4 colorMatrix;
uniform float opacity;