Allow the camerabin source selection to be overridden.
Prefer the default camera-source element if there is one or an element identified by an environment variable to a static list of possible elements which may not be appropriate for the target environment. Change-Id: I53816c949307953780f9046eb11e09effe059be0 Reviewed-by: John Brooks <john.brooks@dereferenced.net> Reviewed-by: Andy Nichols <andy.nichols@digia.com> Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
This commit is contained in:
committed by
The Qt Project
parent
817c548df4
commit
4d3f740795
@@ -57,13 +57,24 @@
|
|||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
|
||||||
QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(QObject *parent)
|
QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(QObject *parent)
|
||||||
:QVideoDeviceSelectorControl(parent), m_selectedDevice(0)
|
:QVideoDeviceSelectorControl(parent), m_source(0), m_selectedDevice(0)
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(GstElement *source, QObject *parent)
|
||||||
|
:QVideoDeviceSelectorControl(parent), m_source(source), m_selectedDevice(0)
|
||||||
|
{
|
||||||
|
if (m_source)
|
||||||
|
gst_object_ref(GST_OBJECT(m_source));
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
QGstreamerVideoInputDeviceControl::~QGstreamerVideoInputDeviceControl()
|
QGstreamerVideoInputDeviceControl::~QGstreamerVideoInputDeviceControl()
|
||||||
{
|
{
|
||||||
|
if (m_source)
|
||||||
|
gst_object_unref(GST_OBJECT(m_source));
|
||||||
}
|
}
|
||||||
|
|
||||||
int QGstreamerVideoInputDeviceControl::deviceCount() const
|
int QGstreamerVideoInputDeviceControl::deviceCount() const
|
||||||
@@ -107,10 +118,15 @@ void QGstreamerVideoInputDeviceControl::update()
|
|||||||
m_names.clear();
|
m_names.clear();
|
||||||
m_descriptions.clear();
|
m_descriptions.clear();
|
||||||
|
|
||||||
#ifdef Q_WS_MAEMO_6
|
// 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_names << QLatin1String("primary") << QLatin1String("secondary");
|
||||||
m_descriptions << tr("Main camera") << tr("Front camera");
|
m_descriptions << tr("Main camera") << tr("Front camera");
|
||||||
#else
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QDir devDir("/dev");
|
QDir devDir("/dev");
|
||||||
devDir.setFilter(QDir::System);
|
devDir.setFilter(QDir::System);
|
||||||
|
|
||||||
@@ -151,5 +167,4 @@ void QGstreamerVideoInputDeviceControl::update()
|
|||||||
}
|
}
|
||||||
::close(fd);
|
::close(fd);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
#include <qvideodeviceselectorcontrol.h>
|
#include <qvideodeviceselectorcontrol.h>
|
||||||
#include <QtCore/qstringlist.h>
|
#include <QtCore/qstringlist.h>
|
||||||
|
|
||||||
|
#include <gst/gst.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QGstreamerVideoInputDeviceControl : public QVideoDeviceSelectorControl
|
class QGstreamerVideoInputDeviceControl : public QVideoDeviceSelectorControl
|
||||||
@@ -52,6 +54,7 @@ class QGstreamerVideoInputDeviceControl : public QVideoDeviceSelectorControl
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QGstreamerVideoInputDeviceControl(QObject *parent);
|
QGstreamerVideoInputDeviceControl(QObject *parent);
|
||||||
|
QGstreamerVideoInputDeviceControl(GstElement *source, QObject *parent);
|
||||||
~QGstreamerVideoInputDeviceControl();
|
~QGstreamerVideoInputDeviceControl();
|
||||||
|
|
||||||
int deviceCount() const;
|
int deviceCount() const;
|
||||||
@@ -68,6 +71,8 @@ public Q_SLOTS:
|
|||||||
private:
|
private:
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
GstElement *m_source;
|
||||||
|
|
||||||
int m_selectedDevice;
|
int m_selectedDevice;
|
||||||
QStringList m_names;
|
QStringList m_names;
|
||||||
QStringList m_descriptions;
|
QStringList m_descriptions;
|
||||||
|
|||||||
@@ -109,7 +109,8 @@ CameraBinService::CameraBinService(const QString &service, QObject *parent):
|
|||||||
if (service == Q_MEDIASERVICE_CAMERA) {
|
if (service == Q_MEDIASERVICE_CAMERA) {
|
||||||
m_captureSession = new CameraBinSession(this);
|
m_captureSession = new CameraBinSession(this);
|
||||||
m_cameraControl = new CameraBinControl(m_captureSession);
|
m_cameraControl = new CameraBinControl(m_captureSession);
|
||||||
m_videoInputDevice = new QGstreamerVideoInputDeviceControl(m_captureSession);
|
m_videoInputDevice = new QGstreamerVideoInputDeviceControl(
|
||||||
|
m_captureSession->buildCameraSource(), m_captureSession);
|
||||||
m_imageCaptureControl = new CameraBinImageCapture(m_captureSession);
|
m_imageCaptureControl = new CameraBinImageCapture(m_captureSession);
|
||||||
|
|
||||||
connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)),
|
connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)),
|
||||||
|
|||||||
@@ -169,6 +169,10 @@ CameraBinSession::CameraBinSession(QObject *parent)
|
|||||||
m_captureDestinationControl = new CameraBinCaptureDestination(this);
|
m_captureDestinationControl = new CameraBinCaptureDestination(this);
|
||||||
m_captureBufferFormatControl = new CameraBinCaptureBufferFormat(this);
|
m_captureBufferFormatControl = new CameraBinCaptureBufferFormat(this);
|
||||||
|
|
||||||
|
QByteArray envFlags = qgetenv("QT_GSTREAMER_CAMERABIN_FLAGS");
|
||||||
|
if (!envFlags.isEmpty())
|
||||||
|
g_object_set(G_OBJECT(m_camerabin), "flags", envFlags.toInt(), NULL);
|
||||||
|
|
||||||
//post image preview in RGB format
|
//post image preview in RGB format
|
||||||
g_object_set(G_OBJECT(m_camerabin), POST_PREVIEWS_PROPERTY, TRUE, NULL);
|
g_object_set(G_OBJECT(m_camerabin), POST_PREVIEWS_PROPERTY, TRUE, NULL);
|
||||||
|
|
||||||
@@ -197,19 +201,10 @@ GstPhotography *CameraBinSession::photography()
|
|||||||
return GST_PHOTOGRAPHY(m_camerabin);
|
return GST_PHOTOGRAPHY(m_camerabin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_videoSrc) {
|
GstElement * const source = buildCameraSource();
|
||||||
m_videoSrc = buildCameraSource();
|
|
||||||
|
|
||||||
if (m_videoSrc)
|
if (source && GST_IS_PHOTOGRAPHY(source))
|
||||||
g_object_set(m_camerabin, CAMERA_SOURCE_PROPERTY, m_videoSrc, NULL);
|
return GST_PHOTOGRAPHY(source);
|
||||||
else
|
|
||||||
g_object_get(m_camerabin, CAMERA_SOURCE_PROPERTY, &m_videoSrc, NULL);
|
|
||||||
|
|
||||||
m_videoInputHasChanged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_videoSrc && GST_IS_PHOTOGRAPHY(m_videoSrc))
|
|
||||||
return GST_PHOTOGRAPHY(m_videoSrc);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -225,17 +220,8 @@ CameraBinSession::CameraRole CameraBinSession::cameraRole() const
|
|||||||
*/
|
*/
|
||||||
bool CameraBinSession::setupCameraBin()
|
bool CameraBinSession::setupCameraBin()
|
||||||
{
|
{
|
||||||
if (m_videoInputHasChanged) {
|
if (!buildCameraSource())
|
||||||
m_videoSrc = buildCameraSource();
|
return false;
|
||||||
|
|
||||||
if (m_videoSrc)
|
|
||||||
g_object_set(m_camerabin, CAMERA_SOURCE_PROPERTY, m_videoSrc, NULL);
|
|
||||||
else
|
|
||||||
g_object_get(m_camerabin, CAMERA_SOURCE_PROPERTY, &m_videoSrc, NULL);
|
|
||||||
|
|
||||||
m_videoInputHasChanged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (m_viewfinderHasChanged) {
|
if (m_viewfinderHasChanged) {
|
||||||
if (m_viewfinderElement)
|
if (m_viewfinderElement)
|
||||||
@@ -370,28 +356,43 @@ GstElement *CameraBinSession::buildCameraSource()
|
|||||||
#if CAMERABIN_DEBUG
|
#if CAMERABIN_DEBUG
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
#endif
|
#endif
|
||||||
|
if (!m_videoInputHasChanged)
|
||||||
|
return m_videoSrc;
|
||||||
|
m_videoInputHasChanged = false;
|
||||||
|
|
||||||
GstElement *videoSrc = 0;
|
GstElement *videoSrc = 0;
|
||||||
|
g_object_get(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, &videoSrc, NULL);
|
||||||
|
|
||||||
QList<QByteArray> candidates;
|
// If the QT_GSTREAMER_CAMERABIN_SRC environment variable has been set use the source
|
||||||
candidates << "subdevsrc" << "wrappercamerabinsrc";
|
// it recommends.
|
||||||
QByteArray sourceElementName;
|
const QByteArray envCandidate = qgetenv("QT_GSTREAMER_CAMERABIN_SRC");
|
||||||
|
if (!m_videoSrc && !envCandidate.isEmpty()) {
|
||||||
foreach (sourceElementName, candidates) {
|
m_videoSrc = gst_element_factory_make(envCandidate.constData(), "camera_source");
|
||||||
videoSrc = gst_element_factory_make(sourceElementName.constData(), "camera_source");
|
|
||||||
if (videoSrc)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (videoSrc && !m_inputDevice.isEmpty()) {
|
// 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
|
#if CAMERABIN_DEBUG
|
||||||
qDebug() << "set camera device" << m_inputDevice;
|
qDebug() << "set camera device" << m_inputDevice;
|
||||||
#endif
|
#endif
|
||||||
if (sourceElementName == "subdevsrc") {
|
|
||||||
if (m_inputDevice == QLatin1String("secondary"))
|
if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "video-source")) {
|
||||||
g_object_set(G_OBJECT(videoSrc), "camera-device", 1, NULL);
|
|
||||||
else
|
|
||||||
g_object_set(G_OBJECT(videoSrc), "camera-device", 0, NULL);
|
|
||||||
} else if (sourceElementName == "wrappercamerabinsrc") {
|
|
||||||
GstElement *src = 0;
|
GstElement *src = 0;
|
||||||
|
|
||||||
if (m_videoInputFactory)
|
if (m_videoInputFactory)
|
||||||
@@ -401,12 +402,21 @@ GstElement *CameraBinSession::buildCameraSource()
|
|||||||
|
|
||||||
if (src) {
|
if (src) {
|
||||||
g_object_set(G_OBJECT(src), "device", m_inputDevice.toUtf8().constData(), NULL);
|
g_object_set(G_OBJECT(src), "device", m_inputDevice.toUtf8().constData(), NULL);
|
||||||
g_object_set(G_OBJECT(videoSrc), "video-source", src, NULL);
|
g_object_set(G_OBJECT(m_videoSrc), "video-source", src, NULL);
|
||||||
|
}
|
||||||
|
} else if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "camera-device")) {
|
||||||
|
if (m_inputDevice == QLatin1String("secondary")) {
|
||||||
|
g_object_set(G_OBJECT(m_videoSrc), "camera-device", 1, NULL);
|
||||||
|
} else {
|
||||||
|
g_object_set(G_OBJECT(m_videoSrc), "camera-device", 0, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return videoSrc;
|
if (m_videoSrc != videoSrc)
|
||||||
|
g_object_set(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, m_videoSrc, NULL);
|
||||||
|
|
||||||
|
return m_videoSrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CameraBinSession::captureImage(int requestId, const QString &fileName)
|
void CameraBinSession::captureImage(int requestId, const QString &fileName)
|
||||||
@@ -626,9 +636,7 @@ void CameraBinSession::setState(QCamera::State newState)
|
|||||||
m_viewfinderInterface->stopRenderer();
|
m_viewfinderInterface->stopRenderer();
|
||||||
|
|
||||||
gst_element_set_state(m_camerabin, GST_STATE_NULL);
|
gst_element_set_state(m_camerabin, GST_STATE_NULL);
|
||||||
m_videoSrc = buildCameraSource();
|
buildCameraSource();
|
||||||
g_object_set(m_camerabin, CAMERA_SOURCE_PROPERTY, m_videoSrc, NULL);
|
|
||||||
m_videoInputHasChanged = false;
|
|
||||||
}
|
}
|
||||||
#ifdef USE_READY_STATE_ON_LOADED
|
#ifdef USE_READY_STATE_ON_LOADED
|
||||||
gst_element_set_state(m_camerabin, GST_STATE_READY);
|
gst_element_set_state(m_camerabin, GST_STATE_READY);
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ public:
|
|||||||
QDir defaultDir(QCamera::CaptureModes mode) const;
|
QDir defaultDir(QCamera::CaptureModes mode) const;
|
||||||
QString generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const;
|
QString generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const;
|
||||||
|
|
||||||
|
GstElement *buildCameraSource();
|
||||||
|
|
||||||
CameraBinAudioEncoder *audioEncodeControl() const { return m_audioEncodeControl; }
|
CameraBinAudioEncoder *audioEncodeControl() const { return m_audioEncodeControl; }
|
||||||
CameraBinVideoEncoder *videoEncodeControl() const { return m_videoEncodeControl; }
|
CameraBinVideoEncoder *videoEncodeControl() const { return m_videoEncodeControl; }
|
||||||
CameraBinImageEncoder *imageEncodeControl() const { return m_imageEncodeControl; }
|
CameraBinImageEncoder *imageEncodeControl() const { return m_imageEncodeControl; }
|
||||||
@@ -188,7 +190,6 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
bool setupCameraBin();
|
bool setupCameraBin();
|
||||||
void setupCaptureResolution();
|
void setupCaptureResolution();
|
||||||
GstElement *buildCameraSource();
|
|
||||||
static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d);
|
static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d);
|
||||||
|
|
||||||
QUrl m_sink;
|
QUrl m_sink;
|
||||||
|
|||||||
Reference in New Issue
Block a user