Updated the camerabin2 based camera with QtMultimedia changes
authorDmytro Poplavskiy <dmytro.poplavskiy@nokia.com>
Mon, 16 Jul 2012 00:55:20 +0000 (10:55 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 16 Jul 2012 05:18:12 +0000 (07:18 +0200)
Moved it to the separate plugin as the rest of gstreamer based services;
Updated with libqgsttools_p changes;
Implemented QMediaRecorder::status property;
Made gst_photography dependency optional,
it's not always available on desktop;
Added video recording case to auto integration test;
Moved backend implementation into qt namespace

Task-number: QTBUG-26046
Change-Id: Iacfc1a6e263a4c0201d5eb28d04c960b87a230c0
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
47 files changed:
config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro [new file with mode: 0644]
config.tests/gstreamer_encodingprofiles/main.cpp [new file with mode: 0644]
qtmultimedia.pro
src/plugins/gstreamer/camerabin/camerabin.json [new file with mode: 0644]
src/plugins/gstreamer/camerabin/camerabin.pro
src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp
src/plugins/gstreamer/camerabin/camerabinaudioencoder.h
src/plugins/gstreamer/camerabin/camerabincapturebufferformat.cpp
src/plugins/gstreamer/camerabin/camerabincapturebufferformat.h
src/plugins/gstreamer/camerabin/camerabincapturedestination.cpp
src/plugins/gstreamer/camerabin/camerabincapturedestination.h
src/plugins/gstreamer/camerabin/camerabincontainer.cpp
src/plugins/gstreamer/camerabin/camerabincontainer.h
src/plugins/gstreamer/camerabin/camerabincontrol.cpp
src/plugins/gstreamer/camerabin/camerabincontrol.h
src/plugins/gstreamer/camerabin/camerabinexposure.cpp
src/plugins/gstreamer/camerabin/camerabinexposure.h
src/plugins/gstreamer/camerabin/camerabinflash.cpp
src/plugins/gstreamer/camerabin/camerabinflash.h
src/plugins/gstreamer/camerabin/camerabinfocus.cpp
src/plugins/gstreamer/camerabin/camerabinfocus.h
src/plugins/gstreamer/camerabin/camerabinimagecapture.cpp
src/plugins/gstreamer/camerabin/camerabinimagecapture.h
src/plugins/gstreamer/camerabin/camerabinimageencoder.cpp
src/plugins/gstreamer/camerabin/camerabinimageencoder.h
src/plugins/gstreamer/camerabin/camerabinimageprocessing.cpp
src/plugins/gstreamer/camerabin/camerabinimageprocessing.h
src/plugins/gstreamer/camerabin/camerabinlocks.cpp
src/plugins/gstreamer/camerabin/camerabinlocks.h
src/plugins/gstreamer/camerabin/camerabinmetadata.cpp
src/plugins/gstreamer/camerabin/camerabinmetadata.h
src/plugins/gstreamer/camerabin/camerabinrecorder.cpp
src/plugins/gstreamer/camerabin/camerabinrecorder.h
src/plugins/gstreamer/camerabin/camerabinresourcepolicy.cpp
src/plugins/gstreamer/camerabin/camerabinresourcepolicy.h
src/plugins/gstreamer/camerabin/camerabinservice.cpp
src/plugins/gstreamer/camerabin/camerabinservice.h
src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp [new file with mode: 0644]
src/plugins/gstreamer/camerabin/camerabinserviceplugin.h [new file with mode: 0644]
src/plugins/gstreamer/camerabin/camerabinsession.cpp
src/plugins/gstreamer/camerabin/camerabinsession.h
src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp
src/plugins/gstreamer/camerabin/camerabinvideoencoder.h
src/plugins/gstreamer/camerabin/camerabuttonlistener_meego.cpp
src/plugins/gstreamer/camerabin/camerabuttonlistener_meego.h
src/plugins/gstreamer/gstreamer.pro
tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp

diff --git a/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro b/config.tests/gstreamer_encodingprofiles/gstreamer_encodingprofiles.pro
new file mode 100644 (file)
index 0000000..7e8a9e7
--- /dev/null
@@ -0,0 +1,12 @@
+SOURCES += main.cpp
+
+CONFIG += link_pkgconfig
+
+PKGCONFIG += \
+    gstreamer-0.10 \
+    gstreamer-base-0.10 \
+    gstreamer-interfaces-0.10 \
+    gstreamer-audio-0.10 \
+    gstreamer-video-0.10 \
+    gstreamer-pbutils-0.10
+
diff --git a/config.tests/gstreamer_encodingprofiles/main.cpp b/config.tests/gstreamer_encodingprofiles/main.cpp
new file mode 100644 (file)
index 0000000..8a6066d
--- /dev/null
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define GST_USE_UNSTABLE_API
+
+#include <gst/pbutils/pbutils.h>
+#include <gst/pbutils/encoding-profile.h>
+
+int main(int argc, char** argv)
+{
+    return 0;
+}
index e025d18..79fbe76 100644 (file)
@@ -11,6 +11,7 @@ win32 {
     qtCompileTest(pulseaudio)
     qtCompileTest(gstreamer) {
         qtCompileTest(gstreamer_photography)
+        qtCompileTest(gstreamer_encodingprofiles)
         qtCompileTest(gstreamer_appsrc)
     }
     qtCompileTest(resourcepolicy)
diff --git a/src/plugins/gstreamer/camerabin/camerabin.json b/src/plugins/gstreamer/camerabin/camerabin.json
new file mode 100644 (file)
index 0000000..d3a58c7
--- /dev/null
@@ -0,0 +1,3 @@
+{
+    "Keys": ["org.qt-project.qt.camera"]
+}
index 6c0c1bf..bf81075 100644 (file)
@@ -3,6 +3,8 @@ load(qt_build_config)
 TARGET = gstcamerabin
 PLUGIN_TYPE = mediaservice
 
+QT += multimedia-private
+
 load(qt_plugin)
 DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE}
 
@@ -13,22 +15,16 @@ INCLUDEPATH += $$PWD \
 
 INCLUDEPATH += camerabin
 
-LIBS += -lgstphotography-0.10
-
-DEFINES += GST_USE_UNSTABLE_API #prevents warnings because of unstable photography API
 
 HEADERS += \
+    $$PWD/camerabinserviceplugin.h \
     $$PWD/camerabinservice.h \
     $$PWD/camerabinsession.h \
     $$PWD/camerabincontrol.h \
     $$PWD/camerabinaudioencoder.h \
-    $$PWD/camerabinfocus.h \
     $$PWD/camerabinimageencoder.h \
-    $$PWD/camerabinlocks.h \
     $$PWD/camerabinrecorder.h \
     $$PWD/camerabincontainer.h \
-    $$PWD/camerabinexposure.h \
-    $$PWD/camerabinflash.h \
     $$PWD/camerabinimagecapture.h \
     $$PWD/camerabinimageprocessing.h \
     $$PWD/camerabinmetadata.h \
@@ -38,18 +34,15 @@ HEADERS += \
     $$PWD/camerabincapturebufferformat.h
 
 SOURCES += \
+    $$PWD/camerabinserviceplugin.cpp \
     $$PWD/camerabinservice.cpp \
     $$PWD/camerabinsession.cpp \
     $$PWD/camerabincontrol.cpp \
     $$PWD/camerabinaudioencoder.cpp \
     $$PWD/camerabincontainer.cpp \
-    $$PWD/camerabinexposure.cpp \
-    $$PWD/camerabinflash.cpp \
-    $$PWD/camerabinfocus.cpp \
     $$PWD/camerabinimagecapture.cpp \
     $$PWD/camerabinimageencoder.cpp \
     $$PWD/camerabinimageprocessing.cpp \
-    $$PWD/camerabinlocks.cpp \
     $$PWD/camerabinmetadata.cpp \
     $$PWD/camerabinrecorder.cpp \
     $$PWD/camerabinvideoencoder.cpp \
@@ -63,8 +56,34 @@ maemo6 {
 
     SOURCES += \
         $$PWD/camerabuttonlistener_meego.cpp
+
+    CONFIG += have_gst_photography
 }
 
+have_gst_photography {
+    DEFINES += HAVE_GST_PHOTOGRAPHY
+
+    HEADERS += \
+        $$PWD/camerabinfocus.h \
+        $$PWD/camerabinexposure.h \
+        $$PWD/camerabinflash.h \
+        $$PWD/camerabinlocks.h
+
+    SOURCES += \
+        $$PWD/camerabinexposure.cpp \
+        $$PWD/camerabinflash.cpp \
+        $$PWD/camerabinfocus.cpp \
+        $$PWD/camerabinlocks.cpp
+
+    LIBS += -lgstphotography-0.10
+    DEFINES += GST_USE_UNSTABLE_API #prevents warnings because of unstable photography API
+}
+
+
+
 target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE}
 INSTALLS += target
 
+OTHER_FILES += \
+    camerabin.json
+
index 546f1aa..bfd22a3 100644 (file)
 
 #include "camerabinaudioencoder.h"
 #include "camerabincontainer.h"
-#include "qgstcodecsinfo.h"
+#include <private/qgstcodecsinfo_p.h>
 
 #include <QtCore/qdebug.h>
 
+QT_BEGIN_NAMESPACE
+
 CameraBinAudioEncoder::CameraBinAudioEncoder(QObject *parent)
     :QAudioEncoderSettingsControl(parent),
      m_codecs(QGstCodecsInfo::AudioEncoder)
@@ -110,3 +112,5 @@ GstEncodingProfile *CameraBinAudioEncoder::createProfile()
                                         NULL, //restriction
                                         0); //presence
 }
+
+QT_END_NAMESPACE
index f8dd342..b3157d7 100644 (file)
@@ -43,7 +43,6 @@
 #define CAMERABINAUDIOENCODE_H
 
 #include <qaudioencodersettingscontrol.h>
-class CameraBinSession;
 
 #include <QtCore/qstringlist.h>
 #include <QtCore/qmap.h>
@@ -54,9 +53,10 @@ class CameraBinSession;
 #include <gst/pbutils/encoding-profile.h>
 
 #include <qaudioformat.h>
-#include "qgstcodecsinfo.h"
+#include <private/qgstcodecsinfo_p.h>
 
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
+class CameraBinSession;
 
 class CameraBinAudioEncoder : public QAudioEncoderSettingsControl
 {
@@ -95,4 +95,6 @@ private:
     QAudioEncoderSettings m_userSettings;
 };
 
+QT_END_NAMESPACE
+
 #endif
index cd04112..53bd88f 100644 (file)
@@ -42,6 +42,8 @@
 #include "camerabincapturebufferformat.h"
 #include "camerabinsession.h"
 
+QT_BEGIN_NAMESPACE
+
 CameraBinCaptureBufferFormat::CameraBinCaptureBufferFormat(CameraBinSession *session)
     :QCameraCaptureBufferFormatControl(session)
      , m_session(session)
@@ -76,3 +78,5 @@ void CameraBinCaptureBufferFormat::setBufferFormat(QVideoFrame::PixelFormat form
         emit bufferFormatChanged(format);
     }
 }
+
+QT_END_NAMESPACE
index c180ba6..e64bf2e 100644 (file)
@@ -48,6 +48,8 @@
 #include <gst/gst.h>
 #include <glib.h>
 
+QT_BEGIN_NAMESPACE
+
 class CameraBinSession;
 
 QT_USE_NAMESPACE
@@ -69,4 +71,6 @@ private:
     QVideoFrame::PixelFormat m_format;
 };
 
+QT_END_NAMESPACE
+
 #endif
index c78d99b..88bd749 100644 (file)
@@ -42,6 +42,8 @@
 #include "camerabincapturedestination.h"
 #include "camerabinsession.h"
 
+QT_BEGIN_NAMESPACE
+
 CameraBinCaptureDestination::CameraBinCaptureDestination(CameraBinSession *session)
     :QCameraCaptureDestinationControl(session)
     , m_session(session)
@@ -72,3 +74,5 @@ void CameraBinCaptureDestination::setCaptureDestination(QCameraImageCapture::Cap
         emit captureDestinationChanged(m_destination);
     }
 }
+
+QT_END_NAMESPACE
index 8343d44..e39f92a 100644 (file)
@@ -45,6 +45,7 @@
 #include <qcameraimagecapture.h>
 #include <qcameracapturedestinationcontrol.h>
 
+QT_BEGIN_NAMESPACE
 
 class CameraBinSession;
 
@@ -66,4 +67,6 @@ private:
     QCameraImageCapture::CaptureDestinations m_destination;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINFLASHCONTROL_H
index 3ed6bca..c24e20a 100644 (file)
@@ -44,6 +44,8 @@
 
 #include <QtCore/qdebug.h>
 
+QT_BEGIN_NAMESPACE
+
 CameraBinContainer::CameraBinContainer(QObject *parent)
     :QMediaContainerControl(parent),
       m_supportedContainers(QGstCodecsInfo::Muxer)
@@ -68,39 +70,43 @@ QString CameraBinContainer::containerDescription(const QString &formatMimeType)
     return m_supportedContainers.codecDescription(formatMimeType);
 }
 
-QString CameraBinContainer::containerMimeType() const
+QString CameraBinContainer::containerFormat() const
 {
     return m_format;
 }
 
-void CameraBinContainer::setContainerMimeType(const QString &formatMimeType)
+void CameraBinContainer::setContainerFormat(const QString &format)
 {
-    m_format = formatMimeType;
-
-    if (m_userFormat != formatMimeType) {
-        m_userFormat = formatMimeType;
+    if (m_format != format) {
+        m_format = format;
         emit settingsChanged();
     }
 }
 
-void CameraBinContainer::setActualContainer(const QString &formatMimeType)
-{
-    m_format = formatMimeType;
-}
-
-void CameraBinContainer::resetActualContainer()
-{
-    m_format = m_userFormat;
-}
-
 GstEncodingContainerProfile *CameraBinContainer::createProfile()
 {
     GstCaps *caps;
 
-    if (m_format.isEmpty())
+    if (m_format.isEmpty()) {
         caps = gst_caps_new_any();
-    else
-        caps = gst_caps_from_string(m_format.toLatin1());
+    } else {
+        QString format = m_format;
+        QStringList supportedFormats = m_supportedContainers.supportedCodecs();
+
+        //if format is not in the list of supported gstreamer mime types,
+        //try to find the mime type with matching extension
+        if (!supportedFormats.contains(format)) {
+            QString extension = suggestedFileExtension(m_format);
+            foreach (const QString &formatCandidate, supportedFormats) {
+                if (suggestedFileExtension(formatCandidate) == extension) {
+                    format = formatCandidate;
+                    break;
+                }
+            }
+        }
+
+        caps = gst_caps_from_string(format.toLatin1());
+    }
 
     return (GstEncodingContainerProfile *)gst_encoding_container_profile_new(
                                         "camerabin2_profile",
@@ -112,9 +118,13 @@ GstEncodingContainerProfile *CameraBinContainer::createProfile()
 /*!
   Suggest file extension for current container mimetype.
  */
-QString CameraBinContainer::suggestedFileExtension() const
+QString CameraBinContainer::suggestedFileExtension(const QString &containerFormat) const
 {
-    QString format = m_format.left(m_format.indexOf(','));
+    //for container names like avi instead of video/x-msvideo, use it as extension
+    if (!containerFormat.contains('/'))
+        return containerFormat;
+
+    QString format = containerFormat.left(containerFormat.indexOf(','));
     QString extension = m_fileExtensions.value(format);
 
     if (!extension.isEmpty() || format.isEmpty())
@@ -127,3 +137,5 @@ QString CameraBinContainer::suggestedFileExtension() const
 
     return extension;
 }
+
+QT_END_NAMESPACE
index 5887043..7830516 100644 (file)
@@ -51,9 +51,9 @@
 #include <gst/pbutils/pbutils.h>
 #include <gst/pbutils/encoding-profile.h>
 
-#include "qgstcodecsinfo.h"
+#include <private/qgstcodecsinfo_p.h>
 
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
 
 class CameraBinContainer : public QMediaContainerControl
 {
@@ -65,13 +65,10 @@ public:
     virtual QStringList supportedContainers() const;
     virtual QString containerDescription(const QString &formatMimeType) const;
 
-    virtual QString containerMimeType() const;
-    virtual void setContainerMimeType(const QString &formatMimeType);
+    virtual QString containerFormat() const;
+    virtual void setContainerFormat(const QString &format);
 
-    void setActualContainer(const QString &formatMimeType);
-    void resetActualContainer();
-
-    QString suggestedFileExtension() const;
+    QString suggestedFileExtension(const QString &containerFormat) const;
 
     GstEncodingContainerProfile *createProfile();
 
@@ -80,10 +77,11 @@ Q_SIGNALS:
 
 private:
     QString m_format; // backend selected format, using m_userFormat
-    QString m_userFormat;
     QMap<QString, QString> m_fileExtensions;
 
     QGstCodecsInfo m_supportedContainers;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINMEDIACONTAINERCONTROL_H
index a13a023..c846e64 100644 (file)
@@ -62,6 +62,8 @@
 #include <sys/mman.h>
 #include <linux/videodev2.h>
 
+QT_BEGIN_NAMESPACE
+
 //#define CAMEABIN_DEBUG 1
 #define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))
 
@@ -113,6 +115,10 @@ void CameraBinControl::setCaptureMode(QCamera::CaptureModes mode)
                         captureMode() == QCamera::CaptureStillImage ?
                             CamerabinResourcePolicy::ImageCaptureResources :
                             CamerabinResourcePolicy::VideoCaptureResources);
+
+            //due to bug in v4l2src, it's necessary to reload camera on video caps changes
+            //https://bugzilla.gnome.org/show_bug.cgi?id=649832
+            reloadLater();
         }
         emit captureModeChanged(mode);
     }
@@ -339,3 +345,5 @@ void CameraBinControl::setViewfinderColorSpaceConversion(bool enabled)
 
     g_object_set(G_OBJECT(m_session->cameraBin()), "flags", flags, NULL);
 }
+
+QT_END_NAMESPACE
index 5bba19e..664bc3e 100644 (file)
@@ -47,7 +47,7 @@
 #include <qcameracontrol.h>
 #include "camerabinsession.h"
 
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
 
 class CamerabinResourcePolicy;
 
@@ -98,4 +98,6 @@ private:
     bool m_reloadPending;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINCONTROL_H
index 6253051..0153e8a 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <QDebug>
 
+QT_BEGIN_NAMESPACE
+
 CameraBinExposure::CameraBinExposure(CameraBinSession *session)
     :QCameraExposureControl(session),
      m_session(session)
@@ -230,3 +232,5 @@ QString CameraBinExposure::extendedParameterName(ExposureParameter)
 {
     return QString();
 }
+
+QT_END_NAMESPACE
index 495195f..8bcd6d2 100644 (file)
@@ -48,9 +48,9 @@
 #include <gst/gst.h>
 #include <glib.h>
 
-class CameraBinSession;
+QT_BEGIN_NAMESPACE
 
-QT_USE_NAMESPACE
+class CameraBinSession;
 
 class Q_MULTIMEDIA_EXPORT CameraBinExposure : public QCameraExposureControl
 {
@@ -80,4 +80,6 @@ private:
     CameraBinSession *m_session;    
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINEXPOSURECONTROL_MAEMO_H
index 07e8696..b2c8609 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <QDebug>
 
+QT_BEGIN_NAMESPACE
+
 CameraBinFlash::CameraBinFlash(CameraBinSession *session)
     :QCameraFlashControl(session),
      m_session(session)
@@ -102,3 +104,4 @@ bool CameraBinFlash::isFlashReady() const
     return true;
 }
 
+QT_END_NAMESPACE
index bb4f3b9..3de4fde 100644 (file)
@@ -48,9 +48,9 @@
 #include <gst/gst.h>
 #include <glib.h>
 
-class CameraBinSession;
+QT_BEGIN_NAMESPACE
 
-QT_USE_NAMESPACE
+class CameraBinSession;
 
 class Q_MULTIMEDIA_EXPORT CameraBinFlash : public QCameraFlashControl
 {
@@ -69,5 +69,7 @@ private:
     CameraBinSession *m_session;    
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINFLASHCONTROL_H
 
index 7a3f6f5..402c88f 100644 (file)
@@ -51,6 +51,8 @@
 #define ZOOM_PROPERTY "zoom"
 #define MAX_ZOOM_PROPERTY "max-zoom"
 
+QT_BEGIN_NAMESPACE
+
 CameraBinFocus::CameraBinFocus(CameraBinSession *session)
     :QCameraFocusControl(session),
      m_session(session),
@@ -223,3 +225,5 @@ void CameraBinFocus::_q_stopFocusing()
     gst_photography_set_autofocus(m_session->photography(), FALSE);
     _q_setFocusStatus(QCamera::Unlocked, QCamera::UserRequest);
 }
+
+QT_END_NAMESPACE
index a966a01..b76c1b6 100644 (file)
@@ -48,9 +48,9 @@
 #include <gst/gst.h>
 #include <glib.h>
 
-class CameraBinSession;
+QT_BEGIN_NAMESPACE
 
-QT_USE_NAMESPACE
+class CameraBinSession;
 
 class CameraBinFocus  : public QCameraFocusControl
 {
@@ -100,4 +100,6 @@ private:
     QCameraFocusZone::FocusZoneStatus m_focusZoneStatus;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINFOCUSCONTROL_H
index 81a5267..c860dab 100644 (file)
@@ -54,6 +54,7 @@
 
 #define IMAGE_DONE_SIGNAL "image-done"
 
+QT_BEGIN_NAMESPACE
 
 CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session)
     :QCameraImageCaptureControl(session)
@@ -254,6 +255,9 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
                 return false;
 
             QString elementName = QString::fromLatin1(gst_element_get_name(element));
+            GstElementClass *elementClass = GST_ELEMENT_GET_CLASS(element);
+            QString elementLongName = elementClass->details.longname;
+
             if (elementName.contains("jpegenc") && element != m_jpegEncoderElement) {
                 m_jpegEncoderElement = element;
                 GstPad *sinkpad = gst_element_get_static_pad(element, "sink");
@@ -275,7 +279,9 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
                                          this);
 
                 gst_object_unref(sinkpad);
-            } else if ((elementName.contains("jifmux") || elementName.startsWith("metadatamux"))
+            } else if ((elementName.contains("jifmux") ||
+                        elementName.startsWith("metadatamux") ||
+                        elementLongName == QLatin1String("JPEG stream muxer"))
                        && element != m_metadataMuxerElement) {
                 //Jpeg encoded buffer probe is added after jifmux/metadatamux
                 //element to ensure the resulting jpeg buffer contains capture metadata
@@ -321,3 +327,4 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
     return false;
 }
 
+QT_END_NAMESPACE
index a526776..0bfa043 100644 (file)
@@ -46,7 +46,7 @@
 #include <qcameraimagecapturecontrol.h>
 #include "camerabinsession.h"
 
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
 
 class CameraBinImageCapture : public QCameraImageCaptureControl, public QGstreamerBusMessageFilter
 {
@@ -80,4 +80,6 @@ private:
     GstElement *m_metadataMuxerElement;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINCAPTURECORNTROL_H
index f97c942..dc208b1 100644 (file)
@@ -44,6 +44,8 @@
 
 #include <QtCore/qdebug.h>
 
+QT_BEGIN_NAMESPACE
+
 CameraBinImageEncoder::CameraBinImageEncoder(CameraBinSession *session)
     :QImageEncoderControl(session), m_session(session)
 {
@@ -85,3 +87,5 @@ void CameraBinImageEncoder::setImageSettings(const QImageEncoderSettings &settin
     m_settings = settings;
     emit settingsChanged();
 }
+
+QT_END_NAMESPACE
index 7e2283d..7a8750c 100644 (file)
 #ifndef CAMERABINIMAGEENCODE_H
 #define CAMERABINIMAGEENCODE_H
 
-class CameraBinSession;
-
 #include <qimageencodercontrol.h>
 
 #include <QtCore/qstringlist.h>
 #include <QtCore/qmap.h>
 
 #include <gst/gst.h>
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
+
+class CameraBinSession;
 
 class CameraBinImageEncoder : public QImageEncoderControl
 {
@@ -83,4 +83,6 @@ private:
     QMap<QString,QStringList> m_codecOptions;
 };
 
+QT_END_NAMESPACE
+
 #endif
index 4983678..d0e75cd 100644 (file)
 #include "camerabinimageprocessing.h"
 #include "camerabinsession.h"
 
+#ifdef HAVE_GST_PHOTOGRAPHY
+#include <gst/interfaces/photography.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
 CameraBinImageProcessing::CameraBinImageProcessing(CameraBinSession *session)
     :QCameraImageProcessingControl(session),
      m_session(session)
 {
+#ifdef HAVE_GST_PHOTOGRAPHY
     m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_AUTO] = QCameraImageProcessing::WhiteBalanceAuto;
     m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT] = QCameraImageProcessing::WhiteBalanceSunlight;
     m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_CLOUDY] = QCameraImageProcessing::WhiteBalanceCloudy;
     m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_SUNSET] = QCameraImageProcessing::WhiteBalanceSunset;
     m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN] = QCameraImageProcessing::WhiteBalanceTungsten;
     m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT] = QCameraImageProcessing::WhiteBalanceFluorescent;
+#endif
 
     updateColorBalanceValues();
 }
@@ -73,22 +81,29 @@ void CameraBinImageProcessing::updateColorBalanceValues()
     const GList *item;
     GstColorBalanceChannel *channel;
     gint cur_value;
+    qreal scaledValue = 0;
 
     for (item = controls; item; item = g_list_next (item)) {
         channel = (GstColorBalanceChannel *)item->data;
         cur_value = gst_color_balance_get_value (balance, channel);
 
+        //map the [min_value..max_value] range to [-1.0 .. 1.0]
+        if (channel->min_value != channel->max_value) {
+            scaledValue = qreal(cur_value - channel->min_value) /
+                    (channel->max_value - channel->min_value) * 2 - 1;
+        }
+
         if (!g_ascii_strcasecmp (channel->label, "brightness")) {
-            m_values[QCameraImageProcessingControl::Brightness] = cur_value;
+            m_values[QCameraImageProcessingControl::BrightnessAdjustment] = scaledValue;
         } else if (!g_ascii_strcasecmp (channel->label, "contrast")) {
-            m_values[QCameraImageProcessingControl::Contrast] = cur_value;
+            m_values[QCameraImageProcessingControl::ContrastAdjustment] = scaledValue;
         } else if (!g_ascii_strcasecmp (channel->label, "saturation")) {
-            m_values[QCameraImageProcessingControl::Saturation] = cur_value;
+            m_values[QCameraImageProcessingControl::SaturationAdjustment] = scaledValue;
         }
     }
 }
 
-bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, int value)
+bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, qreal value)
 {
 
     if (!GST_IS_COLOR_BALANCE(m_session->cameraBin())) {
@@ -106,7 +121,11 @@ bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, int
         colorBalanceChannel = (GstColorBalanceChannel *)item->data;
 
         if (!g_ascii_strcasecmp (colorBalanceChannel->label, channel.toLatin1())) {
-            gst_color_balance_set_value (balance, colorBalanceChannel, value);
+            //map the [-1.0 .. 1.0] range to [min_value..max_value]
+            gint scaledValue = colorBalanceChannel->min_value + qRound(
+                        (value+1.0)/2.0 * (colorBalanceChannel->max_value - colorBalanceChannel->min_value));
+
+            gst_color_balance_set_value (balance, colorBalanceChannel, scaledValue);
             return true;
         }
     }
@@ -116,30 +135,59 @@ bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, int
 
 QCameraImageProcessing::WhiteBalanceMode CameraBinImageProcessing::whiteBalanceMode() const
 {
+#ifdef HAVE_GST_PHOTOGRAPHY
     GstWhiteBalanceMode wbMode;
     gst_photography_get_white_balance_mode(m_session->photography(), &wbMode);
     return m_mappedWbValues[wbMode];
+#else
+    return QCameraImageProcessing::WhiteBalanceAuto;
+#endif
 }
 
 void CameraBinImageProcessing::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode)
 {
+#ifdef HAVE_GST_PHOTOGRAPHY
     if (isWhiteBalanceModeSupported(mode))
         gst_photography_set_white_balance_mode(m_session->photography(), m_mappedWbValues.key(mode));
+#else
+    Q_UNUSED(mode);
+#endif
 }
 
 bool CameraBinImageProcessing::isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const
 {
+#ifdef HAVE_GST_PHOTOGRAPHY
     return m_mappedWbValues.values().contains(mode);
+#else
+    return mode == QCameraImageProcessing::WhiteBalanceAuto;
+#endif
 }
 
-bool CameraBinImageProcessing::isProcessingParameterSupported(QCameraImageProcessingControl::ProcessingParameter parameter) const
+bool CameraBinImageProcessing::isParameterSupported(QCameraImageProcessingControl::ProcessingParameter parameter) const
 {
     return parameter == QCameraImageProcessingControl::Contrast
             || parameter == QCameraImageProcessingControl::Brightness
-            || parameter == QCameraImageProcessingControl::Saturation;
+            || parameter == QCameraImageProcessingControl::Saturation
+            || parameter == QCameraImageProcessingControl::WhiteBalancePreset;
 }
 
-QVariant CameraBinImageProcessing::processingParameter(
+bool CameraBinImageProcessing::isParameterValueSupported(QCameraImageProcessingControl::ProcessingParameter parameter, const QVariant &value) const
+{
+    switch (parameter) {
+    case ContrastAdjustment:
+    case BrightnessAdjustment:
+    case SaturationAdjustment:
+        return qAbs(value.toReal()) <= 1.0;
+    case WhiteBalancePreset:
+        return isWhiteBalanceModeSupported(value.value<QCameraImageProcessing::WhiteBalanceMode>());
+    default:
+        break;
+    }
+
+    return false;
+}
+
+QVariant CameraBinImageProcessing::parameter(
         QCameraImageProcessingControl::ProcessingParameter parameter) const
 {
     if (m_values.contains(parameter))
@@ -148,19 +196,21 @@ QVariant CameraBinImageProcessing::processingParameter(
         return QVariant();
 }
 
-void CameraBinImageProcessing::setProcessingParameter(
-        QCameraImageProcessingControl::ProcessingParameter parameter,
-        QVariant value)
+void CameraBinImageProcessing::setParameter(QCameraImageProcessingControl::ProcessingParameter parameter,
+        const QVariant &value)
 {
     switch (parameter) {
-    case Contrast:
-        setColorBalanceValue("contrast", value.toInt());
+    case ContrastAdjustment:
+        setColorBalanceValue("contrast", value.toReal());
+        break;
+    case BrightnessAdjustment:
+        setColorBalanceValue("brightness", value.toReal());
         break;
-    case Brightness:
-        setColorBalanceValue("brightness", value.toInt());
+    case SaturationAdjustment:
+        setColorBalanceValue("saturation", value.toReal());
         break;
-    case Saturation:
-        setColorBalanceValue("saturation", value.toInt());
+    case WhiteBalancePreset:
+        setWhiteBalanceMode(value.value<QCameraImageProcessing::WhiteBalanceMode>());
         break;
     default:
         break;
@@ -169,3 +219,4 @@ void CameraBinImageProcessing::setProcessingParameter(
     updateColorBalanceValues();
 }
 
+QT_END_NAMESPACE
index dc18a5b..7ba8397 100644 (file)
 #include <gst/gst.h>
 #include <glib.h>
 
-#include <gst/interfaces/photography.h>
 #include <gst/interfaces/colorbalance.h>
 
-class CameraBinSession;
+QT_BEGIN_NAMESPACE
 
-QT_USE_NAMESPACE
+class CameraBinSession;
 
 class CameraBinImageProcessing : public QCameraImageProcessingControl
 {
@@ -67,18 +66,23 @@ public:
     void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode);
     bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const;
 
-    bool isProcessingParameterSupported(ProcessingParameter) const;
-    QVariant processingParameter(ProcessingParameter parameter) const;
-    void setProcessingParameter(ProcessingParameter parameter, QVariant value);
+    bool isParameterSupported(ProcessingParameter) const;
+    bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const;
+    QVariant parameter(ProcessingParameter parameter) const;
+    void setParameter(ProcessingParameter parameter, const QVariant &value);
 
 private:
-    bool setColorBalanceValue(const QString& channel, int value);
+    bool setColorBalanceValue(const QString& channel, qreal value);
     void updateColorBalanceValues();
 
 private:
     CameraBinSession *m_session;
     QMap<QCameraImageProcessingControl::ProcessingParameter, int> m_values;
+#ifdef HAVE_GST_PHOTOGRAPHY
     QMap<GstWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues;
+#endif
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINIMAGEPROCESSINGCONTROL_H
index f94d23e..2a4c18a 100644 (file)
@@ -47,6 +47,8 @@
 
 #include <QDebug>
 
+QT_BEGIN_NAMESPACE
+
 CameraBinLocks::CameraBinLocks(CameraBinSession *session)
     :QCameraLocksControl(session),
      m_session(session),
@@ -86,3 +88,5 @@ void CameraBinLocks::updateFocusStatus(QCamera::LockStatus status, QCamera::Lock
 {
     emit lockStatusChanged(QCamera::LockFocus, status, reason);
 }
+
+QT_END_NAMESPACE
index 71084b7..b6ea0ce 100644 (file)
 #include <gst/gst.h>
 #include <glib.h>
 
+QT_BEGIN_NAMESPACE
+
 class CameraBinSession;
 class CameraBinFocus;
 
-QT_USE_NAMESPACE
-
 class CameraBinLocks  : public QCameraLocksControl
 {
     Q_OBJECT
@@ -76,4 +76,6 @@ private:
     CameraBinFocus *m_focus;
 };
 
+QT_END_NAMESPACE
+
 #endif
index a986230..4e355c0 100644 (file)
@@ -44,6 +44,8 @@
 #include <gst/gst.h>
 #include <gst/gstversion.h>
 
+QT_BEGIN_NAMESPACE
+
 struct QGstreamerMetaDataKeyLookup
 {
     QString key;
@@ -175,3 +177,5 @@ QStringList CameraBinMetaData::availableMetaData() const
 
     return res;
 }
+
+QT_END_NAMESPACE
index 202f36a..7788250 100644 (file)
@@ -44,7 +44,7 @@
 
 #include <qmetadatawritercontrol.h>
 
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
 
 class CameraBinMetaData : public QMetaDataWriterControl
 {
@@ -68,4 +68,6 @@ private:
     QMap<QByteArray, QVariant> m_values;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINCAPTUREMETADATACONTROL_H
index 8b8495c..8e75e71 100644 (file)
 
 #include <gst/pbutils/encoding-profile.h>
 
+QT_BEGIN_NAMESPACE
+
 CameraBinRecorder::CameraBinRecorder(CameraBinSession *session)
     :QMediaRecorderControl(session),
      m_session(session),
-     m_state(QMediaRecorder::StoppedState)
+     m_state(QMediaRecorder::StoppedState),
+     m_status(QMediaRecorder::UnloadedStatus)
 {
-    connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateState()));
+    connect(m_session, SIGNAL(stateChanged(QCamera::State)), SLOT(updateStatus()));
+    connect(m_session, SIGNAL(pendingStateChanged(QCamera::State)), SLOT(updateStatus()));
+    connect(m_session, SIGNAL(busyChanged(bool)), SLOT(updateStatus()));
+
     connect(m_session, SIGNAL(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
     connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
 }
@@ -77,13 +83,43 @@ QMediaRecorder::State CameraBinRecorder::state() const
     return m_state;
 }
 
-void CameraBinRecorder::updateState()
+QMediaRecorder::Status CameraBinRecorder::status() const
 {
-    if (m_session->state() != QCamera::ActiveState &&
-            m_state != QMediaRecorder::StoppedState) {
-        m_session->stopVideoRecording();
-        emit stateChanged(m_state = QMediaRecorder::StoppedState);
+    return m_status;
+}
+
+void CameraBinRecorder::updateStatus()
+{
+    QCamera::State sessionState = m_session->state();
+
+    QMediaRecorder::State oldState = m_state;
+    QMediaRecorder::Status oldStatus = m_status;
+
+    if (sessionState == QCamera::ActiveState &&
+            m_session->captureMode().testFlag(QCamera::CaptureVideo)) {
+
+        if (m_state == QMediaRecorder::RecordingState) {
+            m_status = QMediaRecorder::RecordingStatus;
+        } else {
+            m_status = m_session->isBusy() ?
+                        QMediaRecorder::FinalizingStatus :
+                        QMediaRecorder::LoadedStatus;
+        }
+    } else {
+        if (m_state == QMediaRecorder::RecordingState) {
+            m_state = QMediaRecorder::StoppedState;
+            m_session->stopVideoRecording();
+        }
+        m_status = m_session->pendingState() == QCamera::ActiveState ?
+                    QMediaRecorder::LoadingStatus :
+                    QMediaRecorder::UnloadedStatus;
     }
+
+    if (m_state != oldState)
+        emit stateChanged(m_state);
+
+    if (m_status != oldStatus)
+        emit statusChanged(m_status);
 }
 
 qint64 CameraBinRecorder::duration() const
@@ -91,29 +127,13 @@ qint64 CameraBinRecorder::duration() const
     return m_session->duration();
 }
 
-void CameraBinRecorder::record()
-{
-    if (m_session->state() == QCamera::ActiveState) {
-        m_session->recordVideo();
-        emit stateChanged(m_state = QMediaRecorder::RecordingState);
-    } else
-        emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
-}
 
-void CameraBinRecorder::pause()
+void CameraBinRecorder::applySettings()
 {
-    emit error(QMediaRecorder::ResourceError, tr("QMediaRecorder::pause() is not supported by camerabin2."));
+    //settings are applied during camera startup
 }
 
-void CameraBinRecorder::stop()
-{
-    if (m_session->state() == QCamera::ActiveState) {
-        m_session->stopVideoRecording();
-        emit stateChanged(m_state = QMediaRecorder::StoppedState);
-    }
-}
-
-void CameraBinRecorder::applySettings()
+GstEncodingContainerProfile *CameraBinRecorder::videoProfile()
 {
     GstEncodingContainerProfile *containerProfile = m_session->mediaContainerControl()->createProfile();
 
@@ -125,7 +145,42 @@ void CameraBinRecorder::applySettings()
         gst_encoding_container_profile_add_profile(containerProfile, videoProfile);
     }
 
-    g_object_set (G_OBJECT(m_session->cameraBin()), "video-profile", containerProfile, NULL);
+    return containerProfile;
+}
+
+void CameraBinRecorder::setState(QMediaRecorder::State state)
+{
+    if (m_state == state)
+        return;
+
+    QMediaRecorder::State oldState = m_state;
+    QMediaRecorder::Status oldStatus = m_status;
+
+    switch (state) {
+    case QMediaRecorder::StoppedState:
+        m_state = state;
+        m_status = QMediaRecorder::FinalizingStatus;
+        m_session->stopVideoRecording();
+        break;
+    case QMediaRecorder::PausedState:
+        emit error(QMediaRecorder::ResourceError, tr("QMediaRecorder::pause() is not supported by camerabin2."));
+        break;
+    case QMediaRecorder::RecordingState:
+        if (m_session->state() == QCamera::ActiveState) {
+            m_session->recordVideo();
+            m_state = state;
+            m_status = QMediaRecorder::RecordingStatus;
+            emit actualLocationChanged(m_session->outputLocation());
+        } else {
+            emit error(QMediaRecorder::ResourceError, tr("Service has not been started"));
+        }
+    }
+
+    if (m_state != oldState)
+        emit stateChanged(m_state);
+
+    if (m_status != oldStatus)
+        emit statusChanged(m_status);
 }
 
 bool CameraBinRecorder::isMuted() const
@@ -137,3 +192,5 @@ void CameraBinRecorder::setMuted(bool muted)
 {
     m_session->setMuted(muted);
 }
+
+QT_END_NAMESPACE
index 239dcf7..8d890ba 100644 (file)
@@ -45,7 +45,9 @@
 
 #include <qmediarecordercontrol.h>
 #include "camerabinsession.h"
-QT_USE_NAMESPACE
+#include <gst/pbutils/encoding-profile.h>
+
+QT_BEGIN_NAMESPACE
 
 class CameraBinRecorder : public QMediaRecorderControl
 {
@@ -59,25 +61,28 @@ public:
     bool setOutputLocation(const QUrl &sink);
 
     QMediaRecorder::State state() const;
+    QMediaRecorder::Status status() const;
 
     qint64 duration() const;
 
     bool isMuted() const;
 
     void applySettings();
+    GstEncodingContainerProfile *videoProfile();
 
 public slots:
-    void record();
-    void pause();
-    void stop();
+    void setState(QMediaRecorder::State state);
     void setMuted(bool);
 
 private slots:
-    void updateState();
+    void updateStatus();
 
 private:
     CameraBinSession *m_session;
     QMediaRecorder::State m_state;
+    QMediaRecorder::Status m_status;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINCAPTURECORNTROL_H
index 8e0ee17..cd18aaa 100644 (file)
@@ -51,6 +51,8 @@
 #include <policy/resource-set.h>
 #endif
 
+QT_BEGIN_NAMESPACE
+
 CamerabinResourcePolicy::CamerabinResourcePolicy(QObject *parent) :
     QObject(parent),
     m_resourceSet(NoResources),
@@ -182,3 +184,5 @@ void CamerabinResourcePolicy::handleResourcesReleased()
     m_releasingResources = false;
 #endif
 }
+
+QT_END_NAMESPACE
index 2e334b9..835e25c 100644 (file)
@@ -48,6 +48,8 @@ namespace ResourcePolicy {
 class ResourceSet;
 };
 
+QT_BEGIN_NAMESPACE
+
 class CamerabinResourcePolicy : public QObject
 {
     Q_OBJECT
@@ -81,4 +83,6 @@ private:
     bool m_releasingResources;
 };
 
+QT_END_NAMESPACE
+
 #endif
index 5c58ea3..6fd551d 100644 (file)
 #include "camerabinvideoencoder.h"
 #include "camerabinimageencoder.h"
 #include "camerabincontrol.h"
-#include "camerabinlocks.h"
 #include "camerabinmetadata.h"
+
+#ifdef HAVE_GST_PHOTOGRAPHY
 #include "camerabinexposure.h"
 #include "camerabinflash.h"
 #include "camerabinfocus.h"
+#include "camerabinlocks.h"
+#endif
+
 #include "camerabinimagecapture.h"
 #include "camerabinimageprocessing.h"
 #include "camerabincapturebufferformat.h"
 #include "camerabincapturedestination.h"
 #include <private/qgstreamerbushelper_p.h>
 
-#include "qgstreameraudioinputendpointselector.h"
-#include "qgstreamervideoinputdevicecontrol.h"
+#include <private/qgstreameraudioinputendpointselector_p.h>
+#include <private/qgstreamervideoinputdevicecontrol_p.h>
 
 #if defined(HAVE_WIDGETS)
-#include "qgstreamervideooverlay.h"
-#include "qgstreamervideowindow.h"
-#include "qgstreamervideowidget.h"
+#include <private/qgstreamervideooverlay_p.h>
+#include <private/qgstreamervideowindow_p.h>
+#include <private/qgstreamervideowidget_p.h>
 #endif
 
-#include "qgstreamervideorenderer.h"
+#include <private/qgstreamervideorenderer_p.h>
 
 #if defined(Q_WS_MAEMO_6) && defined(__arm__)
 #include "qgstreamergltexturerenderer.h"
 #endif
 
-#include <qmediaserviceprovider.h>
+#include <private/qmediaserviceprovider_p.h>
 
 #include <QtCore/qdebug.h>
 #include <QtCore/qprocess.h>
@@ -82,6 +86,8 @@
 #include "camerabuttonlistener_meego.h"
 #endif
 
+QT_BEGIN_NAMESPACE
+
 CameraBinService::CameraBinService(const QString &service, QObject *parent):
     QMediaService(parent)
 {
@@ -208,6 +214,7 @@ QMediaControl *CameraBinService::requestControl(const char *name)
     if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
         return m_imageCaptureControl;
 
+#ifdef HAVE_GST_PHOTOGRAPHY
     if (qstrcmp(name, QCameraExposureControl_iid) == 0)
         return m_captureSession->cameraExposureControl();
 
@@ -217,11 +224,12 @@ QMediaControl *CameraBinService::requestControl(const char *name)
     if (qstrcmp(name, QCameraFocusControl_iid) == 0)
         return m_captureSession->cameraFocusControl();
 
-    if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
-        return m_captureSession->imageProcessingControl();
-
     if (qstrcmp(name, QCameraLocksControl_iid) == 0)
         return m_captureSession->cameraLocksControl();
+#endif
+
+    if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
+        return m_captureSession->imageProcessingControl();
 
     if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0)
         return m_captureSession->captureDestinationControl();
@@ -250,3 +258,5 @@ bool CameraBinService::isCameraBinAvailable()
 
     return false;
 }
+
+QT_END_NAMESPACE
index 940ec70..f710eb8 100644 (file)
 #include <qmediaservice.h>
 
 #include <gst/gst.h>
+
 QT_BEGIN_NAMESPACE
 class QAudioEndpointSelectorControl;
 class QVideoDeviceSelectorControl;
-QT_END_NAMESPACE
+
 
 class CameraBinSession;
 class CameraBinControl;
@@ -95,4 +96,6 @@ private:
     CameraBinImageCapture *m_imageCaptureControl;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINCAPTURESERVICE_H
diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.cpp
new file mode 100644 (file)
index 0000000..7e8aebb
--- /dev/null
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+
+#include "camerabinserviceplugin.h"
+
+
+#include "camerabinservice.h"
+#include <private/qgstutils_p.h>
+
+#include <linux/types.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <linux/videodev2.h>
+#include <gst/gst.h>
+
+QT_BEGIN_NAMESPACE
+
+QMediaService* CameraBinServicePlugin::create(const QString &key)
+{
+    QGstUtils::initializeGst();
+
+    if (key == QLatin1String(Q_MEDIASERVICE_CAMERA))
+        return new CameraBinService(key);
+
+    qWarning() << "Gstreamer camerabin service plugin: unsupported key:" << key;
+    return 0;
+}
+
+void CameraBinServicePlugin::release(QMediaService *service)
+{
+    delete service;
+}
+
+QMediaServiceProviderHint::Features CameraBinServicePlugin::supportedFeatures(
+        const QByteArray &service) const
+{
+    if (service == Q_MEDIASERVICE_CAMERA)
+        return QMediaServiceProviderHint::VideoSurface;
+
+    return QMediaServiceProviderHint::Features();
+}
+
+QList<QByteArray> CameraBinServicePlugin::devices(const QByteArray &service) const
+{
+    if (service == Q_MEDIASERVICE_CAMERA) {
+        if (m_cameraDevices.isEmpty())
+            updateDevices();
+
+        return m_cameraDevices;
+    }
+
+    return QList<QByteArray>();
+}
+
+QString CameraBinServicePlugin::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();
+}
+
+QVariant CameraBinServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property)
+{
+    Q_UNUSED(service);
+    Q_UNUSED(device);
+    Q_UNUSED(property);
+    return QVariant();
+}
+
+void CameraBinServicePlugin::updateDevices() const
+{
+    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 = ::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);
+        }
+        ::close(fd);
+    }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h b/src/plugins/gstreamer/camerabin/camerabinserviceplugin.h
new file mode 100644 (file)
index 0000000..4d9931a
--- /dev/null
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef CAMERABINSERVICEPLUGIN_H
+#define CAMERABINSERVICEPLUGIN_H
+
+#include <qmediaserviceproviderplugin.h>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class CameraBinServicePlugin
+    : public QMediaServiceProviderPlugin
+    , public QMediaServiceSupportedDevicesInterface
+    , public QMediaServiceFeaturesInterface
+{
+    Q_OBJECT
+    Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
+    Q_INTERFACES(QMediaServiceFeaturesInterface)
+    Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "camerabin.json")
+public:
+    QMediaService* create(QString const& key);
+    void release(QMediaService *service);
+
+    QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
+
+    QList<QByteArray> devices(const QByteArray &service) const;
+    QString deviceDescription(const QByteArray &service, const QByteArray &device);
+    QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
+
+private:
+    void updateDevices() const;
+
+    mutable QList<QByteArray> m_cameraDevices;
+    mutable QStringList m_cameraDescriptions;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGSTREAMERCAPTURESERVICEPLUGIN_H
index 69095d3..2c26427 100644 (file)
 #include "camerabinaudioencoder.h"
 #include "camerabinvideoencoder.h"
 #include "camerabinimageencoder.h"
+
+#ifdef HAVE_GST_PHOTOGRAPHY
 #include "camerabinexposure.h"
 #include "camerabinflash.h"
 #include "camerabinfocus.h"
-#include "camerabinimageprocessing.h"
 #include "camerabinlocks.h"
+#endif
+
+#include "camerabinimageprocessing.h"
+
 #include "camerabincapturedestination.h"
 #include "camerabincapturebufferformat.h"
 #include <private/qgstreamerbushelper_p.h>
-#include "qgstreamervideorendererinterface.h"
+#include <private/qgstreamervideorendererinterface_p.h>
 #include <qmediarecorder.h>
+
+#ifdef HAVE_GST_PHOTOGRAPHY
 #include <gst/interfaces/photography.h>
+#endif
+
 #include <gst/gsttagsetter.h>
 #include <gst/gstversion.h>
 
 #define AUDIO_SOURCE_PROPERTY "audio-source"
 #define SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-supported-caps"
 #define SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-supported-caps"
-#define FILTER_CAPS_PROPERTY "filter-caps"
+#define IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-caps"
+#define VIDEO_CAPTURE_CAPS_PROPERTY "video-capture-caps"
+#define VIEWFINDER_CAPS_PROPERTY "viewfinder-caps"
 #define PREVIEW_CAPS_PROPERTY "preview-caps"
+#define POST_PREVIEWS_PROPERTY "post-previews"
+
 
 #define CAPTURE_START "start-capture"
 #define CAPTURE_STOP "stop-capture"
-#define SET_VIDEO_RESOLUTION_FPS "set-video-resolution-fps"
-#define SET_IMAGE_RESOLUTION "set-image-resolution"
 
 #define CAMERABIN_IMAGE_MODE 1
 #define CAMERABIN_VIDEO_MODE 2
 
 //#define USE_READY_STATE_ON_LOADED
 
+QT_BEGIN_NAMESPACE
 
 CameraBinSession::CameraBinSession(QObject *parent)
     :QObject(parent),
      m_recordingActive(false),
      m_state(QCamera::UnloadedState),
      m_pendingState(QCamera::UnloadedState),
-     m_pendingResolutionUpdate(false),
      m_muted(false),
      m_busy(false),
      m_captureMode(QCamera::CaptureStillImage),
@@ -145,15 +156,20 @@ CameraBinSession::CameraBinSession(QObject *parent)
     m_imageEncodeControl = new CameraBinImageEncoder(this);
     m_recorderControl = new CameraBinRecorder(this);
     m_mediaContainerControl = new CameraBinContainer(this);
+
+#ifdef HAVE_GST_PHOTOGRAPHY
     m_cameraExposureControl = new CameraBinExposure(this);
     m_cameraFlashControl = new CameraBinFlash(this);
     m_cameraFocusControl = new CameraBinFocus(this);
-    m_imageProcessingControl = new CameraBinImageProcessing(this);
     m_cameraLocksControl = new CameraBinLocks(this);
+#endif
+    m_imageProcessingControl = new CameraBinImageProcessing(this);
     m_captureDestinationControl = new CameraBinCaptureDestination(this);
     m_captureBufferFormatControl = new CameraBinCaptureBufferFormat(this);
 
     //post image preview in RGB format
+    g_object_set(G_OBJECT(m_camerabin), POST_PREVIEWS_PROPERTY, TRUE, NULL);
+
     GstCaps *previewCaps = gst_caps_from_string("video/x-raw-rgb");
     g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL);
     gst_caps_unref(previewCaps);
@@ -172,6 +188,7 @@ CameraBinSession::~CameraBinSession()
     }
 }
 
+#ifdef HAVE_GST_PHOTOGRAPHY
 GstPhotography *CameraBinSession::photography()
 {
     if (GST_IS_PHOTOGRAPHY(m_camerabin)) {
@@ -194,6 +211,7 @@ GstPhotography *CameraBinSession::photography()
 
     return 0;
 }
+#endif
 
 CameraBinSession::CameraRole CameraBinSession::cameraRole() const
 {
@@ -290,7 +308,7 @@ void CameraBinSession::setupCaptureResolution()
 #if CAMERABIN_DEBUG
             qDebug() << Q_FUNC_INFO << "set image resolution" << resolution << gst_caps_to_string(caps);
 #endif
-            g_object_set(m_camerabin, "image-capture-caps", caps, NULL);
+            g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, caps, NULL);
             gst_caps_unref(caps);
 
             if (!resolution.isEmpty()) {
@@ -302,6 +320,8 @@ void CameraBinSession::setupCaptureResolution()
                 else
                     viewfinderResolution = VIEWFINDER_RESOLUTION_3x2;
             }
+        } else {
+            g_object_set(m_camerabin, IMAGE_CAPTURE_CAPS_PROPERTY, GST_CAPS_ANY, NULL);
         }
 
         //on low res cameras the viewfinder resolution should not be bigger
@@ -313,7 +333,7 @@ void CameraBinSession::setupCaptureResolution()
 #if CAMERABIN_DEBUG
         qDebug() << "Set viewfinder resolution" << viewfinderResolution <<gst_caps_to_string(viewfinderCaps);
 #endif
-        g_object_set(m_camerabin, "viewfinder-caps", viewfinderCaps, NULL);
+        g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, viewfinderCaps, NULL);
         gst_caps_unref(viewfinderCaps);
     }
 
@@ -336,7 +356,9 @@ void CameraBinSession::setupCaptureResolution()
         qDebug() << Q_FUNC_INFO << "set video resolution" << resolution << gst_caps_to_string(caps);
 #endif
 
-        g_object_set(m_camerabin, "video-capture-caps", caps, NULL);
+        //Use the same resolution for viewfinder and video capture
+        g_object_set(m_camerabin, VIDEO_CAPTURE_CAPS_PROPERTY, caps, NULL);
+        g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, caps, NULL);
         gst_caps_unref(caps);
     }
 }
@@ -347,34 +369,37 @@ GstElement *CameraBinSession::buildCameraSource()
     qDebug() << Q_FUNC_INFO;
 #endif
     GstElement *videoSrc = 0;
-    if (m_videoInputFactory) {
-        videoSrc = m_videoInputFactory->buildElement();
-    } else {
-        QList<QByteArray> candidates;
-        candidates << "wrappercamerabinsrc";
-        QByteArray sourceElementName;
 
-        foreach(sourceElementName, candidates) {
-            videoSrc = gst_element_factory_make(sourceElementName.constData(), "camera_source");
-            if (videoSrc)
-                break;
-        }
+    QList<QByteArray> candidates;
+    candidates << "subdevsrc" << "wrappercamerabinsrc";
+    QByteArray sourceElementName;
+
+    foreach (sourceElementName, candidates) {
+        videoSrc = gst_element_factory_make(sourceElementName.constData(), "camera_source");
+        if (videoSrc)
+            break;
+    }
 
-        if (videoSrc && !m_inputDevice.isEmpty()) {
+    if (videoSrc && !m_inputDevice.isEmpty()) {
 #if CAMERABIN_DEBUG
-            qDebug() << "set camera device" << m_inputDevice;
+        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 (g_object_class_find_property(G_OBJECT_GET_CLASS(videoSrc), "device"))
-                    g_object_set(G_OBJECT(videoSrc),
-                                 "device",
-                                 m_inputDevice.toLocal8Bit().constData(),
-                                 NULL);
+        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") {
+            GstElement *src = 0;
+
+            if (m_videoInputFactory)
+                src = m_videoInputFactory->buildElement();
+            else
+                src = gst_element_factory_make("v4l2src", "camera_source");
+
+            if (src) {
+                g_object_set(G_OBJECT(src), "device", m_inputDevice.toUtf8().constData(), NULL);
+                g_object_set(G_OBJECT(videoSrc), "video-source", src, NULL);
             }
         }
     }
@@ -558,12 +583,18 @@ QCamera::State CameraBinSession::state() const
     return m_state;
 }
 
+QCamera::State CameraBinSession::pendingState() const
+{
+    return m_pendingState;
+}
+
 void CameraBinSession::setState(QCamera::State newState)
 {
     if (newState == m_pendingState)
         return;
 
     m_pendingState = newState;
+    emit pendingStateChanged(m_pendingState);
 
 #if CAMERABIN_DEBUG
     qDebug() << Q_FUNC_INFO << newState;
@@ -613,14 +644,14 @@ void CameraBinSession::setState(QCamera::State newState)
             GstState pending = GST_STATE_NULL;
             gst_element_get_state(m_camerabin, &binState, &pending, 0);
 
-            if (pending == GST_STATE_VOID_PENDING && binState == GST_STATE_READY) {
-                m_pendingResolutionUpdate = false;
-                setupCaptureResolution();
-                gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
-            } else {
-                m_pendingResolutionUpdate = true;
-                gst_element_set_state(m_camerabin, GST_STATE_READY);
-            }
+            setupCaptureResolution();
+            if (captureMode() == QCamera::CaptureVideo)
+                g_object_set (G_OBJECT(m_camerabin),
+                              "video-profile",
+                              m_recorderControl->videoProfile(),
+                              NULL);
+
+            gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
         }
     }
 }
@@ -790,9 +821,10 @@ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message)
                 return true;
             }
         }
-
+#ifdef HAVE_GST_PHOTOGRAPHY
         if (gst_structure_has_name(gm->structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE))
             m_cameraFocusControl->handleFocusMessage(gm);
+#endif
     }
 
     return false;
@@ -890,11 +922,6 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
                             emit stateChanged(m_state = QCamera::UnloadedState);
                         break;
                     case GST_STATE_READY:
-                        if (m_pendingResolutionUpdate) {
-                            m_pendingResolutionUpdate = false;
-                            setupCaptureResolution();
-                            gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
-                        }
                         if (m_state != QCamera::LoadedState)
                             emit stateChanged(m_state = QCamera::LoadedState);
                         break;
@@ -920,11 +947,14 @@ void CameraBinSession::recordVideo()
     m_recordingActive = true;
     m_actualSink = m_sink;
     if (m_actualSink.isEmpty()) {
-        QString ext = m_mediaContainerControl->suggestedFileExtension();
-        m_actualSink = generateFileName("clip_", defaultDir(QCamera::CaptureVideo), ext);
+        QString ext = m_mediaContainerControl->suggestedFileExtension(m_mediaContainerControl->containerFormat());
+        m_actualSink = QUrl::fromLocalFile(generateFileName("clip_", defaultDir(QCamera::CaptureVideo), ext));
+    } else if (!m_actualSink.isLocalFile()) {
+        m_actualSink = QUrl::fromLocalFile(m_actualSink.toEncoded());
     }
 
-    g_object_set(G_OBJECT(m_camerabin), FILENAME_PROPERTY, m_actualSink.toEncoded().constData(), NULL);
+    QString fileName = m_actualSink.toLocalFile();
+    g_object_set(G_OBJECT(m_camerabin), FILENAME_PROPERTY, QFile::encodeName(fileName).constData(), NULL);
 
     g_signal_emit_by_name(G_OBJECT(m_camerabin), CAPTURE_START, NULL);
 }
@@ -1214,3 +1244,5 @@ QList<QSize> CameraBinSession::supportedResolutions(QPair<int,int> rate,
 
     return res;
 }
+
+QT_END_NAMESPACE
index 06e3748..b6159e1 100644 (file)
 #include <QtCore/qdir.h>
 
 #include <gst/gst.h>
+#ifdef HAVE_GST_PHOTOGRAPHY
 #include <gst/interfaces/photography.h>
+#endif
 
 #include <private/qgstreamerbushelper_p.h>
 #include "qcamera.h"
 
+QT_BEGIN_NAMESPACE
 
 class QGstreamerMessage;
 class QGstreamerBusHelper;
@@ -76,6 +79,7 @@ public:
     virtual GstElement *buildElement() = 0;
 };
 
+
 class CameraBinSession : public QObject,
                          public QGstreamerBusMessageFilter,
                          public QGstreamerSyncMessageFilter
@@ -92,7 +96,9 @@ public:
     CameraBinSession(QObject *parent);
     ~CameraBinSession();
 
+#ifdef HAVE_GST_PHOTOGRAPHY
     GstPhotography *photography();
+#endif
     GstElement *cameraBin() { return m_camerabin; }
     QGstreamerBusHelper *bus() { return m_busHelper; }
 
@@ -113,11 +119,15 @@ public:
     CameraBinAudioEncoder *audioEncodeControl() const { return m_audioEncodeControl; }
     CameraBinVideoEncoder *videoEncodeControl() const { return m_videoEncodeControl; }
     CameraBinImageEncoder *imageEncodeControl() const { return m_imageEncodeControl; }
+
+#ifdef HAVE_GST_PHOTOGRAPHY
     CameraBinExposure *cameraExposureControl() const  { return m_cameraExposureControl; }
     CameraBinFlash *cameraFlashControl() const  { return m_cameraFlashControl; }
     CameraBinFocus *cameraFocusControl() const  { return m_cameraFocusControl; }
-    CameraBinImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; }
     CameraBinLocks *cameraLocksControl() const { return m_cameraLocksControl; }
+#endif
+
+    CameraBinImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; }
     CameraBinCaptureDestination *captureDestinationControl() const { return m_captureDestinationControl; }
     CameraBinCaptureBufferFormat *captureBufferFormatControl() const { return m_captureBufferFormatControl; }
 
@@ -138,6 +148,7 @@ public:
     void captureImage(int requestId, const QString &fileName);
 
     QCamera::State state() const;
+    QCamera::State pendingState() const;
     bool isBusy() const;
 
     qint64 duration() const;
@@ -152,6 +163,7 @@ public:
 
 signals:
     void stateChanged(QCamera::State state);
+    void pendingStateChanged(QCamera::State state);
     void durationChanged(qint64 duration);
     void error(int error, const QString &errorString);
     void imageExposed(int requestId);
@@ -184,7 +196,6 @@ private:
     QCamera::State m_state;
     QCamera::State m_pendingState;
     QString m_inputDevice;
-    bool m_pendingResolutionUpdate;
     bool m_muted;
     bool m_busy;
 
@@ -201,11 +212,14 @@ private:
     CameraBinImageEncoder *m_imageEncodeControl;
     CameraBinRecorder *m_recorderControl;
     CameraBinContainer *m_mediaContainerControl;
+#ifdef HAVE_GST_PHOTOGRAPHY
     CameraBinExposure *m_cameraExposureControl;
     CameraBinFlash *m_cameraFlashControl;
     CameraBinFocus *m_cameraFocusControl;
-    CameraBinImageProcessing *m_imageProcessingControl;
     CameraBinLocks *m_cameraLocksControl;
+#endif
+
+    CameraBinImageProcessing *m_imageProcessingControl;
     CameraBinCaptureDestination *m_captureDestinationControl;
     CameraBinCaptureBufferFormat *m_captureBufferFormatControl;
 
@@ -229,4 +243,6 @@ public:
     int m_requestId;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABINCAPTURESESSION_MAEMO_H
index c7bb47c..085b9a1 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <QtCore/qdebug.h>
 
+QT_BEGIN_NAMESPACE
+
 CameraBinVideoEncoder::CameraBinVideoEncoder(CameraBinSession *session)
     :QVideoEncoderSettingsControl(session),
      m_session(session),
@@ -164,3 +166,5 @@ GstEncodingProfile *CameraBinVideoEncoder::createProfile()
                 NULL, //restriction
                 0); //presence
 }
+
+QT_END_NAMESPACE
index 554e443..9a9dae1 100644 (file)
@@ -43,7 +43,6 @@
 #define CAMERABINVIDEOENCODE_H
 
 #include <qvideoencodersettingscontrol.h>
-class CameraBinSession;
 
 #include <QtCore/qstringlist.h>
 #include <QtCore/qmap.h>
@@ -52,9 +51,11 @@ class CameraBinSession;
 #include <gst/gst.h>
 #include <gst/pbutils/pbutils.h>
 #include <gst/pbutils/encoding-profile.h>
-#include "qgstcodecsinfo.h"
+#include <private/qgstcodecsinfo_p.h>
+
+QT_BEGIN_NAMESPACE
 
-QT_USE_NAMESPACE
+class CameraBinSession;
 
 class CameraBinVideoEncoder : public QVideoEncoderSettingsControl
 {
@@ -94,4 +95,6 @@ private:
     QVideoEncoderSettings m_userSettings;
 };
 
+QT_END_NAMESPACE
+
 #endif
index 026f49b..82b9396 100644 (file)
@@ -46,6 +46,8 @@
 #include <QtWidgets/qwidget.h>
 #include <QtCore/qdebug.h>
 
+QT_BEGIN_NAMESPACE
+
 CameraButtonListener::CameraButtonListener(QObject *parent) :
     QObject(parent),
     m_focusPressed(false),
@@ -90,3 +92,5 @@ void CameraButtonListener::handleQmKeyEvent(MeeGo::QmKeys::Key key, MeeGo::QmKey
         }
     }
 }
+
+QT_END_NAMESPACE
index 01cc389..e142515 100644 (file)
@@ -46,6 +46,8 @@
 #include <QtCore/qobject.h>
 #include <qmsystem2/qmkeys.h>
 
+QT_BEGIN_NAMESPACE
+
 class CameraButtonListener : public QObject
 {
     Q_OBJECT
@@ -62,4 +64,6 @@ private:
     bool m_shutterPressed;
 };
 
+QT_END_NAMESPACE
+
 #endif // CAMERABUTTONLISTENER_MEEGO_H
index 63f2c64..7649010 100644 (file)
@@ -5,11 +5,8 @@ SUBDIRS += \
     mediacapture \
     mediaplayer
 
-# Camerabin2 based camera backend is untested and currently disabled
-disabled {
-    config_gstreamer_photography {
-        SUBDIRS += camerabin
-    }
+config_gstreamer_encodingprofiles {
+    SUBDIRS += camerabin
 }
 
 OTHER_FILES += \
index d5e1722..830d03d 100644 (file)
@@ -91,6 +91,9 @@ private slots:
     void testCameraCaptureMetadata();
     void testExposureCompensation();
     void testExposureMode();
+
+    void testVideoRecording_data();
+    void testVideoRecording();
 private:
 };
 
@@ -565,6 +568,81 @@ void tst_QCameraBackend::testExposureMode()
     QCOMPARE(exposure->exposureMode(), QCameraExposure::ExposureAuto);
 }
 
+void tst_QCameraBackend::testVideoRecording_data()
+{
+    QTest::addColumn<QByteArray>("device");
+
+    QList<QByteArray> devices = QCamera::availableDevices();
+
+    foreach (const QByteArray &device, devices) {
+        QTest::newRow(QCamera::deviceDescription(device).toUtf8())
+                << device;
+    }
+
+    if (devices.isEmpty())
+        QTest::newRow("Default device") << QByteArray();
+}
+
+void tst_QCameraBackend::testVideoRecording()
+{
+    QFETCH(QByteArray, device);
+
+    QCamera *camera = device.isEmpty() ? new QCamera : new QCamera(device);
+
+    QMediaRecorder recorder(camera);
+
+    QSignalSpy errorSignal(camera, SIGNAL(error(QCamera::Error)));
+    QSignalSpy recorderErrorSignal(&recorder, SIGNAL(error(QMediaRecorder::Error)));
+    QSignalSpy recorderStatusSignal(&recorder, SIGNAL(statusChanged(QMediaRecorder::Status)));
+
+    if (!camera->isCaptureModeSupported(QCamera::CaptureVideo)) {
+        QSKIP("Video capture not supported");
+    }
+
+    camera->setCaptureMode(QCamera::CaptureVideo);
+
+    QVideoEncoderSettings videoSettings;
+    videoSettings.setResolution(640, 480);
+    recorder.setVideoSettings(videoSettings);
+
+    recorder.setContainerFormat("ogg");
+
+    QCOMPARE(recorder.status(), QMediaRecorder::UnloadedStatus);
+
+    camera->start();
+    QCOMPARE(recorder.status(), QMediaRecorder::LoadingStatus);
+    QCOMPARE(recorderStatusSignal.last().first().value<QMediaRecorder::Status>(), recorder.status());
+    QTRY_COMPARE(camera->status(), QCamera::ActiveStatus);
+    QTRY_COMPARE(recorder.status(), QMediaRecorder::LoadedStatus);
+    QCOMPARE(recorderStatusSignal.last().first().value<QMediaRecorder::Status>(), recorder.status());
+
+    //record 5 seconds clip
+    recorder.record();
+    QTRY_COMPARE(recorder.status(), QMediaRecorder::RecordingStatus);
+    QCOMPARE(recorderStatusSignal.last().first().value<QMediaRecorder::Status>(), recorder.status());
+    QTest::qWait(5000);
+    recorder.stop();
+    QCOMPARE(recorder.status(), QMediaRecorder::FinalizingStatus);
+    QCOMPARE(recorderStatusSignal.last().first().value<QMediaRecorder::Status>(), recorder.status());
+    QTRY_COMPARE(recorder.status(), QMediaRecorder::LoadedStatus);
+    QCOMPARE(recorderStatusSignal.last().first().value<QMediaRecorder::Status>(), recorder.status());
+
+    QVERIFY(errorSignal.isEmpty());
+    QVERIFY(recorderErrorSignal.isEmpty());
+
+    QString fileName = recorder.actualLocation().toLocalFile();
+    QVERIFY(!fileName.isEmpty());
+
+    QVERIFY(QFileInfo(fileName).size() > 0);
+    QFile(fileName).remove();
+
+    camera->setCaptureMode(QCamera::CaptureStillImage);
+    QTRY_COMPARE(recorder.status(), QMediaRecorder::UnloadedStatus);
+    QCOMPARE(recorderStatusSignal.last().first().value<QMediaRecorder::Status>(), recorder.status());
+
+    delete camera;
+}
+
 QTEST_MAIN(tst_QCameraBackend)
 
 #include "tst_qcamerabackend.moc"