diff --git a/src/plugins/directshow/camera/camera.pri b/src/plugins/directshow/camera/camera.pri index 0e1c1e895279b21b03854786c30335072d274272..3be1acc49d2facfd116b1a8d6415ef740c7aec72 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 0000000000000000000000000000000000000000..912f67a2dd73340f8d937b1ac62db1af09247941 --- /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 0000000000000000000000000000000000000000..6891bea774ddecf5021bdb260f58f21f2d88311d --- /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 a806cabe36e01fef7607902517ea1d7e60561a11..8115ef385fc0a40f682bcdc8cde7789c1fd528c0 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 2e45edcce47327bf84474e3acaa843f38e74c84b..9a8f745f67e7b44c453a46b4f32da6022275822e 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 bf81262d602a100ea5f777b63e86ff8905359619..85947c655215a8b3a0329ff398479566b22ca253 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 ac861ae58c67576d6245a3189a378d4b9fbe0a47..361a0220e56e65541baa7aa9e07f529b3db7185f 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;