Updated the camerabin2 based camera with QtMultimedia changes

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>
This commit is contained in:
Dmytro Poplavskiy
2012-07-16 10:55:20 +10:00
committed by Qt by Nokia
parent fdc197d614
commit b6a8c713bc
47 changed files with 889 additions and 192 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -11,6 +11,7 @@ win32 {
qtCompileTest(pulseaudio) qtCompileTest(pulseaudio)
qtCompileTest(gstreamer) { qtCompileTest(gstreamer) {
qtCompileTest(gstreamer_photography) qtCompileTest(gstreamer_photography)
qtCompileTest(gstreamer_encodingprofiles)
qtCompileTest(gstreamer_appsrc) qtCompileTest(gstreamer_appsrc)
} }
qtCompileTest(resourcepolicy) qtCompileTest(resourcepolicy)

View File

@@ -0,0 +1,3 @@
{
"Keys": ["org.qt-project.qt.camera"]
}

View File

@@ -3,6 +3,8 @@ load(qt_build_config)
TARGET = gstcamerabin TARGET = gstcamerabin
PLUGIN_TYPE = mediaservice PLUGIN_TYPE = mediaservice
QT += multimedia-private
load(qt_plugin) load(qt_plugin)
DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE} DESTDIR = $$QT.multimedia.plugins/$${PLUGIN_TYPE}
@@ -13,22 +15,16 @@ INCLUDEPATH += $$PWD \
INCLUDEPATH += camerabin INCLUDEPATH += camerabin
LIBS += -lgstphotography-0.10
DEFINES += GST_USE_UNSTABLE_API #prevents warnings because of unstable photography API
HEADERS += \ HEADERS += \
$$PWD/camerabinserviceplugin.h \
$$PWD/camerabinservice.h \ $$PWD/camerabinservice.h \
$$PWD/camerabinsession.h \ $$PWD/camerabinsession.h \
$$PWD/camerabincontrol.h \ $$PWD/camerabincontrol.h \
$$PWD/camerabinaudioencoder.h \ $$PWD/camerabinaudioencoder.h \
$$PWD/camerabinfocus.h \
$$PWD/camerabinimageencoder.h \ $$PWD/camerabinimageencoder.h \
$$PWD/camerabinlocks.h \
$$PWD/camerabinrecorder.h \ $$PWD/camerabinrecorder.h \
$$PWD/camerabincontainer.h \ $$PWD/camerabincontainer.h \
$$PWD/camerabinexposure.h \
$$PWD/camerabinflash.h \
$$PWD/camerabinimagecapture.h \ $$PWD/camerabinimagecapture.h \
$$PWD/camerabinimageprocessing.h \ $$PWD/camerabinimageprocessing.h \
$$PWD/camerabinmetadata.h \ $$PWD/camerabinmetadata.h \
@@ -38,18 +34,15 @@ HEADERS += \
$$PWD/camerabincapturebufferformat.h $$PWD/camerabincapturebufferformat.h
SOURCES += \ SOURCES += \
$$PWD/camerabinserviceplugin.cpp \
$$PWD/camerabinservice.cpp \ $$PWD/camerabinservice.cpp \
$$PWD/camerabinsession.cpp \ $$PWD/camerabinsession.cpp \
$$PWD/camerabincontrol.cpp \ $$PWD/camerabincontrol.cpp \
$$PWD/camerabinaudioencoder.cpp \ $$PWD/camerabinaudioencoder.cpp \
$$PWD/camerabincontainer.cpp \ $$PWD/camerabincontainer.cpp \
$$PWD/camerabinexposure.cpp \
$$PWD/camerabinflash.cpp \
$$PWD/camerabinfocus.cpp \
$$PWD/camerabinimagecapture.cpp \ $$PWD/camerabinimagecapture.cpp \
$$PWD/camerabinimageencoder.cpp \ $$PWD/camerabinimageencoder.cpp \
$$PWD/camerabinimageprocessing.cpp \ $$PWD/camerabinimageprocessing.cpp \
$$PWD/camerabinlocks.cpp \
$$PWD/camerabinmetadata.cpp \ $$PWD/camerabinmetadata.cpp \
$$PWD/camerabinrecorder.cpp \ $$PWD/camerabinrecorder.cpp \
$$PWD/camerabinvideoencoder.cpp \ $$PWD/camerabinvideoencoder.cpp \
@@ -63,8 +56,34 @@ maemo6 {
SOURCES += \ SOURCES += \
$$PWD/camerabuttonlistener_meego.cpp $$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} target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE}
INSTALLS += target INSTALLS += target
OTHER_FILES += \
camerabin.json

View File

@@ -41,10 +41,12 @@
#include "camerabinaudioencoder.h" #include "camerabinaudioencoder.h"
#include "camerabincontainer.h" #include "camerabincontainer.h"
#include "qgstcodecsinfo.h" #include <private/qgstcodecsinfo_p.h>
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
CameraBinAudioEncoder::CameraBinAudioEncoder(QObject *parent) CameraBinAudioEncoder::CameraBinAudioEncoder(QObject *parent)
:QAudioEncoderSettingsControl(parent), :QAudioEncoderSettingsControl(parent),
m_codecs(QGstCodecsInfo::AudioEncoder) m_codecs(QGstCodecsInfo::AudioEncoder)
@@ -110,3 +112,5 @@ GstEncodingProfile *CameraBinAudioEncoder::createProfile()
NULL, //restriction NULL, //restriction
0); //presence 0); //presence
} }
QT_END_NAMESPACE

View File

@@ -43,7 +43,6 @@
#define CAMERABINAUDIOENCODE_H #define CAMERABINAUDIOENCODE_H
#include <qaudioencodersettingscontrol.h> #include <qaudioencodersettingscontrol.h>
class CameraBinSession;
#include <QtCore/qstringlist.h> #include <QtCore/qstringlist.h>
#include <QtCore/qmap.h> #include <QtCore/qmap.h>
@@ -54,9 +53,10 @@ class CameraBinSession;
#include <gst/pbutils/encoding-profile.h> #include <gst/pbutils/encoding-profile.h>
#include <qaudioformat.h> #include <qaudioformat.h>
#include "qgstcodecsinfo.h" #include <private/qgstcodecsinfo_p.h>
QT_USE_NAMESPACE QT_BEGIN_NAMESPACE
class CameraBinSession;
class CameraBinAudioEncoder : public QAudioEncoderSettingsControl class CameraBinAudioEncoder : public QAudioEncoderSettingsControl
{ {
@@ -95,4 +95,6 @@ private:
QAudioEncoderSettings m_userSettings; QAudioEncoderSettings m_userSettings;
}; };
QT_END_NAMESPACE
#endif #endif

View File

@@ -42,6 +42,8 @@
#include "camerabincapturebufferformat.h" #include "camerabincapturebufferformat.h"
#include "camerabinsession.h" #include "camerabinsession.h"
QT_BEGIN_NAMESPACE
CameraBinCaptureBufferFormat::CameraBinCaptureBufferFormat(CameraBinSession *session) CameraBinCaptureBufferFormat::CameraBinCaptureBufferFormat(CameraBinSession *session)
:QCameraCaptureBufferFormatControl(session) :QCameraCaptureBufferFormatControl(session)
, m_session(session) , m_session(session)
@@ -76,3 +78,5 @@ void CameraBinCaptureBufferFormat::setBufferFormat(QVideoFrame::PixelFormat form
emit bufferFormatChanged(format); emit bufferFormatChanged(format);
} }
} }
QT_END_NAMESPACE

View File

@@ -48,6 +48,8 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h> #include <glib.h>
QT_BEGIN_NAMESPACE
class CameraBinSession; class CameraBinSession;
QT_USE_NAMESPACE QT_USE_NAMESPACE
@@ -69,4 +71,6 @@ private:
QVideoFrame::PixelFormat m_format; QVideoFrame::PixelFormat m_format;
}; };
QT_END_NAMESPACE
#endif #endif

View File

@@ -42,6 +42,8 @@
#include "camerabincapturedestination.h" #include "camerabincapturedestination.h"
#include "camerabinsession.h" #include "camerabinsession.h"
QT_BEGIN_NAMESPACE
CameraBinCaptureDestination::CameraBinCaptureDestination(CameraBinSession *session) CameraBinCaptureDestination::CameraBinCaptureDestination(CameraBinSession *session)
:QCameraCaptureDestinationControl(session) :QCameraCaptureDestinationControl(session)
, m_session(session) , m_session(session)
@@ -72,3 +74,5 @@ void CameraBinCaptureDestination::setCaptureDestination(QCameraImageCapture::Cap
emit captureDestinationChanged(m_destination); emit captureDestinationChanged(m_destination);
} }
} }
QT_END_NAMESPACE

View File

@@ -45,6 +45,7 @@
#include <qcameraimagecapture.h> #include <qcameraimagecapture.h>
#include <qcameracapturedestinationcontrol.h> #include <qcameracapturedestinationcontrol.h>
QT_BEGIN_NAMESPACE
class CameraBinSession; class CameraBinSession;
@@ -66,4 +67,6 @@ private:
QCameraImageCapture::CaptureDestinations m_destination; QCameraImageCapture::CaptureDestinations m_destination;
}; };
QT_END_NAMESPACE
#endif // CAMERABINFLASHCONTROL_H #endif // CAMERABINFLASHCONTROL_H

View File

@@ -44,6 +44,8 @@
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
CameraBinContainer::CameraBinContainer(QObject *parent) CameraBinContainer::CameraBinContainer(QObject *parent)
:QMediaContainerControl(parent), :QMediaContainerControl(parent),
m_supportedContainers(QGstCodecsInfo::Muxer) m_supportedContainers(QGstCodecsInfo::Muxer)
@@ -68,39 +70,43 @@ QString CameraBinContainer::containerDescription(const QString &formatMimeType)
return m_supportedContainers.codecDescription(formatMimeType); return m_supportedContainers.codecDescription(formatMimeType);
} }
QString CameraBinContainer::containerMimeType() const QString CameraBinContainer::containerFormat() const
{ {
return m_format; return m_format;
} }
void CameraBinContainer::setContainerMimeType(const QString &formatMimeType) void CameraBinContainer::setContainerFormat(const QString &format)
{ {
m_format = formatMimeType; if (m_format != format) {
m_format = format;
if (m_userFormat != formatMimeType) {
m_userFormat = formatMimeType;
emit settingsChanged(); emit settingsChanged();
} }
} }
void CameraBinContainer::setActualContainer(const QString &formatMimeType)
{
m_format = formatMimeType;
}
void CameraBinContainer::resetActualContainer()
{
m_format = m_userFormat;
}
GstEncodingContainerProfile *CameraBinContainer::createProfile() GstEncodingContainerProfile *CameraBinContainer::createProfile()
{ {
GstCaps *caps; GstCaps *caps;
if (m_format.isEmpty()) if (m_format.isEmpty()) {
caps = gst_caps_new_any(); caps = gst_caps_new_any();
else } else {
caps = gst_caps_from_string(m_format.toLatin1()); 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( return (GstEncodingContainerProfile *)gst_encoding_container_profile_new(
"camerabin2_profile", "camerabin2_profile",
@@ -112,9 +118,13 @@ GstEncodingContainerProfile *CameraBinContainer::createProfile()
/*! /*!
Suggest file extension for current container mimetype. 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); QString extension = m_fileExtensions.value(format);
if (!extension.isEmpty() || format.isEmpty()) if (!extension.isEmpty() || format.isEmpty())
@@ -127,3 +137,5 @@ QString CameraBinContainer::suggestedFileExtension() const
return extension; return extension;
} }
QT_END_NAMESPACE

View File

@@ -51,9 +51,9 @@
#include <gst/pbutils/pbutils.h> #include <gst/pbutils/pbutils.h>
#include <gst/pbutils/encoding-profile.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 class CameraBinContainer : public QMediaContainerControl
{ {
@@ -65,13 +65,10 @@ public:
virtual QStringList supportedContainers() const; virtual QStringList supportedContainers() const;
virtual QString containerDescription(const QString &formatMimeType) const; virtual QString containerDescription(const QString &formatMimeType) const;
virtual QString containerMimeType() const; virtual QString containerFormat() const;
virtual void setContainerMimeType(const QString &formatMimeType); virtual void setContainerFormat(const QString &format);
void setActualContainer(const QString &formatMimeType); QString suggestedFileExtension(const QString &containerFormat) const;
void resetActualContainer();
QString suggestedFileExtension() const;
GstEncodingContainerProfile *createProfile(); GstEncodingContainerProfile *createProfile();
@@ -80,10 +77,11 @@ Q_SIGNALS:
private: private:
QString m_format; // backend selected format, using m_userFormat QString m_format; // backend selected format, using m_userFormat
QString m_userFormat;
QMap<QString, QString> m_fileExtensions; QMap<QString, QString> m_fileExtensions;
QGstCodecsInfo m_supportedContainers; QGstCodecsInfo m_supportedContainers;
}; };
QT_END_NAMESPACE
#endif // CAMERABINMEDIACONTAINERCONTROL_H #endif // CAMERABINMEDIACONTAINERCONTROL_H

View File

@@ -62,6 +62,8 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
QT_BEGIN_NAMESPACE
//#define CAMEABIN_DEBUG 1 //#define CAMEABIN_DEBUG 1
#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v))) #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 ? captureMode() == QCamera::CaptureStillImage ?
CamerabinResourcePolicy::ImageCaptureResources : CamerabinResourcePolicy::ImageCaptureResources :
CamerabinResourcePolicy::VideoCaptureResources); 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); emit captureModeChanged(mode);
} }
@@ -339,3 +345,5 @@ void CameraBinControl::setViewfinderColorSpaceConversion(bool enabled)
g_object_set(G_OBJECT(m_session->cameraBin()), "flags", flags, NULL); g_object_set(G_OBJECT(m_session->cameraBin()), "flags", flags, NULL);
} }
QT_END_NAMESPACE

View File

@@ -47,7 +47,7 @@
#include <qcameracontrol.h> #include <qcameracontrol.h>
#include "camerabinsession.h" #include "camerabinsession.h"
QT_USE_NAMESPACE QT_BEGIN_NAMESPACE
class CamerabinResourcePolicy; class CamerabinResourcePolicy;
@@ -98,4 +98,6 @@ private:
bool m_reloadPending; bool m_reloadPending;
}; };
QT_END_NAMESPACE
#endif // CAMERABINCONTROL_H #endif // CAMERABINCONTROL_H

View File

@@ -45,6 +45,8 @@
#include <QDebug> #include <QDebug>
QT_BEGIN_NAMESPACE
CameraBinExposure::CameraBinExposure(CameraBinSession *session) CameraBinExposure::CameraBinExposure(CameraBinSession *session)
:QCameraExposureControl(session), :QCameraExposureControl(session),
m_session(session) m_session(session)
@@ -230,3 +232,5 @@ QString CameraBinExposure::extendedParameterName(ExposureParameter)
{ {
return QString(); return QString();
} }
QT_END_NAMESPACE

View File

@@ -48,9 +48,9 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h> #include <glib.h>
class CameraBinSession; QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE class CameraBinSession;
class Q_MULTIMEDIA_EXPORT CameraBinExposure : public QCameraExposureControl class Q_MULTIMEDIA_EXPORT CameraBinExposure : public QCameraExposureControl
{ {
@@ -80,4 +80,6 @@ private:
CameraBinSession *m_session; CameraBinSession *m_session;
}; };
QT_END_NAMESPACE
#endif // CAMERABINEXPOSURECONTROL_MAEMO_H #endif // CAMERABINEXPOSURECONTROL_MAEMO_H

View File

@@ -45,6 +45,8 @@
#include <QDebug> #include <QDebug>
QT_BEGIN_NAMESPACE
CameraBinFlash::CameraBinFlash(CameraBinSession *session) CameraBinFlash::CameraBinFlash(CameraBinSession *session)
:QCameraFlashControl(session), :QCameraFlashControl(session),
m_session(session) m_session(session)
@@ -102,3 +104,4 @@ bool CameraBinFlash::isFlashReady() const
return true; return true;
} }
QT_END_NAMESPACE

View File

@@ -48,9 +48,9 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h> #include <glib.h>
class CameraBinSession; QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE class CameraBinSession;
class Q_MULTIMEDIA_EXPORT CameraBinFlash : public QCameraFlashControl class Q_MULTIMEDIA_EXPORT CameraBinFlash : public QCameraFlashControl
{ {
@@ -69,5 +69,7 @@ private:
CameraBinSession *m_session; CameraBinSession *m_session;
}; };
QT_END_NAMESPACE
#endif // CAMERABINFLASHCONTROL_H #endif // CAMERABINFLASHCONTROL_H

View File

@@ -51,6 +51,8 @@
#define ZOOM_PROPERTY "zoom" #define ZOOM_PROPERTY "zoom"
#define MAX_ZOOM_PROPERTY "max-zoom" #define MAX_ZOOM_PROPERTY "max-zoom"
QT_BEGIN_NAMESPACE
CameraBinFocus::CameraBinFocus(CameraBinSession *session) CameraBinFocus::CameraBinFocus(CameraBinSession *session)
:QCameraFocusControl(session), :QCameraFocusControl(session),
m_session(session), m_session(session),
@@ -223,3 +225,5 @@ void CameraBinFocus::_q_stopFocusing()
gst_photography_set_autofocus(m_session->photography(), FALSE); gst_photography_set_autofocus(m_session->photography(), FALSE);
_q_setFocusStatus(QCamera::Unlocked, QCamera::UserRequest); _q_setFocusStatus(QCamera::Unlocked, QCamera::UserRequest);
} }
QT_END_NAMESPACE

View File

@@ -48,9 +48,9 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h> #include <glib.h>
class CameraBinSession; QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE class CameraBinSession;
class CameraBinFocus : public QCameraFocusControl class CameraBinFocus : public QCameraFocusControl
{ {
@@ -100,4 +100,6 @@ private:
QCameraFocusZone::FocusZoneStatus m_focusZoneStatus; QCameraFocusZone::FocusZoneStatus m_focusZoneStatus;
}; };
QT_END_NAMESPACE
#endif // CAMERABINFOCUSCONTROL_H #endif // CAMERABINFOCUSCONTROL_H

View File

@@ -54,6 +54,7 @@
#define IMAGE_DONE_SIGNAL "image-done" #define IMAGE_DONE_SIGNAL "image-done"
QT_BEGIN_NAMESPACE
CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session) CameraBinImageCapture::CameraBinImageCapture(CameraBinSession *session)
:QCameraImageCaptureControl(session) :QCameraImageCaptureControl(session)
@@ -254,6 +255,9 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
return false; return false;
QString elementName = QString::fromLatin1(gst_element_get_name(element)); 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) { if (elementName.contains("jpegenc") && element != m_jpegEncoderElement) {
m_jpegEncoderElement = element; m_jpegEncoderElement = element;
GstPad *sinkpad = gst_element_get_static_pad(element, "sink"); GstPad *sinkpad = gst_element_get_static_pad(element, "sink");
@@ -275,7 +279,9 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
this); this);
gst_object_unref(sinkpad); 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) { && element != m_metadataMuxerElement) {
//Jpeg encoded buffer probe is added after jifmux/metadatamux //Jpeg encoded buffer probe is added after jifmux/metadatamux
//element to ensure the resulting jpeg buffer contains capture metadata //element to ensure the resulting jpeg buffer contains capture metadata
@@ -321,3 +327,4 @@ bool CameraBinImageCapture::processBusMessage(const QGstreamerMessage &message)
return false; return false;
} }
QT_END_NAMESPACE

View File

@@ -46,7 +46,7 @@
#include <qcameraimagecapturecontrol.h> #include <qcameraimagecapturecontrol.h>
#include "camerabinsession.h" #include "camerabinsession.h"
QT_USE_NAMESPACE QT_BEGIN_NAMESPACE
class CameraBinImageCapture : public QCameraImageCaptureControl, public QGstreamerBusMessageFilter class CameraBinImageCapture : public QCameraImageCaptureControl, public QGstreamerBusMessageFilter
{ {
@@ -80,4 +80,6 @@ private:
GstElement *m_metadataMuxerElement; GstElement *m_metadataMuxerElement;
}; };
QT_END_NAMESPACE
#endif // CAMERABINCAPTURECORNTROL_H #endif // CAMERABINCAPTURECORNTROL_H

View File

@@ -44,6 +44,8 @@
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
CameraBinImageEncoder::CameraBinImageEncoder(CameraBinSession *session) CameraBinImageEncoder::CameraBinImageEncoder(CameraBinSession *session)
:QImageEncoderControl(session), m_session(session) :QImageEncoderControl(session), m_session(session)
{ {
@@ -85,3 +87,5 @@ void CameraBinImageEncoder::setImageSettings(const QImageEncoderSettings &settin
m_settings = settings; m_settings = settings;
emit settingsChanged(); emit settingsChanged();
} }
QT_END_NAMESPACE

View File

@@ -42,15 +42,15 @@
#ifndef CAMERABINIMAGEENCODE_H #ifndef CAMERABINIMAGEENCODE_H
#define CAMERABINIMAGEENCODE_H #define CAMERABINIMAGEENCODE_H
class CameraBinSession;
#include <qimageencodercontrol.h> #include <qimageencodercontrol.h>
#include <QtCore/qstringlist.h> #include <QtCore/qstringlist.h>
#include <QtCore/qmap.h> #include <QtCore/qmap.h>
#include <gst/gst.h> #include <gst/gst.h>
QT_USE_NAMESPACE QT_BEGIN_NAMESPACE
class CameraBinSession;
class CameraBinImageEncoder : public QImageEncoderControl class CameraBinImageEncoder : public QImageEncoderControl
{ {
@@ -83,4 +83,6 @@ private:
QMap<QString,QStringList> m_codecOptions; QMap<QString,QStringList> m_codecOptions;
}; };
QT_END_NAMESPACE
#endif #endif

View File

@@ -42,16 +42,24 @@
#include "camerabinimageprocessing.h" #include "camerabinimageprocessing.h"
#include "camerabinsession.h" #include "camerabinsession.h"
#ifdef HAVE_GST_PHOTOGRAPHY
#include <gst/interfaces/photography.h>
#endif
QT_BEGIN_NAMESPACE
CameraBinImageProcessing::CameraBinImageProcessing(CameraBinSession *session) CameraBinImageProcessing::CameraBinImageProcessing(CameraBinSession *session)
:QCameraImageProcessingControl(session), :QCameraImageProcessingControl(session),
m_session(session) m_session(session)
{ {
#ifdef HAVE_GST_PHOTOGRAPHY
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_AUTO] = QCameraImageProcessing::WhiteBalanceAuto; m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_AUTO] = QCameraImageProcessing::WhiteBalanceAuto;
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT] = QCameraImageProcessing::WhiteBalanceSunlight; m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT] = QCameraImageProcessing::WhiteBalanceSunlight;
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_CLOUDY] = QCameraImageProcessing::WhiteBalanceCloudy; m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_CLOUDY] = QCameraImageProcessing::WhiteBalanceCloudy;
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_SUNSET] = QCameraImageProcessing::WhiteBalanceSunset; m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_SUNSET] = QCameraImageProcessing::WhiteBalanceSunset;
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN] = QCameraImageProcessing::WhiteBalanceTungsten; m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN] = QCameraImageProcessing::WhiteBalanceTungsten;
m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT] = QCameraImageProcessing::WhiteBalanceFluorescent; m_mappedWbValues[GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT] = QCameraImageProcessing::WhiteBalanceFluorescent;
#endif
updateColorBalanceValues(); updateColorBalanceValues();
} }
@@ -73,22 +81,29 @@ void CameraBinImageProcessing::updateColorBalanceValues()
const GList *item; const GList *item;
GstColorBalanceChannel *channel; GstColorBalanceChannel *channel;
gint cur_value; gint cur_value;
qreal scaledValue = 0;
for (item = controls; item; item = g_list_next (item)) { for (item = controls; item; item = g_list_next (item)) {
channel = (GstColorBalanceChannel *)item->data; channel = (GstColorBalanceChannel *)item->data;
cur_value = gst_color_balance_get_value (balance, channel); 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")) { 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")) { } 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")) { } 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())) { if (!GST_IS_COLOR_BALANCE(m_session->cameraBin())) {
@@ -106,7 +121,11 @@ bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, int
colorBalanceChannel = (GstColorBalanceChannel *)item->data; colorBalanceChannel = (GstColorBalanceChannel *)item->data;
if (!g_ascii_strcasecmp (colorBalanceChannel->label, channel.toLatin1())) { 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; return true;
} }
} }
@@ -116,30 +135,59 @@ bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, int
QCameraImageProcessing::WhiteBalanceMode CameraBinImageProcessing::whiteBalanceMode() const QCameraImageProcessing::WhiteBalanceMode CameraBinImageProcessing::whiteBalanceMode() const
{ {
#ifdef HAVE_GST_PHOTOGRAPHY
GstWhiteBalanceMode wbMode; GstWhiteBalanceMode wbMode;
gst_photography_get_white_balance_mode(m_session->photography(), &wbMode); gst_photography_get_white_balance_mode(m_session->photography(), &wbMode);
return m_mappedWbValues[wbMode]; return m_mappedWbValues[wbMode];
#else
return QCameraImageProcessing::WhiteBalanceAuto;
#endif
} }
void CameraBinImageProcessing::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode) void CameraBinImageProcessing::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode)
{ {
#ifdef HAVE_GST_PHOTOGRAPHY
if (isWhiteBalanceModeSupported(mode)) if (isWhiteBalanceModeSupported(mode))
gst_photography_set_white_balance_mode(m_session->photography(), m_mappedWbValues.key(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 bool CameraBinImageProcessing::isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const
{ {
#ifdef HAVE_GST_PHOTOGRAPHY
return m_mappedWbValues.values().contains(mode); 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 return parameter == QCameraImageProcessingControl::Contrast
|| parameter == QCameraImageProcessingControl::Brightness || 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 QCameraImageProcessingControl::ProcessingParameter parameter) const
{ {
if (m_values.contains(parameter)) if (m_values.contains(parameter))
@@ -148,19 +196,21 @@ QVariant CameraBinImageProcessing::processingParameter(
return QVariant(); return QVariant();
} }
void CameraBinImageProcessing::setProcessingParameter( void CameraBinImageProcessing::setParameter(QCameraImageProcessingControl::ProcessingParameter parameter,
QCameraImageProcessingControl::ProcessingParameter parameter, const QVariant &value)
QVariant value)
{ {
switch (parameter) { switch (parameter) {
case Contrast: case ContrastAdjustment:
setColorBalanceValue("contrast", value.toInt()); setColorBalanceValue("contrast", value.toReal());
break; break;
case Brightness: case BrightnessAdjustment:
setColorBalanceValue("brightness", value.toInt()); setColorBalanceValue("brightness", value.toReal());
break; break;
case Saturation: case SaturationAdjustment:
setColorBalanceValue("saturation", value.toInt()); setColorBalanceValue("saturation", value.toReal());
break;
case WhiteBalancePreset:
setWhiteBalanceMode(value.value<QCameraImageProcessing::WhiteBalanceMode>());
break; break;
default: default:
break; break;
@@ -169,3 +219,4 @@ void CameraBinImageProcessing::setProcessingParameter(
updateColorBalanceValues(); updateColorBalanceValues();
} }
QT_END_NAMESPACE

View File

@@ -48,12 +48,11 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h> #include <glib.h>
#include <gst/interfaces/photography.h>
#include <gst/interfaces/colorbalance.h> #include <gst/interfaces/colorbalance.h>
class CameraBinSession; QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE class CameraBinSession;
class CameraBinImageProcessing : public QCameraImageProcessingControl class CameraBinImageProcessing : public QCameraImageProcessingControl
{ {
@@ -67,18 +66,23 @@ public:
void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode); void setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode);
bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const; bool isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode mode) const;
bool isProcessingParameterSupported(ProcessingParameter) const; bool isParameterSupported(ProcessingParameter) const;
QVariant processingParameter(ProcessingParameter parameter) const; bool isParameterValueSupported(ProcessingParameter parameter, const QVariant &value) const;
void setProcessingParameter(ProcessingParameter parameter, QVariant value); QVariant parameter(ProcessingParameter parameter) const;
void setParameter(ProcessingParameter parameter, const QVariant &value);
private: private:
bool setColorBalanceValue(const QString& channel, int value); bool setColorBalanceValue(const QString& channel, qreal value);
void updateColorBalanceValues(); void updateColorBalanceValues();
private: private:
CameraBinSession *m_session; CameraBinSession *m_session;
QMap<QCameraImageProcessingControl::ProcessingParameter, int> m_values; QMap<QCameraImageProcessingControl::ProcessingParameter, int> m_values;
#ifdef HAVE_GST_PHOTOGRAPHY
QMap<GstWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues; QMap<GstWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues;
#endif
}; };
QT_END_NAMESPACE
#endif // CAMERABINIMAGEPROCESSINGCONTROL_H #endif // CAMERABINIMAGEPROCESSINGCONTROL_H

View File

@@ -47,6 +47,8 @@
#include <QDebug> #include <QDebug>
QT_BEGIN_NAMESPACE
CameraBinLocks::CameraBinLocks(CameraBinSession *session) CameraBinLocks::CameraBinLocks(CameraBinSession *session)
:QCameraLocksControl(session), :QCameraLocksControl(session),
m_session(session), m_session(session),
@@ -86,3 +88,5 @@ void CameraBinLocks::updateFocusStatus(QCamera::LockStatus status, QCamera::Lock
{ {
emit lockStatusChanged(QCamera::LockFocus, status, reason); emit lockStatusChanged(QCamera::LockFocus, status, reason);
} }
QT_END_NAMESPACE

View File

@@ -48,11 +48,11 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h> #include <glib.h>
QT_BEGIN_NAMESPACE
class CameraBinSession; class CameraBinSession;
class CameraBinFocus; class CameraBinFocus;
QT_USE_NAMESPACE
class CameraBinLocks : public QCameraLocksControl class CameraBinLocks : public QCameraLocksControl
{ {
Q_OBJECT Q_OBJECT
@@ -76,4 +76,6 @@ private:
CameraBinFocus *m_focus; CameraBinFocus *m_focus;
}; };
QT_END_NAMESPACE
#endif #endif

View File

@@ -44,6 +44,8 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/gstversion.h> #include <gst/gstversion.h>
QT_BEGIN_NAMESPACE
struct QGstreamerMetaDataKeyLookup struct QGstreamerMetaDataKeyLookup
{ {
QString key; QString key;
@@ -175,3 +177,5 @@ QStringList CameraBinMetaData::availableMetaData() const
return res; return res;
} }
QT_END_NAMESPACE

View File

@@ -44,7 +44,7 @@
#include <qmetadatawritercontrol.h> #include <qmetadatawritercontrol.h>
QT_USE_NAMESPACE QT_BEGIN_NAMESPACE
class CameraBinMetaData : public QMetaDataWriterControl class CameraBinMetaData : public QMetaDataWriterControl
{ {
@@ -68,4 +68,6 @@ private:
QMap<QByteArray, QVariant> m_values; QMap<QByteArray, QVariant> m_values;
}; };
QT_END_NAMESPACE
#endif // CAMERABINCAPTUREMETADATACONTROL_H #endif // CAMERABINCAPTUREMETADATACONTROL_H

View File

@@ -47,12 +47,18 @@
#include <gst/pbutils/encoding-profile.h> #include <gst/pbutils/encoding-profile.h>
QT_BEGIN_NAMESPACE
CameraBinRecorder::CameraBinRecorder(CameraBinSession *session) CameraBinRecorder::CameraBinRecorder(CameraBinSession *session)
:QMediaRecorderControl(session), :QMediaRecorderControl(session),
m_session(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(durationChanged(qint64)), SIGNAL(durationChanged(qint64)));
connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool))); connect(m_session, SIGNAL(mutedChanged(bool)), this, SIGNAL(mutedChanged(bool)));
} }
@@ -77,13 +83,43 @@ QMediaRecorder::State CameraBinRecorder::state() const
return m_state; return m_state;
} }
void CameraBinRecorder::updateState() QMediaRecorder::Status CameraBinRecorder::status() const
{ {
if (m_session->state() != QCamera::ActiveState && return m_status;
m_state != QMediaRecorder::StoppedState) { }
m_session->stopVideoRecording();
emit stateChanged(m_state = QMediaRecorder::StoppedState); 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 qint64 CameraBinRecorder::duration() const
@@ -91,29 +127,13 @@ qint64 CameraBinRecorder::duration() const
return m_session->duration(); 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()
{
emit error(QMediaRecorder::ResourceError, tr("QMediaRecorder::pause() is not supported by camerabin2."));
}
void CameraBinRecorder::stop()
{
if (m_session->state() == QCamera::ActiveState) {
m_session->stopVideoRecording();
emit stateChanged(m_state = QMediaRecorder::StoppedState);
}
}
void CameraBinRecorder::applySettings() void CameraBinRecorder::applySettings()
{
//settings are applied during camera startup
}
GstEncodingContainerProfile *CameraBinRecorder::videoProfile()
{ {
GstEncodingContainerProfile *containerProfile = m_session->mediaContainerControl()->createProfile(); GstEncodingContainerProfile *containerProfile = m_session->mediaContainerControl()->createProfile();
@@ -125,7 +145,42 @@ void CameraBinRecorder::applySettings()
gst_encoding_container_profile_add_profile(containerProfile, videoProfile); 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 bool CameraBinRecorder::isMuted() const
@@ -137,3 +192,5 @@ void CameraBinRecorder::setMuted(bool muted)
{ {
m_session->setMuted(muted); m_session->setMuted(muted);
} }
QT_END_NAMESPACE

View File

@@ -45,7 +45,9 @@
#include <qmediarecordercontrol.h> #include <qmediarecordercontrol.h>
#include "camerabinsession.h" #include "camerabinsession.h"
QT_USE_NAMESPACE #include <gst/pbutils/encoding-profile.h>
QT_BEGIN_NAMESPACE
class CameraBinRecorder : public QMediaRecorderControl class CameraBinRecorder : public QMediaRecorderControl
{ {
@@ -59,25 +61,28 @@ public:
bool setOutputLocation(const QUrl &sink); bool setOutputLocation(const QUrl &sink);
QMediaRecorder::State state() const; QMediaRecorder::State state() const;
QMediaRecorder::Status status() const;
qint64 duration() const; qint64 duration() const;
bool isMuted() const; bool isMuted() const;
void applySettings(); void applySettings();
GstEncodingContainerProfile *videoProfile();
public slots: public slots:
void record(); void setState(QMediaRecorder::State state);
void pause();
void stop();
void setMuted(bool); void setMuted(bool);
private slots: private slots:
void updateState(); void updateStatus();
private: private:
CameraBinSession *m_session; CameraBinSession *m_session;
QMediaRecorder::State m_state; QMediaRecorder::State m_state;
QMediaRecorder::Status m_status;
}; };
QT_END_NAMESPACE
#endif // CAMERABINCAPTURECORNTROL_H #endif // CAMERABINCAPTURECORNTROL_H

View File

@@ -51,6 +51,8 @@
#include <policy/resource-set.h> #include <policy/resource-set.h>
#endif #endif
QT_BEGIN_NAMESPACE
CamerabinResourcePolicy::CamerabinResourcePolicy(QObject *parent) : CamerabinResourcePolicy::CamerabinResourcePolicy(QObject *parent) :
QObject(parent), QObject(parent),
m_resourceSet(NoResources), m_resourceSet(NoResources),
@@ -182,3 +184,5 @@ void CamerabinResourcePolicy::handleResourcesReleased()
m_releasingResources = false; m_releasingResources = false;
#endif #endif
} }
QT_END_NAMESPACE

View File

@@ -48,6 +48,8 @@ namespace ResourcePolicy {
class ResourceSet; class ResourceSet;
}; };
QT_BEGIN_NAMESPACE
class CamerabinResourcePolicy : public QObject class CamerabinResourcePolicy : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -81,4 +83,6 @@ private:
bool m_releasingResources; bool m_releasingResources;
}; };
QT_END_NAMESPACE
#endif #endif

View File

@@ -47,33 +47,37 @@
#include "camerabinvideoencoder.h" #include "camerabinvideoencoder.h"
#include "camerabinimageencoder.h" #include "camerabinimageencoder.h"
#include "camerabincontrol.h" #include "camerabincontrol.h"
#include "camerabinlocks.h"
#include "camerabinmetadata.h" #include "camerabinmetadata.h"
#ifdef HAVE_GST_PHOTOGRAPHY
#include "camerabinexposure.h" #include "camerabinexposure.h"
#include "camerabinflash.h" #include "camerabinflash.h"
#include "camerabinfocus.h" #include "camerabinfocus.h"
#include "camerabinlocks.h"
#endif
#include "camerabinimagecapture.h" #include "camerabinimagecapture.h"
#include "camerabinimageprocessing.h" #include "camerabinimageprocessing.h"
#include "camerabincapturebufferformat.h" #include "camerabincapturebufferformat.h"
#include "camerabincapturedestination.h" #include "camerabincapturedestination.h"
#include <private/qgstreamerbushelper_p.h> #include <private/qgstreamerbushelper_p.h>
#include "qgstreameraudioinputendpointselector.h" #include <private/qgstreameraudioinputendpointselector_p.h>
#include "qgstreamervideoinputdevicecontrol.h" #include <private/qgstreamervideoinputdevicecontrol_p.h>
#if defined(HAVE_WIDGETS) #if defined(HAVE_WIDGETS)
#include "qgstreamervideooverlay.h" #include <private/qgstreamervideooverlay_p.h>
#include "qgstreamervideowindow.h" #include <private/qgstreamervideowindow_p.h>
#include "qgstreamervideowidget.h" #include <private/qgstreamervideowidget_p.h>
#endif #endif
#include "qgstreamervideorenderer.h" #include <private/qgstreamervideorenderer_p.h>
#if defined(Q_WS_MAEMO_6) && defined(__arm__) #if defined(Q_WS_MAEMO_6) && defined(__arm__)
#include "qgstreamergltexturerenderer.h" #include "qgstreamergltexturerenderer.h"
#endif #endif
#include <qmediaserviceprovider.h> #include <private/qmediaserviceprovider_p.h>
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
#include <QtCore/qprocess.h> #include <QtCore/qprocess.h>
@@ -82,6 +86,8 @@
#include "camerabuttonlistener_meego.h" #include "camerabuttonlistener_meego.h"
#endif #endif
QT_BEGIN_NAMESPACE
CameraBinService::CameraBinService(const QString &service, QObject *parent): CameraBinService::CameraBinService(const QString &service, QObject *parent):
QMediaService(parent) QMediaService(parent)
{ {
@@ -208,6 +214,7 @@ QMediaControl *CameraBinService::requestControl(const char *name)
if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0)
return m_imageCaptureControl; return m_imageCaptureControl;
#ifdef HAVE_GST_PHOTOGRAPHY
if (qstrcmp(name, QCameraExposureControl_iid) == 0) if (qstrcmp(name, QCameraExposureControl_iid) == 0)
return m_captureSession->cameraExposureControl(); return m_captureSession->cameraExposureControl();
@@ -217,11 +224,12 @@ QMediaControl *CameraBinService::requestControl(const char *name)
if (qstrcmp(name, QCameraFocusControl_iid) == 0) if (qstrcmp(name, QCameraFocusControl_iid) == 0)
return m_captureSession->cameraFocusControl(); return m_captureSession->cameraFocusControl();
if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
return m_captureSession->imageProcessingControl();
if (qstrcmp(name, QCameraLocksControl_iid) == 0) if (qstrcmp(name, QCameraLocksControl_iid) == 0)
return m_captureSession->cameraLocksControl(); return m_captureSession->cameraLocksControl();
#endif
if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
return m_captureSession->imageProcessingControl();
if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0) if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0)
return m_captureSession->captureDestinationControl(); return m_captureSession->captureDestinationControl();
@@ -250,3 +258,5 @@ bool CameraBinService::isCameraBinAvailable()
return false; return false;
} }
QT_END_NAMESPACE

View File

@@ -45,10 +45,11 @@
#include <qmediaservice.h> #include <qmediaservice.h>
#include <gst/gst.h> #include <gst/gst.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QAudioEndpointSelectorControl; class QAudioEndpointSelectorControl;
class QVideoDeviceSelectorControl; class QVideoDeviceSelectorControl;
QT_END_NAMESPACE
class CameraBinSession; class CameraBinSession;
class CameraBinControl; class CameraBinControl;
@@ -95,4 +96,6 @@ private:
CameraBinImageCapture *m_imageCaptureControl; CameraBinImageCapture *m_imageCaptureControl;
}; };
QT_END_NAMESPACE
#endif // CAMERABINCAPTURESERVICE_H #endif // CAMERABINCAPTURESERVICE_H

View File

@@ -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

View File

@@ -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

View File

@@ -44,17 +44,26 @@
#include "camerabinaudioencoder.h" #include "camerabinaudioencoder.h"
#include "camerabinvideoencoder.h" #include "camerabinvideoencoder.h"
#include "camerabinimageencoder.h" #include "camerabinimageencoder.h"
#ifdef HAVE_GST_PHOTOGRAPHY
#include "camerabinexposure.h" #include "camerabinexposure.h"
#include "camerabinflash.h" #include "camerabinflash.h"
#include "camerabinfocus.h" #include "camerabinfocus.h"
#include "camerabinimageprocessing.h"
#include "camerabinlocks.h" #include "camerabinlocks.h"
#endif
#include "camerabinimageprocessing.h"
#include "camerabincapturedestination.h" #include "camerabincapturedestination.h"
#include "camerabincapturebufferformat.h" #include "camerabincapturebufferformat.h"
#include <private/qgstreamerbushelper_p.h> #include <private/qgstreamerbushelper_p.h>
#include "qgstreamervideorendererinterface.h" #include <private/qgstreamervideorendererinterface_p.h>
#include <qmediarecorder.h> #include <qmediarecorder.h>
#ifdef HAVE_GST_PHOTOGRAPHY
#include <gst/interfaces/photography.h> #include <gst/interfaces/photography.h>
#endif
#include <gst/gsttagsetter.h> #include <gst/gsttagsetter.h>
#include <gst/gstversion.h> #include <gst/gstversion.h>
@@ -80,13 +89,15 @@
#define AUDIO_SOURCE_PROPERTY "audio-source" #define AUDIO_SOURCE_PROPERTY "audio-source"
#define SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-supported-caps" #define SUPPORTED_IMAGE_CAPTURE_CAPS_PROPERTY "image-capture-supported-caps"
#define SUPPORTED_VIDEO_CAPTURE_CAPS_PROPERTY "video-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 PREVIEW_CAPS_PROPERTY "preview-caps"
#define POST_PREVIEWS_PROPERTY "post-previews"
#define CAPTURE_START "start-capture" #define CAPTURE_START "start-capture"
#define CAPTURE_STOP "stop-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_IMAGE_MODE 1
#define CAMERABIN_VIDEO_MODE 2 #define CAMERABIN_VIDEO_MODE 2
@@ -106,13 +117,13 @@
//#define USE_READY_STATE_ON_LOADED //#define USE_READY_STATE_ON_LOADED
QT_BEGIN_NAMESPACE
CameraBinSession::CameraBinSession(QObject *parent) CameraBinSession::CameraBinSession(QObject *parent)
:QObject(parent), :QObject(parent),
m_recordingActive(false), m_recordingActive(false),
m_state(QCamera::UnloadedState), m_state(QCamera::UnloadedState),
m_pendingState(QCamera::UnloadedState), m_pendingState(QCamera::UnloadedState),
m_pendingResolutionUpdate(false),
m_muted(false), m_muted(false),
m_busy(false), m_busy(false),
m_captureMode(QCamera::CaptureStillImage), m_captureMode(QCamera::CaptureStillImage),
@@ -145,15 +156,20 @@ CameraBinSession::CameraBinSession(QObject *parent)
m_imageEncodeControl = new CameraBinImageEncoder(this); m_imageEncodeControl = new CameraBinImageEncoder(this);
m_recorderControl = new CameraBinRecorder(this); m_recorderControl = new CameraBinRecorder(this);
m_mediaContainerControl = new CameraBinContainer(this); m_mediaContainerControl = new CameraBinContainer(this);
#ifdef HAVE_GST_PHOTOGRAPHY
m_cameraExposureControl = new CameraBinExposure(this); m_cameraExposureControl = new CameraBinExposure(this);
m_cameraFlashControl = new CameraBinFlash(this); m_cameraFlashControl = new CameraBinFlash(this);
m_cameraFocusControl = new CameraBinFocus(this); m_cameraFocusControl = new CameraBinFocus(this);
m_imageProcessingControl = new CameraBinImageProcessing(this);
m_cameraLocksControl = new CameraBinLocks(this); m_cameraLocksControl = new CameraBinLocks(this);
#endif
m_imageProcessingControl = new CameraBinImageProcessing(this);
m_captureDestinationControl = new CameraBinCaptureDestination(this); m_captureDestinationControl = new CameraBinCaptureDestination(this);
m_captureBufferFormatControl = new CameraBinCaptureBufferFormat(this); m_captureBufferFormatControl = new CameraBinCaptureBufferFormat(this);
//post image preview in RGB format //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"); GstCaps *previewCaps = gst_caps_from_string("video/x-raw-rgb");
g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL); g_object_set(G_OBJECT(m_camerabin), PREVIEW_CAPS_PROPERTY, previewCaps, NULL);
gst_caps_unref(previewCaps); gst_caps_unref(previewCaps);
@@ -172,6 +188,7 @@ CameraBinSession::~CameraBinSession()
} }
} }
#ifdef HAVE_GST_PHOTOGRAPHY
GstPhotography *CameraBinSession::photography() GstPhotography *CameraBinSession::photography()
{ {
if (GST_IS_PHOTOGRAPHY(m_camerabin)) { if (GST_IS_PHOTOGRAPHY(m_camerabin)) {
@@ -194,6 +211,7 @@ GstPhotography *CameraBinSession::photography()
return 0; return 0;
} }
#endif
CameraBinSession::CameraRole CameraBinSession::cameraRole() const CameraBinSession::CameraRole CameraBinSession::cameraRole() const
{ {
@@ -290,7 +308,7 @@ void CameraBinSession::setupCaptureResolution()
#if CAMERABIN_DEBUG #if CAMERABIN_DEBUG
qDebug() << Q_FUNC_INFO << "set image resolution" << resolution << gst_caps_to_string(caps); qDebug() << Q_FUNC_INFO << "set image resolution" << resolution << gst_caps_to_string(caps);
#endif #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); gst_caps_unref(caps);
if (!resolution.isEmpty()) { if (!resolution.isEmpty()) {
@@ -302,6 +320,8 @@ void CameraBinSession::setupCaptureResolution()
else else
viewfinderResolution = VIEWFINDER_RESOLUTION_3x2; 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 //on low res cameras the viewfinder resolution should not be bigger
@@ -313,7 +333,7 @@ void CameraBinSession::setupCaptureResolution()
#if CAMERABIN_DEBUG #if CAMERABIN_DEBUG
qDebug() << "Set viewfinder resolution" << viewfinderResolution <<gst_caps_to_string(viewfinderCaps); qDebug() << "Set viewfinder resolution" << viewfinderResolution <<gst_caps_to_string(viewfinderCaps);
#endif #endif
g_object_set(m_camerabin, "viewfinder-caps", viewfinderCaps, NULL); g_object_set(m_camerabin, VIEWFINDER_CAPS_PROPERTY, viewfinderCaps, NULL);
gst_caps_unref(viewfinderCaps); gst_caps_unref(viewfinderCaps);
} }
@@ -336,7 +356,9 @@ void CameraBinSession::setupCaptureResolution()
qDebug() << Q_FUNC_INFO << "set video resolution" << resolution << gst_caps_to_string(caps); qDebug() << Q_FUNC_INFO << "set video resolution" << resolution << gst_caps_to_string(caps);
#endif #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); gst_caps_unref(caps);
} }
} }
@@ -347,34 +369,37 @@ GstElement *CameraBinSession::buildCameraSource()
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
#endif #endif
GstElement *videoSrc = 0; GstElement *videoSrc = 0;
if (m_videoInputFactory) {
videoSrc = m_videoInputFactory->buildElement();
} else {
QList<QByteArray> candidates;
candidates << "wrappercamerabinsrc";
QByteArray sourceElementName;
foreach(sourceElementName, candidates) { QList<QByteArray> candidates;
videoSrc = gst_element_factory_make(sourceElementName.constData(), "camera_source"); candidates << "subdevsrc" << "wrappercamerabinsrc";
if (videoSrc) QByteArray sourceElementName;
break;
}
if (videoSrc && !m_inputDevice.isEmpty()) { foreach (sourceElementName, candidates) {
videoSrc = gst_element_factory_make(sourceElementName.constData(), "camera_source");
if (videoSrc)
break;
}
if (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 (sourceElementName == "subdevsrc") {
if (m_inputDevice == QLatin1String("secondary")) if (m_inputDevice == QLatin1String("secondary"))
g_object_set(G_OBJECT(videoSrc), "camera-device", 1, NULL); g_object_set(G_OBJECT(videoSrc), "camera-device", 1, NULL);
else else
g_object_set(G_OBJECT(videoSrc), "camera-device", 0, NULL); g_object_set(G_OBJECT(videoSrc), "camera-device", 0, NULL);
} else { } else if (sourceElementName == "wrappercamerabinsrc") {
if (g_object_class_find_property(G_OBJECT_GET_CLASS(videoSrc), "device")) GstElement *src = 0;
g_object_set(G_OBJECT(videoSrc),
"device", if (m_videoInputFactory)
m_inputDevice.toLocal8Bit().constData(), src = m_videoInputFactory->buildElement();
NULL); 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; return m_state;
} }
QCamera::State CameraBinSession::pendingState() const
{
return m_pendingState;
}
void CameraBinSession::setState(QCamera::State newState) void CameraBinSession::setState(QCamera::State newState)
{ {
if (newState == m_pendingState) if (newState == m_pendingState)
return; return;
m_pendingState = newState; m_pendingState = newState;
emit pendingStateChanged(m_pendingState);
#if CAMERABIN_DEBUG #if CAMERABIN_DEBUG
qDebug() << Q_FUNC_INFO << newState; qDebug() << Q_FUNC_INFO << newState;
@@ -613,14 +644,14 @@ void CameraBinSession::setState(QCamera::State newState)
GstState pending = GST_STATE_NULL; GstState pending = GST_STATE_NULL;
gst_element_get_state(m_camerabin, &binState, &pending, 0); gst_element_get_state(m_camerabin, &binState, &pending, 0);
if (pending == GST_STATE_VOID_PENDING && binState == GST_STATE_READY) { setupCaptureResolution();
m_pendingResolutionUpdate = false; if (captureMode() == QCamera::CaptureVideo)
setupCaptureResolution(); g_object_set (G_OBJECT(m_camerabin),
gst_element_set_state(m_camerabin, GST_STATE_PLAYING); "video-profile",
} else { m_recorderControl->videoProfile(),
m_pendingResolutionUpdate = true; NULL);
gst_element_set_state(m_camerabin, GST_STATE_READY);
} gst_element_set_state(m_camerabin, GST_STATE_PLAYING);
} }
} }
} }
@@ -790,9 +821,10 @@ bool CameraBinSession::processSyncMessage(const QGstreamerMessage &message)
return true; return true;
} }
} }
#ifdef HAVE_GST_PHOTOGRAPHY
if (gst_structure_has_name(gm->structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE)) if (gst_structure_has_name(gm->structure, GST_PHOTOGRAPHY_AUTOFOCUS_DONE))
m_cameraFocusControl->handleFocusMessage(gm); m_cameraFocusControl->handleFocusMessage(gm);
#endif
} }
return false; return false;
@@ -890,11 +922,6 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message)
emit stateChanged(m_state = QCamera::UnloadedState); emit stateChanged(m_state = QCamera::UnloadedState);
break; break;
case GST_STATE_READY: 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) if (m_state != QCamera::LoadedState)
emit stateChanged(m_state = QCamera::LoadedState); emit stateChanged(m_state = QCamera::LoadedState);
break; break;
@@ -920,11 +947,14 @@ void CameraBinSession::recordVideo()
m_recordingActive = true; m_recordingActive = true;
m_actualSink = m_sink; m_actualSink = m_sink;
if (m_actualSink.isEmpty()) { if (m_actualSink.isEmpty()) {
QString ext = m_mediaContainerControl->suggestedFileExtension(); QString ext = m_mediaContainerControl->suggestedFileExtension(m_mediaContainerControl->containerFormat());
m_actualSink = generateFileName("clip_", defaultDir(QCamera::CaptureVideo), ext); 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); 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; return res;
} }
QT_END_NAMESPACE

View File

@@ -48,11 +48,14 @@
#include <QtCore/qdir.h> #include <QtCore/qdir.h>
#include <gst/gst.h> #include <gst/gst.h>
#ifdef HAVE_GST_PHOTOGRAPHY
#include <gst/interfaces/photography.h> #include <gst/interfaces/photography.h>
#endif
#include <private/qgstreamerbushelper_p.h> #include <private/qgstreamerbushelper_p.h>
#include "qcamera.h" #include "qcamera.h"
QT_BEGIN_NAMESPACE
class QGstreamerMessage; class QGstreamerMessage;
class QGstreamerBusHelper; class QGstreamerBusHelper;
@@ -76,6 +79,7 @@ public:
virtual GstElement *buildElement() = 0; virtual GstElement *buildElement() = 0;
}; };
class CameraBinSession : public QObject, class CameraBinSession : public QObject,
public QGstreamerBusMessageFilter, public QGstreamerBusMessageFilter,
public QGstreamerSyncMessageFilter public QGstreamerSyncMessageFilter
@@ -92,7 +96,9 @@ public:
CameraBinSession(QObject *parent); CameraBinSession(QObject *parent);
~CameraBinSession(); ~CameraBinSession();
#ifdef HAVE_GST_PHOTOGRAPHY
GstPhotography *photography(); GstPhotography *photography();
#endif
GstElement *cameraBin() { return m_camerabin; } GstElement *cameraBin() { return m_camerabin; }
QGstreamerBusHelper *bus() { return m_busHelper; } QGstreamerBusHelper *bus() { return m_busHelper; }
@@ -113,11 +119,15 @@ public:
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; }
#ifdef HAVE_GST_PHOTOGRAPHY
CameraBinExposure *cameraExposureControl() const { return m_cameraExposureControl; } CameraBinExposure *cameraExposureControl() const { return m_cameraExposureControl; }
CameraBinFlash *cameraFlashControl() const { return m_cameraFlashControl; } CameraBinFlash *cameraFlashControl() const { return m_cameraFlashControl; }
CameraBinFocus *cameraFocusControl() const { return m_cameraFocusControl; } CameraBinFocus *cameraFocusControl() const { return m_cameraFocusControl; }
CameraBinImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; }
CameraBinLocks *cameraLocksControl() const { return m_cameraLocksControl; } CameraBinLocks *cameraLocksControl() const { return m_cameraLocksControl; }
#endif
CameraBinImageProcessing *imageProcessingControl() const { return m_imageProcessingControl; }
CameraBinCaptureDestination *captureDestinationControl() const { return m_captureDestinationControl; } CameraBinCaptureDestination *captureDestinationControl() const { return m_captureDestinationControl; }
CameraBinCaptureBufferFormat *captureBufferFormatControl() const { return m_captureBufferFormatControl; } CameraBinCaptureBufferFormat *captureBufferFormatControl() const { return m_captureBufferFormatControl; }
@@ -138,6 +148,7 @@ public:
void captureImage(int requestId, const QString &fileName); void captureImage(int requestId, const QString &fileName);
QCamera::State state() const; QCamera::State state() const;
QCamera::State pendingState() const;
bool isBusy() const; bool isBusy() const;
qint64 duration() const; qint64 duration() const;
@@ -152,6 +163,7 @@ public:
signals: signals:
void stateChanged(QCamera::State state); void stateChanged(QCamera::State state);
void pendingStateChanged(QCamera::State state);
void durationChanged(qint64 duration); void durationChanged(qint64 duration);
void error(int error, const QString &errorString); void error(int error, const QString &errorString);
void imageExposed(int requestId); void imageExposed(int requestId);
@@ -184,7 +196,6 @@ private:
QCamera::State m_state; QCamera::State m_state;
QCamera::State m_pendingState; QCamera::State m_pendingState;
QString m_inputDevice; QString m_inputDevice;
bool m_pendingResolutionUpdate;
bool m_muted; bool m_muted;
bool m_busy; bool m_busy;
@@ -201,11 +212,14 @@ private:
CameraBinImageEncoder *m_imageEncodeControl; CameraBinImageEncoder *m_imageEncodeControl;
CameraBinRecorder *m_recorderControl; CameraBinRecorder *m_recorderControl;
CameraBinContainer *m_mediaContainerControl; CameraBinContainer *m_mediaContainerControl;
#ifdef HAVE_GST_PHOTOGRAPHY
CameraBinExposure *m_cameraExposureControl; CameraBinExposure *m_cameraExposureControl;
CameraBinFlash *m_cameraFlashControl; CameraBinFlash *m_cameraFlashControl;
CameraBinFocus *m_cameraFocusControl; CameraBinFocus *m_cameraFocusControl;
CameraBinImageProcessing *m_imageProcessingControl;
CameraBinLocks *m_cameraLocksControl; CameraBinLocks *m_cameraLocksControl;
#endif
CameraBinImageProcessing *m_imageProcessingControl;
CameraBinCaptureDestination *m_captureDestinationControl; CameraBinCaptureDestination *m_captureDestinationControl;
CameraBinCaptureBufferFormat *m_captureBufferFormatControl; CameraBinCaptureBufferFormat *m_captureBufferFormatControl;
@@ -229,4 +243,6 @@ public:
int m_requestId; int m_requestId;
}; };
QT_END_NAMESPACE
#endif // CAMERABINCAPTURESESSION_MAEMO_H #endif // CAMERABINCAPTURESESSION_MAEMO_H

View File

@@ -45,6 +45,8 @@
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
CameraBinVideoEncoder::CameraBinVideoEncoder(CameraBinSession *session) CameraBinVideoEncoder::CameraBinVideoEncoder(CameraBinSession *session)
:QVideoEncoderSettingsControl(session), :QVideoEncoderSettingsControl(session),
m_session(session), m_session(session),
@@ -164,3 +166,5 @@ GstEncodingProfile *CameraBinVideoEncoder::createProfile()
NULL, //restriction NULL, //restriction
0); //presence 0); //presence
} }
QT_END_NAMESPACE

View File

@@ -43,7 +43,6 @@
#define CAMERABINVIDEOENCODE_H #define CAMERABINVIDEOENCODE_H
#include <qvideoencodersettingscontrol.h> #include <qvideoencodersettingscontrol.h>
class CameraBinSession;
#include <QtCore/qstringlist.h> #include <QtCore/qstringlist.h>
#include <QtCore/qmap.h> #include <QtCore/qmap.h>
@@ -52,9 +51,11 @@ class CameraBinSession;
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/pbutils/pbutils.h> #include <gst/pbutils/pbutils.h>
#include <gst/pbutils/encoding-profile.h> #include <gst/pbutils/encoding-profile.h>
#include "qgstcodecsinfo.h" #include <private/qgstcodecsinfo_p.h>
QT_USE_NAMESPACE QT_BEGIN_NAMESPACE
class CameraBinSession;
class CameraBinVideoEncoder : public QVideoEncoderSettingsControl class CameraBinVideoEncoder : public QVideoEncoderSettingsControl
{ {
@@ -94,4 +95,6 @@ private:
QVideoEncoderSettings m_userSettings; QVideoEncoderSettings m_userSettings;
}; };
QT_END_NAMESPACE
#endif #endif

View File

@@ -46,6 +46,8 @@
#include <QtWidgets/qwidget.h> #include <QtWidgets/qwidget.h>
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
CameraButtonListener::CameraButtonListener(QObject *parent) : CameraButtonListener::CameraButtonListener(QObject *parent) :
QObject(parent), QObject(parent),
m_focusPressed(false), m_focusPressed(false),
@@ -90,3 +92,5 @@ void CameraButtonListener::handleQmKeyEvent(MeeGo::QmKeys::Key key, MeeGo::QmKey
} }
} }
} }
QT_END_NAMESPACE

View File

@@ -46,6 +46,8 @@
#include <QtCore/qobject.h> #include <QtCore/qobject.h>
#include <qmsystem2/qmkeys.h> #include <qmsystem2/qmkeys.h>
QT_BEGIN_NAMESPACE
class CameraButtonListener : public QObject class CameraButtonListener : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -62,4 +64,6 @@ private:
bool m_shutterPressed; bool m_shutterPressed;
}; };
QT_END_NAMESPACE
#endif // CAMERABUTTONLISTENER_MEEGO_H #endif // CAMERABUTTONLISTENER_MEEGO_H

View File

@@ -5,11 +5,8 @@ SUBDIRS += \
mediacapture \ mediacapture \
mediaplayer mediaplayer
# Camerabin2 based camera backend is untested and currently disabled config_gstreamer_encodingprofiles {
disabled { SUBDIRS += camerabin
config_gstreamer_photography {
SUBDIRS += camerabin
}
} }
OTHER_FILES += \ OTHER_FILES += \

View File

@@ -91,6 +91,9 @@ private slots:
void testCameraCaptureMetadata(); void testCameraCaptureMetadata();
void testExposureCompensation(); void testExposureCompensation();
void testExposureMode(); void testExposureMode();
void testVideoRecording_data();
void testVideoRecording();
private: private:
}; };
@@ -565,6 +568,81 @@ void tst_QCameraBackend::testExposureMode()
QCOMPARE(exposure->exposureMode(), QCameraExposure::ExposureAuto); 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) QTEST_MAIN(tst_QCameraBackend)
#include "tst_qcamerabackend.moc" #include "tst_qcamerabackend.moc"