summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-01-27 19:30:58 +0100
committerLars Knoll <lars.knoll@qt.io>2021-01-29 08:54:31 +0000
commit3987aad97c74193db273f047a215f0921be35bb4 (patch)
treee864db657350fea4be37a6cb941b69d49782478a /src/multimedia
parent24a440a5c2b884285f384fbfddc2ba5637ce35fd (diff)
Define some wrapper classes for Gstreamer structures
Define some wrapper classes for GstCaps, GstStructure and GValue with a decent C++ API to use them. This will help simplify our code within the gstreamer plugin. Change-Id: Ifcae40f04030e89b2ae3fd73bf7ea2eb1db49d16 Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstutils.cpp24
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstutils_p.h90
-rw-r--r--src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp34
3 files changed, 114 insertions, 34 deletions
diff --git a/src/multimedia/platform/gstreamer/common/qgstutils.cpp b/src/multimedia/platform/gstreamer/common/qgstutils.cpp
index 4e96f523d..5f1c64333 100644
--- a/src/multimedia/platform/gstreamer/common/qgstutils.cpp
+++ b/src/multimedia/platform/gstreamer/common/qgstutils.cpp
@@ -190,7 +190,7 @@ QSize QGstUtils::capsResolution(const GstCaps *caps)
if (gst_caps_get_size(caps) == 0)
return QSize();
- return structureResolution(gst_caps_get_structure(caps, 0));
+ return QGstCaps(caps).at(0).resolution();
}
/*!
@@ -757,12 +757,14 @@ GstCaps *QGstUtils::videoFilterCaps()
return gst_caps_make_writable(gst_static_caps_get(&staticCaps));
}
-QSize QGstUtils::structureResolution(const GstStructure *s)
+QSize QGstStructure::resolution() const
{
QSize size;
int w, h;
- if (s && gst_structure_get_int(s, "width", &w) && gst_structure_get_int(s, "height", &h)) {
+ if (structure &&
+ gst_structure_get_int(structure, "width", &w) &&
+ gst_structure_get_int(structure, "height", &h)) {
size.rwidth() = w;
size.rheight() = h;
}
@@ -770,7 +772,7 @@ QSize QGstUtils::structureResolution(const GstStructure *s)
return size;
}
-QVideoFrame::PixelFormat QGstUtils::structurePixelFormat(const GstStructure *structure)
+QVideoFrame::PixelFormat QGstStructure::pixelFormat() const
{
QVideoFrame::PixelFormat pixelFormat = QVideoFrame::Format_Invalid;
@@ -791,13 +793,13 @@ QVideoFrame::PixelFormat QGstUtils::structurePixelFormat(const GstStructure *str
return pixelFormat;
}
-QSize QGstUtils::structurePixelAspectRatio(const GstStructure *s)
+QSize QGstStructure::pixelAspectRatio() const
{
QSize ratio(1, 1);
gint aspectNum = 0;
gint aspectDenum = 0;
- if (s && gst_structure_get_fraction(s, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
+ if (structure && gst_structure_get_fraction(structure, "pixel-aspect-ratio", &aspectNum, &aspectDenum)) {
if (aspectDenum > 0) {
ratio.rwidth() = aspectNum;
ratio.rheight() = aspectDenum;
@@ -807,12 +809,12 @@ QSize QGstUtils::structurePixelAspectRatio(const GstStructure *s)
return ratio;
}
-QPair<float, float> QGstUtils::structureFrameRateRange(const GstStructure *s)
+QGRange<float> QGstStructure::frameRateRange() const
{
float minRate = 0.;
float maxRate = 0.;
- if (!s)
+ if (!structure)
return {0.f, 0.f};
auto extractFraction = [] (const GValue *v) -> float {
@@ -836,7 +838,7 @@ QPair<float, float> QGstUtils::structureFrameRateRange(const GstStructure *s)
}
};
- const GValue *gstFrameRates = gst_structure_get_value(s, "framerate");
+ const GValue *gstFrameRates = gst_structure_get_value(structure, "framerate");
if (gstFrameRates) {
if (GST_VALUE_HOLDS_LIST(gstFrameRates)) {
guint nFrameRates = gst_value_list_get_size(gstFrameRates);
@@ -847,8 +849,8 @@ QPair<float, float> QGstUtils::structureFrameRateRange(const GstStructure *s)
extractFrameRate(gstFrameRates);
}
} else {
- const GValue *min = gst_structure_get_value(s, "min-framerate");
- const GValue *max = gst_structure_get_value(s, "max-framerate");
+ const GValue *min = gst_structure_get_value(structure, "min-framerate");
+ const GValue *max = gst_structure_get_value(structure, "max-framerate");
if (min && max) {
minRate = extractFraction(min);
maxRate = extractFraction(max);
diff --git a/src/multimedia/platform/gstreamer/common/qgstutils_p.h b/src/multimedia/platform/gstreamer/common/qgstutils_p.h
index 8a94ac53c..bcc5ac4f4 100644
--- a/src/multimedia/platform/gstreamer/common/qgstutils_p.h
+++ b/src/multimedia/platform/gstreamer/common/qgstutils_p.h
@@ -109,11 +109,6 @@ namespace QGstUtils {
Q_MULTIMEDIA_EXPORT GstCaps *videoFilterCaps();
- Q_MULTIMEDIA_EXPORT QSize structureResolution(const GstStructure *s);
- Q_MULTIMEDIA_EXPORT QVideoFrame::PixelFormat structurePixelFormat(const GstStructure *s);
- Q_MULTIMEDIA_EXPORT QSize structurePixelAspectRatio(const GstStructure *s);
- Q_MULTIMEDIA_EXPORT QPair<float, float> structureFrameRateRange(const GstStructure *s);
-
Q_MULTIMEDIA_EXPORT QString fileExtensionForMimeType(const QString &mimeType);
Q_MULTIMEDIA_EXPORT QVariant fromGStreamerOrientation(const QVariant &value);
@@ -122,6 +117,91 @@ namespace QGstUtils {
Q_MULTIMEDIA_EXPORT bool useOpenGL();
}
+template <typename T> struct QGRange
+{
+ T min;
+ T max;
+};
+
+class QGValue
+{
+public:
+ QGValue(const GValue *v) : value(v) {}
+ const GValue *value;
+
+ bool isNull() const { return !value; }
+
+ std::optional<bool> toBool() const
+ {
+ if (!G_VALUE_HOLDS_BOOLEAN(value))
+ return std::nullopt;
+ return g_value_get_boolean(value);
+ }
+ std::optional<int> toInt() const
+ {
+ if (!G_VALUE_HOLDS_INT(value))
+ return std::nullopt;
+ return g_value_get_int(value);
+ }
+ const char *toString() const
+ {
+ return g_value_get_string(value);
+ }
+ std::optional<float> getFraction() const
+ {
+ if (!GST_VALUE_HOLDS_FRACTION(value))
+ return std::nullopt;
+ return (float)gst_value_get_fraction_numerator(value)/(float)gst_value_get_fraction_denominator(value);
+ }
+
+ std::optional<QGRange<float>> getFractionRange() const
+ {
+ if (!GST_VALUE_HOLDS_FRACTION_RANGE(value))
+ return std::nullopt;
+ QGValue min = gst_value_get_fraction_range_min(value);
+ QGValue max = gst_value_get_fraction_range_max(value);
+ return QGRange<float>{ *min.getFraction(), *max.getFraction() };
+ }
+
+ std::optional<QGRange<int>> getIntRange() const
+ {
+ if (!GST_VALUE_HOLDS_INT_RANGE(value))
+ return std::nullopt;
+ return QGRange<int>{ gst_value_get_int_range_min(value), gst_value_get_int_range_max(value) };
+ }
+
+};
+
+class QGstStructure {
+public:
+ GstStructure *structure;
+ QGstStructure(GstStructure *s) : structure(s) {}
+ void free() { gst_structure_free(structure); structure = nullptr; }
+
+ bool isNull() const { return !structure; }
+
+ QByteArray name() const { return gst_structure_get_name(structure); }
+
+ QGValue operator[](const char *name) const { return gst_structure_get_value(structure, name); }
+
+ Q_MULTIMEDIA_EXPORT QSize resolution() const;
+ Q_MULTIMEDIA_EXPORT QVideoFrame::PixelFormat pixelFormat() const;
+ Q_MULTIMEDIA_EXPORT QSize pixelAspectRatio() const;
+ Q_MULTIMEDIA_EXPORT QGRange<float> frameRateRange() const;
+
+};
+
+class QGstCaps {
+public:
+ QGstCaps(const GstCaps *c) : caps(c) {}
+ const GstCaps *caps;
+
+ 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); }
+};
+
Q_MULTIMEDIA_EXPORT void qt_gst_object_ref_sink(gpointer object);
Q_MULTIMEDIA_EXPORT GstCaps *qt_gst_pad_get_current_caps(GstPad *pad);
Q_MULTIMEDIA_EXPORT GstCaps *qt_gst_pad_get_caps(GstPad *pad);
diff --git a/src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp b/src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp
index db175075c..f3707ffad 100644
--- a/src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp
+++ b/src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp
@@ -139,46 +139,44 @@ QList<QCameraInfo> QGstreamerDeviceManager::videoInputs() const
QList<QCameraInfo> devices;
for (auto *d : qAsConst(m_videoSources)) {
- auto *properties = gst_device_get_properties(d);
- if (properties) {
+ QGstStructure properties = gst_device_get_properties(d);
+ if (!properties.isNull()) {
QCameraInfoPrivate *info = new QCameraInfoPrivate;
auto *desc = gst_device_get_display_name(d);
info->description = QString::fromUtf8(desc);
g_free(desc);
- auto *name = gst_structure_get_string(properties, "device.path");
- info->id = name;
-// info->driver = gst_structure_get_string(properties, "v4l2.device.driver");
- gboolean def = false;
- gst_structure_get_boolean(properties, "is-default", &def);
- info->isDefault = def;
+ info->id = properties["device.path"].toString();
+// info->driver = properties["v4l2.device.driver"].getString();
+ auto def = properties["is-default"].toBool();
+ info->isDefault = *def;
if (def)
devices.prepend(info->create());
else
devices.append(info->create());
- gst_structure_free(properties);
- auto *caps = gst_device_get_caps(d);
- if (caps) {
+ properties.free();
+ QGstCaps caps = gst_device_get_caps(d);
+ if (!caps.isNull()) {
QList<QCameraFormat> formats;
QSet<QSize> photoResolutions;
- int size = gst_caps_get_size(caps);
+ int size = caps.size();
for (int i = 0; i < size; ++i) {
- auto *cap = gst_caps_get_structure(caps, i);
+ auto cap = caps.at(i);
- QSize resolution = QGstUtils::structureResolution(cap);
+ QSize resolution = cap.resolution();
if (!resolution.isValid())
continue;
- auto pixelFormat = QGstUtils::structurePixelFormat(cap);
- auto frameRate = QGstUtils::structureFrameRateRange(cap);
+ auto pixelFormat = cap.pixelFormat();
+ auto frameRate = cap.frameRateRange();
auto *f = new QCameraFormatPrivate{
QSharedData(),
pixelFormat,
resolution,
- frameRate.first,
- frameRate.second
+ frameRate.min,
+ frameRate.max
};
formats << f->create();
photoResolutions.insert(resolution);