summaryrefslogtreecommitdiffstats
path: root/src/gsttools
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den.exter@jollamobile.com>2014-07-08 15:56:05 +1000
committerAndrew den Exter <andrew.den.exter@qinetic.com.au>2014-07-12 02:46:10 +0200
commitcddbe8736d995b4bfdfbbf1abfc3d6aeae3eb214 (patch)
tree8d775c9ee17902ae39aebae0d825ee3a93455135 /src/gsttools
parent074bd6ab37bbbb4dbba188921783fd98be872555 (diff)
Provide face and orientation info from gstreamer camera backend.
Cleans up duplicate device enumeration code so the devices listed by the QMediaServiceProviderPlugin are the same as those in the QVideoInputDeviceControl and includes face and orientation information if available. Change-Id: Iaa4c303c973bcf3e0f7c8c2fd7a7de629bccec86 Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
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)