From 6156d0c27b37cc8322a243dd54e1d3d83d1b9d4b Mon Sep 17 00:00:00 2001 From: Piotr Srebrny Date: Wed, 12 Oct 2022 16:47:46 +0200 Subject: Don't use device.path gst property for device ID, instead generate it The gst_device_get_properties does not work for libcamera; thus, we cannot use the device.path property as the device ID. Instead, we generate ID locally and bind it with GstDevice* in one object. Fixes: QTBUG-104226 Change-Id: I837b74175e48ee15d3fbb3ab26cf21d6a5fea794 Reviewed-by: Lars Knoll (cherry picked from commit 31430b1d1b2f89cc81a7301013e381cc3fab1a75) --- .../platform/gstreamer/qgstreamermediadevices.cpp | 98 ++++++++++++---------- .../platform/gstreamer/qgstreamermediadevices_p.h | 10 ++- 2 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/multimedia/platform/gstreamer/qgstreamermediadevices.cpp b/src/multimedia/platform/gstreamer/qgstreamermediadevices.cpp index 6e49057cf..bd75d80c3 100644 --- a/src/multimedia/platform/gstreamer/qgstreamermediadevices.cpp +++ b/src/multimedia/platform/gstreamer/qgstreamermediadevices.cpp @@ -136,52 +136,53 @@ QList QGstreamerMediaDevices::videoInputs() const { QList devices; - for (auto *d : qAsConst(m_videoSources)) { - QGstStructure properties = gst_device_get_properties(d); - if (!properties.isNull()) { - QCameraDevicePrivate *info = new QCameraDevicePrivate; - auto *desc = gst_device_get_display_name(d); - info->description = QString::fromUtf8(desc); - g_free(desc); - - info->id = properties["device.path"].toString(); + for (auto device : m_videoSources) { + QCameraDevicePrivate *info = new QCameraDevicePrivate; + auto *desc = gst_device_get_display_name(device.gstDevice); + info->description = QString::fromUtf8(desc); + g_free(desc); + info->id = device.id; + + if (QGstStructure properties = gst_device_get_properties(device.gstDevice); !properties.isNull()) { auto def = properties["is-default"].toBool(); info->isDefault = def && *def; - if (def) - devices.prepend(info->create()); - else - devices.append(info->create()); properties.free(); - QGstCaps caps = gst_device_get_caps(d); - if (!caps.isNull()) { - QList formats; - QSet photoResolutions; - - int size = caps.size(); - for (int i = 0; i < size; ++i) { - auto cap = caps.at(i); - - QSize resolution = cap.resolution(); - if (!resolution.isValid()) - continue; - - auto pixelFormat = cap.pixelFormat(); - auto frameRate = cap.frameRateRange(); - - auto *f = new QCameraFormatPrivate{ - QSharedData(), - pixelFormat, - resolution, - frameRate.min, - frameRate.max - }; - formats << f->create(); - photoResolutions.insert(resolution); - } - info->videoFormats = formats; - // ### sort resolutions? - info->photoResolutions = photoResolutions.values(); + } + + if (info->isDefault) + devices.prepend(info->create()); + else + devices.append(info->create()); + + QGstCaps caps = gst_device_get_caps(device.gstDevice); + if (!caps.isNull()) { + QList formats; + QSet photoResolutions; + + int size = caps.size(); + for (int i = 0; i < size; ++i) { + auto cap = caps.at(i); + + QSize resolution = cap.resolution(); + if (!resolution.isValid()) + continue; + + auto pixelFormat = cap.pixelFormat(); + auto frameRate = cap.frameRateRange(); + + auto *f = new QCameraFormatPrivate{ + QSharedData(), + pixelFormat, + resolution, + frameRate.min, + frameRate.max + }; + formats << f->create(); + photoResolutions.insert(resolution); } + info->videoFormats = formats; + // ### sort resolutions? + info->photoResolutions = photoResolutions.values(); } } return devices; @@ -203,8 +204,9 @@ void QGstreamerMediaDevices::addDevice(GstDevice *device) // qDebug() << "adding device:" << device << type << gst_device_get_display_name(device) << gst_structure_to_string(gst_device_get_properties(device)); gst_object_ref(device); if (!strcmp(type, "Video/Source")) { - m_videoSources.insert(device); + m_videoSources.push_back({device, QByteArray::number(m_idGenerator)}); videoInputsChanged(); + m_idGenerator++; } else if (!strcmp(type, "Audio/Source")) { m_audioSources.insert(device); audioInputsChanged(); @@ -220,7 +222,11 @@ void QGstreamerMediaDevices::addDevice(GstDevice *device) void QGstreamerMediaDevices::removeDevice(GstDevice *device) { // qDebug() << "removing device:" << device << gst_device_get_display_name(device); - if (m_videoSources.remove(device)) { + auto it = std::find_if(m_videoSources.begin(), m_videoSources.end(), + [=](const QGstDevice &a) { return a.gstDevice == device; }); + + if (it != m_videoSources.end()) { + m_videoSources.erase(it); videoInputsChanged(); } else if (m_audioSources.remove(device)) { audioInputsChanged(); @@ -259,7 +265,9 @@ GstDevice *QGstreamerMediaDevices::audioDevice(const QByteArray &id, QAudioDevic GstDevice *QGstreamerMediaDevices::videoDevice(const QByteArray &id) const { - return getDevice(m_videoSources, "device.path", id); + auto it = std::find_if(m_videoSources.begin(), m_videoSources.end(), + [=](const QGstDevice &a) { return a.id == id; }); + return it != m_videoSources.end() ? it->gstDevice : nullptr; } QT_END_NAMESPACE diff --git a/src/multimedia/platform/gstreamer/qgstreamermediadevices_p.h b/src/multimedia/platform/gstreamer/qgstreamermediadevices_p.h index e3f34433f..121e080e6 100644 --- a/src/multimedia/platform/gstreamer/qgstreamermediadevices_p.h +++ b/src/multimedia/platform/gstreamer/qgstreamermediadevices_p.h @@ -55,6 +55,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -76,7 +77,14 @@ public: GstDevice *videoDevice(const QByteArray &id) const; private: - QSet m_videoSources; + struct QGstDevice { + GstDevice *gstDevice = nullptr; + QByteArray id; + }; + + quint64 m_idGenerator = 0; + std::vector m_videoSources; + QSet m_audioSources; QSet m_audioSinks; }; -- cgit v1.2.3