summaryrefslogtreecommitdiffstats
path: root/src/gsttools
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsttools')
-rw-r--r--src/gsttools/qgstreamervideoinputdevicecontrol.cpp85
-rw-r--r--src/gsttools/qgstutils.cpp165
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)