From 8351c569af51562d8b5e1d0de0b35c42e95b79b5 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Fri, 6 Sep 2019 12:11:36 +0200 Subject: Fix leaking QVideoFilterRunnable when window is closed When QDeclarativeVideoOutput::releaseResources() is called, means the window is going to be destroyed and it is too late to use scheduleRenderJob() to clear filters. This beforeSynchronizingJobs will not be handled in this case. Which produces a leak of filter's runnable. Fixes: QTBUG-51588 Change-Id: I71ec351463a2c4136d8b7e241d61e628a1b0c64b Reviewed-by: Timur Pocheptsov --- src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp index 40568d118..863cefa4e 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp @@ -163,8 +163,7 @@ void QDeclarativeVideoRendererBackend::scheduleDeleteFilterResources() void QDeclarativeVideoRendererBackend::releaseResources() { // Called on the gui thread when the window is closed or changed. - QMutexLocker lock(&m_frameMutex); - scheduleDeleteFilterResources(); + invalidateSceneGraph(); } void QDeclarativeVideoRendererBackend::invalidateSceneGraph() -- cgit v1.2.3 From 494eafa612a88ca8edd8dfc128408ea651fa2a1e Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Wed, 11 Sep 2019 15:39:00 +0200 Subject: DirectShow: Fix tst_QMediaPlayerBackend::seekPauseSeek Fixed tests about start times. Since DirectShow can provide frames with negative start time, also from the beginning, also pixels can vary, e.g. (rgb) 255:0:0 would be 230:19:19 after decoding. Task-number: QTBUG-46368 Change-Id: I025f7cf9238ddf9ba2a04f63e3e54b77f3cceafe Reviewed-by: Ville Voutilainen --- .../qmediaplayerbackend/tst_qmediaplayerbackend.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp index 9d29025c8..df218be7f 100644 --- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp +++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp @@ -791,16 +791,18 @@ void tst_QMediaPlayerBackend::seekPauseSeek() player.pause(); QTRY_COMPARE(player.state(), QMediaPlayer::PausedState); // it might take some time for the operation to be completed - QTRY_VERIFY(!surface->m_frameList.isEmpty()); // we must see a frame at position 7000 here + QTRY_VERIFY_WITH_TIMEOUT(!surface->m_frameList.isEmpty(), 10000); // we must see a frame at position 7000 here // Make sure that the frame has a timestamp before testing - not all backends provides this - if (surface->m_frameList.back().startTime() < 0) + if (!surface->m_frameList.back().isValid() || surface->m_frameList.back().startTime() < 0) QSKIP("No timestamp"); { QVideoFrame frame = surface->m_frameList.back(); +#if !QT_CONFIG(directshow) const qint64 elapsed = (frame.startTime() / 1000) - position; // frame.startTime() is microsecond, position is milliseconds. QVERIFY2(qAbs(elapsed) < (qint64)500, QByteArray::number(elapsed).constData()); +#endif QCOMPARE(frame.width(), 160); QCOMPARE(frame.height(), 120); @@ -808,9 +810,9 @@ void tst_QMediaPlayerBackend::seekPauseSeek() QVERIFY(frame.map(QAbstractVideoBuffer::ReadOnly)); QImage image(frame.bits(), frame.width(), frame.height(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); QVERIFY(!image.isNull()); - QVERIFY(qRed(image.pixel(0, 0)) >= 240); // conversion from YUV => RGB, that's why it's not 255 - QCOMPARE(qGreen(image.pixel(0, 0)), 0); - QCOMPARE(qBlue(image.pixel(0, 0)), 0); + QVERIFY(qRed(image.pixel(0, 0)) >= 230); // conversion from YUV => RGB, that's why it's not 255 + QVERIFY(qGreen(image.pixel(0, 0)) < 20); + QVERIFY(qBlue(image.pixel(0, 0)) < 20); frame.unmap(); } @@ -824,17 +826,19 @@ void tst_QMediaPlayerBackend::seekPauseSeek() { QVideoFrame frame = surface->m_frameList.back(); +#if !QT_CONFIG(directshow) const qint64 elapsed = (frame.startTime() / 1000) - position; QVERIFY2(qAbs(elapsed) < (qint64)500, QByteArray::number(elapsed).constData()); +#endif QCOMPARE(frame.width(), 160); QCOMPARE(frame.height(), 120); QVERIFY(frame.map(QAbstractVideoBuffer::ReadOnly)); QImage image(frame.bits(), frame.width(), frame.height(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat())); QVERIFY(!image.isNull()); - QCOMPARE(qRed(image.pixel(0, 0)), 0); - QVERIFY(qGreen(image.pixel(0, 0)) >= 240); - QCOMPARE(qBlue(image.pixel(0, 0)), 0); + QVERIFY(qRed(image.pixel(0, 0)) < 20); + QVERIFY(qGreen(image.pixel(0, 0)) >= 230); + QVERIFY(qBlue(image.pixel(0, 0)) < 20); frame.unmap(); } } -- cgit v1.2.3 From 163846dba1ef9171699b5203cf9bfbb91a609df0 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Fri, 13 Sep 2019 13:18:57 +0200 Subject: DirectShow: Emit media status before error Media status should be emitted before any error. Since error can cause changing the media and changing to new media status. Fixes BFAIL : tst_QMediaPlayerBackend::playlistObject() Compared values are not the same Actual (mediaStatusSpy.count()): 4 Expected (6) : 6 Task-number: QTBUG-46368 Change-Id: I8eb82e7a551d78abd143baa594cfda9bacd7e544 Reviewed-by: Ville Voutilainen --- src/plugins/directshow/player/directshowplayercontrol.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/directshow/player/directshowplayercontrol.cpp b/src/plugins/directshow/player/directshowplayercontrol.cpp index 7de0a686f..14f272f17 100644 --- a/src/plugins/directshow/player/directshowplayercontrol.cpp +++ b/src/plugins/directshow/player/directshowplayercontrol.cpp @@ -293,6 +293,9 @@ void DirectShowPlayerControl::emitPropertyChanges() int properties = m_updateProperties; m_updateProperties = 0; + if (properties & StatusProperty) + emit mediaStatusChanged(m_status); + if ((properties & ErrorProperty) && m_error != QMediaPlayer::NoError) emit error(m_error, m_errorString); @@ -313,9 +316,6 @@ void DirectShowPlayerControl::emitPropertyChanges() if (properties & SeekableProperty) emit seekableChanged(m_seekable); - if (properties & StatusProperty) - emit mediaStatusChanged(m_status); - if (properties & StateProperty) emit stateChanged(m_state); } -- cgit v1.2.3 From 9eef3390241f8c6e25c5ccc7b1baa25058146927 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Tue, 10 Sep 2019 11:37:39 +0200 Subject: GStreamer: Recreate playbin after custom pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/gsttools/qgstreamerplayersession.cpp | 90 ++++++++++++++++++++++---------- src/gsttools/qgstreamerplayersession_p.h | 3 ++ 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 @@ -112,6 +112,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) { @@ -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 +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(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; -- cgit v1.2.3 From 7aa08ffafd5ac69bca02038aae80ea014f444174 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Fri, 6 Sep 2019 16:14:46 +0200 Subject: DirectShow: Don't seek if playback is stopped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the playback is already stopped, and after that new position is requested twice, e.g. stop(); setPosition(0); setPosition(0); this causes the playback to start. Need to postpone setting of new position until play is requested. Also no need to emit positionChanged when position is not changed. Fixes: QTBUG-68778 Change-Id: Ib62942ee155d9c8ed2310132dcc6b501dfef1a04 Reviewed-by: Christian Strømme --- src/plugins/directshow/player/directshowplayercontrol.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/directshow/player/directshowplayercontrol.cpp b/src/plugins/directshow/player/directshowplayercontrol.cpp index 14f272f17..87bd53bc4 100644 --- a/src/plugins/directshow/player/directshowplayercontrol.cpp +++ b/src/plugins/directshow/player/directshowplayercontrol.cpp @@ -102,9 +102,11 @@ void DirectShowPlayerControl::setPosition(qint64 position) emit mediaStatusChanged(m_status); } - if (m_state == QMediaPlayer::StoppedState && m_pendingPosition != position) { - m_pendingPosition = position; - emit positionChanged(m_pendingPosition); + if (m_state == QMediaPlayer::StoppedState) { + if (m_pendingPosition != position) { + m_pendingPosition = position; + emit positionChanged(m_pendingPosition); + } return; } -- cgit v1.2.3 From 182b4b56011b70fa9afdedf53d3c25f73028c335 Mon Sep 17 00:00:00 2001 From: Ratchanan Srirattanamet Date: Fri, 27 Sep 2019 23:31:57 +0700 Subject: Gstreamer: also remove features when simplifying caps Some element can return caps with same resolution/framerate but different features. gst_simplify_caps() won't de-duplicate this, resulting in duplicated entries for the same resolution/framerate. This commit add calls to also remove features from the caps in addition to setting name to video/x-raw. The GST_CHECK_VERSION macro is added to maintain compatibility with earlier version of Gstreamer without GstCapsFeatures. [ChangeLog][CameraBin] Fixed duplicated entries in supported resolution/ framerate if the underlying element uses caps' features. Change-Id: I15101899eb0369925013ccc1d925afb890a01205 Reviewed-by: VaL Doroshchuk --- src/plugins/gstreamer/camerabin/camerabinsession.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index b96ba6792..3e505a413 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -1312,6 +1312,9 @@ QList< QPair > CameraBinSession::supportedFrameRates(const QSize &frame for (uint i=0; i CameraBinSession::supportedResolutions(QPair rate, for (uint i=0; i Date: Tue, 17 Sep 2019 16:00:55 +0200 Subject: Override QGraphicsItem::type in QGraphicsVideoItem Fixes: QTBUG-45064 Change-Id: I6b4a7a4b92affe80fc288e08d514092ac3d6899a Reviewed-by: Ville Voutilainen --- src/multimediawidgets/qgraphicsvideoitem.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/multimediawidgets/qgraphicsvideoitem.h b/src/multimediawidgets/qgraphicsvideoitem.h index 3902389d9..5aa3bd75c 100644 --- a/src/multimediawidgets/qgraphicsvideoitem.h +++ b/src/multimediawidgets/qgraphicsvideoitem.h @@ -81,6 +81,15 @@ public: void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + enum { Type = 14 }; + int type() const override + { + // Enable the use of qgraphicsitem_cast with this item. + return Type; + } +#endif + Q_SIGNALS: void nativeSizeChanged(const QSizeF &size); -- cgit v1.2.3 From c7bd3131a8854814d59881339ac1d7a4af3c9863 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Wed, 11 Sep 2019 11:09:52 +0200 Subject: imx6: Fix mapping VPU texture using real physical address of data * Get real physical address of video frame data and provide it to imx6 vivante videonode to prevent memory leak from kernel. By default qtmultimedia does not depend on gstreamer-imx, but the plugin should exist on imx platform. So gstreamer_imxcommon will be disabled. And should be manually enabled in yocto receipt. Change-Id: I6e75746a2ba651d12bdd7697ae483699aad450fc Fixes: QTBUG-73084 Reviewed-by: Ville Voutilainen --- src/multimedia/configure.json | 17 +++++++++++++++++ src/plugins/videonode/imx6/imx6.pro | 6 ++++++ src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp | 12 +++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/multimedia/configure.json b/src/multimedia/configure.json index 6d56af5ed..2db8ce55c 100644 --- a/src/multimedia/configure.json +++ b/src/multimedia/configure.json @@ -95,6 +95,18 @@ { "libs": "-lgstphotography-1.0" } ] }, + "gstreamer_imxcommon": { + "label": "GStreamer i.MX common", + "export": "gstreamer_imxcommon", + "test": { + "include": "gst/allocators/imx/phys_mem_meta.h" + }, + "use": "gstreamer_1_0", + "sources": [ + { "type": "pkgConfig", + "args": "gstimxcommon" } + ] + }, "libresourceqt5": { "label": "libresourceqt5", "test": "resourcepolicy", @@ -229,6 +241,11 @@ "condition": "(features.gstreamer_1_0 && libs.gstreamer_photography_1_0) || (features.gstreamer_0_10 && libs.gstreamer_photography_0_10)", "output": [ "privateFeature" ] }, + "gstreamer_imxcommon": { + "label": "GStreamer i.MX common", + "condition": "(features.gstreamer_1_0 && libs.gstreamer_imxcommon)", + "output": [ "privateFeature" ] + }, "gpu_vivante": { "label": "Vivante GPU", "condition": "features.gui && features.opengles2 && tests.gpu_vivante", diff --git a/src/plugins/videonode/imx6/imx6.pro b/src/plugins/videonode/imx6/imx6.pro index c8085a31e..43e17e725 100644 --- a/src/plugins/videonode/imx6/imx6.pro +++ b/src/plugins/videonode/imx6/imx6.pro @@ -2,6 +2,12 @@ TARGET = imx6vivantevideonode QT += multimedia-private qtmultimediaquicktools-private +qtConfig(gstreamer_imxcommon) { + QT += multimediagsttools-private + QMAKE_USE += gstreamer_imxcommon + DEFINES += GST_USE_UNSTABLE_API +} + HEADERS += \ qsgvivantevideonode.h \ qsgvivantevideomaterialshader.h \ diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp index 4b68f47a4..e1468fe34 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp @@ -49,6 +49,11 @@ #include +#include +#if QT_CONFIG(gstreamer_imxcommon) +#include "private/qgstvideobuffer_p.h" +#include +#endif //#define QT_VIVANTE_VIDEO_DEBUG @@ -224,7 +229,12 @@ GLuint QSGVivanteVideoMaterial::vivanteMapping(QVideoFrame vF) #endif GLuint physical = ~0U; - +#if QT_CONFIG(gstreamer_imxcommon) + auto buffer = reinterpret_cast(vF.buffer()); + GstImxPhysMemMeta *meta = GST_IMX_PHYS_MEM_META_GET(buffer->buffer()); + if (meta && meta->phys_addr) + physical = meta->phys_addr; +#endif glBindTexture(GL_TEXTURE_2D, tmpTexId); glTexDirectVIVMap_LOCAL(GL_TEXTURE_2D, fullWidth, fullHeight, -- cgit v1.2.3 From fa4d01ae128dd5605910bafda580e856239e36c6 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 4 Oct 2019 17:42:31 +0200 Subject: Small performance improvements suggested by clang-tidy * Add const & to function parameters * Add const & to variables assigned from functions returning const & Change-Id: Idc141bd48f37eae92a4d1775caade3c977a42391 Reviewed-by: VaL Doroshchuk --- src/gsttools/qgstutils.cpp | 2 +- src/plugins/alsa/qalsaaudiodeviceinfo.cpp | 2 +- src/plugins/alsa/qalsaaudiodeviceinfo.h | 2 +- src/plugins/gstreamer/mediacapture/qgstreameraudioencode.cpp | 4 ++-- src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp index ac8808115..f8a9d79c1 100644 --- a/src/gsttools/qgstutils.cpp +++ b/src/gsttools/qgstutils.cpp @@ -1309,7 +1309,7 @@ void QGstUtils::setMetaData(GstElement *element, const QMap options = m_options.value(codec); for (auto it = options.cbegin(), end = options.cend(); it != end; ++it) { - QString option = it.key(); - QVariant value = it.value(); + const QString &option = it.key(); + const QVariant &value = it.value(); switch (value.type()) { case QVariant::Int: diff --git a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp index 4cc0e5f25..a2ed1d288 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamervideoencode.cpp @@ -196,8 +196,8 @@ GstElement *QGstreamerVideoEncode::createEncoder() QMap options = m_options.value(codec); for (auto it = options.cbegin(), end = options.cend(); it != end; ++it) { - QString option = it.key(); - QVariant value = it.value(); + const QString &option = it.key(); + const QVariant &value = it.value(); switch (value.type()) { case QVariant::Int: -- cgit v1.2.3 From d2475bdd4cbb9a70abf19db465ddbdbf29591568 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 7 Oct 2019 08:23:11 +0200 Subject: Fix build with ALSA in non-system location This amends commit f0ea2641. Fixes: QTBUG-79014 Change-Id: Ib04d844ef64e335785408dc8d7e512a5a3651655 Reviewed-by: VaL Doroshchuk --- src/plugins/alsa/alsa.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/alsa/alsa.pro b/src/plugins/alsa/alsa.pro index 56657f100..4012bb8f6 100644 --- a/src/plugins/alsa/alsa.pro +++ b/src/plugins/alsa/alsa.pro @@ -1,7 +1,7 @@ TARGET = qtaudio_alsa QT += multimedia-private -LIBS += -lasound +QMAKE_USE += alsa HEADERS += \ qalsaplugin.h \ -- cgit v1.2.3 From f06d3d8967bbb5092f0e676b9e0a6ba7c87efec1 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Tue, 8 Oct 2019 10:42:22 +0200 Subject: Fix qConvertFuncs to respect QVideoFrame::Format_YUV422P After changing sequence in QVideoFrame, need to fix qConvertFuncs Change-Id: Ie022676a66d9c47a1b89cf5ef61c2146921a2a0b Reviewed-by: Ville Voutilainen --- src/multimedia/video/qvideoframe.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/multimedia/video/qvideoframe.cpp b/src/multimedia/video/qvideoframe.cpp index dfc6ad3ee..5e2d6df39 100644 --- a/src/multimedia/video/qvideoframe.cpp +++ b/src/multimedia/video/qvideoframe.cpp @@ -1056,7 +1056,6 @@ static VideoFrameConvertFunc qConvertFuncs[QVideoFrame::NPixelFormats] = { /* Format_ARGB8565_Premultiplied */ nullptr, // Not needed /* Format_BGRA32 */ qt_convert_BGRA32_to_ARGB32, /* Format_BGRA32_Premultiplied */ qt_convert_BGRA32_to_ARGB32, - /* Format_ABGR32 */ nullptr, /* Format_BGR32 */ qt_convert_BGRA32_to_ARGB32, /* Format_BGR24 */ qt_convert_BGR24_to_ARGB32, /* Format_BGR565 */ qt_convert_BGR565_to_ARGB32, @@ -1066,7 +1065,6 @@ static VideoFrameConvertFunc qConvertFuncs[QVideoFrame::NPixelFormats] = { /* Format_AYUV444_Premultiplied */ nullptr, /* Format_YUV444 */ qt_convert_YUV444_to_ARGB32, /* Format_YUV420P */ qt_convert_YUV420P_to_ARGB32, - /* Format_YUV422P */ nullptr, /* Format_YV12 */ qt_convert_YV12_to_ARGB32, /* Format_UYVY */ qt_convert_UYVY_to_ARGB32, /* Format_YUYV */ qt_convert_YUYV_to_ARGB32, @@ -1080,7 +1078,9 @@ static VideoFrameConvertFunc qConvertFuncs[QVideoFrame::NPixelFormats] = { /* Format_Y16 */ nullptr, /* Format_Jpeg */ nullptr, // Not needed /* Format_CameraRaw */ nullptr, - /* Format_AdobeDng */ nullptr + /* Format_AdobeDng */ nullptr, + /* Format_ABGR32 */ nullptr, // ### Qt 6: reorder + /* Format_YUV422P */ nullptr, }; static void qInitConvertFuncsAsm() -- cgit v1.2.3 From 8277070128197744c0073c867dc78caea912bfce Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Wed, 9 Oct 2019 10:56:52 +0200 Subject: Remove Format_ABGR32 from supported formats for sq texture video node Format_ABGR32 was introduced together with gst opengl support. And is supposed to be used with QT_GSTREAMER_USE_OPENGL_PLUGIN=1, Which should be fine for Raspberry Pi, but suddenly does not work for iMX boards. RPI's omxh264dec provides buffers in RGBA format, and corresponding textures will be created using GL_RGBA. Since we return Format_ABGR32 as supported format, which is RGBA, no conversion is needed and everything was ok. But for iMX, imxvpudec provides buffers in I420 format. And textures will be created using GL_RED with only 1 plane. Following patch https://bugzilla.gnome.org/show_bug.cgi?id=779067 requests RGBA too. Since incaps contains I420 and RGBA, and we say that we support RGBA, this leads to use buffers in I420 but *passthrough* in gst_gl_color_convert_element_prepare_output_buffer(). Since incaps and outcaps contain the same video format. No conversion will be done there and textures will be rendered incorrectly. Removing support of Format_ABGR32 from texture video node will cause to ignore requested RGBA from DIRECTVIV and perform converting, I420->BGRx on iMX and RGBA->BGRA on RPI. QT_GSTREAMER_USE_OPENGL_PLUGIN should be used together with decoders that use gpu memory. Otherwise some converting/uploading operations will be done which will also introduce some performance issues, so not recommended to be used for iMX. Change-Id: I8f037316c40587c81b2116c43a7262c6a70a5b44 Fixes: QTBUG-78855 Reviewed-by: Ville Voutilainen --- src/qtmultimediaquicktools/qsgvideonode_texture.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp index 318e4cef5..473a4144f 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp @@ -44,6 +44,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -58,7 +59,9 @@ QList QSGVideoNodeFactory_Texture::supportedPixelForma pixelFormats.append(QVideoFrame::Format_ARGB32); pixelFormats.append(QVideoFrame::Format_BGR32); pixelFormats.append(QVideoFrame::Format_BGRA32); +#if !QT_CONFIG(gpu_vivante) pixelFormats.append(QVideoFrame::Format_ABGR32); +#endif } return pixelFormats; -- cgit v1.2.3