Implement exposure and whitebalance lock for gstreamer camera.

Change-Id: I58277d69c18ad2e31cad719a2dd6361c0c2d7e98
Reviewed-by: Yoann Lopes <yoann.lopes@theqtcompany.com>
This commit is contained in:
Andrew den Exter
2014-11-25 09:22:23 +10:00
parent dc2fec1bd8
commit 9932feec63
4 changed files with 227 additions and 18 deletions

View File

@@ -44,15 +44,17 @@ QT_BEGIN_NAMESPACE
CameraBinImageProcessing::CameraBinImageProcessing(CameraBinSession *session) CameraBinImageProcessing::CameraBinImageProcessing(CameraBinSession *session)
:QCameraImageProcessingControl(session), :QCameraImageProcessingControl(session),
m_session(session) m_session(session),
m_whiteBalanceMode(QCameraImageProcessing::WhiteBalanceAuto)
{ {
#ifdef HAVE_GST_PHOTOGRAPHY #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;
unlockWhiteBalance();
#endif #endif
updateColorBalanceValues(); updateColorBalanceValues();
@@ -129,20 +131,23 @@ bool CameraBinImageProcessing::setColorBalanceValue(const QString& channel, qrea
QCameraImageProcessing::WhiteBalanceMode CameraBinImageProcessing::whiteBalanceMode() const QCameraImageProcessing::WhiteBalanceMode CameraBinImageProcessing::whiteBalanceMode() const
{ {
#ifdef HAVE_GST_PHOTOGRAPHY return m_whiteBalanceMode;
GstPhotographyWhiteBalanceMode 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) void CameraBinImageProcessing::setWhiteBalanceMode(QCameraImageProcessing::WhiteBalanceMode mode)
{ {
#ifdef HAVE_GST_PHOTOGRAPHY #ifdef HAVE_GST_PHOTOGRAPHY
if (isWhiteBalanceModeSupported(mode)) if (isWhiteBalanceModeSupported(mode)) {
gst_photography_set_white_balance_mode(m_session->photography(), m_mappedWbValues.key(mode)); m_whiteBalanceMode = mode;
#if GST_CHECK_VERSION(1, 2, 0)
GstPhotographyWhiteBalanceMode currentMode;
if (gst_photography_get_white_balance_mode(m_session->photography(), &currentMode)
&& currentMode != GST_PHOTOGRAPHY_WB_MODE_MANUAL)
#endif
{
unlockWhiteBalance();
}
}
#else #else
Q_UNUSED(mode); Q_UNUSED(mode);
#endif #endif
@@ -215,4 +220,23 @@ void CameraBinImageProcessing::setParameter(QCameraImageProcessingControl::Proce
updateColorBalanceValues(); updateColorBalanceValues();
} }
#ifdef HAVE_GST_PHOTOGRAPHY
void CameraBinImageProcessing::lockWhiteBalance()
{
#if GST_CHECK_VERSION(1, 2, 0)
if (GstPhotography *photography = m_session->photography()) {
gst_photography_set_white_balance_mode(photography, GST_PHOTOGRAPHY_WB_MODE_MANUAL);
}
#endif
}
void CameraBinImageProcessing::unlockWhiteBalance()
{
if (GstPhotography *photography = m_session->photography()) {
gst_photography_set_white_balance_mode(
photography, m_mappedWbValues.key(m_whiteBalanceMode));
}
}
#endif
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -68,6 +68,11 @@ public:
QVariant parameter(ProcessingParameter parameter) const; QVariant parameter(ProcessingParameter parameter) const;
void setParameter(ProcessingParameter parameter, const QVariant &value); void setParameter(ProcessingParameter parameter, const QVariant &value);
#ifdef HAVE_GST_PHOTOGRAPHY
void lockWhiteBalance();
void unlockWhiteBalance();
#endif
private: private:
bool setColorBalanceValue(const QString& channel, qreal value); bool setColorBalanceValue(const QString& channel, qreal value);
void updateColorBalanceValues(); void updateColorBalanceValues();
@@ -78,6 +83,7 @@ private:
#ifdef HAVE_GST_PHOTOGRAPHY #ifdef HAVE_GST_PHOTOGRAPHY
QMap<GstPhotographyWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues; QMap<GstPhotographyWhiteBalanceMode, QCameraImageProcessing::WhiteBalanceMode> m_mappedWbValues;
#endif #endif
QCameraImageProcessing::WhiteBalanceMode m_whiteBalanceMode;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -34,6 +34,9 @@
#include "camerabinlocks.h" #include "camerabinlocks.h"
#include "camerabinsession.h" #include "camerabinsession.h"
#include "camerabinfocus.h" #include "camerabinfocus.h"
#include "camerabinimageprocessing.h"
#include <QtCore/qcoreevent.h>
#include <gst/interfaces/photography.h> #include <gst/interfaces/photography.h>
@@ -56,29 +59,186 @@ CameraBinLocks::~CameraBinLocks()
QCamera::LockTypes CameraBinLocks::supportedLocks() const QCamera::LockTypes CameraBinLocks::supportedLocks() const
{ {
return QCamera::LockFocus; QCamera::LockTypes locks = QCamera::LockFocus;
#if GST_CHECK_VERSION(1, 2, 0)
if (GstPhotography *photography = m_session->photography()) {
if (gst_photography_get_capabilities(photography) & GST_PHOTOGRAPHY_CAPS_WB_MODE)
locks |= QCamera::LockWhiteBalance;
if (g_object_class_find_property(
G_OBJECT_GET_CLASS(m_session->cameraSource()), "exposure-mode")) {
locks |= QCamera::LockExposure;
}
}
#endif
return locks;
} }
QCamera::LockStatus CameraBinLocks::lockStatus(QCamera::LockType lock) const QCamera::LockStatus CameraBinLocks::lockStatus(QCamera::LockType lock) const
{ {
switch (lock) {
case QCamera::LockFocus:
return m_focus->focusStatus();
#if GST_CHECK_VERSION(1, 2, 0)
case QCamera::LockExposure:
if (m_pendingLocks & QCamera::LockExposure)
return QCamera::Searching;
return isExposureLocked() ? QCamera::Locked : QCamera::Unlocked;
case QCamera::LockWhiteBalance:
if (m_pendingLocks & QCamera::LockWhiteBalance)
return QCamera::Searching;
return isWhiteBalanceLocked() ? QCamera::Locked : QCamera::Unlocked;
#endif
default:
return QCamera::Unlocked;
}
return lock == QCamera::LockFocus ? m_focus->focusStatus() : QCamera::Unlocked; return lock == QCamera::LockFocus ? m_focus->focusStatus() : QCamera::Unlocked;
} }
void CameraBinLocks::searchAndLock(QCamera::LockTypes locks) void CameraBinLocks::searchAndLock(QCamera::LockTypes locks)
{ {
if (locks & QCamera::LockFocus) m_pendingLocks &= ~locks;
if (locks & QCamera::LockFocus) {
m_pendingLocks |= QCamera::LockFocus;
m_focus->_q_startFocusing(); m_focus->_q_startFocusing();
}
#if GST_CHECK_VERSION(1, 2, 0)
if (!m_pendingLocks)
m_lockTimer.stop();
if (locks & QCamera::LockExposure) {
if (isExposureLocked()) {
unlockExposure(QCamera::Searching, QCamera::UserRequest);
m_pendingLocks |= QCamera::LockExposure;
m_lockTimer.start(1000, this);
} else {
lockExposure(QCamera::UserRequest);
}
}
if (locks & QCamera::LockWhiteBalance) {
if (isWhiteBalanceLocked()) {
unlockWhiteBalance(QCamera::Searching, QCamera::UserRequest);
m_pendingLocks |= QCamera::LockWhiteBalance;
m_lockTimer.start(1000, this);
} else {
lockWhiteBalance(QCamera::UserRequest);
}
}
#endif
} }
void CameraBinLocks::unlock(QCamera::LockTypes locks) void CameraBinLocks::unlock(QCamera::LockTypes locks)
{ {
m_pendingLocks &= ~locks;
if (locks & QCamera::LockFocus) if (locks & QCamera::LockFocus)
m_focus->_q_stopFocusing(); m_focus->_q_stopFocusing();
#if GST_CHECK_VERSION(1, 2, 0)
if (!m_pendingLocks)
m_lockTimer.stop();
if (locks & QCamera::LockExposure)
unlockExposure(QCamera::Unlocked, QCamera::UserRequest);
if (locks & QCamera::LockWhiteBalance)
unlockWhiteBalance(QCamera::Unlocked, QCamera::UserRequest);
#endif
} }
void CameraBinLocks::updateFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason) void CameraBinLocks::updateFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason)
{ {
if (status != QCamera::Searching)
m_pendingLocks &= ~QCamera::LockFocus;
#if GST_CHECK_VERSION(1, 2, 0)
if (status == QCamera::Locked && !m_lockTimer.isActive()) {
if (m_pendingLocks & QCamera::LockExposure)
lockExposure(QCamera::LockAcquired);
if (m_pendingLocks & QCamera::LockWhiteBalance)
lockWhiteBalance(QCamera::LockAcquired);
}
#endif
emit lockStatusChanged(QCamera::LockFocus, status, reason); emit lockStatusChanged(QCamera::LockFocus, status, reason);
} }
#if GST_CHECK_VERSION(1, 2, 0)
void CameraBinLocks::timerEvent(QTimerEvent *event)
{
if (event->timerId() != m_lockTimer.timerId())
return QCameraLocksControl::timerEvent(event);
m_lockTimer.stop();
if (!(m_pendingLocks & QCamera::LockFocus)) {
if (m_pendingLocks & QCamera::LockExposure)
lockExposure(QCamera::LockAcquired);
if (m_pendingLocks & QCamera::LockWhiteBalance)
lockWhiteBalance(QCamera::LockAcquired);
}
}
bool CameraBinLocks::isExposureLocked() const
{
if (GstElement *source = m_session->cameraSource()) {
GstPhotographyExposureMode exposureMode = GST_PHOTOGRAPHY_EXPOSURE_MODE_AUTO;
g_object_get (G_OBJECT(source), "exposure-mode", &exposureMode, NULL);
return exposureMode == GST_PHOTOGRAPHY_EXPOSURE_MODE_MANUAL;
} else {
return false;
}
}
void CameraBinLocks::lockExposure(QCamera::LockChangeReason reason)
{
m_pendingLocks &= ~QCamera::LockExposure;
g_object_set(
G_OBJECT(m_session->cameraSource()),
"exposure-mode",
GST_PHOTOGRAPHY_EXPOSURE_MODE_MANUAL,
NULL);
emit lockStatusChanged(QCamera::LockExposure, QCamera::Locked, reason);
}
void CameraBinLocks::unlockExposure(QCamera::LockStatus status, QCamera::LockChangeReason reason)
{
g_object_set(
G_OBJECT(m_session->cameraSource()),
"exposure-mode",
GST_PHOTOGRAPHY_EXPOSURE_MODE_AUTO,
NULL);
emit lockStatusChanged(QCamera::LockExposure, status, reason);
}
bool CameraBinLocks::isWhiteBalanceLocked() const
{
if (GstPhotography *photography = m_session->photography()) {
GstPhotographyWhiteBalanceMode whiteBalanceMode;
return gst_photography_get_white_balance_mode(photography, &whiteBalanceMode)
&& whiteBalanceMode == GST_PHOTOGRAPHY_WB_MODE_MANUAL;
} else {
return false;
}
}
void CameraBinLocks::lockWhiteBalance(QCamera::LockChangeReason reason)
{
m_pendingLocks &= ~QCamera::LockWhiteBalance;
m_session->imageProcessingControl()->lockWhiteBalance();
emit lockStatusChanged(QCamera::LockWhiteBalance, QCamera::Locked, reason);
}
void CameraBinLocks::unlockWhiteBalance(
QCamera::LockStatus status, QCamera::LockChangeReason reason)
{
m_session->imageProcessingControl()->lockWhiteBalance();
emit lockStatusChanged(QCamera::LockWhiteBalance, status, reason);
}
#endif
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -37,6 +37,8 @@
#include <qcamera.h> #include <qcamera.h>
#include <qcameralockscontrol.h> #include <qcameralockscontrol.h>
#include <QtCore/qbasictimer.h>
#include <gst/gst.h> #include <gst/gst.h>
#include <glib.h> #include <glib.h>
@@ -60,12 +62,29 @@ public:
void searchAndLock(QCamera::LockTypes locks); void searchAndLock(QCamera::LockTypes locks);
void unlock(QCamera::LockTypes locks); void unlock(QCamera::LockTypes locks);
protected:
#if GST_CHECK_VERSION(1, 2, 0)
void timerEvent(QTimerEvent *event);
#endif
private slots: private slots:
void updateFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason); void updateFocusStatus(QCamera::LockStatus status, QCamera::LockChangeReason reason);
private: private:
#if GST_CHECK_VERSION(1, 2, 0)
bool isExposureLocked() const;
void lockExposure(QCamera::LockChangeReason reason);
void unlockExposure(QCamera::LockStatus status, QCamera::LockChangeReason reason);
bool isWhiteBalanceLocked() const;
void lockWhiteBalance(QCamera::LockChangeReason reason);
void unlockWhiteBalance(QCamera::LockStatus status, QCamera::LockChangeReason reason);
#endif
CameraBinSession *m_session; CameraBinSession *m_session;
CameraBinFocus *m_focus; CameraBinFocus *m_focus;
QBasicTimer m_lockTimer;
QCamera::LockTypes m_pendingLocks;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE