blob: 5e7d026c2786517dbc827fdb2a104bcb10e8b3c3 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2016 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 DSCAMERASESSION_H
#define DSCAMERASESSION_H
#include <QtCore/qobject.h>
#include <QTime>
#include <QUrl>
#include <QMutex>
#include <QTimer>
#include <qcamera.h>
#include <QtMultimedia/qvideoframe.h>
#include <QtMultimedia/qabstractvideosurface.h>
#include <QtMultimedia/qvideosurfaceformat.h>
#include <QtMultimedia/qcameraimageprocessingcontrol.h>
#include <QtMultimedia/qcameraimagecapture.h>
#include <QtMultimedia/qmediaencodersettings.h>
#include <private/qmediastoragelocation_p.h>
#include <tchar.h>
#include <dshow.h>
#include <objbase.h>
#include <initguid.h>
#include "directshowmediatype.h"
#ifdef Q_CC_MSVC
# pragma comment(lib, "strmiids.lib")
# pragma comment(lib, "ole32.lib")
#endif // Q_CC_MSVC
#include <windows.h>
#ifdef Q_CC_MSVC
# pragma include_alias("dxtrans.h","qedit.h")
#endif // Q_CC_MSVC
#define __IDxtCompositor_INTERFACE_DEFINED__
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
#define __IDxtJpeg_INTERFACE_DEFINED__
#define __IDxtKey_INTERFACE_DEFINED__
struct ICaptureGraphBuilder2;
QT_BEGIN_NAMESPACE
class DirectShowSampleGrabber;
class DirectShowVideoProbeControl;
class DSCameraSession : public QObject
{
Q_OBJECT
public:
DSCameraSession(QObject *parent = nullptr);
~DSCameraSession() override;
QCamera::Status status() const { return m_status; }
void setDevice(const QString &device);
bool load();
bool unload();
bool startPreview();
bool stopPreview();
bool isReadyForCapture();
int captureImage(const QString &fileName);
void setSurface(QAbstractVideoSurface* surface);
QCameraViewfinderSettings viewfinderSettings() const;
void setViewfinderSettings(const QCameraViewfinderSettings &settings);
QList<QCameraViewfinderSettings> 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 &);
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);
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);
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);
void cameraError(int error, const QString &errorString);
private Q_SLOTS:
void presentFrame();
void updateReadyForCapture();
private:
struct ImageProcessingParameterInfo
{
LONG minimumValue = 0;
LONG maximumValue = 0;
LONG defaultValue = 0;
LONG currentValue = 0;
LONG capsFlags = 0;
bool hasBeenExplicitlySet = false;
VideoProcAmpProperty videoProcAmpProperty = VideoProcAmp_Brightness;
};
void setStatus(QCamera::Status status);
void onFrameAvailable(double time, const QByteArray &data);
void processCapturedImage(int id, QCameraImageCapture::CaptureDestinations captureDestinations, const QImage &image, const QString &path);
bool createFilterGraph();
bool connectGraph();
void disconnectGraph();
void updateSourceCapabilities();
bool configurePreviewFormat();
void updateImageProcessingParametersInfos();
void setError(int error, const QString &errorString, HRESULT hr);
// 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(
const ImageProcessingParameterInfo &sourceValueInfo);
static qint32 sourceImageProcessingParameterValue(
qreal scaledValue, const ImageProcessingParameterInfo &sourceValueInfo);
QMutex m_presentMutex;
QMutex m_captureMutex;
ICaptureGraphBuilder2* m_graphBuilder = nullptr;
IGraphBuilder* m_filterGraph = nullptr;
// Source (camera)
QString m_sourceDeviceName = QLatin1String("default");
IBaseFilter* m_sourceFilter = nullptr;
bool m_needsHorizontalMirroring = false;
QList<DirectShowMediaType> m_supportedFormats;
QList<QCameraViewfinderSettings> m_supportedViewfinderSettings;
DirectShowMediaType m_sourceFormat;
QMap<QCameraImageProcessingControl::ProcessingParameter, ImageProcessingParameterInfo> m_imageProcessingParametersInfos;
// Preview
DirectShowSampleGrabber *m_previewSampleGrabber = nullptr;
IBaseFilter *m_nullRendererFilter = nullptr;
QVideoFrame m_currentFrame;
bool m_previewStarted = false;
QAbstractVideoSurface* m_surface = nullptr;
QVideoSurfaceFormat m_previewSurfaceFormat;
QVideoFrame::PixelFormat m_previewPixelFormat = QVideoFrame::Format_RGB32;
QSize m_previewSize;
int m_stride = -1;
QCameraViewfinderSettings m_viewfinderSettings;
QCameraViewfinderSettings m_actualViewfinderSettings;
// Image capture
QString m_imageCaptureFileName;
QMediaStorageLocation m_fileNameGenerator;
bool m_readyForCapture = false;
int m_imageIdCounter = 0;
int m_currentImageId = -1;
QVideoFrame m_capturedFrame;
QCameraImageCapture::CaptureDestinations m_captureDestinations = QCameraImageCapture::CaptureToFile;
// Video probe
QMutex m_probeMutex;
DirectShowVideoProbeControl *m_videoProbeControl = nullptr;
QImageEncoderSettings m_imageEncoderSettings;
// Internal state
QCamera::Status m_status = QCamera::UnloadedStatus;
QTimer m_deviceLostEventTimer;
QMap<QCameraImageProcessingControl::ProcessingParameter, QVariant> m_pendingImageProcessingParametrs;
friend class SampleGrabberCallbackPrivate;
};
QT_END_NAMESPACE
#endif