diff options
Diffstat (limited to 'src/gsttools')
-rw-r--r-- | src/gsttools/qgstreamervideoinputdevicecontrol.cpp | 85 | ||||
-rw-r--r-- | src/gsttools/qgstutils.cpp | 165 |
2 files changed, 177 insertions, 73 deletions
diff --git a/src/gsttools/qgstreamervideoinputdevicecontrol.cpp b/src/gsttools/qgstreamervideoinputdevicecontrol.cpp index e4e202caf..c26029cbf 100644 --- a/src/gsttools/qgstreamervideoinputdevicecontrol.cpp +++ b/src/gsttools/qgstreamervideoinputdevicecontrol.cpp @@ -44,43 +44,40 @@ #include <QtCore/QDir> #include <QtCore/QDebug> -#include <private/qcore_unix_p.h> -#include <linux/videodev2.h> +#include <private/qgstutils_p.h> QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(QObject *parent) - :QVideoDeviceSelectorControl(parent), m_source(0), m_selectedDevice(0) + :QVideoDeviceSelectorControl(parent), m_factory(0), m_selectedDevice(0) { - update(); } -QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(GstElement *source, QObject *parent) - :QVideoDeviceSelectorControl(parent), m_source(source), m_selectedDevice(0) +QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl( + GstElementFactory *factory, QObject *parent) + : QVideoDeviceSelectorControl(parent), m_factory(factory), m_selectedDevice(0) { - if (m_source) - gst_object_ref(GST_OBJECT(m_source)); - - update(); + if (m_factory) + gst_object_ref(GST_OBJECT(m_factory)); } QGstreamerVideoInputDeviceControl::~QGstreamerVideoInputDeviceControl() { - if (m_source) - gst_object_unref(GST_OBJECT(m_source)); + if (m_factory) + gst_object_unref(GST_OBJECT(m_factory)); } int QGstreamerVideoInputDeviceControl::deviceCount() const { - return m_names.size(); + return QGstUtils::enumerateCameras(m_factory).count(); } QString QGstreamerVideoInputDeviceControl::deviceName(int index) const { - return m_names[index]; + return QGstUtils::enumerateCameras(m_factory).value(index).name; } QString QGstreamerVideoInputDeviceControl::deviceDescription(int index) const { - return m_descriptions[index]; + return QGstUtils::enumerateCameras(m_factory).value(index).description; } int QGstreamerVideoInputDeviceControl::defaultDevice() const @@ -93,7 +90,6 @@ int QGstreamerVideoInputDeviceControl::selectedDevice() const return m_selectedDevice; } - void QGstreamerVideoInputDeviceControl::setSelectedDevice(int index) { if (index != m_selectedDevice) { @@ -102,60 +98,3 @@ void QGstreamerVideoInputDeviceControl::setSelectedDevice(int index) emit selectedDeviceChanged(deviceName(index)); } } - - -void QGstreamerVideoInputDeviceControl::update() -{ - m_names.clear(); - m_descriptions.clear(); - - // subdevsrc and the like have a camera-device property that takes an enumeration - // identifying a primary or secondary camera, so return identifiers that map to those - // instead of a list of actual devices. - if (m_source && g_object_class_find_property(G_OBJECT_GET_CLASS(m_source), "camera-device")) { - m_names << QLatin1String("primary") << QLatin1String("secondary"); - m_descriptions << tr("Main camera") << tr("Front camera"); - return; - } - - QDir devDir("/dev"); - devDir.setFilter(QDir::System); - - QFileInfoList entries = devDir.entryInfoList(QStringList() << "video*"); - - foreach( const QFileInfo &entryInfo, entries ) { - //qDebug() << "Try" << entryInfo.filePath(); - - int fd = qt_safe_open(entryInfo.filePath().toLatin1().constData(), O_RDWR ); - if (fd == -1) - continue; - - bool isCamera = false; - - v4l2_input input; - memset(&input, 0, sizeof(input)); - for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) { - if(input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) { - isCamera = ::ioctl(fd, VIDIOC_S_INPUT, input.index) != 0; - break; - } - } - - if (isCamera) { - // find out its driver "name" - QString name; - struct v4l2_capability vcap; - memset(&vcap, 0, sizeof(struct v4l2_capability)); - - if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0) - name = entryInfo.fileName(); - else - name = QString((const char*)vcap.card); - //qDebug() << "found camera: " << name; - - m_names.append(entryInfo.filePath()); - m_descriptions.append(name); - } - qt_safe_close(fd); - } -} diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp index 41bd005bd..9d94cb6db 100644 --- a/src/gsttools/qgstutils.cpp +++ b/src/gsttools/qgstutils.cpp @@ -42,6 +42,7 @@ #include "qgstutils_p.h" #include <QtCore/qdatetime.h> +#include <QtCore/qdir.h> #include <QtCore/qbytearray.h> #include <QtCore/qvariant.h> #include <QtCore/qsize.h> @@ -49,6 +50,11 @@ #include <QtCore/qstringlist.h> #include <qaudioformat.h> +#include <private/qcore_unix_p.h> +#include <linux/videodev2.h> + +#include "qgstreamervideoinputdevicecontrol_p.h" + QT_BEGIN_NAMESPACE //internal @@ -401,6 +407,165 @@ QMultimedia::SupportEstimate QGstUtils::hasSupport(const QString &mimeType, return QMultimedia::MaybeSupported; } +namespace { + +typedef QHash<GstElementFactory *, QVector<QGstUtils::CameraInfo> > FactoryCameraInfoMap; + +Q_GLOBAL_STATIC(FactoryCameraInfoMap, qt_camera_device_info); + +} + +QVector<QGstUtils::CameraInfo> QGstUtils::enumerateCameras(GstElementFactory *factory) +{ + FactoryCameraInfoMap::const_iterator it = qt_camera_device_info()->constFind(factory); + if (it != qt_camera_device_info()->constEnd()) + return *it; + + QVector<CameraInfo> &devices = (*qt_camera_device_info())[factory]; + + if (factory) { + bool hasVideoSource = false; + + const GType type = gst_element_factory_get_element_type(factory); + GObjectClass * const objectClass = type + ? static_cast<GObjectClass *>(g_type_class_ref(type)) + : 0; + if (objectClass) { + if (g_object_class_find_property(objectClass, "camera-device")) { + const CameraInfo primary = { + QStringLiteral("primary"), + QGstreamerVideoInputDeviceControl::primaryCamera(), + 0, + QCamera::BackFace + }; + const CameraInfo secondary = { + QStringLiteral("secondary"), + QGstreamerVideoInputDeviceControl::secondaryCamera(), + 0, + QCamera::FrontFace + }; + + devices.append(primary); + devices.append(secondary); + + GstElement *camera = g_object_class_find_property(objectClass, "sensor-mount-angle") + ? gst_element_factory_create(factory, 0) + : 0; + if (camera) { + if (gst_element_set_state(camera, GST_STATE_READY) != GST_STATE_CHANGE_SUCCESS) { + // no-op + } else for (int i = 0; i < 2; ++i) { + gint orientation = 0; + g_object_set(G_OBJECT(camera), "camera-device", i, NULL); + g_object_get(G_OBJECT(camera), "sensor-mount-angle", &orientation, NULL); + + devices[i].orientation = (720 - orientation) % 360; + } + gst_element_set_state(camera, GST_STATE_NULL); + gst_object_unref(GST_OBJECT(camera)); + + } + } else if (g_object_class_find_property(objectClass, "video-source")) { + hasVideoSource = true; + } + + g_type_class_unref(objectClass); + } + + if (!devices.isEmpty() || !hasVideoSource) { + return devices; + } + } + + QDir devDir(QStringLiteral("/dev")); + devDir.setFilter(QDir::System); + + QFileInfoList entries = devDir.entryInfoList(QStringList() + << QStringLiteral("video*")); + + foreach (const QFileInfo &entryInfo, entries) { + //qDebug() << "Try" << entryInfo.filePath(); + + int fd = qt_safe_open(entryInfo.filePath().toLatin1().constData(), O_RDWR ); + if (fd == -1) + continue; + + bool isCamera = false; + + v4l2_input input; + memset(&input, 0, sizeof(input)); + for (; ::ioctl(fd, VIDIOC_ENUMINPUT, &input) >= 0; ++input.index) { + if (input.type == V4L2_INPUT_TYPE_CAMERA || input.type == 0) { + isCamera = ::ioctl(fd, VIDIOC_S_INPUT, input.index) != 0; + break; + } + } + + if (isCamera) { + // find out its driver "name" + QString name; + struct v4l2_capability vcap; + memset(&vcap, 0, sizeof(struct v4l2_capability)); + + if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0) + name = entryInfo.fileName(); + else + name = QString::fromUtf8((const char*)vcap.card); + //qDebug() << "found camera: " << name; + + + CameraInfo device = { + entryInfo.absoluteFilePath(), + name, + 0, + QCamera::UnspecifiedPosition + }; + devices.append(device); + } + qt_safe_close(fd); + } + + return devices; +} + +QList<QByteArray> QGstUtils::cameraDevices(GstElementFactory * factory) +{ + QList<QByteArray> devices; + + foreach (const CameraInfo &camera, enumerateCameras(factory)) + devices.append(camera.name.toUtf8()); + + return devices; +} + +QString QGstUtils::cameraDescription(const QString &device, GstElementFactory * factory) +{ + foreach (const CameraInfo &camera, enumerateCameras(factory)) { + if (camera.name == device) + return camera.description; + } + return QString(); +} + +QCamera::Position QGstUtils::cameraPosition(const QString &device, GstElementFactory * factory) +{ + foreach (const CameraInfo &camera, enumerateCameras(factory)) { + if (camera.name == device) + return camera.position; + } + return QCamera::UnspecifiedPosition; +} + +int QGstUtils::cameraOrientation(const QString &device, GstElementFactory * factory) +{ + foreach (const CameraInfo &camera, enumerateCameras(factory)) { + if (camera.name == device) + return camera.orientation; + } + return 0; +} + + void qt_gst_object_ref_sink(gpointer object) { #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 24) |