From 4d3f740795ece7fb46760d384f21913e02b296d7 Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Tue, 10 Dec 2013 13:11:07 +1000 Subject: 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 Reviewed-by: Andy Nichols Reviewed-by: Yoann Lopes --- src/gsttools/qgstreamervideoinputdevicecontrol.cpp | 27 +++++-- .../qgstreamervideoinputdevicecontrol_p.h | 5 ++ .../gstreamer/camerabin/camerabinservice.cpp | 3 +- .../gstreamer/camerabin/camerabinsession.cpp | 92 ++++++++++++---------- src/plugins/gstreamer/camerabin/camerabinsession.h | 3 +- 5 files changed, 80 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/gsttools/qgstreamervideoinputdevicecontrol.cpp b/src/gsttools/qgstreamervideoinputdevicecontrol.cpp index 960853bba..ad61aefad 100644 --- a/src/gsttools/qgstreamervideoinputdevicecontrol.cpp +++ b/src/gsttools/qgstreamervideoinputdevicecontrol.cpp @@ -57,13 +57,24 @@ #include QGstreamerVideoInputDeviceControl::QGstreamerVideoInputDeviceControl(QObject *parent) - :QVideoDeviceSelectorControl(parent), m_selectedDevice(0) + :QVideoDeviceSelectorControl(parent), m_source(0), m_selectedDevice(0) { 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() { + if (m_source) + gst_object_unref(GST_OBJECT(m_source)); } int QGstreamerVideoInputDeviceControl::deviceCount() const @@ -107,10 +118,15 @@ void QGstreamerVideoInputDeviceControl::update() m_names.clear(); m_descriptions.clear(); -#ifdef Q_WS_MAEMO_6 - m_names << QLatin1String("primary") << QLatin1String("secondary"); - m_descriptions << tr("Main camera") << tr("Front camera"); -#else + // 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); @@ -151,5 +167,4 @@ void QGstreamerVideoInputDeviceControl::update() } ::close(fd); } -#endif } diff --git a/src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h b/src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h index 401f50245..eeb576ef5 100644 --- a/src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h +++ b/src/multimedia/gsttools_headers/qgstreamervideoinputdevicecontrol_p.h @@ -45,6 +45,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QGstreamerVideoInputDeviceControl : public QVideoDeviceSelectorControl @@ -52,6 +54,7 @@ class QGstreamerVideoInputDeviceControl : public QVideoDeviceSelectorControl Q_OBJECT public: QGstreamerVideoInputDeviceControl(QObject *parent); + QGstreamerVideoInputDeviceControl(GstElement *source, QObject *parent); ~QGstreamerVideoInputDeviceControl(); int deviceCount() const; @@ -68,6 +71,8 @@ public Q_SLOTS: private: void update(); + GstElement *m_source; + int m_selectedDevice; QStringList m_names; QStringList m_descriptions; diff --git a/src/plugins/gstreamer/camerabin/camerabinservice.cpp b/src/plugins/gstreamer/camerabin/camerabinservice.cpp index 54c49f41c..58d44332f 100644 --- a/src/plugins/gstreamer/camerabin/camerabinservice.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinservice.cpp @@ -109,7 +109,8 @@ CameraBinService::CameraBinService(const QString &service, QObject *parent): if (service == Q_MEDIASERVICE_CAMERA) { m_captureSession = new CameraBinSession(this); 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); connect(m_videoInputDevice, SIGNAL(selectedDeviceChanged(QString)), diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index 2e5c53a4d..6e857d589 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -169,6 +169,10 @@ CameraBinSession::CameraBinSession(QObject *parent) m_captureDestinationControl = new CameraBinCaptureDestination(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 g_object_set(G_OBJECT(m_camerabin), POST_PREVIEWS_PROPERTY, TRUE, NULL); @@ -197,19 +201,10 @@ GstPhotography *CameraBinSession::photography() return GST_PHOTOGRAPHY(m_camerabin); } - if (!m_videoSrc) { - m_videoSrc = buildCameraSource(); - - 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; - } + GstElement * const source = buildCameraSource(); - if (m_videoSrc && GST_IS_PHOTOGRAPHY(m_videoSrc)) - return GST_PHOTOGRAPHY(m_videoSrc); + if (source && GST_IS_PHOTOGRAPHY(source)) + return GST_PHOTOGRAPHY(source); return 0; } @@ -225,17 +220,8 @@ CameraBinSession::CameraRole CameraBinSession::cameraRole() const */ bool CameraBinSession::setupCameraBin() { - if (m_videoInputHasChanged) { - m_videoSrc = buildCameraSource(); - - 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 (!buildCameraSource()) + return false; if (m_viewfinderHasChanged) { if (m_viewfinderElement) @@ -370,28 +356,43 @@ GstElement *CameraBinSession::buildCameraSource() #if CAMERABIN_DEBUG qDebug() << Q_FUNC_INFO; #endif + if (!m_videoInputHasChanged) + return m_videoSrc; + m_videoInputHasChanged = false; + GstElement *videoSrc = 0; + g_object_get(G_OBJECT(m_camerabin), CAMERA_SOURCE_PROPERTY, &videoSrc, NULL); - QList candidates; - candidates << "subdevsrc" << "wrappercamerabinsrc"; - QByteArray sourceElementName; + // 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 gstreamer has set a default source use it. + if (!m_videoSrc) + m_videoSrc = videoSrc; - foreach (sourceElementName, candidates) { - videoSrc = gst_element_factory_make(sourceElementName.constData(), "camera_source"); - if (videoSrc) - break; + // If there's no better guidance try the names of some known camera source elements. + if (!m_videoSrc) { + const QList candidates = QList() + << "subdevsrc" + << "wrappercamerabinsrc"; + + foreach (const QByteArray &sourceElementName, candidates) { + m_videoSrc = gst_element_factory_make(sourceElementName.constData(), "camera_source"); + if (m_videoSrc) + break; + } } - if (videoSrc && !m_inputDevice.isEmpty()) { + if (m_videoSrc && !m_inputDevice.isEmpty()) { #if CAMERABIN_DEBUG qDebug() << "set camera device" << m_inputDevice; #endif - if (sourceElementName == "subdevsrc") { - if (m_inputDevice == QLatin1String("secondary")) - 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") { + + if (g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSrc), "video-source")) { GstElement *src = 0; if (m_videoInputFactory) @@ -401,12 +402,21 @@ GstElement *CameraBinSession::buildCameraSource() if (src) { 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) @@ -626,9 +636,7 @@ void CameraBinSession::setState(QCamera::State newState) m_viewfinderInterface->stopRenderer(); gst_element_set_state(m_camerabin, GST_STATE_NULL); - m_videoSrc = buildCameraSource(); - g_object_set(m_camerabin, CAMERA_SOURCE_PROPERTY, m_videoSrc, NULL); - m_videoInputHasChanged = false; + buildCameraSource(); } #ifdef USE_READY_STATE_ON_LOADED gst_element_set_state(m_camerabin, GST_STATE_READY); diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h index 305c1168b..bdc27f33f 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.h +++ b/src/plugins/gstreamer/camerabin/camerabinsession.h @@ -117,6 +117,8 @@ public: QDir defaultDir(QCamera::CaptureModes mode) const; QString generateFileName(const QString &prefix, const QDir &dir, const QString &ext) const; + GstElement *buildCameraSource(); + CameraBinAudioEncoder *audioEncodeControl() const { return m_audioEncodeControl; } CameraBinVideoEncoder *videoEncodeControl() const { return m_videoEncodeControl; } CameraBinImageEncoder *imageEncodeControl() const { return m_imageEncodeControl; } @@ -188,7 +190,6 @@ private slots: private: bool setupCameraBin(); void setupCaptureResolution(); - GstElement *buildCameraSource(); static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d); QUrl m_sink; -- cgit v1.2.3