summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Srebrny <piotr.srebrny@qt.io>2022-12-15 15:42:33 +0100
committerPiotr Srebrny <piotr.srebrny@qt.io>2023-01-04 15:35:23 +0100
commit31411c025a823536c5b4e5da6230eab728bbe344 (patch)
treee1bebfc6698d03dcc976e73c8ebd9da25e71b6c7
parente98cfba8b1ef3d1c0fa4fccc2f2e12379e16db7b (diff)
Fix memleak in QGstCaps
gst_device_get_caps and gst_pad_query_caps require decreasing of reference count when caps are not longer needed. This was not done with QGstCaps. This patch adds reference counting on QGstCaps and remove QGstCapsMutable as it was based on a missconception. GstCaps can be mutated only when refernce count is 1. This was not ensured with QGstCapsMutable. Change-Id: Id058a0a916b5f76eef758a099791bec7cc917af9 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> Reviewed-by: Lars Knoll <lars@knoll.priv.no> (cherry picked from commit f0ae787ec3d087a8afac45b1473a22c535a44dc3)
-rw-r--r--src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp2
-rw-r--r--src/plugins/multimedia/gstreamer/audio/qgstreameraudiodevice.cpp2
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgst_p.h118
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstreamervideooverlay.cpp2
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstsubtitlesink.cpp2
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstutils.cpp39
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstutils_p.h4
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstvideorenderersink.cpp25
-rw-r--r--src/plugins/multimedia/gstreamer/common/qgstvideorenderersink_p.h8
-rw-r--r--src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp4
-rw-r--r--src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp4
-rw-r--r--src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp4
-rw-r--r--src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediaencoder.cpp4
-rw-r--r--src/plugins/multimedia/gstreamer/qgstreamerformatinfo.cpp24
-rw-r--r--src/plugins/multimedia/gstreamer/qgstreamerformatinfo_p.h6
-rw-r--r--src/plugins/multimedia/gstreamer/qgstreamervideodevices.cpp3
16 files changed, 116 insertions, 135 deletions
diff --git a/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp b/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
index 0c1b13ebb..5dd6ca7f8 100644
--- a/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
+++ b/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodecoder.cpp
@@ -290,7 +290,7 @@ void QGstreamerAudioDecoder::start()
if (m_appSink) {
if (mFormat.isValid()) {
setAudioFlags(false);
- QGstMutableCaps caps = QGstUtils::capsForAudioFormat(mFormat);
+ auto caps = QGstUtils::capsForAudioFormat(mFormat);
gst_app_sink_set_caps(m_appSink, caps.get());
} else {
// We want whatever the native audio format is
diff --git a/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodevice.cpp b/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodevice.cpp
index 288cf34ac..b44921a1f 100644
--- a/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodevice.cpp
+++ b/src/plugins/multimedia/gstreamer/audio/qgstreameraudiodevice.cpp
@@ -19,7 +19,7 @@ QGStreamerAudioDeviceInfo::QGStreamerAudioDeviceInfo(GstDevice *d, const QByteAr
description = QString::fromUtf8(n);
g_free(n);
- QGstCaps caps = gst_device_get_caps(gstDevice);
+ auto caps = QGstCaps(gst_device_get_caps(gstDevice),QGstCaps::HasRef);
int size = caps.size();
for (int i = 0; i < size; ++i) {
auto c = caps.at(i);
diff --git a/src/plugins/multimedia/gstreamer/common/qgst_p.h b/src/plugins/multimedia/gstreamer/common/qgst_p.h
index 40897ad9d..ec92a4d30 100644
--- a/src/plugins/multimedia/gstreamer/common/qgst_p.h
+++ b/src/plugins/multimedia/gstreamer/common/qgst_p.h
@@ -158,85 +158,73 @@ public:
};
class QGstCaps {
- const GstCaps *caps = nullptr;
+ GstCaps *caps = nullptr;
public:
- enum MemoryFormat {
- CpuMemory,
- GLTexture,
- DMABuf
- };
+ enum RefMode { HasRef, NeedsRef };
+ enum MemoryFormat { CpuMemory, GLTexture, DMABuf };
QGstCaps() = default;
- QGstCaps(const GstCaps *c) : caps(c) {}
-
- bool isNull() const { return !caps; }
- int size() const { return gst_caps_get_size(caps); }
- QGstStructure at(int index) { return gst_caps_get_structure(caps, index); }
- const GstCaps *get() const { return caps; }
- QByteArray toString() const
+ explicit QGstCaps(GstCaps *c, RefMode mode) : caps(c)
{
- gchar *c = gst_caps_to_string(caps);
- QByteArray b(c);
- g_free(c);
- return b;
- }
- MemoryFormat memoryFormat() const {
- auto *features = gst_caps_get_features(caps, 0);
- if (gst_caps_features_contains(features, "memory:GLMemory"))
- return GLTexture;
- else if (gst_caps_features_contains(features, "memory:DMABuf"))
- return DMABuf;
- return CpuMemory;
- }
- QVideoFrameFormat formatForCaps(GstVideoInfo *info) const;
-};
-
-class QGstMutableCaps : public QGstCaps {
- GstCaps *caps = nullptr;
-public:
- enum RefMode { HasRef, NeedsRef };
- QGstMutableCaps() = default;
- QGstMutableCaps(GstCaps *c, RefMode mode = HasRef)
- : QGstCaps(c), caps(c)
- {
- Q_ASSERT(QGstCaps::get() == caps);
if (mode == NeedsRef)
gst_caps_ref(caps);
}
- QGstMutableCaps(const QGstMutableCaps &other)
- : QGstCaps(other), caps(other.caps)
+
+ QGstCaps(const QGstCaps &other) : caps(other.caps)
{
- Q_ASSERT(QGstCaps::get() == caps);
if (caps)
gst_caps_ref(caps);
}
- QGstMutableCaps &operator=(const QGstMutableCaps &other)
- {
- QGstCaps::operator=(other);
- if (other.caps)
- gst_caps_ref(other.caps);
+
+ ~QGstCaps() {
if (caps)
gst_caps_unref(caps);
- caps = other.caps;
- Q_ASSERT(QGstCaps::get() == caps);
- return *this;
}
- ~QGstMutableCaps() {
- Q_ASSERT(QGstCaps::get() == caps);
- if (caps)
- gst_caps_unref(caps);
+
+ QGstCaps &operator=(const QGstCaps &other)
+ {
+ if (this != &other) {
+ if (other.caps)
+ gst_caps_ref(other.caps);
+ if (caps)
+ gst_caps_unref(caps);
+ caps = other.caps;
+ }
+ return *this;
}
- void create() {
- caps = gst_caps_new_empty();
- QGstCaps::operator=(QGstCaps(caps));
+ bool isNull() const { return !caps; }
+
+ QByteArray toString() const { return toString(caps); }
+ int size() const { return int(gst_caps_get_size(caps)); }
+ QGstStructure at(int index) const { return gst_caps_get_structure(caps, index); }
+ GstCaps *get() const { return caps; }
+ MemoryFormat memoryFormat() const {
+ auto *features = gst_caps_get_features(caps, 0);
+ if (gst_caps_features_contains(features, "memory:GLMemory"))
+ return GLTexture;
+ else if (gst_caps_features_contains(features, "memory:DMABuf"))
+ return DMABuf;
+ return CpuMemory;
}
+ QVideoFrameFormat formatForCaps(GstVideoInfo *info) const;
void addPixelFormats(const QList<QVideoFrameFormat::PixelFormat> &formats, const char *modifier = nullptr);
- static QGstMutableCaps fromCameraFormat(const QCameraFormat &format);
- GstCaps *get() const { return caps; }
+ static QGstCaps create() {
+ return QGstCaps(gst_caps_new_empty(), HasRef);
+ }
+
+ static QByteArray toString(const GstCaps *caps)
+ {
+ gchar *c = gst_caps_to_string(caps);
+ QByteArray b(c);
+ g_free(c);
+ return b;
+ }
+
+ static QGstCaps fromCameraFormat(const QCameraFormat &format);
};
class QGstObject
@@ -305,7 +293,7 @@ public:
void set(const char *property, quint64 i) { g_object_set(m_object, property, guint64(i), nullptr); }
void set(const char *property, double d) { g_object_set(m_object, property, gdouble(d), nullptr); }
void set(const char *property, const QGstObject &o) { g_object_set(m_object, property, o.object(), nullptr); }
- void set(const char *property, const QGstMutableCaps &c) { g_object_set(m_object, property, c.get(), nullptr); }
+ void set(const char *property, const QGstCaps &c) { g_object_set(m_object, property, c.get(), nullptr); }
QGString getString(const char *property) const
{ char *s = nullptr; g_object_get(m_object, property, &s, nullptr); return s; }
@@ -339,10 +327,10 @@ public:
: QGstObject(&pad->object, mode)
{}
- QGstMutableCaps currentCaps() const
- { return QGstMutableCaps(gst_pad_get_current_caps(pad())); }
+ QGstCaps currentCaps() const
+ { return QGstCaps(gst_pad_get_current_caps(pad()), QGstCaps::HasRef); }
QGstCaps queryCaps() const
- { return QGstCaps(gst_pad_query_caps(pad(), nullptr)); }
+ { return QGstCaps(gst_pad_query_caps(pad(), nullptr), QGstCaps::HasRef); }
bool isLinked() const { return gst_pad_is_linked(pad()); }
bool link(const QGstPad &sink) const { return gst_pad_link(pad(), sink.pad()) == GST_PAD_LINK_OK; }
@@ -432,8 +420,6 @@ public:
{
}
- bool linkFiltered(const QGstElement &next, const QGstMutableCaps &caps)
- { return gst_element_link_filtered(element(), next.element(), caps.get()); }
bool link(const QGstElement &next)
{ return gst_element_link(element(), next.element()); }
bool link(const QGstElement &n1, const QGstElement &n2)
@@ -591,8 +577,8 @@ inline QGstStructure QGValue::toStructure() const
inline QGstCaps QGValue::toCaps() const
{
if (!value || !GST_VALUE_HOLDS_CAPS(value))
- return QGstCaps();
- return QGstCaps(gst_value_get_caps(value));
+ return {};
+ return QGstCaps(gst_caps_copy(gst_value_get_caps(value)), QGstCaps::HasRef);
}
QT_END_NAMESPACE
diff --git a/src/plugins/multimedia/gstreamer/common/qgstreamervideooverlay.cpp b/src/plugins/multimedia/gstreamer/common/qgstreamervideooverlay.cpp
index fbb6477bf..c24ba7cc9 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstreamervideooverlay.cpp
+++ b/src/plugins/multimedia/gstreamer/common/qgstreamervideooverlay.cpp
@@ -184,7 +184,7 @@ void QGstreamerVideoOverlay::applyRenderRect()
void QGstreamerVideoOverlay::probeCaps(GstCaps *caps)
{
- QSize size = QGstCaps(caps).at(0).resolution();
+ QSize size = QGstCaps(caps, QGstCaps::NeedsRef).at(0).resolution();
if (size != m_nativeVideoSize) {
m_nativeVideoSize = size;
m_gstreamerVideoSink->setNativeSize(m_nativeVideoSize);
diff --git a/src/plugins/multimedia/gstreamer/common/qgstsubtitlesink.cpp b/src/plugins/multimedia/gstreamer/common/qgstsubtitlesink.cpp
index e00a21a34..ce444a29a 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstsubtitlesink.cpp
+++ b/src/plugins/multimedia/gstreamer/common/qgstsubtitlesink.cpp
@@ -119,7 +119,7 @@ GstCaps *QGstSubtitleSink::get_caps(GstBaseSink *base, GstCaps *filter)
gboolean QGstSubtitleSink::set_caps(GstBaseSink *base, GstCaps *caps)
{
- qDebug() << "set_caps:" << QGstCaps(caps).toString();
+ qDebug() << "set_caps:" << QGstCaps::toString(caps);
return sink_parent_class->set_caps(base, caps);
}
diff --git a/src/plugins/multimedia/gstreamer/common/qgstutils.cpp b/src/plugins/multimedia/gstreamer/common/qgstutils.cpp
index 9c994cdd7..ef93f1b88 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstutils.cpp
+++ b/src/plugins/multimedia/gstreamer/common/qgstutils.cpp
@@ -63,13 +63,13 @@ static QAudioFormat::SampleFormat gstSampleFormatToSampleFormat(const char *fmt)
*/
QAudioFormat QGstUtils::audioFormatForSample(GstSample *sample)
{
- QGstCaps caps = gst_sample_get_caps(sample);
+ auto caps = QGstCaps(gst_sample_get_caps(sample), QGstCaps::NeedsRef);
if (caps.isNull())
- return QAudioFormat();
+ return {};
return audioFormatForCaps(caps);
}
-QAudioFormat QGstUtils::audioFormatForCaps(QGstCaps caps)
+QAudioFormat QGstUtils::audioFormatForCaps(const QGstCaps &caps)
{
QAudioFormat format;
QGstStructure s = caps.at(0);
@@ -96,19 +96,21 @@ QAudioFormat QGstUtils::audioFormatForCaps(QGstCaps caps)
\note Caller must unreference GstCaps.
*/
-QGstMutableCaps QGstUtils::capsForAudioFormat(const QAudioFormat &format)
+QGstCaps QGstUtils::capsForAudioFormat(const QAudioFormat &format)
{
if (!format.isValid())
return {};
auto sampleFormat = format.sampleFormat();
- return gst_caps_new_simple(
+ auto caps = gst_caps_new_simple(
"audio/x-raw",
"format" , G_TYPE_STRING, audioSampleFormatNames[sampleFormat],
"rate" , G_TYPE_INT , format.sampleRate(),
"channels", G_TYPE_INT , format.channelCount(),
"layout" , G_TYPE_STRING, "interleaved",
nullptr);
+
+ return QGstCaps(caps, QGstCaps::HasRef);
}
QList<QAudioFormat::SampleFormat> QGValue::getSampleFormats() const
@@ -284,8 +286,11 @@ QVideoFrameFormat QGstCaps::formatForCaps(GstVideoInfo *info) const
return QVideoFrameFormat();
}
-void QGstMutableCaps::addPixelFormats(const QList<QVideoFrameFormat::PixelFormat> &formats, const char *modifier)
+void QGstCaps::addPixelFormats(const QList<QVideoFrameFormat::PixelFormat> &formats, const char *modifier)
{
+ if (!gst_caps_is_writable(caps))
+ caps = gst_caps_make_writable(caps);
+
GValue list = {};
g_value_init(&list, GST_TYPE_LIST);
@@ -300,7 +305,7 @@ void QGstMutableCaps::addPixelFormats(const QList<QVideoFrameFormat::PixelFormat
gst_value_list_append_value(&list, &item);
g_value_unset(&item);
}
- QGValue v(&list);
+
auto *structure = gst_structure_new("video/x-raw",
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, INT_MAX, 1,
"width" , GST_TYPE_INT_RANGE, 1, INT_MAX,
@@ -314,34 +319,27 @@ void QGstMutableCaps::addPixelFormats(const QList<QVideoFrameFormat::PixelFormat
gst_caps_set_features(caps, size() - 1, gst_caps_features_from_string(modifier));
}
-QGstMutableCaps QGstMutableCaps::fromCameraFormat(const QCameraFormat &format)
+QGstCaps QGstCaps::fromCameraFormat(const QCameraFormat &format)
{
- QGstMutableCaps caps;
- caps.create();
-
QSize size = format.resolution();
GstStructure *structure = nullptr;
-// auto [num, den] = qRealToFraction(format.maxFrameRate());
-// qDebug() << "fromCameraFormat" << format.maxFrameRate() << num << den;
-
if (format.pixelFormat() == QVideoFrameFormat::Format_Jpeg) {
structure = gst_structure_new("image/jpeg",
"width" , G_TYPE_INT, size.width(),
"height" , G_TYPE_INT, size.height(),
-// "framerate", GST_TYPE_FRACTION, num, den,
nullptr);
} else {
int index = indexOfVideoFormat(format.pixelFormat());
if (index < 0)
- return QGstMutableCaps();
+ return {};
auto gstFormat = qt_videoFormatLookup[index].gstFormat;
structure = gst_structure_new("video/x-raw",
"format" , G_TYPE_STRING, gst_video_format_to_string(gstFormat),
"width" , G_TYPE_INT, size.width(),
"height" , G_TYPE_INT, size.height(),
-// "framerate", GST_TYPE_FRACTION, num, den,
nullptr);
}
+ auto caps = QGstCaps::create();
gst_caps_append_structure(caps.caps, structure);
return caps;
}
@@ -450,12 +448,9 @@ QGRange<float> QGstStructure::frameRateRange() const
GList *qt_gst_video_sinks()
{
- GList *list = nullptr;
-
- list = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_SINK | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO,
+ return gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_SINK
+ | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO,
GST_RANK_MARGINAL);
-
- return list;
}
QT_END_NAMESPACE
diff --git a/src/plugins/multimedia/gstreamer/common/qgstutils_p.h b/src/plugins/multimedia/gstreamer/common/qgstutils_p.h
index 809505868..7ba97a97d 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstutils_p.h
+++ b/src/plugins/multimedia/gstreamer/common/qgstutils_p.h
@@ -36,8 +36,8 @@ class QVideoFrameFormat;
namespace QGstUtils {
Q_MULTIMEDIA_EXPORT QAudioFormat audioFormatForSample(GstSample *sample);
- QAudioFormat audioFormatForCaps(QGstCaps caps);
- Q_MULTIMEDIA_EXPORT QGstMutableCaps capsForAudioFormat(const QAudioFormat &format);
+ QAudioFormat audioFormatForCaps(const QGstCaps &caps);
+ Q_MULTIMEDIA_EXPORT QGstCaps capsForAudioFormat(const QAudioFormat &format);
void setFrameTimeStamps(QVideoFrame *frame, GstBuffer *buffer);
}
diff --git a/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink.cpp b/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink.cpp
index 3a486957e..5ad2c9ad7 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink.cpp
+++ b/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink.cpp
@@ -53,8 +53,7 @@ void QGstVideoRenderer::createSurfaceCaps()
QRhi *rhi = m_sink->rhi();
Q_UNUSED(rhi);
- QGstMutableCaps caps;
- caps.create();
+ auto caps = QGstCaps::create();
// All the formats that both we and gstreamer support
auto formats = QList<QVideoFrameFormat::PixelFormat>()
@@ -110,16 +109,16 @@ void QGstVideoRenderer::createSurfaceCaps()
m_surfaceCaps = caps;
}
-QGstMutableCaps QGstVideoRenderer::caps()
+QGstCaps QGstVideoRenderer::caps()
{
QMutexLocker locker(&m_mutex);
return m_surfaceCaps;
}
-bool QGstVideoRenderer::start(GstCaps *caps)
+bool QGstVideoRenderer::start(const QGstCaps& caps)
{
- qCDebug(qLcGstVideoRenderer) << "QGstVideoRenderer::start" << QGstCaps(caps).toString();
+ qCDebug(qLcGstVideoRenderer) << "QGstVideoRenderer::start" << caps.toString();
QMutexLocker locker(&m_mutex);
m_frameMirrored = false;
@@ -130,7 +129,7 @@ bool QGstVideoRenderer::start(GstCaps *caps)
m_stop = true;
}
- m_startCaps = QGstMutableCaps(caps, QGstMutableCaps::NeedsRef);
+ m_startCaps = caps;
/*
Waiting for start() to be invoked in the main thread may block
@@ -311,7 +310,7 @@ bool QGstVideoRenderer::handleEvent(QMutexLocker<QMutex> *locker)
Q_ASSERT(!m_active);
auto startCaps = m_startCaps;
- m_startCaps = nullptr;
+ m_startCaps = {};
if (m_sink) {
locker->unlock();
@@ -561,21 +560,23 @@ GstCaps *QGstVideoRendererSink::get_caps(GstBaseSink *base, GstCaps *filter)
{
VO_SINK(base);
- QGstMutableCaps caps = sink->renderer->caps();
+ QGstCaps caps = sink->renderer->caps();
if (filter)
- caps = gst_caps_intersect(caps.get(), filter);
+ caps = QGstCaps(gst_caps_intersect(caps.get(), filter), QGstCaps::HasRef);
gst_caps_ref(caps.get());
return caps.get();
}
-gboolean QGstVideoRendererSink::set_caps(GstBaseSink *base, GstCaps *caps)
+gboolean QGstVideoRendererSink::set_caps(GstBaseSink *base, GstCaps *gcaps)
{
VO_SINK(base);
- qCDebug(qLcGstVideoRenderer) << "set_caps:" << QGstCaps(caps).toString();
+ auto caps = QGstCaps(gcaps, QGstCaps::NeedsRef);
+
+ qCDebug(qLcGstVideoRenderer) << "set_caps:" << caps.toString();
- if (!caps) {
+ if (caps.isNull()) {
sink->renderer->stop();
return TRUE;
diff --git a/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink_p.h b/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink_p.h
index 139eaec5e..fa9cfaddc 100644
--- a/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink_p.h
+++ b/src/plugins/multimedia/gstreamer/common/qgstvideorenderersink_p.h
@@ -39,9 +39,9 @@ public:
QGstVideoRenderer(QGstreamerVideoSink *sink);
~QGstVideoRenderer();
- QGstMutableCaps caps();
+ QGstCaps caps();
- bool start(GstCaps *caps);
+ bool start(const QGstCaps& caps);
void stop();
void unlock();
bool proposeAllocation(GstQuery *query);
@@ -72,9 +72,9 @@ private:
GstFlowReturn m_renderReturn = GST_FLOW_OK;
bool m_active = false;
- QGstMutableCaps m_surfaceCaps;
+ QGstCaps m_surfaceCaps;
- QGstMutableCaps m_startCaps;
+ QGstCaps m_startCaps;
GstBuffer *m_renderBuffer = nullptr;
bool m_notified = false;
diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
index 3f8ca10f3..9bfd13812 100644
--- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
+++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamercamera.cpp
@@ -81,7 +81,7 @@ void QGstreamerCamera::setCamera(const QCameraDevice &camera)
}
QCameraFormat f = findBestCameraFormat(camera);
- auto caps = QGstMutableCaps::fromCameraFormat(f);
+ auto caps = QGstCaps::fromCameraFormat(f);
auto gstNewDecode = QGstElement(f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
gstCamera.unlink(gstCapsFilter);
@@ -125,7 +125,7 @@ bool QGstreamerCamera::setCameraFormat(const QCameraFormat &format)
if (f.isNull())
f = findBestCameraFormat(m_cameraDevice);
- auto caps = QGstMutableCaps::fromCameraFormat(f);
+ auto caps = QGstCaps::fromCameraFormat(f);
auto newGstDecode = QGstElement(f.pixelFormat() == QVideoFrameFormat::Format_Jpeg ? "jpegdec" : "identity");
gstCameraBin.add(newGstDecode);
diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp
index 4da415881..04a65d899 100644
--- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp
+++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamerimagecapture.cpp
@@ -129,12 +129,12 @@ bool QGstreamerImageCapture::probeBuffer(GstBuffer *buffer)
emit readyForCaptureChanged(isReadyForCapture());
- QGstCaps caps = gst_pad_get_current_caps(bin.staticPad("sink").pad());
+ auto caps = QGstCaps(gst_pad_get_current_caps(bin.staticPad("sink").pad()), QGstCaps::HasRef);
GstVideoInfo previewInfo;
gst_video_info_from_caps(&previewInfo, caps.get());
auto memoryFormat = caps.memoryFormat();
- auto fmt = QGstCaps(caps).formatForCaps(&previewInfo);
+ auto fmt = caps.formatForCaps(&previewInfo);
auto *sink = m_session->gstreamerVideoSink();
auto *gstBuffer = new QGstVideoBuffer(buffer, previewInfo, sink, fmt, memoryFormat);
QVideoFrame frame(gstBuffer, fmt);
diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp
index d4a10c012..5f4899161 100644
--- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp
+++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediacapture.cpp
@@ -181,7 +181,7 @@ void QGstreamerMediaCapture::linkEncoder(QGstPad audioSink, QGstPad videoSink)
auto caps = gst_pad_get_current_caps(gstVideoTee.sink().pad());
encoderVideoCapsFilter = QGstElement("capsfilter", "encoderVideoCapsFilter");
- encoderVideoCapsFilter.set("caps", QGstMutableCaps(caps));
+ encoderVideoCapsFilter.set("caps", QGstCaps(caps, QGstCaps::HasRef));
gstPipeline.add(encoderVideoCapsFilter);
@@ -195,7 +195,7 @@ void QGstreamerMediaCapture::linkEncoder(QGstPad audioSink, QGstPad videoSink)
auto caps = gst_pad_get_current_caps(gstAudioTee.sink().pad());
encoderAudioCapsFilter = QGstElement("capsfilter", "encoderAudioCapsFilter");
- encoderAudioCapsFilter.set("caps", QGstMutableCaps(caps));
+ encoderAudioCapsFilter.set("caps", QGstCaps(caps, QGstCaps::HasRef));
gstPipeline.add(encoderAudioCapsFilter);
diff --git a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediaencoder.cpp b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediaencoder.cpp
index 9849d6d91..5f3631111 100644
--- a/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediaencoder.cpp
+++ b/src/plugins/multimedia/gstreamer/mediacapture/qgstreamermediaencoder.cpp
@@ -108,7 +108,7 @@ static GstEncodingContainerProfile *createContainerProfile(const QMediaEncoderSe
{
auto *formatInfo = QGstreamerIntegration::instance()->gstFormatsInfo();
- QGstMutableCaps caps = formatInfo->formatCaps(settings.fileFormat());
+ auto caps = formatInfo->formatCaps(settings.fileFormat());
GstEncodingContainerProfile *profile = (GstEncodingContainerProfile *)gst_encoding_container_profile_new(
"container_profile",
@@ -122,7 +122,7 @@ static GstEncodingProfile *createVideoProfile(const QMediaEncoderSettings &setti
{
auto *formatInfo = QGstreamerIntegration::instance()->gstFormatsInfo();
- QGstMutableCaps caps = formatInfo->videoCaps(settings.mediaFormat());
+ auto caps = formatInfo->videoCaps(settings.mediaFormat());
if (caps.isNull())
return nullptr;
diff --git a/src/plugins/multimedia/gstreamer/qgstreamerformatinfo.cpp b/src/plugins/multimedia/gstreamer/qgstreamerformatinfo.cpp
index 538797cf8..c5e3061e1 100644
--- a/src/plugins/multimedia/gstreamer/qgstreamerformatinfo.cpp
+++ b/src/plugins/multimedia/gstreamer/qgstreamerformatinfo.cpp
@@ -156,7 +156,7 @@ static QPair<QList<QMediaFormat::AudioCodec>, QList<QMediaFormat::VideoCodec>> g
padTemplates = padTemplates->next;
if (padTemplate->direction == padDirection) {
- QGstMutableCaps caps = gst_static_caps_get(&padTemplate->static_caps);
+ auto caps = QGstCaps(gst_static_caps_get(&padTemplate->static_caps), QGstCaps::HasRef);
for (int i = 0; i < caps.size(); i++) {
QGstStructure structure = caps.at(i);
@@ -198,7 +198,7 @@ QList<QGstreamerFormatInfo::CodecMap> QGstreamerFormatInfo::getMuxerList(bool de
padTemplates = padTemplates->next;
if (padTemplate->direction == padDirection) {
- QGstMutableCaps caps = gst_static_caps_get(&padTemplate->static_caps);
+ auto caps = QGstCaps(gst_static_caps_get(&padTemplate->static_caps), QGstCaps::HasRef);
for (int i = 0; i < caps.size(); i++) {
QGstStructure structure = caps.at(i);
@@ -221,7 +221,7 @@ QList<QGstreamerFormatInfo::CodecMap> QGstreamerFormatInfo::getMuxerList(bool de
// check the other side for supported inputs/outputs
if (padTemplate->direction != padDirection) {
- QGstMutableCaps caps = gst_static_caps_get(&padTemplate->static_caps);
+ auto caps = QGstCaps(gst_static_caps_get(&padTemplate->static_caps), QGstCaps::HasRef);
bool acceptsRawAudio = false;
for (int i = 0; i < caps.size(); i++) {
@@ -288,7 +288,7 @@ static QList<QImageCapture::FileFormat> getImageFormatList()
padTemplates = padTemplates->next;
if (padTemplate->direction == GST_PAD_SRC) {
- QGstMutableCaps caps = gst_static_caps_get(&padTemplate->static_caps);
+ QGstCaps caps = QGstCaps(gst_static_caps_get(&padTemplate->static_caps), QGstCaps::HasRef);
for (int i = 0; i < caps.size(); i++) {
QGstStructure structure = caps.at(i);
@@ -351,7 +351,7 @@ QGstreamerFormatInfo::QGstreamerFormatInfo()
QGstreamerFormatInfo::~QGstreamerFormatInfo() = default;
-QGstMutableCaps QGstreamerFormatInfo::formatCaps(const QMediaFormat &f) const
+QGstCaps QGstreamerFormatInfo::formatCaps(const QMediaFormat &f) const
{
auto format = f.fileFormat();
Q_ASSERT(format != QMediaFormat::UnspecifiedFormat);
@@ -371,14 +371,14 @@ QGstMutableCaps QGstreamerFormatInfo::formatCaps(const QMediaFormat &f) const
"audio/x-flac", // FLAC
"audio/x-wav" // Wave
};
- return gst_caps_from_string(capsForFormat[format]);
+ return QGstCaps(gst_caps_from_string(capsForFormat[format]), QGstCaps::HasRef);
}
-QGstMutableCaps QGstreamerFormatInfo::audioCaps(const QMediaFormat &f) const
+QGstCaps QGstreamerFormatInfo::audioCaps(const QMediaFormat &f) const
{
auto codec = f.audioCodec();
if (codec == QMediaFormat::AudioCodec::Unspecified)
- return nullptr;
+ return {};
const char *capsForCodec[(int)QMediaFormat::AudioCodec::LastAudioCodec + 1] = {
"audio/mpeg, mpegversion=(int)1, layer=(int)3", // MP3
@@ -393,14 +393,14 @@ QGstMutableCaps QGstreamerFormatInfo::audioCaps(const QMediaFormat &f) const
"audio/x-wma", // WMA
"audio/x-alac", // ALAC
};
- return gst_caps_from_string(capsForCodec[(int)codec]);
+ return QGstCaps(gst_caps_from_string(capsForCodec[(int)codec]), QGstCaps::HasRef);
}
-QGstMutableCaps QGstreamerFormatInfo::videoCaps(const QMediaFormat &f) const
+QGstCaps QGstreamerFormatInfo::videoCaps(const QMediaFormat &f) const
{
auto codec = f.videoCodec();
if (codec == QMediaFormat::VideoCodec::Unspecified)
- return nullptr;
+ return {};
const char *capsForCodec[(int)QMediaFormat::VideoCodec::LastVideoCodec + 1] = {
"video/mpeg, mpegversion=(int)1", // MPEG1,
@@ -415,7 +415,7 @@ QGstMutableCaps QGstreamerFormatInfo::videoCaps(const QMediaFormat &f) const
"audio/x-wmv", // WMV
"video/x-jpeg", // MotionJPEG,
};
- return gst_caps_from_string(capsForCodec[(int)codec]);
+ return QGstCaps(gst_caps_from_string(capsForCodec[(int)codec]), QGstCaps::HasRef);
}
QT_END_NAMESPACE
diff --git a/src/plugins/multimedia/gstreamer/qgstreamerformatinfo_p.h b/src/plugins/multimedia/gstreamer/qgstreamerformatinfo_p.h
index 12348bbe3..f9ea4cbd5 100644
--- a/src/plugins/multimedia/gstreamer/qgstreamerformatinfo_p.h
+++ b/src/plugins/multimedia/gstreamer/qgstreamerformatinfo_p.h
@@ -28,9 +28,9 @@ public:
QGstreamerFormatInfo();
~QGstreamerFormatInfo();
- QGstMutableCaps formatCaps(const QMediaFormat &f) const;
- QGstMutableCaps audioCaps(const QMediaFormat &f) const;
- QGstMutableCaps videoCaps(const QMediaFormat &f) const;
+ QGstCaps formatCaps(const QMediaFormat &f) const;
+ QGstCaps audioCaps(const QMediaFormat &f) const;
+ QGstCaps videoCaps(const QMediaFormat &f) const;
static QMediaFormat::AudioCodec audioCodecForCaps(QGstStructure structure);
static QMediaFormat::VideoCodec videoCodecForCaps(QGstStructure structure);
diff --git a/src/plugins/multimedia/gstreamer/qgstreamervideodevices.cpp b/src/plugins/multimedia/gstreamer/qgstreamervideodevices.cpp
index cd4d15e02..3902d4e9e 100644
--- a/src/plugins/multimedia/gstreamer/qgstreamervideodevices.cpp
+++ b/src/plugins/multimedia/gstreamer/qgstreamervideodevices.cpp
@@ -83,7 +83,7 @@ QList<QCameraDevice> QGstreamerVideoDevices::videoDevices() const
else
devices.append(info->create());
- QGstCaps caps = gst_device_get_caps(device.gstDevice);
+ auto caps = QGstCaps(gst_device_get_caps(device.gstDevice), QGstCaps::HasRef);
if (!caps.isNull()) {
QList<QCameraFormat> formats;
QSet<QSize> photoResolutions;
@@ -129,7 +129,6 @@ void QGstreamerVideoDevices::addDevice(GstDevice *device)
void QGstreamerVideoDevices::removeDevice(GstDevice *device)
{
-// qDebug() << "removing device:" << device << gst_device_get_display_name(device);
auto it = std::find_if(m_videoSources.begin(), m_videoSources.end(),
[=](const QGstDevice &a) { return a.gstDevice == device; });