summaryrefslogtreecommitdiffstats
path: root/src/plugins/directshow
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/directshow')
-rw-r--r--src/plugins/directshow/camera/camera.pri12
-rw-r--r--src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.cpp65
-rw-r--r--src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.h60
-rw-r--r--src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.cpp68
-rw-r--r--src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.h66
-rw-r--r--src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp411
-rw-r--r--src/plugins/directshow/camera/directshowcameraexposurecontrol.h100
-rw-r--r--src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp209
-rw-r--r--src/plugins/directshow/camera/directshowcamerazoomcontrol.h88
-rw-r--r--src/plugins/directshow/camera/dscameraservice.cpp56
-rw-r--r--src/plugins/directshow/camera/dscameraservice.h12
-rw-r--r--src/plugins/directshow/camera/dscamerasession.cpp78
-rw-r--r--src/plugins/directshow/camera/dscamerasession.h18
-rw-r--r--src/plugins/directshow/camera/dsimagecapturecontrol.cpp2
-rw-r--r--src/plugins/directshow/directshow.pro8
-rw-r--r--src/plugins/directshow/dsserviceplugin.cpp6
-rw-r--r--src/plugins/directshow/player/directshowvideorenderercontrol.cpp4
17 files changed, 1236 insertions, 27 deletions
diff --git a/src/plugins/directshow/camera/camera.pri b/src/plugins/directshow/camera/camera.pri
index d8ee59aa9..0e1c1e895 100644
--- a/src/plugins/directshow/camera/camera.pri
+++ b/src/plugins/directshow/camera/camera.pri
@@ -11,7 +11,11 @@ HEADERS += \
$$PWD/dscamerasession.h \
$$PWD/directshowcameraglobal.h \
$$PWD/dscameraviewfindersettingscontrol.h \
- $$PWD/dscameraimageprocessingcontrol.h
+ $$PWD/dscameraimageprocessingcontrol.h \
+ $$PWD/directshowcameraexposurecontrol.h \
+ $$PWD/directshowcameracapturedestinationcontrol.h \
+ $$PWD/directshowcameracapturebufferformatcontrol.h \
+ $$PWD/directshowcamerazoomcontrol.h
SOURCES += \
$$PWD/dscameraservice.cpp \
@@ -21,7 +25,11 @@ SOURCES += \
$$PWD/dsimagecapturecontrol.cpp \
$$PWD/dscamerasession.cpp \
$$PWD/dscameraviewfindersettingscontrol.cpp \
- $$PWD/dscameraimageprocessingcontrol.cpp
+ $$PWD/dscameraimageprocessingcontrol.cpp \
+ $$PWD/directshowcameraexposurecontrol.cpp \
+ $$PWD/directshowcameracapturedestinationcontrol.cpp \
+ $$PWD/directshowcameracapturebufferformatcontrol.cpp \
+ $$PWD/directshowcamerazoomcontrol.cpp
*-msvc*:INCLUDEPATH += $$(DXSDK_DIR)/include
QMAKE_USE += directshow
diff --git a/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.cpp b/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.cpp
new file mode 100644
index 000000000..cc0a0ad17
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "directshowcameracapturebufferformatcontrol.h"
+
+#include "dscamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+DirectShowCameraCaptureBufferFormatControl::DirectShowCameraCaptureBufferFormatControl()
+{
+}
+
+QList<QVideoFrame::PixelFormat> DirectShowCameraCaptureBufferFormatControl::supportedBufferFormats() const
+{
+ return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_RGB32;
+}
+
+QVideoFrame::PixelFormat DirectShowCameraCaptureBufferFormatControl::bufferFormat() const
+{
+ return QVideoFrame::Format_RGB32;
+}
+
+void DirectShowCameraCaptureBufferFormatControl::setBufferFormat(QVideoFrame::PixelFormat format)
+{
+ Q_UNUSED(format);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.h b/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.h
new file mode 100644
index 000000000..cacd3652b
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DIRECTSHOWCAMERACAPTUREBUFFERFORMATCONTROL_H
+#define DIRECTSHOWCAMERACAPTUREBUFFERFORMATCONTROL_H
+
+#include <QtMultimedia/qcameracapturebufferformatcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class DirectShowCameraCaptureBufferFormatControl : public QCameraCaptureBufferFormatControl
+{
+ Q_OBJECT
+public:
+ DirectShowCameraCaptureBufferFormatControl();
+
+ QList<QVideoFrame::PixelFormat> supportedBufferFormats() const override;
+ QVideoFrame::PixelFormat bufferFormat() const override;
+ void setBufferFormat(QVideoFrame::PixelFormat format) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // DIRECTSHOWCAMERACAPTUREBUFFERFORMATCONTROL_H
diff --git a/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.cpp b/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.cpp
new file mode 100644
index 000000000..bfb10fc03
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "directshowcameracapturedestinationcontrol.h"
+
+#include "dscamerasession.h"
+
+QT_BEGIN_NAMESPACE
+
+DirectShowCameraCaptureDestinationControl::DirectShowCameraCaptureDestinationControl(DSCameraSession *session)
+ : m_session(session)
+{
+ connect(m_session, &DSCameraSession::captureDestinationChanged,
+ this, &DirectShowCameraCaptureDestinationControl::captureDestinationChanged);
+}
+
+bool DirectShowCameraCaptureDestinationControl::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+{
+ return m_session->isCaptureDestinationSupported(destination);
+}
+
+QCameraImageCapture::CaptureDestinations DirectShowCameraCaptureDestinationControl::captureDestination() const
+{
+ return m_session->captureDestination();
+}
+
+void DirectShowCameraCaptureDestinationControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination)
+{
+ m_session->setCaptureDestination(destination);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.h b/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.h
new file mode 100644
index 000000000..224df9dbc
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DIRECTSHOWCAMERACAPTUREDESTINATIONCONTROL_H
+#define DIRECTSHOWCAMERACAPTUREDESTINATIONCONTROL_H
+
+#include <QtMultimedia/qcameracapturedestinationcontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class DSCameraSession;
+
+class DirectShowCameraCaptureDestinationControl : public QCameraCaptureDestinationControl
+{
+ Q_OBJECT
+public:
+ DirectShowCameraCaptureDestinationControl(DSCameraSession *session);
+
+ bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const override;
+ QCameraImageCapture::CaptureDestinations captureDestination() const override;
+ void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) override;
+
+private:
+ DSCameraSession *m_session;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // DIRECTSHOWCAMERACAPTUREDESTINATIONCONTROL_H
diff --git a/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp b/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp
new file mode 100644
index 000000000..7ece366ea
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp
@@ -0,0 +1,411 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "directshowcameraexposurecontrol.h"
+#include "dscamerasession.h"
+#include "directshowglobal.h"
+#include "directshowutils.h"
+
+#include <functional>
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+static qreal convertToSec(long v) { return (v < 0) ? (1 / std::pow(2., qreal(v))) : std::pow(2., qreal(v)); }
+static Q_DECL_CONSTEXPR qreal convertToFvalue(long v) { return qreal(v) / 10.; }
+
+DirectShowCameraExposureControl::DirectShowCameraExposureControl(DSCameraSession *session)
+ : m_session(session)
+ , m_shutterSpeedValues({ 0, 0, 0, 0, 0 })
+ , m_apertureValues({ 0, 0, 0, 0, 0 })
+ , m_requestedShutterSpeed(qreal(0.0))
+ , m_currentShutterSpeed(qreal(-1.0))
+ , m_requestedAperture(qreal(0.0))
+ , m_currentAperture(qreal(-1.0))
+ , m_requestedExposureMode(QCameraExposure::ExposureAuto)
+ , m_currentExposureMode(QCameraExposure::ExposureAuto)
+{
+ Q_ASSERT(m_session);
+ connect(m_session, &DSCameraSession::statusChanged,
+ this, &DirectShowCameraExposureControl::onStatusChanged);
+}
+
+bool DirectShowCameraExposureControl::isParameterSupported(QCameraExposureControl::ExposureParameter parameter) const
+{
+ if (parameter == ShutterSpeed)
+ return (m_shutterSpeedValues.caps & CameraControl_Flags_Manual);
+ if (parameter == Aperture)
+ return (m_apertureValues.caps & CameraControl_Flags_Manual);
+ if (parameter == ExposureMode)
+ return true;
+
+ return false;
+}
+
+QVariantList DirectShowCameraExposureControl::supportedParameterRange(QCameraExposureControl::ExposureParameter parameter,
+ bool *continuous) const
+{
+ if (continuous)
+ *continuous = false;
+
+ if (parameter == ShutterSpeed)
+ return m_supportedShutterSpeeds;
+
+ if (parameter == Aperture)
+ return m_supportedApertureValues;
+
+ if (parameter == ExposureMode)
+ return m_supportedExposureModes;
+
+ return QVariantList();
+}
+
+QVariant DirectShowCameraExposureControl::requestedValue(QCameraExposureControl::ExposureParameter parameter) const
+{
+ if (parameter == ShutterSpeed)
+ return QVariant::fromValue(m_requestedShutterSpeed);
+
+ if (parameter == Aperture)
+ return QVariant::fromValue(m_requestedAperture);
+
+ if (parameter == ExposureMode)
+ return QVariant::fromValue(m_requestedExposureMode);
+
+ return QVariant();
+}
+
+QVariant DirectShowCameraExposureControl::actualValue(QCameraExposureControl::ExposureParameter parameter) const
+{
+ if (parameter == ExposureMode)
+ return QVariant::fromValue(m_currentExposureMode);
+
+ if (parameter == ShutterSpeed) {
+ return qFuzzyCompare(m_currentShutterSpeed, qreal(-1.0))
+ ? QVariant()
+ : QVariant::fromValue(m_currentShutterSpeed);
+ }
+
+ if (parameter == Aperture) {
+ return qFuzzyCompare(m_currentAperture, qreal(-1.0))
+ ? QVariant()
+ : QVariant::fromValue(m_currentAperture);
+ }
+
+ return QVariant();
+}
+
+bool DirectShowCameraExposureControl::setValue(QCameraExposureControl::ExposureParameter parameter,
+ const QVariant &value)
+{
+ IAMCameraControl *cameraControl = nullptr;
+ const DirectShowUtils::ScopedSafeRelease<IAMCameraControl> rControl { &cameraControl };
+ if (!m_session->getCameraControlInterface(&cameraControl))
+ return false;
+
+ // Reset exposure mode if the value is invalid.
+ if (!value.isValid()) {
+ m_requestedExposureMode = QCameraExposure::ExposureAuto;
+ return setExposureMode(cameraControl, m_requestedExposureMode);
+ }
+
+ if (parameter == ShutterSpeed || parameter == Aperture) {
+ bool ok = false;
+ const qreal newValue = value.toReal(&ok);
+ if (!ok)
+ return false;
+
+ // Change the exposure mode first
+ setExposureMode(cameraControl, QCameraExposure::ExposureManual);
+
+ if (parameter == ShutterSpeed) {
+ m_requestedShutterSpeed = newValue;
+ return setShutterSpeed(cameraControl, m_requestedShutterSpeed);
+ } else {
+ m_requestedAperture = newValue;
+ return setAperture(cameraControl, m_requestedAperture);
+ }
+ }
+
+ if (parameter == ExposureMode) {
+ m_requestedExposureMode = value.value<QCameraExposure::ExposureMode>();
+ return setExposureMode(cameraControl, m_requestedExposureMode);
+ }
+
+ return false;
+}
+
+void DirectShowCameraExposureControl::onStatusChanged(QCamera::Status status)
+{
+ const bool shouldUpdate = (qFuzzyCompare(m_currentAperture, qreal(-1.0)) && qFuzzyCompare(m_currentShutterSpeed, qreal(-1.0)));
+
+ if (status == QCamera::LoadedStatus && shouldUpdate)
+ updateExposureSettings();
+
+ if (status == QCamera::UnloadedStatus) {
+ m_supportedApertureValues.clear();
+ m_supportedExposureModes.clear();
+ m_supportedShutterSpeeds.clear();
+ m_currentAperture = qreal(-1.0);
+ m_currentShutterSpeed = qreal(-1.0);
+ m_currentExposureMode = QCameraExposure::ExposureAuto;
+ }
+}
+
+void DirectShowCameraExposureControl::updateExposureSettings()
+{
+ IAMCameraControl *cameraControl = nullptr;
+ const DirectShowUtils::ScopedSafeRelease<IAMCameraControl> rControl { &cameraControl };
+ if (!m_session->getCameraControlInterface(&cameraControl))
+ return;
+
+ const auto updateValues = [cameraControl](long property,
+ ExposureValues &currentValues,
+ QVariantList &parameterRange,
+ const std::function<qreal(long)> &converter,
+ bool *changed) -> bool {
+ ExposureValues values { 0, 0, 0, 0, 0 };
+ if (FAILED(cameraControl->GetRange(property,
+ &values.minValue,
+ &values.maxValue,
+ &values.stepping,
+ &values.defaultValue,
+ &values.caps))) {
+ return false;
+ }
+
+ const bool minValueChanged = values.minValue != currentValues.minValue;
+ const bool maxValueChanged = values.maxValue != currentValues.maxValue;
+ const bool steppingChanged = values.stepping != currentValues.stepping;
+
+ if (minValueChanged || maxValueChanged || steppingChanged) {
+ parameterRange.clear();
+ long nextValue = values.minValue;
+ while (nextValue != values.maxValue && values.stepping != 0) {
+ parameterRange << converter(nextValue);
+ nextValue += values.stepping;
+ }
+
+ if (changed)
+ *changed = true;
+ }
+
+ currentValues = values;
+ return true;
+ };
+
+ const auto getCurrentValue = [cameraControl](long property, const std::function<qreal(long)> &converter, qreal *value) -> bool {
+ long currentValue;
+ long currentFlags;
+ if (FAILED(cameraControl->Get(property, &currentValue, &currentFlags)))
+ return false;
+
+ *value = converter(currentValue);
+ return true;
+ };
+
+ // Shutter speed
+ bool changed = false;
+ if (!updateValues(CameraControl_Exposure, m_shutterSpeedValues, m_supportedShutterSpeeds, convertToSec, &changed))
+ qCDebug(qtDirectShowPlugin, "Unable to update the shutter speed values");
+
+ if (changed)
+ Q_EMIT parameterRangeChanged(int(ShutterSpeed));
+
+ if ((m_shutterSpeedValues.caps & CameraControl_Flags_Manual)) {
+ if (getCurrentValue(CameraControl_Exposure, convertToSec, &m_currentShutterSpeed)) {
+ if (m_currentExposureMode == QCameraExposure::ExposureManual)
+ setShutterSpeed(cameraControl, m_requestedShutterSpeed);
+ } else {
+ m_currentShutterSpeed = qreal(-1.0);
+ qCDebug(qtDirectShowPlugin, "Unable to get the current shutter speed!");
+ }
+ }
+
+ // Aperture
+ changed = false;
+ if (!updateValues(CameraControl_Iris, m_apertureValues, m_supportedApertureValues, convertToFvalue, &changed))
+ qCDebug(qtDirectShowPlugin, "Unable to update the aperture values");
+
+ if (changed)
+ Q_EMIT parameterRangeChanged(int(Aperture));
+
+ if (getCurrentValue(CameraControl_Iris, convertToFvalue, &m_currentAperture)) {
+ if (m_currentExposureMode == QCameraExposure::ExposureManual)
+ setAperture(cameraControl, m_requestedAperture);
+ } else {
+ m_currentAperture = qreal(-1.0);
+ qCDebug(qtDirectShowPlugin, "Unable to get the current aperture value!");
+ }
+
+ // Update exposure modes
+ const bool hasAutoExposure = (m_apertureValues.caps & CameraControl_Flags_Auto)
+ || (m_shutterSpeedValues.caps & CameraControl_Flags_Auto);
+ const bool hasManualExposure = (m_apertureValues.caps & CameraControl_Flags_Manual)
+ || (m_shutterSpeedValues.caps & CameraControl_Flags_Manual);
+
+ QVariantList exposureModes;
+ if (hasAutoExposure && !m_supportedExposureModes.contains(QVariant::fromValue(QCameraExposure::ExposureAuto)))
+ exposureModes << QVariant::fromValue(QCameraExposure::ExposureAuto);
+
+ if (hasManualExposure && !m_supportedExposureModes.contains(QVariant::fromValue(QCameraExposure::ExposureManual)))
+ exposureModes << QVariant::fromValue(QCameraExposure::ExposureManual);
+
+ if (!exposureModes.isEmpty() || !m_supportedExposureModes.isEmpty()) {
+ m_supportedExposureModes = exposureModes;
+ Q_EMIT parameterRangeChanged(int(ExposureMode));
+ }
+}
+
+bool DirectShowCameraExposureControl::setShutterSpeed(IAMCameraControl *cameraControl, qreal shutterSpeed)
+{
+ if (m_currentExposureMode != QCameraExposure::ExposureManual) {
+ qCDebug(qtDirectShowPlugin, "Trying to set shutter speed value while in auto exposure mode!");
+ return false;
+ }
+
+ if (qFuzzyCompare(m_currentShutterSpeed, shutterSpeed))
+ return true;
+
+ if ((m_shutterSpeedValues.caps & CameraControl_Flags_Manual) == 0)
+ return false;
+
+ if (!m_supportedShutterSpeeds.contains(QVariant::fromValue(shutterSpeed)))
+ return false;
+
+ if (qFuzzyIsNull(shutterSpeed) || (shutterSpeed < qreal(0.0)))
+ return false;
+
+ const long newValue = long(log2(shutterSpeed));
+ if (FAILED(cameraControl->Set(CameraControl_Exposure, newValue, CameraControl_Flags_Manual))) {
+ qCDebug(qtDirectShowPlugin, "Unable to set shutter speed value to: %d", int(shutterSpeed));
+ return false;
+ }
+
+ m_currentShutterSpeed = shutterSpeed;
+ Q_EMIT actualValueChanged(int(ShutterSpeed));
+ return true;
+}
+
+bool DirectShowCameraExposureControl::setAperture(IAMCameraControl *cameraControl, qreal aperture)
+{
+ if (m_currentExposureMode != QCameraExposure::ExposureManual) {
+ qCDebug(qtDirectShowPlugin, "Trying to set aperture value while in auto exposure mode!");
+ return false;
+ }
+
+ if (qFuzzyCompare(m_currentAperture, aperture))
+ return true;
+
+ if ((m_apertureValues.caps & CameraControl_Flags_Manual) == 0)
+ return false;
+
+ if (!m_supportedApertureValues.contains(QVariant::fromValue(aperture)))
+ return false;
+
+ if (aperture < qreal(0.0))
+ return false;
+
+ const long newValue = long(10 * aperture);
+ if (FAILED(cameraControl->Set(CameraControl_Iris, newValue, CameraControl_Flags_Manual))) {
+ qCDebug(qtDirectShowPlugin, "Unable to set aperture value to: %d", int(aperture));
+ return false;
+ }
+
+ m_currentAperture = aperture;
+ Q_EMIT actualValueChanged(int(Aperture));
+
+ return true;
+}
+
+bool DirectShowCameraExposureControl::setExposureMode(IAMCameraControl *cameraControl, QCameraExposure::ExposureMode mode)
+{
+ if (m_currentExposureMode == mode)
+ return true;
+
+ bool exposureModeChanged = true;
+
+ // Set auto exposure mode
+ if (mode == QCameraExposure::ExposureAuto) {
+ if ((m_apertureValues.caps & CameraControl_Flags_Auto)
+ && FAILED(cameraControl->Set(CameraControl_Iris, 0, CameraControl_Flags_Auto))) {
+ qCDebug(qtDirectShowPlugin, "Setting auto exposure mode failed!");
+ exposureModeChanged = false;
+ }
+
+ if ((m_shutterSpeedValues.caps & CameraControl_Flags_Auto)
+ && FAILED(cameraControl->Set(CameraControl_Exposure, 0, CameraControl_Flags_Auto))) {
+ qCDebug(qtDirectShowPlugin, "Setting auto exposure mode failed");
+ exposureModeChanged = false;
+ }
+
+ if (exposureModeChanged) {
+ m_currentExposureMode = mode;
+ Q_EMIT actualValueChanged(int(ExposureMode));
+ }
+
+ return exposureModeChanged;
+ }
+
+ // Change the current exposure mode to manual first.
+ m_currentExposureMode = QCameraExposure::ExposureManual;
+
+ const qreal newShutterSpeed = qFuzzyCompare(m_requestedShutterSpeed, -1.0)
+ ? convertToSec(m_shutterSpeedValues.defaultValue)
+ : m_requestedShutterSpeed;
+ if ((m_shutterSpeedValues.caps & CameraControl_Flags_Manual))
+ setShutterSpeed(cameraControl, newShutterSpeed);
+
+ const qreal newAperture = qFuzzyCompare(m_requestedAperture, -1.0)
+ ? convertToFvalue(m_apertureValues.defaultValue)
+ : m_requestedAperture;
+ if ((m_apertureValues.caps & CameraControl_Flags_Manual))
+ setAperture(cameraControl, newAperture);
+
+
+ // Check if any of the values changed.
+ exposureModeChanged = (qFuzzyCompare(m_currentShutterSpeed, newShutterSpeed)
+ || qFuzzyCompare(m_currentAperture, newAperture));
+
+ if (exposureModeChanged)
+ Q_EMIT actualValueChanged(int(ExposureMode));
+
+ return exposureModeChanged;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/directshowcameraexposurecontrol.h b/src/plugins/directshow/camera/directshowcameraexposurecontrol.h
new file mode 100644
index 000000000..db3fc5984
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameraexposurecontrol.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DIRECTSHOWCAMERAEXPOSURECONTROL_H
+#define DIRECTSHOWCAMERAEXPOSURECONTROL_H
+
+#include <QtMultimedia/qcameraexposurecontrol.h>
+
+struct IAMCameraControl;
+
+QT_BEGIN_NAMESPACE
+
+class DSCameraSession;
+
+class DirectShowCameraExposureControl : public QCameraExposureControl
+{
+ Q_OBJECT
+public:
+ DirectShowCameraExposureControl(DSCameraSession *session);
+
+ bool isParameterSupported(ExposureParameter parameter) const override;
+ QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const override;
+ QVariant requestedValue(ExposureParameter parameter) const override;
+ QVariant actualValue(ExposureParameter parameter) const override;
+ bool setValue(ExposureParameter parameter, const QVariant &value) override;
+
+private Q_SLOTS:
+ void onStatusChanged(QCamera::Status status);
+
+private:
+ DSCameraSession *m_session;
+
+ struct ExposureValues
+ {
+ long caps;
+ long minValue;
+ long maxValue;
+ long stepping;
+ long defaultValue;
+ } m_shutterSpeedValues, m_apertureValues;
+
+ qreal m_requestedShutterSpeed;
+ qreal m_currentShutterSpeed;
+
+ qreal m_requestedAperture;
+ qreal m_currentAperture;
+
+ QVariantList m_supportedShutterSpeeds;
+ QVariantList m_supportedApertureValues;
+ QVariantList m_supportedExposureModes;
+
+ QCameraExposure::ExposureMode m_requestedExposureMode;
+ QCameraExposure::ExposureMode m_currentExposureMode;
+
+ void updateExposureSettings();
+
+ bool setShutterSpeed(IAMCameraControl *cameraControl, qreal shutterSpeed);
+ bool setAperture(IAMCameraControl *cameraControl, qreal aperture);
+ bool setExposureMode(IAMCameraControl *cameraControl, QCameraExposure::ExposureMode mode);
+};
+
+QT_END_NAMESPACE
+
+#endif // DIRECTSHOWCAMERAEXPOSURECONTROL_H
diff --git a/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp b/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp
new file mode 100644
index 000000000..209cb5d96
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "directshowcamerazoomcontrol.h"
+#include "dscamerasession.h"
+#include "directshowutils.h"
+
+QT_BEGIN_NAMESPACE
+
+inline static qreal defaultZoomValue() { return qreal(1.0); }
+
+DirectShowCameraZoomControl::DirectShowCameraZoomControl(DSCameraSession *session)
+ : m_session(session)
+ , m_opticalZoom({0, 0, 0, 0, 0})
+ , m_currentOpticalZoom(qreal(0.0))
+ , m_requestedOpticalZoom(qreal(0.0))
+ , m_maxOpticalZoom(qreal(1.0))
+{
+ Q_ASSERT(m_session);
+ connect(m_session, &DSCameraSession::statusChanged,
+ this, &DirectShowCameraZoomControl::onStatusChanged);
+}
+
+qreal DirectShowCameraZoomControl::maximumOpticalZoom() const
+{
+ return m_maxOpticalZoom;
+}
+
+qreal DirectShowCameraZoomControl::maximumDigitalZoom() const
+{
+ return defaultZoomValue();
+}
+
+qreal DirectShowCameraZoomControl::requestedOpticalZoom() const
+{
+ return qMax(defaultZoomValue(), m_requestedOpticalZoom);
+}
+
+qreal DirectShowCameraZoomControl::requestedDigitalZoom() const
+{
+ return defaultZoomValue();
+}
+
+qreal DirectShowCameraZoomControl::currentOpticalZoom() const
+{
+ return qMax(defaultZoomValue(), m_currentOpticalZoom);
+}
+
+qreal DirectShowCameraZoomControl::currentDigitalZoom() const
+{
+ return defaultZoomValue();
+}
+
+void DirectShowCameraZoomControl::zoomTo(qreal optical, qreal digital)
+{
+ Q_UNUSED(digital);
+ if (!(m_opticalZoom.caps & CameraControl_Flags_Manual))
+ return;
+
+ if (qFuzzyCompare(optical, m_requestedOpticalZoom))
+ return;
+
+ m_requestedOpticalZoom = optical;
+ Q_EMIT requestedOpticalZoomChanged(m_requestedOpticalZoom);
+
+ if (qFuzzyCompare(m_requestedOpticalZoom, m_currentOpticalZoom))
+ return;
+
+ if (m_session->status() != QCamera::LoadedStatus && m_session->status() != QCamera::ActiveStatus)
+ return; // We'll wait until the camera is loaded, see: statusChanged connection
+
+ opticalZoomToPrivate(optical);
+}
+
+void DirectShowCameraZoomControl::onStatusChanged(QCamera::Status status)
+{
+ if (status == QCamera::LoadedStatus) {
+ updateZoomValues();
+ } else if (status == QCamera::UnloadedStatus) {
+ SecureZeroMemory(&m_opticalZoom, sizeof(ZoomValues));
+ m_currentOpticalZoom = qreal(0.0);
+ m_requestedOpticalZoom = qreal(0.0);
+ }
+
+}
+
+void DirectShowCameraZoomControl::updateZoomValues()
+{
+ IAMCameraControl *cameraControl = nullptr;
+ const DirectShowUtils::ScopedSafeRelease<IAMCameraControl> rControl { &cameraControl };
+ if (!m_session->getCameraControlInterface(&cameraControl))
+ return;
+
+ ZoomValues values { 0, 0, 0, 0, 0 };
+ // Zoom levels in DS are in the range [10, 600]
+ // The default zoom is device specific.
+ HRESULT hr = cameraControl->GetRange(CameraControl_Zoom,
+ &values.minZoom,
+ &values.maxZoom,
+ &values.stepping,
+ &values.defaultZoom,
+ &values.caps);
+
+ if (FAILED(hr)) {
+ qCDebug(qtDirectShowPlugin, "Getting the camera's zoom properties failed");
+ SecureZeroMemory(&m_opticalZoom, sizeof(ZoomValues));
+ return;
+ }
+
+ if (!(values.caps & CameraControl_Flags_Manual)) {
+ qCDebug(qtDirectShowPlugin, "Camera does not support manual zoom");
+ SecureZeroMemory(&m_opticalZoom, sizeof(ZoomValues));
+ return;
+ }
+
+ if (values.maxZoom != m_opticalZoom.maxZoom) {
+ const qreal newMaxZoomScale = (values.minZoom == 0) ? defaultZoomValue()
+ : (qreal(values.maxZoom) / qreal(values.minZoom));
+ if (!qFuzzyCompare(newMaxZoomScale, m_maxOpticalZoom)) {
+ m_maxOpticalZoom = newMaxZoomScale;
+ Q_EMIT maximumOpticalZoomChanged(m_maxOpticalZoom);
+ }
+ }
+
+ m_opticalZoom = values;
+
+ long currentZoom = 0;
+ long flags = 0;
+ if (FAILED(cameraControl->Get(CameraControl_Zoom, &currentZoom, &flags))) {
+ qCDebug(qtDirectShowPlugin, "Getting the camera's current zoom value failed!");
+ return;
+ }
+
+ qreal currentOpticalZoom = (m_opticalZoom.minZoom == 0) ? defaultZoomValue()
+ : (qreal(currentZoom) / qreal(m_opticalZoom.minZoom));
+ currentOpticalZoom = qMax(defaultZoomValue(), currentOpticalZoom);
+ if (!qFuzzyCompare(m_currentOpticalZoom, currentOpticalZoom)) {
+ m_currentOpticalZoom = currentOpticalZoom;
+ Q_EMIT currentOpticalZoomChanged(m_currentOpticalZoom);
+ }
+
+ // Check if there is a pending zoom value.
+ if (!qFuzzyCompare(m_currentOpticalZoom, m_requestedOpticalZoom))
+ opticalZoomToPrivate(m_requestedOpticalZoom);
+}
+
+bool DirectShowCameraZoomControl::opticalZoomToPrivate(qreal scaleFactor)
+{
+ IAMCameraControl *cameraControl = nullptr;
+ const DirectShowUtils::ScopedSafeRelease<IAMCameraControl> rControl { &cameraControl };
+ if (!m_session->getCameraControlInterface(&cameraControl))
+ return false;
+
+ // Convert to DS zoom value
+ const int newDSOpticalZoom = qRound(m_opticalZoom.minZoom * scaleFactor);
+ long newDSOpticalZoomAdjusted = newDSOpticalZoom - (newDSOpticalZoom % m_opticalZoom.stepping);
+ newDSOpticalZoomAdjusted = qBound(m_opticalZoom.minZoom, newDSOpticalZoomAdjusted, m_opticalZoom.maxZoom);
+
+ if (FAILED(cameraControl->Set(CameraControl_Zoom, newDSOpticalZoomAdjusted, CameraControl_Flags_Manual))) {
+ qCDebug(qtDirectShowPlugin, "Setting the camera's zoom value failed");
+ return false;
+ }
+
+ const qreal newScaleFactor = (m_opticalZoom.minZoom == 0) ? defaultZoomValue()
+ : (qreal(newDSOpticalZoomAdjusted) / qreal(m_opticalZoom.minZoom));
+ // convert back to Qt scale value
+ m_currentOpticalZoom = qMax(defaultZoomValue(), newScaleFactor);
+ Q_EMIT currentOpticalZoomChanged(m_currentOpticalZoom);
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/directshowcamerazoomcontrol.h b/src/plugins/directshow/camera/directshowcamerazoomcontrol.h
new file mode 100644
index 000000000..f6fb05b0e
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcamerazoomcontrol.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DIRECTSHOWCAMERAZOOMCONTROL_H
+#define DIRECTSHOWCAMERAZOOMCONTROL_H
+
+#include <QtMultimedia/qcamerazoomcontrol.h>
+#include <QtMultimedia/qcamera.h>
+
+QT_BEGIN_NAMESPACE
+
+class DSCameraSession;
+
+class DirectShowCameraZoomControl : public QCameraZoomControl
+{
+ Q_OBJECT
+public:
+ DirectShowCameraZoomControl(DSCameraSession *session);
+
+ qreal maximumOpticalZoom() const override;
+ qreal maximumDigitalZoom() const override;
+ qreal requestedOpticalZoom() const override;
+ qreal requestedDigitalZoom() const override;
+ qreal currentOpticalZoom() const override;
+ qreal currentDigitalZoom() const override;
+ void zoomTo(qreal optical, qreal digital) override;
+
+private Q_SLOTS:
+ void onStatusChanged(QCamera::Status status);
+
+private:
+ DSCameraSession *m_session;
+ struct ZoomValues
+ {
+ long maxZoom;
+ long minZoom;
+ long stepping;
+ long defaultZoom;
+ long caps;
+ } m_opticalZoom;
+
+ qreal m_currentOpticalZoom;
+ qreal m_requestedOpticalZoom;
+ qreal m_maxOpticalZoom;
+
+ void updateZoomValues();
+ bool opticalZoomToPrivate(qreal value);
+};
+
+QT_END_NAMESPACE
+
+#endif // DIRECTSHOWCAMERAZOOMCONTROL_H
diff --git a/src/plugins/directshow/camera/dscameraservice.cpp b/src/plugins/directshow/camera/dscameraservice.cpp
index 836f1aaa5..a806cabe3 100644
--- a/src/plugins/directshow/camera/dscameraservice.cpp
+++ b/src/plugins/directshow/camera/dscameraservice.cpp
@@ -48,19 +48,29 @@
#include "dsimagecapturecontrol.h"
#include "dscameraviewfindersettingscontrol.h"
#include "dscameraimageprocessingcontrol.h"
+#include "directshowcameraexposurecontrol.h"
+#include "directshowcameracapturedestinationcontrol.h"
+#include "directshowcameracapturebufferformatcontrol.h"
+#include "directshowvideoprobecontrol.h"
+#include "directshowcamerazoomcontrol.h"
QT_BEGIN_NAMESPACE
DSCameraService::DSCameraService(QObject *parent):
QMediaService(parent)
+ , m_session(new DSCameraSession(this))
+ , m_control(new DSCameraControl(m_session))
+ , m_videoDevice(new DSVideoDeviceControl(m_session))
, m_videoRenderer(0)
+ , m_imageCapture(new DSImageCaptureControl(m_session))
+ , m_viewfinderSettings(new DSCameraViewfinderSettingsControl(m_session))
+ , m_imageProcessingControl(new DSCameraImageProcessingControl(m_session))
+ , m_exposureControl(new DirectShowCameraExposureControl(m_session))
+ , m_captureDestinationControl(new DirectShowCameraCaptureDestinationControl(m_session))
+ , m_captureBufferFormatControl(new DirectShowCameraCaptureBufferFormatControl)
+ , m_videoProbeControl(nullptr)
+ , m_zoomControl(new DirectShowCameraZoomControl(m_session))
{
- m_session = new DSCameraSession(this);
- m_control = new DSCameraControl(m_session);
- 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()
@@ -72,6 +82,11 @@ DSCameraService::~DSCameraService()
delete m_videoRenderer;
delete m_imageCapture;
delete m_session;
+ delete m_exposureControl;
+ delete m_captureDestinationControl;
+ delete m_captureBufferFormatControl;
+ delete m_videoProbeControl;
+ delete m_zoomControl;
}
QMediaControl* DSCameraService::requestControl(const char *name)
@@ -98,6 +113,27 @@ QMediaControl* DSCameraService::requestControl(const char *name)
if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0)
return m_imageProcessingControl;
+ if (qstrcmp(name, QCameraExposureControl_iid) == 0)
+ return m_exposureControl;
+
+ if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0)
+ return m_captureDestinationControl;
+
+ if (qstrcmp(name, QCameraCaptureBufferFormatControl_iid) == 0)
+ return m_captureBufferFormatControl;
+
+ if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) {
+ if (!m_videoProbeControl)
+ m_videoProbeControl = new DirectShowVideoProbeControl;
+
+ m_videoProbeControl->ref();
+ m_session->addVideoProbe(m_videoProbeControl);
+ return m_videoProbeControl;
+ }
+
+ if (qstrcmp(name, QCameraZoomControl_iid) == 0)
+ return m_zoomControl;
+
return 0;
}
@@ -108,6 +144,14 @@ void DSCameraService::releaseControl(QMediaControl *control)
m_videoRenderer = 0;
return;
}
+
+ if (control == m_videoProbeControl) {
+ m_session->removeVideoProbe(m_videoProbeControl);
+ if (!m_videoProbeControl->deref()) {
+ delete m_videoProbeControl;
+ m_videoProbeControl = nullptr;
+ }
+ }
}
QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/dscameraservice.h b/src/plugins/directshow/camera/dscameraservice.h
index 8976e41cf..f444eeb51 100644
--- a/src/plugins/directshow/camera/dscameraservice.h
+++ b/src/plugins/directshow/camera/dscameraservice.h
@@ -52,6 +52,11 @@ class DSVideoDeviceControl;
class DSImageCaptureControl;
class DSCameraViewfinderSettingsControl;
class DSCameraImageProcessingControl;
+class DirectShowCameraExposureControl;
+class DirectShowCameraCaptureDestinationControl;
+class DirectShowCameraCaptureBufferFormatControl;
+class DirectShowVideoProbeControl;
+class DirectShowCameraZoomControl;
class DSCameraService : public QMediaService
{
@@ -65,13 +70,18 @@ public:
virtual void releaseControl(QMediaControl *control);
private:
- DSCameraControl *m_control;
DSCameraSession *m_session;
+ DSCameraControl *m_control;
DSVideoDeviceControl *m_videoDevice;
QMediaControl *m_videoRenderer;
DSImageCaptureControl *m_imageCapture;
DSCameraViewfinderSettingsControl *m_viewfinderSettings;
DSCameraImageProcessingControl *m_imageProcessingControl;
+ DirectShowCameraExposureControl *m_exposureControl;
+ DirectShowCameraCaptureDestinationControl *m_captureDestinationControl;
+ DirectShowCameraCaptureBufferFormatControl *m_captureBufferFormatControl;
+ DirectShowVideoProbeControl *m_videoProbeControl;
+ DirectShowCameraZoomControl *m_zoomControl;
};
QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp
index dc0dfc8b3..9b642872a 100644
--- a/src/plugins/directshow/camera/dscamerasession.cpp
+++ b/src/plugins/directshow/camera/dscamerasession.cpp
@@ -51,24 +51,27 @@
#include "directshowcameraglobal.h"
#include "directshowmediatype.h"
#include "directshowutils.h"
+#include "directshowvideoprobecontrol.h"
QT_BEGIN_NAMESPACE
DSCameraSession::DSCameraSession(QObject *parent)
: QObject(parent)
- , m_graphBuilder(Q_NULLPTR)
- , m_filterGraph(Q_NULLPTR)
+ , m_graphBuilder(nullptr)
+ , m_filterGraph(nullptr)
, m_sourceDeviceName(QLatin1String("default"))
- , m_sourceFilter(Q_NULLPTR)
+ , m_sourceFilter(nullptr)
, m_needsHorizontalMirroring(false)
- , m_previewSampleGrabber(Q_NULLPTR)
- , m_nullRendererFilter(Q_NULLPTR)
+ , m_previewSampleGrabber(nullptr)
+ , m_nullRendererFilter(nullptr)
, m_previewStarted(false)
- , m_surface(Q_NULLPTR)
+ , m_surface(nullptr)
, m_previewPixelFormat(QVideoFrame::Format_Invalid)
, m_readyForCapture(false)
, m_imageIdCounter(0)
, m_currentImageId(-1)
+ , m_captureDestinations(QCameraImageCapture::CaptureToFile)
+ , m_videoProbeControl(nullptr)
, m_status(QCamera::UnloadedStatus)
{
connect(this, SIGNAL(statusChanged(QCamera::Status)),
@@ -354,6 +357,39 @@ bool DSCameraSession::getCameraControlInterface(IAMCameraControl **cameraControl
return true;
}
+bool DSCameraSession::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const
+{
+ return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer);
+}
+
+QCameraImageCapture::CaptureDestinations DSCameraSession::captureDestination() const
+{
+ return m_captureDestinations;
+}
+
+void DSCameraSession::setCaptureDestination(QCameraImageCapture::CaptureDestinations destinations)
+{
+ if (m_captureDestinations == destinations)
+ return;
+
+ m_captureDestinations = destinations;
+ Q_EMIT captureDestinationChanged(m_captureDestinations);
+}
+
+void DSCameraSession::addVideoProbe(DirectShowVideoProbeControl *probe)
+{
+ const QMutexLocker locker(&m_probeMutex);
+ m_videoProbeControl = probe;
+}
+
+void DSCameraSession::removeVideoProbe(DirectShowVideoProbeControl *probe)
+{
+ Q_UNUSED(probe);
+ Q_ASSERT(m_videoProbeControl == probe);
+ const QMutexLocker locker(&m_probeMutex);
+ m_videoProbeControl = nullptr;
+}
+
bool DSCameraSession::load()
{
unload();
@@ -547,6 +583,12 @@ void DSCameraSession::onFrameAvailable(double time, const QByteArray &data)
m_presentMutex.unlock();
+ {
+ const QMutexLocker locker(&m_probeMutex);
+ if (m_currentFrame.isValid() && m_videoProbeControl)
+ Q_EMIT m_videoProbeControl->videoFrameProbed(m_currentFrame);
+ }
+
// Image capture
QMutexLocker locker(&m_captureMutex);
if (m_currentImageId != -1 && !m_capturedFrame.isValid()) {
@@ -586,8 +628,8 @@ void DSCameraSession::presentFrame()
m_capturedFrame.unmap();
- QtConcurrent::run(this, &DSCameraSession::saveCapturedImage,
- m_currentImageId, captureImage, m_imageCaptureFileName);
+ QtConcurrent::run(this, &DSCameraSession::processCapturedImage,
+ m_currentImageId, m_captureDestinations, captureImage, m_imageCaptureFileName);
m_imageCaptureFileName.clear();
m_currentImageId = -1;
@@ -603,14 +645,22 @@ void DSCameraSession::presentFrame()
updateReadyForCapture();
}
-void DSCameraSession::saveCapturedImage(int id, const QImage &image, const QString &path)
+void DSCameraSession::processCapturedImage(int id,
+ QCameraImageCapture::CaptureDestinations captureDestinations,
+ const QImage &image,
+ const QString &path)
{
- if (image.save(path, "JPG")) {
- emit imageSaved(id, path);
- } else {
- emit captureError(id, QCameraImageCapture::ResourceError,
- tr("Could not save image to file."));
+ if (captureDestinations & QCameraImageCapture::CaptureToFile) {
+ if (image.save(path, "JPG")) {
+ Q_EMIT imageSaved(id, path);
+ } else {
+ Q_EMIT captureError(id, QCameraImageCapture::ResourceError,
+ tr("Could not save image to file."));
+ }
}
+
+ if (captureDestinations & QCameraImageCapture::CaptureToBuffer)
+ Q_EMIT imageAvailable(id, QVideoFrame(image));
}
bool DSCameraSession::createFilterGraph()
diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h
index 90407f49e..e28015534 100644
--- a/src/plugins/directshow/camera/dscamerasession.h
+++ b/src/plugins/directshow/camera/dscamerasession.h
@@ -50,6 +50,7 @@
#include <QtMultimedia/qabstractvideosurface.h>
#include <QtMultimedia/qvideosurfaceformat.h>
#include <QtMultimedia/qcameraimageprocessingcontrol.h>
+#include <QtMultimedia/qcameraimagecapture.h>
#include <private/qmediastoragelocation_p.h>
#include <tchar.h>
@@ -76,6 +77,7 @@ struct ICaptureGraphBuilder2;
QT_BEGIN_NAMESPACE
class DirectShowSampleGrabber;
+class DirectShowVideoProbeControl;
class DSCameraSession : public QObject
{
@@ -120,13 +122,22 @@ public:
bool getCameraControlInterface(IAMCameraControl **cameraControl) const;
+ bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const;
+ QCameraImageCapture::CaptureDestinations captureDestination() const;
+ void setCaptureDestination(QCameraImageCapture::CaptureDestinations destinations);
+
+ void addVideoProbe(DirectShowVideoProbeControl *probe);
+ void removeVideoProbe(DirectShowVideoProbeControl *probe);
+
Q_SIGNALS:
void statusChanged(QCamera::Status);
void imageExposed(int id);
void imageCaptured(int id, const QImage &preview);
void imageSaved(int id, const QString &fileName);
+ void imageAvailable(int id, const QVideoFrame &buffer);
void readyForCaptureChanged(bool);
void captureError(int id, int error, const QString &errorString);
+ void captureDestinationChanged(QCameraImageCapture::CaptureDestinations);
private Q_SLOTS:
void presentFrame();
@@ -157,7 +168,7 @@ private:
void setStatus(QCamera::Status status);
void onFrameAvailable(double time, const QByteArray &data);
- void saveCapturedImage(int id, const QImage &image, const QString &path);
+ void processCapturedImage(int id, QCameraImageCapture::CaptureDestinations captureDestinations, const QImage &image, const QString &path);
bool createFilterGraph();
bool connectGraph();
@@ -208,6 +219,11 @@ private:
int m_imageIdCounter;
int m_currentImageId;
QVideoFrame m_capturedFrame;
+ QCameraImageCapture::CaptureDestinations m_captureDestinations;
+
+ // Video probe
+ QMutex m_probeMutex;
+ DirectShowVideoProbeControl *m_videoProbeControl;
// Internal state
QCamera::Status m_status;
diff --git a/src/plugins/directshow/camera/dsimagecapturecontrol.cpp b/src/plugins/directshow/camera/dsimagecapturecontrol.cpp
index 9d4a7ea1d..c92ce98e1 100644
--- a/src/plugins/directshow/camera/dsimagecapturecontrol.cpp
+++ b/src/plugins/directshow/camera/dsimagecapturecontrol.cpp
@@ -57,6 +57,8 @@ DSImageCaptureControl::DSImageCaptureControl(DSCameraSession *session)
this, SIGNAL(readyForCaptureChanged(bool)));
connect(m_session, SIGNAL(captureError(int,int,QString)),
this, SIGNAL(error(int,int,QString)));
+ connect(m_session, &DSCameraSession::imageAvailable,
+ this, &DSImageCaptureControl::imageAvailable);
}
DSImageCaptureControl::~DSImageCaptureControl()
diff --git a/src/plugins/directshow/directshow.pro b/src/plugins/directshow/directshow.pro
index 2857f87d9..54d617166 100644
--- a/src/plugins/directshow/directshow.pro
+++ b/src/plugins/directshow/directshow.pro
@@ -8,7 +8,13 @@ win32:!qtHaveModule(opengl)|qtConfig(dynamicgl) {
HEADERS += dsserviceplugin.h
SOURCES += dsserviceplugin.cpp
-mingw: DEFINES += NO_DSHOW_STRSAFE
+# Remove WINVER/_WIN32_WINNT definitions added to qt_build_config.prf
+# by qtbase/d57a7c41712f8627a462d893329dc3f0dbb52d32 since the multimedia
+# headers of MinGW 5.3/7.1 are too broken to compile with 0x0601.
+mingw {
+ DEFINES -= WINVER=0x0601 _WIN32_WINNT=0x0601
+ DEFINES += NO_DSHOW_STRSAFE
+}
include(common/common.pri)
qtConfig(directshow-player): include(player/player.pri)
diff --git a/src/plugins/directshow/dsserviceplugin.cpp b/src/plugins/directshow/dsserviceplugin.cpp
index 51be7e500..cb4f0cdf9 100644
--- a/src/plugins/directshow/dsserviceplugin.cpp
+++ b/src/plugins/directshow/dsserviceplugin.cpp
@@ -123,7 +123,9 @@ QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures(
QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
+ addRefCount();
const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
+ releaseRefCount();
if (!devs.isEmpty())
return devs.first().first;
}
@@ -135,7 +137,9 @@ QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
QList<QByteArray> result;
if (service == Q_MEDIASERVICE_CAMERA) {
+ addRefCount();
const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
+ releaseRefCount();
for (const DSVideoDeviceInfo &info : devs)
result.append(info.first);
}
@@ -146,7 +150,9 @@ QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
{
if (service == Q_MEDIASERVICE_CAMERA) {
+ addRefCount();
const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
+ releaseRefCount();
for (const DSVideoDeviceInfo &info : devs) {
if (info.first == device)
return info.second;
diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp
index 40f77e899..ee7f5ec9e 100644
--- a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp
+++ b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp
@@ -63,7 +63,7 @@ DirectShowVideoRendererControl::~DirectShowVideoRendererControl()
{
#if QT_CONFIG(evr)
if (m_evrPresenter) {
- m_evrPresenter->setSurface(Q_NULLPTR);
+ m_evrPresenter->setSurface(nullptr);
m_evrPresenter->Release();
}
#endif
@@ -83,7 +83,7 @@ void DirectShowVideoRendererControl::setSurface(QAbstractVideoSurface *surface)
#if QT_CONFIG(evr)
if (m_evrPresenter) {
- m_evrPresenter->setSurface(Q_NULLPTR);
+ m_evrPresenter->setSurface(nullptr);
m_evrPresenter->Release();
m_evrPresenter = 0;
}