From 7f0459885991d56307cd79d94ad932ecd3df0666 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Sun, 8 Nov 2015 18:34:01 +0300 Subject: DirectShow: Implement basic QCameraImageProcessingControl interface This commit implements the contrast, saturation, brightness and sharpening adjustments, using DirectShow backend. Change-Id: I438595550ff804f2a20028b4bc020c566d309127 Reviewed-by: Yoann Lopes --- src/plugins/directshow/camera/camera.pri | 6 +- .../camera/dscameraimageprocessingcontrol.cpp | 74 +++++++ .../camera/dscameraimageprocessingcontrol.h | 63 ++++++ src/plugins/directshow/camera/dscameraservice.cpp | 6 + src/plugins/directshow/camera/dscameraservice.h | 2 + src/plugins/directshow/camera/dscamerasession.cpp | 224 +++++++++++++++++++++ src/plugins/directshow/camera/dscamerasession.h | 39 ++++ 7 files changed, 412 insertions(+), 2 deletions(-) create mode 100644 src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp create mode 100644 src/plugins/directshow/camera/dscameraimageprocessingcontrol.h (limited to 'src/plugins/directshow/camera') diff --git a/src/plugins/directshow/camera/camera.pri b/src/plugins/directshow/camera/camera.pri index 3a532f472..c6b16da59 100644 --- a/src/plugins/directshow/camera/camera.pri +++ b/src/plugins/directshow/camera/camera.pri @@ -14,7 +14,8 @@ HEADERS += \ $$PWD/dsimagecapturecontrol.h \ $$PWD/dscamerasession.h \ $$PWD/directshowglobal.h \ - $$PWD/dscameraviewfindersettingscontrol.h + $$PWD/dscameraviewfindersettingscontrol.h \ + $$PWD/dscameraimageprocessingcontrol.h SOURCES += \ $$PWD/dscameraservice.cpp \ @@ -23,7 +24,8 @@ SOURCES += \ $$PWD/dsvideodevicecontrol.cpp \ $$PWD/dsimagecapturecontrol.cpp \ $$PWD/dscamerasession.cpp \ - $$PWD/dscameraviewfindersettingscontrol.cpp + $$PWD/dscameraviewfindersettingscontrol.cpp \ + $$PWD/dscameraimageprocessingcontrol.cpp *-msvc*:INCLUDEPATH += $$(DXSDK_DIR)/include LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 diff --git a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp new file mode 100644 index 000000000..39fa471ec --- /dev/null +++ b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Denis Shienkov +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "dscameraimageprocessingcontrol.h" +#include "dscamerasession.h" + +QT_BEGIN_NAMESPACE + +DSCameraImageProcessingControl::DSCameraImageProcessingControl(DSCameraSession *session) + : QCameraImageProcessingControl(session) + , m_session(session) +{ +} + +DSCameraImageProcessingControl::~DSCameraImageProcessingControl() +{ +} + +bool DSCameraImageProcessingControl::isParameterSupported( + QCameraImageProcessingControl::ProcessingParameter parameter) const +{ + return m_session->isImageProcessingParameterSupported(parameter); +} + +bool DSCameraImageProcessingControl::isParameterValueSupported( + QCameraImageProcessingControl::ProcessingParameter parameter, + const QVariant &value) const +{ + return m_session->isImageProcessingParameterValueSupported(parameter, value); +} + +QVariant DSCameraImageProcessingControl::parameter( + QCameraImageProcessingControl::ProcessingParameter parameter) const +{ + return m_session->imageProcessingParameter(parameter); +} + +void DSCameraImageProcessingControl::setParameter(QCameraImageProcessingControl::ProcessingParameter parameter, + const QVariant &value) +{ + m_session->setImageProcessingParameter(parameter, value); +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h new file mode 100644 index 000000000..2e50fe14d --- /dev/null +++ b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Denis Shienkov +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DSCAMERAIMAGEPROCESSINGCONTROL_H +#define DSCAMERAIMAGEPROCESSINGCONTROL_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class DSCameraSession; + +class DSCameraImageProcessingControl : public QCameraImageProcessingControl +{ + Q_OBJECT + +public: + DSCameraImageProcessingControl(DSCameraSession *session); + virtual ~DSCameraImageProcessingControl(); + + 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: + DSCameraSession *m_session; +}; + +QT_END_NAMESPACE + +#endif // DSCAMERAIMAGEPROCESSINGCONTROL_H diff --git a/src/plugins/directshow/camera/dscameraservice.cpp b/src/plugins/directshow/camera/dscameraservice.cpp index 9fcd4de70..6c92df04b 100644 --- a/src/plugins/directshow/camera/dscameraservice.cpp +++ b/src/plugins/directshow/camera/dscameraservice.cpp @@ -41,6 +41,7 @@ #include "dsvideodevicecontrol.h" #include "dsimagecapturecontrol.h" #include "dscameraviewfindersettingscontrol.h" +#include "dscameraimageprocessingcontrol.h" QT_BEGIN_NAMESPACE @@ -53,12 +54,14 @@ DSCameraService::DSCameraService(QObject *parent): m_videoDevice = new DSVideoDeviceControl(m_session); m_imageCapture = new DSImageCaptureControl(m_session); m_viewfinderSettings = new DSCameraViewfinderSettingsControl(m_session); + m_imageProcessingControl = new DSCameraImageProcessingControl(m_session); } DSCameraService::~DSCameraService() { delete m_control; delete m_viewfinderSettings; + delete m_imageProcessingControl; delete m_videoDevice; delete m_videoRenderer; delete m_imageCapture; @@ -86,6 +89,9 @@ QMediaControl* DSCameraService::requestControl(const char *name) if (qstrcmp(name, QCameraViewfinderSettingsControl2_iid) == 0) return m_viewfinderSettings; + if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0) + return m_imageProcessingControl; + return 0; } diff --git a/src/plugins/directshow/camera/dscameraservice.h b/src/plugins/directshow/camera/dscameraservice.h index c3c881d0e..05222ebc4 100644 --- a/src/plugins/directshow/camera/dscameraservice.h +++ b/src/plugins/directshow/camera/dscameraservice.h @@ -46,6 +46,7 @@ class DSVideoOutputControl; class DSVideoDeviceControl; class DSImageCaptureControl; class DSCameraViewfinderSettingsControl; +class DSCameraImageProcessingControl; class DSCameraService : public QMediaService { @@ -66,6 +67,7 @@ private: QMediaControl *m_videoRenderer; DSImageCaptureControl *m_imageCapture; DSCameraViewfinderSettingsControl *m_viewfinderSettings; + DSCameraImageProcessingControl *m_imageProcessingControl; }; QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index 2d3aa1bce..7ec91cfa2 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -230,6 +230,162 @@ void DSCameraSession::setViewfinderSettings(const QCameraViewfinderSettings &set m_viewfinderSettings = settings; } +qreal DSCameraSession::scaledImageProcessingParameterValue( + qint32 sourceValue, const ImageProcessingParameterInfo &sourceValueInfo) +{ + if (sourceValue == sourceValueInfo.defaultValue) { + return 0.0f; + } else if (sourceValue < sourceValueInfo.defaultValue) { + return ((sourceValue - sourceValueInfo.minimumValue) + / qreal(sourceValueInfo.defaultValue - sourceValueInfo.minimumValue)) + + (-1.0f); + } else { + return ((sourceValue - sourceValueInfo.defaultValue) + / qreal(sourceValueInfo.maximumValue - sourceValueInfo.defaultValue)); + } +} + +qint32 DSCameraSession::sourceImageProcessingParameterValue( + qreal scaledValue, const ImageProcessingParameterInfo &valueRange) +{ + if (qFuzzyIsNull(scaledValue)) { + return valueRange.defaultValue; + } else if (scaledValue < 0.0f) { + return ((scaledValue - (-1.0f)) * (valueRange.defaultValue - valueRange.minimumValue)) + + valueRange.minimumValue; + } else { + return (scaledValue * (valueRange.maximumValue - valueRange.defaultValue)) + + valueRange.defaultValue; + } +} + +bool DSCameraSession::isImageProcessingParameterSupported( + QCameraImageProcessingControl::ProcessingParameter parameter) const +{ + return m_imageProcessingParametersInfos.contains(parameter); +} + +bool DSCameraSession::isImageProcessingParameterValueSupported( + QCameraImageProcessingControl::ProcessingParameter parameter, + const QVariant &value) const +{ + QMap::const_iterator sourceValueInfo = + m_imageProcessingParametersInfos.constFind(parameter); + + if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) + return false; + + // This conversion is required only for сontrast, saturation + // brightness, and sharpening. + const qint32 sourceValue = sourceImageProcessingParameterValue( + value.toReal(), (*sourceValueInfo)); + if (sourceValue < (*sourceValueInfo).minimumValue + || sourceValue > (*sourceValueInfo).maximumValue) + return false; + + return true; +} + +QVariant DSCameraSession::imageProcessingParameter( + QCameraImageProcessingControl::ProcessingParameter parameter) const +{ + if (!m_graphBuilder) { + qWarning() << "failed to access to the graph builder"; + return QVariant(); + } + + QMap::const_iterator sourceValueInfo = + m_imageProcessingParametersInfos.constFind(parameter); + + if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) + return QVariant(); + + IAMVideoProcAmp *pVideoProcAmp = NULL; + HRESULT hr = m_graphBuilder->FindInterface( + NULL, + NULL, + m_sourceFilter, + IID_IAMVideoProcAmp, + reinterpret_cast(&pVideoProcAmp) + ); + + if (FAILED(hr) || !pVideoProcAmp) { + qWarning() << "failed to find the video proc amp"; + return QVariant(); + } + + LONG sourceValue = 0; + LONG valueFlags = 0; + + hr = pVideoProcAmp->Get( + (*sourceValueInfo).videoProcAmpProperty, + &sourceValue, + &valueFlags); + + pVideoProcAmp->Release(); + + if (FAILED(hr)) { + qWarning() << "failed to get the parameter value"; + return QVariant(); + } + + // This conversion is required only for сontrast, saturation + // brightness, and sharpening. + return scaledImageProcessingParameterValue( + sourceValue, (*sourceValueInfo)); +} + +void DSCameraSession::setImageProcessingParameter( + QCameraImageProcessingControl::ProcessingParameter parameter, + const QVariant &value) +{ + if (!m_graphBuilder) { + qWarning() << "failed to access to the graph builder"; + return; + } + + QMap::const_iterator sourceValueInfo = + m_imageProcessingParametersInfos.constFind(parameter); + + if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) + return; + + LONG sourceValue = 0; + LONG valueFlags = VideoProcAmp_Flags_Manual; + + // This conversion is required only for сontrast, saturation + // brightness, and sharpening. + sourceValue = sourceImageProcessingParameterValue( + value.toReal(), (*sourceValueInfo)); + + IAMVideoProcAmp *pVideoProcAmp = NULL; + HRESULT hr = m_graphBuilder->FindInterface( + NULL, + NULL, + m_sourceFilter, + IID_IAMVideoProcAmp, + reinterpret_cast(&pVideoProcAmp) + ); + + if (FAILED(hr) || !pVideoProcAmp) { + qWarning() << "failed to find the video proc amp"; + return; + } + + hr = pVideoProcAmp->Set( + (*sourceValueInfo).videoProcAmpProperty, + sourceValue, + valueFlags); + + pVideoProcAmp->Release(); + + if (FAILED(hr)) + qWarning() << "failed to set the parameter value"; +} + bool DSCameraSession::load() { unload(); @@ -720,6 +876,71 @@ bool DSCameraSession::configurePreviewFormat() return true; } +void DSCameraSession::updateImageProcessingParametersInfos() +{ + if (!m_graphBuilder) { + qWarning() << "failed to access to the graph builder"; + return; + } + + IAMVideoProcAmp *pVideoProcAmp = NULL; + const HRESULT hr = m_graphBuilder->FindInterface( + NULL, + NULL, + m_sourceFilter, + IID_IAMVideoProcAmp, + reinterpret_cast(&pVideoProcAmp) + ); + + if (FAILED(hr) || !pVideoProcAmp) { + qWarning() << "failed to find the video proc amp"; + return; + } + + for (int property = VideoProcAmp_Brightness; property <= VideoProcAmp_Gain; ++property) { + + QCameraImageProcessingControl::ProcessingParameter processingParameter; // not initialized + + switch (property) { + case VideoProcAmp_Brightness: + processingParameter = QCameraImageProcessingControl::BrightnessAdjustment; + break; + case VideoProcAmp_Contrast: + processingParameter = QCameraImageProcessingControl::ContrastAdjustment; + break; + case VideoProcAmp_Saturation: + processingParameter = QCameraImageProcessingControl::SaturationAdjustment; + break; + case VideoProcAmp_Sharpness: + processingParameter = QCameraImageProcessingControl::SharpeningAdjustment; + break; + default: // unsupported or not implemented yet parameter + continue; + } + + ImageProcessingParameterInfo sourceValueInfo; + LONG steppingDelta = 0; + LONG capsFlags = 0; + + const HRESULT hr = pVideoProcAmp->GetRange( + property, + &sourceValueInfo.minimumValue, + &sourceValueInfo.maximumValue, + &steppingDelta, + &sourceValueInfo.defaultValue, + &capsFlags); + + if (FAILED(hr)) + continue; + + sourceValueInfo.videoProcAmpProperty = static_cast(property); + + m_imageProcessingParametersInfos.insert(processingParameter, sourceValueInfo); + } + + pVideoProcAmp->Release(); +} + bool DSCameraSession::connectGraph() { HRESULT hr = m_filterGraph->AddFilter(m_sourceFilter, L"Capture Filter"); @@ -806,6 +1027,7 @@ void DSCameraSession::updateSourceCapabilities() Q_FOREACH (AM_MEDIA_TYPE f, m_supportedFormats) _FreeMediaType(f); m_supportedFormats.clear(); + m_imageProcessingParametersInfos.clear(); IAMVideoControl *pVideoControl = 0; hr = m_graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, @@ -915,6 +1137,8 @@ void DSCameraSession::updateSourceCapabilities() } pConfig->Release(); + + updateImageProcessingParametersInfos(); } HRESULT getPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin) diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h index 9ac121463..7ad3a2e3d 100644 --- a/src/plugins/directshow/camera/dscamerasession.h +++ b/src/plugins/directshow/camera/dscamerasession.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -97,6 +98,20 @@ public: QList supportedViewfinderSettings() const { return m_supportedViewfinderSettings; } + bool isImageProcessingParameterSupported( + QCameraImageProcessingControl::ProcessingParameter) const; + + bool isImageProcessingParameterValueSupported( + QCameraImageProcessingControl::ProcessingParameter, + const QVariant &) const; + + QVariant imageProcessingParameter( + QCameraImageProcessingControl::ProcessingParameter) const; + + void setImageProcessingParameter( + QCameraImageProcessingControl::ProcessingParameter, + const QVariant &); + Q_SIGNALS: void statusChanged(QCamera::Status); void imageExposed(int id); @@ -110,6 +125,21 @@ private Q_SLOTS: void updateReadyForCapture(); private: + struct ImageProcessingParameterInfo { + ImageProcessingParameterInfo() + : minimumValue(0) + , maximumValue(0) + , defaultValue(0) + , videoProcAmpProperty(VideoProcAmp_Brightness) + { + } + + LONG minimumValue; + LONG maximumValue; + LONG defaultValue; + VideoProcAmpProperty videoProcAmpProperty; + }; + void setStatus(QCamera::Status status); void onFrameAvailable(const char *frameData, long len); @@ -120,6 +150,14 @@ private: void disconnectGraph(); void updateSourceCapabilities(); bool configurePreviewFormat(); + void updateImageProcessingParametersInfos(); + + // These static functions are used for scaling of adjustable parameters, + // which have the ranges from -1.0 to +1.0 in the QCameraImageProcessing API. + static qreal scaledImageProcessingParameterValue( + qint32 sourceValue, const ImageProcessingParameterInfo &sourceValueInfo); + static qint32 sourceImageProcessingParameterValue( + qreal scaledValue, const ImageProcessingParameterInfo &sourceValueInfo); QMutex m_presentMutex; QMutex m_captureMutex; @@ -135,6 +173,7 @@ private: QList m_supportedFormats; QList m_supportedViewfinderSettings; AM_MEDIA_TYPE m_sourceFormat; + QMap m_imageProcessingParametersInfos; // Preview IBaseFilter *m_previewFilter; -- cgit v1.2.3 From 5becd7c1a9786acd80f0cb7d4a7b837442cd8836 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Sat, 5 Dec 2015 20:51:28 +0300 Subject: DirectShow: Add WhiteBalancePreset and ColorTemperature for the camera Change-Id: I9a646418d6177338735e1eb38967fd092e21e0cf Reviewed-by: Yoann Lopes --- src/plugins/directshow/camera/dscamerasession.cpp | 162 ++++++++++++++++++---- src/plugins/directshow/camera/dscamerasession.h | 6 + 2 files changed, 142 insertions(+), 26 deletions(-) (limited to 'src/plugins/directshow/camera') diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index 7ec91cfa2..e0261e035 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -259,30 +259,74 @@ qint32 DSCameraSession::sourceImageProcessingParameterValue( } } +static QCameraImageProcessingControl::ProcessingParameter searchRelatedResultingParameter( + QCameraImageProcessingControl::ProcessingParameter sourceParameter) +{ + if (sourceParameter == QCameraImageProcessingControl::WhiteBalancePreset) + return QCameraImageProcessingControl::ColorTemperature; + return sourceParameter; +} + bool DSCameraSession::isImageProcessingParameterSupported( QCameraImageProcessingControl::ProcessingParameter parameter) const { - return m_imageProcessingParametersInfos.contains(parameter); + const QCameraImageProcessingControl::ProcessingParameter resultingParameter = + searchRelatedResultingParameter(parameter); + + return m_imageProcessingParametersInfos.contains(resultingParameter); } bool DSCameraSession::isImageProcessingParameterValueSupported( QCameraImageProcessingControl::ProcessingParameter parameter, const QVariant &value) const { + const QCameraImageProcessingControl::ProcessingParameter resultingParameter = + searchRelatedResultingParameter(parameter); + QMap::const_iterator sourceValueInfo = - m_imageProcessingParametersInfos.constFind(parameter); + m_imageProcessingParametersInfos.constFind(resultingParameter); if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) return false; - // This conversion is required only for сontrast, saturation - // brightness, and sharpening. - const qint32 sourceValue = sourceImageProcessingParameterValue( - value.toReal(), (*sourceValueInfo)); - if (sourceValue < (*sourceValueInfo).minimumValue - || sourceValue > (*sourceValueInfo).maximumValue) + switch (parameter) { + + case QCameraImageProcessingControl::WhiteBalancePreset: { + const QCameraImageProcessing::WhiteBalanceMode checkedValue = + value.value(); + // Supports only the Manual and the Auto values + if (checkedValue != QCameraImageProcessing::WhiteBalanceManual + && checkedValue != QCameraImageProcessing::WhiteBalanceAuto) { + return false; + } + } + break; + + case QCameraImageProcessingControl::ColorTemperature: { + const qint32 checkedValue = value.toInt(); + if (checkedValue < (*sourceValueInfo).minimumValue + || checkedValue > (*sourceValueInfo).maximumValue) { + return false; + } + } + break; + + case QCameraImageProcessingControl::ContrastAdjustment: // falling back + case QCameraImageProcessingControl::SaturationAdjustment: // falling back + case QCameraImageProcessingControl::BrightnessAdjustment: // falling back + case QCameraImageProcessingControl::SharpeningAdjustment: { + const qint32 sourceValue = sourceImageProcessingParameterValue( + value.toReal(), (*sourceValueInfo)); + if (sourceValue < (*sourceValueInfo).minimumValue + || sourceValue > (*sourceValueInfo).maximumValue) + return false; + } + break; + + default: return false; + } return true; } @@ -295,9 +339,12 @@ QVariant DSCameraSession::imageProcessingParameter( return QVariant(); } + const QCameraImageProcessingControl::ProcessingParameter resultingParameter = + searchRelatedResultingParameter(parameter); + QMap::const_iterator sourceValueInfo = - m_imageProcessingParametersInfos.constFind(parameter); + m_imageProcessingParametersInfos.constFind(resultingParameter); if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) return QVariant(); @@ -317,12 +364,12 @@ QVariant DSCameraSession::imageProcessingParameter( } LONG sourceValue = 0; - LONG valueFlags = 0; + LONG capsFlags = 0; hr = pVideoProcAmp->Get( (*sourceValueInfo).videoProcAmpProperty, &sourceValue, - &valueFlags); + &capsFlags); pVideoProcAmp->Release(); @@ -331,10 +378,27 @@ QVariant DSCameraSession::imageProcessingParameter( return QVariant(); } - // This conversion is required only for сontrast, saturation - // brightness, and sharpening. - return scaledImageProcessingParameterValue( - sourceValue, (*sourceValueInfo)); + switch (parameter) { + + case QCameraImageProcessingControl::WhiteBalancePreset: + return QVariant::fromValue( + capsFlags == VideoProcAmp_Flags_Auto + ? QCameraImageProcessing::WhiteBalanceAuto + : QCameraImageProcessing::WhiteBalanceManual); + + case QCameraImageProcessingControl::ColorTemperature: + return QVariant::fromValue(sourceValue); + + case QCameraImageProcessingControl::ContrastAdjustment: // falling back + case QCameraImageProcessingControl::SaturationAdjustment: // falling back + case QCameraImageProcessingControl::BrightnessAdjustment: // falling back + case QCameraImageProcessingControl::SharpeningAdjustment: + return scaledImageProcessingParameterValue( + sourceValue, (*sourceValueInfo)); + + default: + return QVariant(); + } } void DSCameraSession::setImageProcessingParameter( @@ -346,20 +410,59 @@ void DSCameraSession::setImageProcessingParameter( return; } + const QCameraImageProcessingControl::ProcessingParameter resultingParameter = + searchRelatedResultingParameter(parameter); + QMap::const_iterator sourceValueInfo = - m_imageProcessingParametersInfos.constFind(parameter); + ImageProcessingParameterInfo>::iterator sourceValueInfo = + m_imageProcessingParametersInfos.find(resultingParameter); if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) return; LONG sourceValue = 0; - LONG valueFlags = VideoProcAmp_Flags_Manual; + LONG capsFlags = VideoProcAmp_Flags_Manual; + + switch (parameter) { + + case QCameraImageProcessingControl::WhiteBalancePreset: { + const QCameraImageProcessing::WhiteBalanceMode checkedValue = + value.value(); + // Supports only the Manual and the Auto values + if (checkedValue == QCameraImageProcessing::WhiteBalanceManual) + capsFlags = VideoProcAmp_Flags_Manual; + else if (checkedValue == QCameraImageProcessing::WhiteBalanceAuto) + capsFlags = VideoProcAmp_Flags_Auto; + else + return; + + sourceValue = ((*sourceValueInfo).hasBeenExplicitlySet) + ? (*sourceValueInfo).currentValue + : (*sourceValueInfo).defaultValue; + } + break; + + case QCameraImageProcessingControl::ColorTemperature: + sourceValue = value.isValid() ? + value.value() : (*sourceValueInfo).defaultValue; + capsFlags = (*sourceValueInfo).capsFlags; + break; + + case QCameraImageProcessingControl::ContrastAdjustment: // falling back + case QCameraImageProcessingControl::SaturationAdjustment: // falling back + case QCameraImageProcessingControl::BrightnessAdjustment: // falling back + case QCameraImageProcessingControl::SharpeningAdjustment: + if (value.isValid()) { + sourceValue = sourceImageProcessingParameterValue( + value.toReal(), (*sourceValueInfo)); + } else { + sourceValue = (*sourceValueInfo).defaultValue; + } + break; - // This conversion is required only for сontrast, saturation - // brightness, and sharpening. - sourceValue = sourceImageProcessingParameterValue( - value.toReal(), (*sourceValueInfo)); + default: + return; + } IAMVideoProcAmp *pVideoProcAmp = NULL; HRESULT hr = m_graphBuilder->FindInterface( @@ -378,12 +481,17 @@ void DSCameraSession::setImageProcessingParameter( hr = pVideoProcAmp->Set( (*sourceValueInfo).videoProcAmpProperty, sourceValue, - valueFlags); + capsFlags); pVideoProcAmp->Release(); - if (FAILED(hr)) + if (FAILED(hr)) { qWarning() << "failed to set the parameter value"; + } else { + (*sourceValueInfo).capsFlags = capsFlags; + (*sourceValueInfo).hasBeenExplicitlySet = true; + (*sourceValueInfo).currentValue = sourceValue; + } } bool DSCameraSession::load() @@ -914,13 +1022,15 @@ void DSCameraSession::updateImageProcessingParametersInfos() case VideoProcAmp_Sharpness: processingParameter = QCameraImageProcessingControl::SharpeningAdjustment; break; + case VideoProcAmp_WhiteBalance: + processingParameter = QCameraImageProcessingControl::ColorTemperature; + break; default: // unsupported or not implemented yet parameter continue; } ImageProcessingParameterInfo sourceValueInfo; LONG steppingDelta = 0; - LONG capsFlags = 0; const HRESULT hr = pVideoProcAmp->GetRange( property, @@ -928,7 +1038,7 @@ void DSCameraSession::updateImageProcessingParametersInfos() &sourceValueInfo.maximumValue, &steppingDelta, &sourceValueInfo.defaultValue, - &capsFlags); + &sourceValueInfo.capsFlags); if (FAILED(hr)) continue; diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h index 7ad3a2e3d..619a006fa 100644 --- a/src/plugins/directshow/camera/dscamerasession.h +++ b/src/plugins/directshow/camera/dscamerasession.h @@ -130,6 +130,9 @@ private: : minimumValue(0) , maximumValue(0) , defaultValue(0) + , currentValue(0) + , capsFlags(0) + , hasBeenExplicitlySet(false) , videoProcAmpProperty(VideoProcAmp_Brightness) { } @@ -137,6 +140,9 @@ private: LONG minimumValue; LONG maximumValue; LONG defaultValue; + LONG currentValue; + LONG capsFlags; + bool hasBeenExplicitlySet; VideoProcAmpProperty videoProcAmpProperty; }; -- cgit v1.2.3 From fcb511b6d6985820e0c049e6bd0f25e8715e9e3f Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Tue, 8 Dec 2015 21:58:16 +0300 Subject: DirectShow: Get current image processing parameter from the cache We can simplify a code, do not need to call pVideoProcAmp->Get() each time when we want to get current parameter value. It is better to do this once from updateImageProcessingParametersInfos(). In this case we will return desired parameter from the local cache. Change-Id: If33c3882230c9ae817071ace5b792dfe31685a7f Reviewed-by: Yoann Lopes --- src/plugins/directshow/camera/dscamerasession.cpp | 56 +++++++---------------- src/plugins/directshow/camera/dscamerasession.h | 2 +- 2 files changed, 18 insertions(+), 40 deletions(-) (limited to 'src/plugins/directshow/camera') diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index e0261e035..2e92cb37d 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -231,16 +231,16 @@ void DSCameraSession::setViewfinderSettings(const QCameraViewfinderSettings &set } qreal DSCameraSession::scaledImageProcessingParameterValue( - qint32 sourceValue, const ImageProcessingParameterInfo &sourceValueInfo) + const ImageProcessingParameterInfo &sourceValueInfo) { - if (sourceValue == sourceValueInfo.defaultValue) { + if (sourceValueInfo.currentValue == sourceValueInfo.defaultValue) { return 0.0f; - } else if (sourceValue < sourceValueInfo.defaultValue) { - return ((sourceValue - sourceValueInfo.minimumValue) + } else if (sourceValueInfo.currentValue < sourceValueInfo.defaultValue) { + return ((sourceValueInfo.currentValue - sourceValueInfo.minimumValue) / qreal(sourceValueInfo.defaultValue - sourceValueInfo.minimumValue)) + (-1.0f); } else { - return ((sourceValue - sourceValueInfo.defaultValue) + return ((sourceValueInfo.currentValue - sourceValueInfo.defaultValue) / qreal(sourceValueInfo.maximumValue - sourceValueInfo.defaultValue)); } } @@ -349,52 +349,22 @@ QVariant DSCameraSession::imageProcessingParameter( if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) return QVariant(); - IAMVideoProcAmp *pVideoProcAmp = NULL; - HRESULT hr = m_graphBuilder->FindInterface( - NULL, - NULL, - m_sourceFilter, - IID_IAMVideoProcAmp, - reinterpret_cast(&pVideoProcAmp) - ); - - if (FAILED(hr) || !pVideoProcAmp) { - qWarning() << "failed to find the video proc amp"; - return QVariant(); - } - - LONG sourceValue = 0; - LONG capsFlags = 0; - - hr = pVideoProcAmp->Get( - (*sourceValueInfo).videoProcAmpProperty, - &sourceValue, - &capsFlags); - - pVideoProcAmp->Release(); - - if (FAILED(hr)) { - qWarning() << "failed to get the parameter value"; - return QVariant(); - } - switch (parameter) { case QCameraImageProcessingControl::WhiteBalancePreset: return QVariant::fromValue( - capsFlags == VideoProcAmp_Flags_Auto + (*sourceValueInfo).capsFlags == VideoProcAmp_Flags_Auto ? QCameraImageProcessing::WhiteBalanceAuto : QCameraImageProcessing::WhiteBalanceManual); case QCameraImageProcessingControl::ColorTemperature: - return QVariant::fromValue(sourceValue); + return QVariant::fromValue((*sourceValueInfo).currentValue); case QCameraImageProcessingControl::ContrastAdjustment: // falling back case QCameraImageProcessingControl::SaturationAdjustment: // falling back case QCameraImageProcessingControl::BrightnessAdjustment: // falling back case QCameraImageProcessingControl::SharpeningAdjustment: - return scaledImageProcessingParameterValue( - sourceValue, (*sourceValueInfo)); + return scaledImageProcessingParameterValue((*sourceValueInfo)); default: return QVariant(); @@ -1032,7 +1002,7 @@ void DSCameraSession::updateImageProcessingParametersInfos() ImageProcessingParameterInfo sourceValueInfo; LONG steppingDelta = 0; - const HRESULT hr = pVideoProcAmp->GetRange( + HRESULT hr = pVideoProcAmp->GetRange( property, &sourceValueInfo.minimumValue, &sourceValueInfo.maximumValue, @@ -1043,6 +1013,14 @@ void DSCameraSession::updateImageProcessingParametersInfos() if (FAILED(hr)) continue; + hr = pVideoProcAmp->Get( + property, + &sourceValueInfo.currentValue, + &sourceValueInfo.capsFlags); + + if (FAILED(hr)) + continue; + sourceValueInfo.videoProcAmpProperty = static_cast(property); m_imageProcessingParametersInfos.insert(processingParameter, sourceValueInfo); diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h index 619a006fa..768e3583a 100644 --- a/src/plugins/directshow/camera/dscamerasession.h +++ b/src/plugins/directshow/camera/dscamerasession.h @@ -161,7 +161,7 @@ private: // These static functions are used for scaling of adjustable parameters, // which have the ranges from -1.0 to +1.0 in the QCameraImageProcessing API. static qreal scaledImageProcessingParameterValue( - qint32 sourceValue, const ImageProcessingParameterInfo &sourceValueInfo); + const ImageProcessingParameterInfo &sourceValueInfo); static qint32 sourceImageProcessingParameterValue( qreal scaledValue, const ImageProcessingParameterInfo &sourceValueInfo); -- cgit v1.2.3