summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVal Doroshchuk <valentyn.doroshchuk@qt.io>2017-12-27 13:32:44 +0100
committerVaL Doroshchuk <valentyn.doroshchuk@qt.io>2018-09-25 10:37:26 +0000
commitcac5f507e1f84c99c7627129eaeba4a52231d2e3 (patch)
treeb200759841fd4bfd17f02765b41e5c61805f9a34
parentae48330c105c24851312004a189487608542eb49 (diff)
DirectShow: Implement image capture settings
Added camera image encoder control that 1. applies image encoder settings (resolution and codec) used to capture images 2. returns supported image codecs from QImageWriter::supportedImageFormats 3. returns supported resolutions Since DirectShow camera session uses QImage based on QVideoFrame image encoder control returns viewfinder supported resolutions. Not available if camera is not loaded. Setting resolution via encoder control causes viewfinder resolution to be ignored. Task-number: QTBUG-32743 Change-Id: I1de3ca9c6543937cb62f73cb64a81d23b0d5c4c9 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Andy Shaw <andy.shaw@qt.io> Reviewed-by: Christian Stromme <christian.stromme@qt.io>
-rw-r--r--src/plugins/directshow/camera/camera.pri6
-rw-r--r--src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp95
-rw-r--r--src/plugins/directshow/camera/directshowcameraimageencodercontrol.h70
-rw-r--r--src/plugins/directshow/camera/dscameraservice.cpp6
-rw-r--r--src/plugins/directshow/camera/dscameraservice.h2
-rw-r--r--src/plugins/directshow/camera/dscamerasession.cpp31
-rw-r--r--src/plugins/directshow/camera/dscamerasession.h8
7 files changed, 213 insertions, 5 deletions
diff --git a/src/plugins/directshow/camera/camera.pri b/src/plugins/directshow/camera/camera.pri
index 0e1c1e895..3be1acc49 100644
--- a/src/plugins/directshow/camera/camera.pri
+++ b/src/plugins/directshow/camera/camera.pri
@@ -15,7 +15,8 @@ HEADERS += \
$$PWD/directshowcameraexposurecontrol.h \
$$PWD/directshowcameracapturedestinationcontrol.h \
$$PWD/directshowcameracapturebufferformatcontrol.h \
- $$PWD/directshowcamerazoomcontrol.h
+ $$PWD/directshowcamerazoomcontrol.h \
+ $$PWD/directshowcameraimageencodercontrol.h
SOURCES += \
$$PWD/dscameraservice.cpp \
@@ -29,7 +30,8 @@ SOURCES += \
$$PWD/directshowcameraexposurecontrol.cpp \
$$PWD/directshowcameracapturedestinationcontrol.cpp \
$$PWD/directshowcameracapturebufferformatcontrol.cpp \
- $$PWD/directshowcamerazoomcontrol.cpp
+ $$PWD/directshowcamerazoomcontrol.cpp \
+ $$PWD/directshowcameraimageencodercontrol.cpp
*-msvc*:INCLUDEPATH += $$(DXSDK_DIR)/include
QMAKE_USE += directshow
diff --git a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp
new file mode 100644
index 000000000..912f67a2d
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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 "directshowcameraimageencodercontrol.h"
+#include "dscamerasession.h"
+#include <QImageWriter>
+
+QT_BEGIN_NAMESPACE
+
+DirectShowCameraImageEncoderControl::DirectShowCameraImageEncoderControl(DSCameraSession *session)
+ : QImageEncoderControl(session)
+ , m_session(session)
+{
+}
+
+QList<QSize> DirectShowCameraImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const
+{
+ QList<QSize> res;
+ if (!settings.codec().isEmpty() && !supportedImageCodecs().contains(settings.codec(), Qt::CaseInsensitive))
+ return res;
+
+ QList<QSize> resolutions = m_session->supportedResolutions(continuous);
+ QSize r = settings.resolution();
+ if (!r.isValid())
+ return resolutions;
+
+ if (resolutions.contains(r))
+ res << settings.resolution();
+
+ return res;
+}
+
+QStringList DirectShowCameraImageEncoderControl::supportedImageCodecs() const
+{
+ QStringList supportedCodecs;
+ for (const QByteArray &type: QImageWriter::supportedImageFormats()) {
+ supportedCodecs << type;
+ }
+
+ return supportedCodecs;
+}
+
+QString DirectShowCameraImageEncoderControl::imageCodecDescription(const QString &codecName) const
+{
+ Q_UNUSED(codecName);
+ return QString();
+}
+
+QImageEncoderSettings DirectShowCameraImageEncoderControl::imageSettings() const
+{
+ return m_session->imageEncoderSettings();
+}
+
+void DirectShowCameraImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings)
+{
+ m_session->setImageEncoderSettings(settings);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h
new file mode 100644
index 000000000..6891bea77
--- /dev/null
+++ b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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 DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H
+#define DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H
+
+#include <qimageencodercontrol.h>
+
+QT_BEGIN_NAMESPACE
+
+class DSCameraSession;
+class DirectShowCameraImageEncoderControl : public QImageEncoderControl
+{
+ Q_OBJECT
+public:
+ DirectShowCameraImageEncoderControl(DSCameraSession *session);
+
+ QList<QSize> supportedResolutions(
+ const QImageEncoderSettings &settings = QImageEncoderSettings(),
+ bool *continuous = nullptr) const override;
+
+ QStringList supportedImageCodecs() const override;
+ QString imageCodecDescription(const QString &formatName) const override;
+
+ QImageEncoderSettings imageSettings() const override;
+ void setImageSettings(const QImageEncoderSettings &settings) override;
+
+private:
+ DSCameraSession *m_session;
+};
+
+QT_END_NAMESPACE
+
+#endif // DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H
diff --git a/src/plugins/directshow/camera/dscameraservice.cpp b/src/plugins/directshow/camera/dscameraservice.cpp
index a806cabe3..8115ef385 100644
--- a/src/plugins/directshow/camera/dscameraservice.cpp
+++ b/src/plugins/directshow/camera/dscameraservice.cpp
@@ -53,6 +53,7 @@
#include "directshowcameracapturebufferformatcontrol.h"
#include "directshowvideoprobecontrol.h"
#include "directshowcamerazoomcontrol.h"
+#include "directshowcameraimageencodercontrol.h"
QT_BEGIN_NAMESPACE
@@ -70,6 +71,7 @@ DSCameraService::DSCameraService(QObject *parent):
, m_captureBufferFormatControl(new DirectShowCameraCaptureBufferFormatControl)
, m_videoProbeControl(nullptr)
, m_zoomControl(new DirectShowCameraZoomControl(m_session))
+ , m_imageEncoderControl(new DirectShowCameraImageEncoderControl(m_session))
{
}
@@ -81,6 +83,7 @@ DSCameraService::~DSCameraService()
delete m_videoDevice;
delete m_videoRenderer;
delete m_imageCapture;
+ delete m_imageEncoderControl;
delete m_session;
delete m_exposureControl;
delete m_captureDestinationControl;
@@ -134,6 +137,9 @@ QMediaControl* DSCameraService::requestControl(const char *name)
if (qstrcmp(name, QCameraZoomControl_iid) == 0)
return m_zoomControl;
+ if (qstrcmp(name, QImageEncoderControl_iid) == 0)
+ return m_imageEncoderControl;
+
return 0;
}
diff --git a/src/plugins/directshow/camera/dscameraservice.h b/src/plugins/directshow/camera/dscameraservice.h
index 2e45edcce..9a8f745f6 100644
--- a/src/plugins/directshow/camera/dscameraservice.h
+++ b/src/plugins/directshow/camera/dscameraservice.h
@@ -57,6 +57,7 @@ class DirectShowCameraCaptureDestinationControl;
class DirectShowCameraCaptureBufferFormatControl;
class DirectShowVideoProbeControl;
class DirectShowCameraZoomControl;
+class DirectShowCameraImageEncoderControl;
class DSCameraService : public QMediaService
{
@@ -82,6 +83,7 @@ private:
DirectShowCameraCaptureBufferFormatControl *m_captureBufferFormatControl;
DirectShowVideoProbeControl *m_videoProbeControl;
DirectShowCameraZoomControl *m_zoomControl;
+ DirectShowCameraImageEncoderControl *m_imageEncoderControl;
};
QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp
index bf81262d6..85947c655 100644
--- a/src/plugins/directshow/camera/dscamerasession.cpp
+++ b/src/plugins/directshow/camera/dscamerasession.cpp
@@ -584,10 +584,13 @@ int DSCameraSession::captureImage(const QString &fileName)
return m_imageIdCounter;
}
+ const QString ext = !m_imageEncoderSettings.codec().isEmpty()
+ ? m_imageEncoderSettings.codec().toLower()
+ : QLatin1String("jpg");
m_imageCaptureFileName = m_fileNameGenerator.generateFileName(fileName,
QMediaStorageLocation::Pictures,
QLatin1String("IMG_"),
- QLatin1String("jpg"));
+ ext);
updateReadyForCapture();
@@ -687,8 +690,9 @@ void DSCameraSession::processCapturedImage(int id,
const QImage &image,
const QString &path)
{
+ const QString format = m_imageEncoderSettings.codec();
if (captureDestinations & QCameraImageCapture::CaptureToFile) {
- if (image.save(path, "JPG")) {
+ if (image.save(path, !format.isEmpty() ? format.toUtf8().constData() : "JPG")) {
Q_EMIT imageSaved(id, path);
} else {
Q_EMIT captureError(id, QCameraImageCapture::ResourceError,
@@ -844,9 +848,11 @@ bool DSCameraSession::configurePreviewFormat()
{
// Resolve viewfinder settings
int settingsIndex = 0;
+ const QSize captureResolution = m_imageEncoderSettings.resolution();
+ const QSize resolution = captureResolution.isValid() ? captureResolution : m_viewfinderSettings.resolution();
QCameraViewfinderSettings resolvedViewfinderSettings;
for (const QCameraViewfinderSettings &s : qAsConst(m_supportedViewfinderSettings)) {
- if ((m_viewfinderSettings.resolution().isEmpty() || m_viewfinderSettings.resolution() == s.resolution())
+ if ((resolution.isEmpty() || resolution == s.resolution())
&& (qFuzzyIsNull(m_viewfinderSettings.minimumFrameRate()) || qFuzzyCompare((float)m_viewfinderSettings.minimumFrameRate(), (float)s.minimumFrameRate()))
&& (qFuzzyIsNull(m_viewfinderSettings.maximumFrameRate()) || qFuzzyCompare((float)m_viewfinderSettings.maximumFrameRate(), (float)s.maximumFrameRate()))
&& (m_viewfinderSettings.pixelFormat() == QVideoFrame::Format_Invalid || m_viewfinderSettings.pixelFormat() == s.pixelFormat())
@@ -1171,4 +1177,23 @@ void DSCameraSession::updateSourceCapabilities()
updateImageProcessingParametersInfos();
}
+QList<QSize> DSCameraSession::supportedResolutions(bool *continuous) const
+{
+ if (continuous)
+ *continuous = false;
+
+ QList<QSize> res;
+ for (auto &settings : m_supportedViewfinderSettings) {
+ auto size = settings.resolution();
+ if (!res.contains(size))
+ res << size;
+ }
+
+ std::sort(res.begin(), res.end(), [](const QSize &r1, const QSize &r2) {
+ return qlonglong(r1.width()) * r1.height() < qlonglong(r2.width()) * r2.height();
+ });
+
+ return res;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h
index ac861ae58..361a0220e 100644
--- a/src/plugins/directshow/camera/dscamerasession.h
+++ b/src/plugins/directshow/camera/dscamerasession.h
@@ -51,6 +51,7 @@
#include <QtMultimedia/qvideosurfaceformat.h>
#include <QtMultimedia/qcameraimageprocessingcontrol.h>
#include <QtMultimedia/qcameraimagecapture.h>
+#include <QtMultimedia/qmediaencodersettings.h>
#include <private/qmediastoragelocation_p.h>
#include <tchar.h>
@@ -129,6 +130,11 @@ public:
void addVideoProbe(DirectShowVideoProbeControl *probe);
void removeVideoProbe(DirectShowVideoProbeControl *probe);
+ QList<QSize> supportedResolutions(bool *continuous) const;
+ QImageEncoderSettings imageEncoderSettings() const { return m_imageEncoderSettings; }
+ void setImageEncoderSettings(const QImageEncoderSettings &settings)
+ { m_imageEncoderSettings = settings; }
+
Q_SIGNALS:
void statusChanged(QCamera::Status);
void imageExposed(int id);
@@ -217,6 +223,8 @@ private:
QMutex m_probeMutex;
DirectShowVideoProbeControl *m_videoProbeControl;
+ QImageEncoderSettings m_imageEncoderSettings;
+
// Internal state
QCamera::Status m_status;
QTimer m_deviceLostEventTimer;