summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gsttools/qgstreamervideoinputdevicecontrol.cpp85
-rw-r--r--src/gsttools/qgstutils.cpp165
-rw-r--r--src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h12
-rw-r--r--src/multimedia/gsttools_headers/qgstutils_p.h16
-rw-r--r--src/plugins/gstreamer/camerabin/camerabin.pro6
-rw-r--r--src/plugins/gstreamer/camerabin/camerabininfocontrol.cpp71
-rw-r--r--src/plugins/gstreamer/camerabin/camerabininfocontrol.h67
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinservice.cpp44
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinservice.h3
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp116
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinserviceplugin.h18
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.cpp32
-rw-r--r--src/plugins/gstreamer/camerabin/camerabinsession.h4
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp84
-rw-r--r--src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h7
15 files changed, 446 insertions, 284 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)
diff --git a/src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h b/src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h
index eeb576ef5..c4fe83fbc 100644
--- a/src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h
+++ b/src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h
@@ -46,6 +46,7 @@
#include <QtCore/qstringlist.h>
#include <gst/gst.h>
+#include <qcamera.h>
QT_BEGIN_NAMESPACE
@@ -54,7 +55,7 @@ class QGstreamerVideoInputDeviceControl : public QVideoDeviceSelectorControl
Q_OBJECT
public:
QGstreamerVideoInputDeviceControl(QObject *parent);
- QGstreamerVideoInputDeviceControl(GstElement *source, QObject *parent);
+ QGstreamerVideoInputDeviceControl(GstElementFactory *factory, QObject *parent);
~QGstreamerVideoInputDeviceControl();
int deviceCount() const;
@@ -65,17 +66,16 @@ public:
int defaultDevice() const;
int selectedDevice() const;
+ static QString primaryCamera() { return tr("Main camera"); }
+ static QString secondaryCamera() { return tr("Front camera"); }
+
public Q_SLOTS:
void setSelectedDevice(int index);
private:
- void update();
-
- GstElement *m_source;
+ GstElementFactory *m_factory;
int m_selectedDevice;
- QStringList m_names;
- QStringList m_descriptions;
};
QT_END_NAMESPACE
diff --git a/src/multimedia/gsttools_headers/qgstutils_p.h b/src/multimedia/gsttools_headers/qgstutils_p.h
index eea1e15d9..701de59da 100644
--- a/src/multimedia/gsttools_headers/qgstutils_p.h
+++ b/src/multimedia/gsttools_headers/qgstutils_p.h
@@ -55,8 +55,10 @@
#include <QtCore/qmap.h>
#include <QtCore/qset.h>
+#include <QtCore/qvector.h>
#include <gst/gst.h>
#include <qaudioformat.h>
+#include <qcamera.h>
QT_BEGIN_NAMESPACE
@@ -65,6 +67,14 @@ class QVariant;
class QByteArray;
namespace QGstUtils {
+ struct CameraInfo
+ {
+ QString name;
+ QString description;
+ int orientation;
+ QCamera::Position position;
+ };
+
QMap<QByteArray, QVariant> gstTagListToMap(const GstTagList *list);
QSize capsResolution(const GstCaps *caps);
@@ -76,6 +86,12 @@ namespace QGstUtils {
QMultimedia::SupportEstimate hasSupport(const QString &mimeType,
const QStringList &codecs,
const QSet<QString> &supportedMimeTypeSet);
+
+ QVector<CameraInfo> enumerateCameras(GstElementFactory *factory = 0);
+ QList<QByteArray> cameraDevices(GstElementFactory * factory = 0);
+ QString cameraDescription(const QString &device, GstElementFactory * factory = 0);
+ QCamera::Position cameraPosition(const QString &device, GstElementFactory * factory = 0);
+ int cameraOrientation(const QString &device, GstElementFactory * factory = 0);
}
void qt_gst_object_ref_sink(gpointer object);
diff --git a/src/plugins/gstreamer/camerabin/camerabin.pro b/src/plugins/gstreamer/camerabin/camerabin.pro
index 9efa0812a..bba797f5e 100644
--- a/src/plugins/gstreamer/camerabin/camerabin.pro
+++ b/src/plugins/gstreamer/camerabin/camerabin.pro
@@ -30,7 +30,8 @@ HEADERS += \
$$PWD/camerabinresourcepolicy.h \
$$PWD/camerabincapturedestination.h \
$$PWD/camerabincapturebufferformat.h \
- $$PWD/camerabinviewfindersettings.h
+ $$PWD/camerabinviewfindersettings.h \
+ $$PWD/camerabininfocontrol.h
SOURCES += \
$$PWD/camerabinserviceplugin.cpp \
@@ -48,7 +49,8 @@ SOURCES += \
$$PWD/camerabinresourcepolicy.cpp \
$$PWD/camerabincapturedestination.cpp \
$$PWD/camerabinviewfindersettings.cpp \
- $$PWD/camerabincapturebufferformat.cpp
+ $$PWD/camerabincapturebufferformat.cpp \
+ $$PWD/camerabininfocontrol.cpp
maemo6 {
HEADERS += \
diff --git a/src/plugins/gstreamer/camerabin/camerabininfocontrol.cpp b/src/plugins/gstreamer/camerabin/camerabininfocontrol.cpp
new file mode 100644
index 000000000..a3ee369c1
--- /dev/null
+++ b/src/plugins/gstreamer/camerabin/camerabininfocontrol.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "camerabininfocontrol.h"
+
+#include <private/qgstutils_p.h>
+
+QT_BEGIN_NAMESPACE
+
+CameraBinInfoControl::CameraBinInfoControl(GstElementFactory *sourceFactory, QObject *parent)
+ : QCameraInfoControl(parent)
+ , m_sourceFactory(sourceFactory)
+{
+ gst_object_ref(GST_OBJECT(m_sourceFactory));
+}
+
+CameraBinInfoControl::~CameraBinInfoControl()
+{
+ gst_object_unref(GST_OBJECT(m_sourceFactory));
+}
+
+QCamera::Position CameraBinInfoControl::cameraPosition(const QString &device) const
+{
+ return QGstUtils::cameraPosition(device, m_sourceFactory);
+}
+
+int CameraBinInfoControl::cameraOrientation(const QString &device) const
+{
+ return QGstUtils::cameraOrientation(device, m_sourceFactory);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabininfocontrol.h b/src/plugins/gstreamer/camerabin/camerabininfocontrol.h
new file mode 100644
index 000000000..577eb3f4a
--- /dev/null
+++ b/src/plugins/gstreamer/camerabin/camerabininfocontrol.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CAMERABININFOCONTROL_H
+#define CAMERABININFOCONTROL_H
+
+#include <qcamerainfocontrol.h>
+
+#include <gst/gst.h>
+
+QT_BEGIN_NAMESPACE
+
+class CameraBinInfoControl : public QCameraInfoControl
+{
+ Q_OBJECT
+public:
+ CameraBinInfoControl(GstElementFactory *sourceFactory, QObject *parent);
+ ~CameraBinInfoControl();
+
+ QCamera::Position cameraPosition(const QString &deviceName) const;
+ int cameraOrientation(const QString &deviceName) const;
+
+private:
+ GstElementFactory * const m_sourceFactory;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/gstreamer/camerabin/camerabinservice.cpp b/src/plugins/gstreamer/camerabin/camerabinservice.cpp
index df02a9ecc..5db723696 100644
--- a/src/plugins/gstreamer/camerabin/camerabinservice.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinservice.cpp
@@ -48,6 +48,7 @@
#include "camerabinimageencoder.h"
#include "camerabincontrol.h"
#include "camerabinmetadata.h"
+#include "camerabininfocontrol.h"
#ifdef HAVE_GST_PHOTOGRAPHY
#include "camerabinexposure.h"
@@ -89,8 +90,9 @@
QT_BEGIN_NAMESPACE
-CameraBinService::CameraBinService(const QString &service, QObject *parent):
- QMediaService(parent)
+CameraBinService::CameraBinService(GstElementFactory *sourceFactory, QObject *parent):
+ QMediaService(parent),
+ m_cameraInfoControl(0)
{
m_captureSession = 0;
m_metaDataControl = 0;
@@ -106,40 +108,32 @@ CameraBinService::CameraBinService(const QString &service, QObject *parent):
#endif
m_imageCaptureControl = 0;
- if (service == Q_MEDIASERVICE_CAMERA) {
- m_captureSession = new CameraBinSession(this);
- m_videoInputDevice = new QGstreamerVideoInputDeviceControl(
- m_captureSession->buildCameraSource(), m_captureSession);
- m_imageCaptureControl = new CameraBinImageCapture(m_captureSession);
+ m_captureSession = new CameraBinSession(sourceFactory, this);
+ m_videoInputDevice = new QGstreamerVideoInputDeviceControl(sourceFactory, m_captureSession);
+ m_imageCaptureControl = new CameraBinImageCapture(m_captureSession);
- connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)),
- m_captureSession, SLOT(setDevice(QString)));
+ connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)),
+ m_captureSession, SLOT(setDevice(QString)));
- if (m_videoInputDevice->deviceCount())
- m_captureSession->setDevice(m_videoInputDevice->deviceName(m_videoInputDevice->selectedDevice()));
+ if (m_videoInputDevice->deviceCount())
+ m_captureSession->setDevice(m_videoInputDevice->deviceName(m_videoInputDevice->selectedDevice()));
#if defined(Q_WS_MAEMO_6) && defined(__arm__) && defined(HAVE_WIDGETS)
- m_videoRenderer = new QGstreamerGLTextureRenderer(this);
+ m_videoRenderer = new QGstreamerGLTextureRenderer(this);
#else
- m_videoRenderer = new QGstreamerVideoRenderer(this);
+ m_videoRenderer = new QGstreamerVideoRenderer(this);
#endif
#ifdef Q_WS_MAEMO_6
- m_videoWindow = new QGstreamerVideoWindow(this, "omapxvsink");
+ m_videoWindow = new QGstreamerVideoWindow(this, "omapxvsink");
#else
- m_videoWindow = new QGstreamerVideoWindow(this);
+ m_videoWindow = new QGstreamerVideoWindow(this);
#endif
#if defined(HAVE_WIDGETS)
- m_videoWidgetControl = new QGstreamerVideoWidgetControl(this);
+ m_videoWidgetControl = new QGstreamerVideoWidgetControl(this);
#endif
- }
- if (!m_captureSession) {
- qWarning() << Q_FUNC_INFO << "Service type is not supported:" << service;
- return;
- }
-
m_audioInputSelector = new QGstreamerAudioInputSelector(this);
connect(m_audioInputSelector, SIGNAL(activeInputChanged(QString)), m_captureSession, SLOT(setCaptureDevice(QString)));
@@ -244,6 +238,12 @@ QMediaControl *CameraBinService::requestControl(const char *name)
if (qstrcmp(name, QCameraViewfinderSettingsControl_iid) == 0)
return m_captureSession->viewfinderSettingsControl();
+ if (qstrcmp(name, QCameraInfoControl_iid) == 0) {
+ if (!m_cameraInfoControl)
+ m_cameraInfoControl = new CameraBinInfoControl(m_captureSession->sourceFactory(), this);
+ return m_cameraInfoControl;
+ }
+
return 0;
}
diff --git a/src/plugins/gstreamer/camerabin/camerabinservice.h b/src/plugins/gstreamer/camerabin/camerabinservice.h
index 7d3b3df09..4dc0f40f0 100644
--- a/src/plugins/gstreamer/camerabin/camerabinservice.h
+++ b/src/plugins/gstreamer/camerabin/camerabinservice.h
@@ -67,7 +67,7 @@ class CameraBinService : public QMediaService
Q_OBJECT
public:
- CameraBinService(const QString &service, QObject *parent = 0);
+ CameraBinService(GstElementFactory *sourceFactory, QObject *parent = 0);
virtual ~CameraBinService();
QMediaControl *requestControl(const char *name);
@@ -92,6 +92,7 @@ private:
QGstreamerVideoWidgetControl *m_videoWidgetControl;
#endif
CameraBinImageCapture *m_imageCaptureControl;
+ QMediaControl *m_cameraInfoControl;
};
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
index 3decd6070..bfb0c4935 100644
--- a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
@@ -55,12 +55,25 @@
QT_BEGIN_NAMESPACE
+template <typename T, int N> static int lengthOf(const T(&)[N]) { return N; }
+
+CameraBinServicePlugin::CameraBinServicePlugin()
+ : m_sourceFactory(0)
+{
+}
+
+CameraBinServicePlugin::~CameraBinServicePlugin()
+{
+ if (m_sourceFactory)
+ gst_object_unref(GST_OBJECT(m_sourceFactory));
+}
+
QMediaService* CameraBinServicePlugin::create(const QString &key)
{
QGstUtils::initializeGst();
if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
- return new CameraBinService(key);
+ return new CameraBinService(sourceFactory());
qWarning() << "Gstreamer camerabin service plugin: unsupported key:" << key;
return 0;
@@ -82,40 +95,24 @@ QMediaServiceProviderHint::Features CameraBinServicePlugin::supportedFeatures(
QByteArray CameraBinServicePlugin::defaultDevice(const QByteArray &service) const
{
- if (service == Q_MEDIASERVICE_CAMERA) {
- if (m_cameraDevices.isEmpty())
- updateDevices();
-
- return m_defaultCameraDevice;
- }
-
- return QByteArray();
+ return service == Q_MEDIASERVICE_CAMERA
+ ? QGstUtils::enumerateCameras(sourceFactory()).value(0).name.toUtf8()
+ : QByteArray();
}
QList<QByteArray> CameraBinServicePlugin::devices(const QByteArray &service) const
{
- if (service == Q_MEDIASERVICE_CAMERA) {
- if (m_cameraDevices.isEmpty())
- updateDevices();
- return m_cameraDevices;
- }
-
- return QList<QByteArray>();
+ return service == Q_MEDIASERVICE_CAMERA
+ ? QGstUtils::cameraDevices(m_sourceFactory)
+ : QList<QByteArray>();
}
-QString CameraBinServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
+QString CameraBinServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &deviceName)
{
- if (service == Q_MEDIASERVICE_CAMERA) {
- if (m_cameraDevices.isEmpty())
- updateDevices();
-
- for (int i=0; i<m_cameraDevices.count(); i++)
- if (m_cameraDevices[i] == device)
- return m_cameraDescriptions[i];
- }
-
- return QString();
+ return service == Q_MEDIASERVICE_CAMERA
+ ? QGstUtils::cameraDescription(deviceName, m_sourceFactory)
+ : QString();
}
QVariant CameraBinServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property)
@@ -126,53 +123,36 @@ QVariant CameraBinServicePlugin::deviceProperty(const QByteArray &service, const
return QVariant();
}
-void CameraBinServicePlugin::updateDevices() const
+QCamera::Position CameraBinServicePlugin::cameraPosition(const QByteArray &deviceName) const
{
- m_defaultCameraDevice.clear();
- m_cameraDevices.clear();
- m_cameraDescriptions.clear();
-
- QDir devDir("/dev");
- devDir.setFilter(QDir::System);
-
- QFileInfoList entries = devDir.entryInfoList(QStringList() << "video*");
-
- foreach (const QFileInfo &entryInfo, entries) {
- 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));
+ return QGstUtils::cameraPosition(deviceName, m_sourceFactory);
+}
- if (ioctl(fd, VIDIOC_QUERYCAP, &vcap) != 0)
- name = entryInfo.fileName();
- else
- name = QString((const char*)vcap.card);
- //qDebug() << "found camera: " << name;
+int CameraBinServicePlugin::cameraOrientation(const QByteArray &deviceName) const
+{
+ return QGstUtils::cameraOrientation(deviceName, m_sourceFactory);
+}
- m_cameraDevices.append(entryInfo.filePath().toLocal8Bit());
- m_cameraDescriptions.append(name);
+GstElementFactory *CameraBinServicePlugin::sourceFactory() const
+{
+ if (!m_sourceFactory) {
+ GstElementFactory *factory = 0;
+ const QByteArray envCandidate = qgetenv("QT_GSTREAMER_CAMERABIN_SRC");
+ if (!envCandidate.isEmpty())
+ factory = gst_element_factory_find(envCandidate.constData());
+
+ static const char *candidates[] = { "subdevsrc", "wrappercamerabinsrc" };
+ for (int i = 0; !factory && i < lengthOf(candidates); ++i)
+ factory = gst_element_factory_find(candidates[i]);
+
+ if (factory) {
+ m_sourceFactory = GST_ELEMENT_FACTORY(gst_plugin_feature_load(
+ GST_PLUGIN_FEATURE(factory)));
+ gst_object_unref((GST_OBJECT(factory)));
}
- qt_safe_close(fd);
}
- if (!m_cameraDevices.isEmpty())
- m_defaultCameraDevice = m_cameraDevices.first();
+ return m_sourceFactory;
}
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h
index 50ffc59b2..6b192d8ea 100644
--- a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h
+++ b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h
@@ -44,7 +44,9 @@
#define CAMERABINSERVICEPLUGIN_H
#include <qmediaserviceproviderplugin.h>
-#include <QtCore/QObject>
+#include <private/qgstreamervideoinputdevicecontrol_p.h>
+
+#include <gst/gst.h>
QT_BEGIN_NAMESPACE
@@ -53,13 +55,18 @@ class CameraBinServicePlugin
, public QMediaServiceSupportedDevicesInterface
, public QMediaServiceDefaultDeviceInterface
, public QMediaServiceFeaturesInterface
+ , public QMediaServiceCameraInfoInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_INTERFACES(QMediaServiceFeaturesInterface)
+ Q_INTERFACES(QMediaServiceCameraInfoInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "camerabin.json")
public:
+ CameraBinServicePlugin();
+ ~CameraBinServicePlugin();
+
QMediaService* create(QString const& key);
void release(QMediaService *service);
@@ -70,12 +77,13 @@ public:
QString deviceDescription(const QByteArray &service, const QByteArray &device);
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
+ QCamera::Position cameraPosition(const QByteArray &device) const;
+ int cameraOrientation(const QByteArray &device) const;
+
private:
- void updateDevices() const;
+ GstElementFactory *sourceFactory() const;
- mutable QByteArray m_defaultCameraDevice;
- mutable QList<QByteArray> m_cameraDevices;
- mutable QStringList m_cameraDescriptions;
+ mutable GstElementFactory *m_sourceFactory;
};
QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
index a835b1ce5..b18e9c93c 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp
@@ -119,7 +119,7 @@
QT_BEGIN_NAMESPACE
-CameraBinSession::CameraBinSession(QObject *parent)
+CameraBinSession::CameraBinSession(GstElementFactory *sourceFactory, QObject *parent)
:QObject(parent),
m_recordingActive(false),
m_state(QCamera::UnloadedState),
@@ -133,6 +133,7 @@ CameraBinSession::CameraBinSession(QObject *parent)
m_viewfinderInterface(0),
m_videoSrc(0),
m_viewfinderElement(0),
+ m_sourceFactory(sourceFactory),
m_viewfinderHasChanged(true),
m_videoInputHasChanged(true),
m_audioSrc(0),
@@ -142,6 +143,9 @@ CameraBinSession::CameraBinSession(QObject *parent)
m_audioEncoder(0),
m_muxer(0)
{
+ if (m_sourceFactory)
+ gst_object_ref(GST_OBJECT(m_sourceFactory));
+
m_camerabin = gst_element_factory_make("camerabin2", "camerabin2");
g_signal_connect(G_OBJECT(m_camerabin), "notify::idle", G_CALLBACK(updateBusyStatus), this);
qt_gst_object_ref_sink(m_camerabin);
@@ -195,6 +199,9 @@ CameraBinSession::~CameraBinSession()
}
if (m_viewfinderElement)
gst_object_unref(GST_OBJECT(m_viewfinderElement));
+
+ if (m_sourceFactory)
+ gst_object_unref(GST_OBJECT(m_sourceFactory));
}
#ifdef HAVE_GST_PHOTOGRAPHY
@@ -383,32 +390,17 @@ GstElement *CameraBinSession::buildCameraSource()
m_videoInputHasChanged = false;
GstElement *videoSrc = 0;
+
+ if (!videoSrc)
g_object_get(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, &videoSrc, NULL);
- // If the QT_GSTREAMER_CAMERABIN_SRC environment variable has been set use the source
- // it recommends.
- const QByteArray envCandidate = qgetenv("QT_GSTREAMER_CAMERABIN_SRC");
- if (!m_videoSrc && !envCandidate.isEmpty()) {
- m_videoSrc = gst_element_factory_make(envCandidate.constData(), "camera_source");
- }
+ if (m_sourceFactory)
+ m_videoSrc = gst_element_factory_create(m_sourceFactory, "camera_source");
// If gstreamer has set a default source use it.
if (!m_videoSrc)
m_videoSrc = videoSrc;
- // If there's no better guidance try the names of some known camera source elements.
- if (!m_videoSrc) {
- const QList<QByteArray> candidates = QList<QByteArray>()
- << "subdevsrc"
- << "wrappercamerabinsrc";
-
- foreach (const QByteArray &sourceElementName, candidates) {
- m_videoSrc = gst_element_factory_make(sourceElementName.constData(), "camera_source");
- if (m_videoSrc)
- break;
- }
- }
-
if (m_videoSrc && !m_inputDevice.isEmpty()) {
#if CAMERABIN_DEBUG
qDebug() << "set camera device" << m_inputDevice;
diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h
index 54800e9ed..836c0866a 100644
--- a/src/plugins/gstreamer/camerabin/camerabinsession.h
+++ b/src/plugins/gstreamer/camerabin/camerabinsession.h
@@ -96,7 +96,7 @@ public:
BackCamera // Main photo camera
};
- CameraBinSession(QObject *parent);
+ CameraBinSession(GstElementFactory *sourceFactory, QObject *parent);
~CameraBinSession();
#ifdef HAVE_GST_PHOTOGRAPHY
@@ -121,6 +121,7 @@ public:
QString generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const;
GstElement *buildCameraSource();
+ GstElementFactory *sourceFactory() const { return m_sourceFactory; }
CameraBinControl *cameraControl() const { return m_cameraControl; }
CameraBinAudioEncoder *audioEncodeControl() const { return m_audioEncodeControl; }
@@ -239,6 +240,7 @@ private:
GstElement *m_camerabin;
GstElement *m_videoSrc;
GstElement *m_viewfinderElement;
+ GstElementFactory *m_sourceFactory;
bool m_viewfinderHasChanged;
bool m_videoInputHasChanged;
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
index 8b88fbb71..6763c68e2 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp
@@ -51,9 +51,6 @@
#include "qgstreamercaptureservice.h"
#include <private/qgstutils_p.h>
-#include <private/qcore_unix_p.h>
-#include <linux/videodev2.h>
-
QMediaService* QGstreamerCaptureServicePlugin::create(const QString &key)
{
QGstUtils::initializeGst();
@@ -87,40 +84,19 @@ QMediaServiceProviderHint::Features QGstreamerCaptureServicePlugin::supportedFea
QByteArray QGstreamerCaptureServicePlugin::defaultDevice(const QByteArray &service) const
{
- if (service == Q_MEDIASERVICE_CAMERA) {
- if (m_cameraDevices.isEmpty())
- updateDevices();
-
- return m_defaultCameraDevice;
- }
-
- return QByteArray();
+ return service == Q_MEDIASERVICE_CAMERA
+ ? QGstUtils::enumerateCameras().value(0).name.toUtf8()
+ : QByteArray();
}
QList<QByteArray> QGstreamerCaptureServicePlugin::devices(const QByteArray &service) const
{
- if (service == Q_MEDIASERVICE_CAMERA) {
- if (m_cameraDevices.isEmpty())
- updateDevices();
-
- return m_cameraDevices;
- }
-
- return QList<QByteArray>();
+ return service == Q_MEDIASERVICE_CAMERA ? QGstUtils::cameraDevices() : QList<QByteArray>();
}
QString QGstreamerCaptureServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
{
- if (service == Q_MEDIASERVICE_CAMERA) {
- if (m_cameraDevices.isEmpty())
- updateDevices();
-
- for (int i=0; i<m_cameraDevices.count(); i++)
- if (m_cameraDevices[i] == device)
- return m_cameraDescriptions[i];
- }
-
- return QString();
+ return service == Q_MEDIASERVICE_CAMERA ? QGstUtils::cameraDescription(deviceName) : QString();
}
QVariant QGstreamerCaptureServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property)
@@ -131,56 +107,6 @@ QVariant QGstreamerCaptureServicePlugin::deviceProperty(const QByteArray &servic
return QVariant();
}
-void QGstreamerCaptureServicePlugin::updateDevices() const
-{
- m_defaultCameraDevice.clear();
- m_cameraDevices.clear();
- m_cameraDescriptions.clear();
-
- 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_cameraDevices.append(entryInfo.filePath().toLocal8Bit());
- m_cameraDescriptions.append(name);
- }
- qt_safe_close(fd);
- }
-
- if (!m_cameraDevices.isEmpty())
- m_defaultCameraDevice = m_cameraDevices.first();
-}
#endif
QMultimedia::SupportEstimate QGstreamerCaptureServicePlugin::hasSupport(const QString &mimeType,
diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h
index a1141d324..a46be9ebd 100644
--- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h
+++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.h
@@ -87,13 +87,6 @@ public:
QStringList supportedMimeTypes() const;
private:
-#if defined(USE_GSTREAMER_CAMERA)
- void updateDevices() const;
-
- mutable QByteArray m_defaultCameraDevice;
- mutable QList<QByteArray> m_cameraDevices;
- mutable QStringList m_cameraDescriptions;
-#endif
void updateSupportedMimeTypes() const;
mutable QSet<QString> m_supportedMimeTypeSet; //for fast access