diff options
Diffstat (limited to 'tests/auto/unit/mockbackend')
19 files changed, 1524 insertions, 0 deletions
diff --git a/tests/auto/unit/mockbackend/CMakeLists.txt b/tests/auto/unit/mockbackend/CMakeLists.txt new file mode 100644 index 000000000..959341366 --- /dev/null +++ b/tests/auto/unit/mockbackend/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Generated from mockbackend.pro. + +##################################################################### +## MockMultimediaPlugin Generic Library: +##################################################################### + +qt_internal_add_plugin(MockMultimediaPlugin + STATIC + OUTPUT_NAME mockmultimediaplugin + PLUGIN_TYPE multimedia + OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../plugins" + DEFAULT_IF FALSE + SOURCES + qmockaudiodecoder.cpp qmockaudiodecoder.h + qmockaudiooutput.h + qmockcamera.cpp qmockcamera.h + qmockimagecapture.cpp qmockimagecapture.h + qmockmediaplayer.h + qmockmediaencoder.h + qmockmediacapturesession.h + qmockvideosink.h + qmockmediadevices.cpp qmockmediadevices.h + qmockintegration.cpp qmockintegration.h + LIBRARIES + Qt::MultimediaPrivate + Qt::CorePrivate +) + +#### Keys ignored in scope 1:.:.:mockbackend.pro:<TRUE>: +# TEMPLATE = "lib" diff --git a/tests/auto/unit/mockbackend/mock.json b/tests/auto/unit/mockbackend/mock.json new file mode 100644 index 000000000..499a3de8c --- /dev/null +++ b/tests/auto/unit/mockbackend/mock.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "mock" ] +} diff --git a/tests/auto/unit/mockbackend/qmockaudiodecoder.cpp b/tests/auto/unit/mockbackend/qmockaudiodecoder.cpp new file mode 100644 index 000000000..3c6b940a9 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockaudiodecoder.cpp @@ -0,0 +1,139 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qmockaudiodecoder.h" + +QT_BEGIN_NAMESPACE + +QMockAudioDecoder::QMockAudioDecoder(QAudioDecoder *parent) + : QPlatformAudioDecoder(parent), mDevice(0), mPosition(-1), mSerial(0) +{ + mFormat.setChannelCount(1); + mFormat.setSampleFormat(QAudioFormat::UInt8); + mFormat.setSampleRate(1000); +} + +QUrl QMockAudioDecoder::source() const +{ + return mSource; +} + +void QMockAudioDecoder::setSource(const QUrl &fileName) +{ + mSource = fileName; + mDevice = 0; + stop(); +} + +QIODevice *QMockAudioDecoder::sourceDevice() const +{ + return mDevice; +} + +void QMockAudioDecoder::setSourceDevice(QIODevice *device) +{ + mDevice = device; + mSource.clear(); + stop(); +} + +QAudioFormat QMockAudioDecoder::audioFormat() const +{ + return mFormat; +} + +void QMockAudioDecoder::setAudioFormat(const QAudioFormat &format) +{ + if (mFormat != format) { + mFormat = format; + formatChanged(mFormat); + } +} + +// When decoding we decode to first buffer, then second buffer +// we then stop until the first is read again and so on, for +// 5 buffers +void QMockAudioDecoder::start() +{ + if (!isDecoding()) { + if (!mSource.isEmpty()) { + setIsDecoding(true); + durationChanged(duration()); + + QTimer::singleShot(50, this, &QMockAudioDecoder::pretendDecode); + } else { + error(QAudioDecoder::ResourceError, "No source set"); + } + } +} + +void QMockAudioDecoder::stop() +{ + if (isDecoding()) { + mSerial = 0; + mPosition = 0; + mBuffers.clear(); + setIsDecoding(false); + bufferAvailableChanged(false); + } +} + +QAudioBuffer QMockAudioDecoder::read() +{ + QAudioBuffer a; + if (mBuffers.size() > 0) { + a = mBuffers.takeFirst(); + mPosition = a.startTime() / 1000; + positionChanged(mPosition); + + if (mBuffers.isEmpty()) + bufferAvailableChanged(false); + + if (mBuffers.isEmpty() && mSerial >= MOCK_DECODER_MAX_BUFFERS) { + finished(); + } else + QTimer::singleShot(50, this, &QMockAudioDecoder::pretendDecode); + } + + return a; +} + +bool QMockAudioDecoder::bufferAvailable() const +{ + return mBuffers.size() > 0; +} + +qint64 QMockAudioDecoder::position() const +{ + return mPosition; +} + +qint64 QMockAudioDecoder::duration() const +{ + return (sizeof(mSerial) * MOCK_DECODER_MAX_BUFFERS * qint64(1000)) + / (mFormat.sampleRate() * mFormat.channelCount()); +} + +void QMockAudioDecoder::pretendDecode() +{ + // Check if we've reached end of stream + if (mSerial >= MOCK_DECODER_MAX_BUFFERS) + return; + + // We just keep the length of mBuffers to 3 or less. + if (mBuffers.size() < 3) { + QByteArray b(sizeof(mSerial), 0); + memcpy(b.data(), &mSerial, sizeof(mSerial)); + qint64 position = (sizeof(mSerial) * mSerial * qint64(1000000)) + / (mFormat.sampleRate() * mFormat.channelCount()); + mSerial++; + mBuffers.push_back(QAudioBuffer(b, mFormat, position)); + bufferReady(); + if (mBuffers.size() == 1) + bufferAvailableChanged(true); + } +} + +QT_END_NAMESPACE + +#include "moc_qmockaudiodecoder.cpp" diff --git a/tests/auto/unit/mockbackend/qmockaudiodecoder.h b/tests/auto/unit/mockbackend/qmockaudiodecoder.h new file mode 100644 index 000000000..89e21ef23 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockaudiodecoder.h @@ -0,0 +1,69 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef MOCKAUDIODECODERCONTROL_H +#define MOCKAUDIODECODERCONTROL_H + +#include "private/qplatformaudiodecoder_p.h" + +#include <QtCore/qpair.h> +#include <QtCore/qurl.h> + +#include "qaudiobuffer.h" +#include <QTimer> +#include <QIODevice> + +#define MOCK_DECODER_MAX_BUFFERS 10 + +QT_BEGIN_NAMESPACE + +class QMockAudioDecoder : public QPlatformAudioDecoder +{ + Q_OBJECT + +public: + QMockAudioDecoder(QAudioDecoder *parent = nullptr); + + QUrl source() const override; + + void setSource(const QUrl &fileName) override; + + QIODevice *sourceDevice() const override; + + void setSourceDevice(QIODevice *device) override; + + QAudioFormat audioFormat() const override; + + void setAudioFormat(const QAudioFormat &format) override; + + // When decoding we decode to first buffer, then second buffer + // we then stop until the first is read again and so on, for + // 5 buffers + void start() override; + + void stop() override; + + QAudioBuffer read() override; + + bool bufferAvailable() const override; + + qint64 position() const override; + + qint64 duration() const override; + +private slots: + void pretendDecode(); + +public: + QUrl mSource; + QIODevice *mDevice; + QAudioFormat mFormat; + qint64 mPosition; + + int mSerial; + QList<QAudioBuffer> mBuffers; +}; + +QT_END_NAMESPACE + +#endif // QAUDIODECODERCONTROL_H diff --git a/tests/auto/unit/mockbackend/qmockaudiooutput.h b/tests/auto/unit/mockbackend/qmockaudiooutput.h new file mode 100644 index 000000000..a35fc8fe4 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockaudiooutput.h @@ -0,0 +1,30 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +#ifndef QMOCKAUDIOOUTPUT_H +#define QMOCKAUDIOOUTPUT_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qplatformaudiooutput_p.h> + +QT_BEGIN_NAMESPACE + +class QMockAudioOutput : public QPlatformAudioOutput +{ +public: + QMockAudioOutput(QAudioOutput *qq) : QPlatformAudioOutput(qq) {} +}; + +QT_END_NAMESPACE + + +#endif // QMOCKAUDIOOUTPUT_H diff --git a/tests/auto/unit/mockbackend/qmockcamera.cpp b/tests/auto/unit/mockbackend/qmockcamera.cpp new file mode 100644 index 000000000..23ecc36ae --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockcamera.cpp @@ -0,0 +1,158 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qmockcamera.h" + +QT_BEGIN_NAMESPACE + +QMockCamera::QMockCamera(QCamera *parent) + : QPlatformCamera(parent), m_propertyChangesSupported(false) +{ + if (!simpleCamera) { + minIsoChanged(100); + maxIsoChanged(800); + minExposureTimeChanged(.001f); + maxExposureTimeChanged(1.f); + exposureCompensationRangeChanged(-2, 2); + maximumZoomFactorChanged(4.); + setFlashMode(QCamera::FlashAuto); + } +} + +QMockCamera::~QMockCamera() { } + +bool QMockCamera::isActive() const +{ + return m_active; +} + +void QMockCamera::setActive(bool active) +{ + if (m_active == active) + return; + m_active = active; + emit activeChanged(active); +} + +void QMockCamera::setCamera(const QCameraDevice &camera) +{ + m_camera = camera; +} + +bool QMockCamera::setCameraFormat(const QCameraFormat &format) +{ + if (!format.isNull() && !m_camera.videoFormats().contains(format)) + return false; + return true; +} + +void QMockCamera::setFocusMode(QCamera::FocusMode mode) +{ + if (isFocusModeSupported(mode)) + focusModeChanged(mode); +} + +bool QMockCamera::isFocusModeSupported(QCamera::FocusMode mode) const +{ + return simpleCamera ? mode == QCamera::FocusModeAuto : mode != QCamera::FocusModeInfinity; +} + +void QMockCamera::setCustomFocusPoint(const QPointF &point) +{ + if (!simpleCamera) + customFocusPointChanged(point); +} + +void QMockCamera::setFocusDistance(float d) +{ + if (!simpleCamera) + focusDistanceChanged(d); +} + +void QMockCamera::zoomTo(float newZoomFactor, float /*rate*/) +{ + zoomFactorChanged(newZoomFactor); +} + +void QMockCamera::setFlashMode(QCamera::FlashMode mode) +{ + if (!simpleCamera) + flashModeChanged(mode); + flashReadyChanged(mode != QCamera::FlashOff); +} +bool QMockCamera::isFlashModeSupported(QCamera::FlashMode mode) const +{ + return simpleCamera ? mode == QCamera::FlashOff : true; +} + +bool QMockCamera::isFlashReady() const +{ + return flashMode() != QCamera::FlashOff; +} + +void QMockCamera::setExposureMode(QCamera::ExposureMode mode) +{ + if (!simpleCamera && isExposureModeSupported(mode)) + exposureModeChanged(mode); +} + +bool QMockCamera::isExposureModeSupported(QCamera::ExposureMode mode) const +{ + return simpleCamera ? mode == QCamera::ExposureAuto : mode <= QCamera::ExposureBeach; +} + +void QMockCamera::setExposureCompensation(float c) +{ + if (!simpleCamera) + exposureCompensationChanged(qBound(-2., c, 2.)); +} + +int QMockCamera::isoSensitivity() const +{ + if (simpleCamera) + return -1; + return manualIsoSensitivity() > 0 ? manualIsoSensitivity() : 100; +} + +void QMockCamera::setManualIsoSensitivity(int iso) +{ + if (!simpleCamera) + isoSensitivityChanged(qBound(100, iso, 800)); +} + +void QMockCamera::setManualExposureTime(float secs) +{ + if (!simpleCamera) + exposureTimeChanged(qBound(0.001, secs, 1.)); +} + +float QMockCamera::exposureTime() const +{ + if (simpleCamera) + return -1.; + return manualExposureTime() > 0 ? manualExposureTime() : .05; +} + +bool QMockCamera::isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const +{ + if (simpleCamera) + return mode == QCamera::WhiteBalanceAuto; + return mode == QCamera::WhiteBalanceAuto || mode == QCamera::WhiteBalanceManual + || mode == QCamera::WhiteBalanceSunlight; +} + +void QMockCamera::setWhiteBalanceMode(QCamera::WhiteBalanceMode mode) +{ + if (isWhiteBalanceModeSupported(mode)) + whiteBalanceModeChanged(mode); +} + +void QMockCamera::setColorTemperature(int temperature) +{ + if (!simpleCamera) + colorTemperatureChanged(temperature); +} + +QT_END_NAMESPACE + +#include "moc_qmockcamera.cpp" diff --git a/tests/auto/unit/mockbackend/qmockcamera.h b/tests/auto/unit/mockbackend/qmockcamera.h new file mode 100644 index 000000000..3d8159e84 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockcamera.h @@ -0,0 +1,81 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKCAMERA_H +#define QMOCKCAMERA_H + +#include "private/qplatformcamera_p.h" +#include "qcameradevice.h" +#include <qtimer.h> + +QT_BEGIN_NAMESPACE + +class QMockCamera : public QPlatformCamera +{ + friend class MockCaptureControl; + Q_OBJECT + + static bool simpleCamera; +public: + + struct Simple { + Simple() { simpleCamera = true; } + ~Simple() { simpleCamera = false; } + }; + + QMockCamera(QCamera *parent); + + ~QMockCamera() override; + + bool isActive() const override; + + void setActive(bool active) override; + + void setCamera(const QCameraDevice &camera) override; + + bool setCameraFormat(const QCameraFormat &format) override; + + void setFocusMode(QCamera::FocusMode mode) override; + + bool isFocusModeSupported(QCamera::FocusMode mode) const override; + + void setCustomFocusPoint(const QPointF &point) override; + + void setFocusDistance(float d) override; + + void zoomTo(float newZoomFactor, float /*rate*/) override; + + void setFlashMode(QCamera::FlashMode mode) override; + + bool isFlashModeSupported(QCamera::FlashMode mode) const override; + + bool isFlashReady() const override; + + void setExposureMode(QCamera::ExposureMode mode) override; + + bool isExposureModeSupported(QCamera::ExposureMode mode) const override; + + void setExposureCompensation(float c) override; + + int isoSensitivity() const override; + + void setManualIsoSensitivity(int iso) override; + + void setManualExposureTime(float secs) override; + + float exposureTime() const override; + + bool isWhiteBalanceModeSupported(QCamera::WhiteBalanceMode mode) const override; + + void setWhiteBalanceMode(QCamera::WhiteBalanceMode mode) override; + + void setColorTemperature(int temperature) override; + + bool m_active = false; + QCameraDevice m_camera; + bool m_propertyChangesSupported; +}; + +QT_END_NAMESPACE + +#endif // QMOCKCAMERA_H diff --git a/tests/auto/unit/mockbackend/qmockimagecapture.cpp b/tests/auto/unit/mockbackend/qmockimagecapture.cpp new file mode 100644 index 000000000..96e53b2f4 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockimagecapture.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <qmockimagecapture.h> +#include <qmockcamera.h> +#include <qmockmediacapturesession.h> +#include <qimagecapture.h> +#include <qcamera.h> + +QT_BEGIN_NAMESPACE + +QMockImageCapture::QMockImageCapture(QImageCapture *parent) + : QPlatformImageCapture(parent) +{ +} + +bool QMockImageCapture::isReadyForCapture() const +{ + return m_ready; +} + +int QMockImageCapture::capture(const QString &fileName) +{ + if (isReadyForCapture()) { + m_fileName = fileName; + m_captureRequest++; + emit readyForCaptureChanged(m_ready = false); + QTimer::singleShot(5, this, &QMockImageCapture::captured); + return m_captureRequest; + } else { + emit error(-1, QImageCapture::NotReadyError, + QLatin1String("Could not capture in stopped state")); + } + + return -1; +} + +void QMockImageCapture::captured() +{ + emit imageCaptured(m_captureRequest, QImage()); + + QMediaMetaData metaData; + metaData.insert(QMediaMetaData::Author, QStringLiteral("Author")); + metaData.insert(QMediaMetaData::Date, QDateTime(QDate(2021, 1, 1), QTime())); + + emit imageMetadataAvailable(m_captureRequest, metaData); + + if (!m_ready) + { + emit readyForCaptureChanged(m_ready = true); + emit imageExposed(m_captureRequest); + } + + emit imageSaved(m_captureRequest, m_fileName); +} + +QT_END_NAMESPACE + +#include "moc_qmockimagecapture.cpp" diff --git a/tests/auto/unit/mockbackend/qmockimagecapture.h b/tests/auto/unit/mockbackend/qmockimagecapture.h new file mode 100644 index 000000000..376f53cbc --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockimagecapture.h @@ -0,0 +1,48 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKCAMERAIMAGECAPTURE_H +#define QMOCKCAMERAIMAGECAPTURE_H + +#include <QDateTime> +#include <QTimer> +#include <QtMultimedia/qmediametadata.h> + +#include "private/qplatformimagecapture_p.h" +#include "private/qplatformcamera_p.h" + +QT_BEGIN_NAMESPACE + +class QMockMediaCaptureSession; + +class QMockImageCapture : public QPlatformImageCapture +{ + Q_OBJECT +public: + QMockImageCapture(QImageCapture *parent); + + ~QMockImageCapture() + { + } + + bool isReadyForCapture() const override; + + int capture(const QString &fileName) override; + int captureToBuffer() override { return -1; } + + QImageEncoderSettings imageSettings() const override { return m_settings; } + void setImageSettings(const QImageEncoderSettings &settings) override { m_settings = settings; } + +private Q_SLOTS: + void captured(); + +private: + QString m_fileName; + int m_captureRequest = 0; + bool m_ready = true; + QImageEncoderSettings m_settings; +}; + +QT_END_NAMESPACE + +#endif // QMOCKCAMERAIMAGECAPTURE_H diff --git a/tests/auto/unit/mockbackend/qmockintegration.cpp b/tests/auto/unit/mockbackend/qmockintegration.cpp new file mode 100644 index 000000000..b554b31e0 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockintegration.cpp @@ -0,0 +1,198 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QtMultimedia/private/qplatformmediaplugin_p.h> +#include "qmockintegration.h" +#include "qmockmediaplayer.h" +#include "qmockaudiodecoder.h" +#include "qmockcamera.h" +#include "qmockmediacapturesession.h" +#include "qmockvideosink.h" +#include "qmockimagecapture.h" +#include "qmockaudiooutput.h" +#include "qmocksurfacecapture.h" +#include <private/qcameradevice_p.h> +#include <private/qplatformvideodevices_p.h> + +#include "qmockmediadevices.h" + +QT_BEGIN_NAMESPACE + +class MockMultimediaPlugin : public QPlatformMediaPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QPlatformMediaPlugin_iid FILE "mock.json") + +public: + MockMultimediaPlugin() : QPlatformMediaPlugin() { } + + QPlatformMediaIntegration *create(const QString &name) override + { + if (name == QLatin1String("mock")) + return new QMockIntegration; + return nullptr; + } +}; + +class QMockVideoDevices : public QPlatformVideoDevices +{ +public: + QMockVideoDevices(QPlatformMediaIntegration *pmi) + : QPlatformVideoDevices(pmi) + { + QCameraDevicePrivate *info = new QCameraDevicePrivate; + info->description = QStringLiteral("defaultCamera"); + info->id = "default"; + info->isDefault = true; + auto *f = new QCameraFormatPrivate{ + QSharedData(), + QVideoFrameFormat::Format_ARGB8888, + QSize(640, 480), + 0, + 30 + }; + info->videoFormats << f->create(); + m_cameraDevices.append(info->create()); + info = new QCameraDevicePrivate; + info->description = QStringLiteral("frontCamera"); + info->id = "front"; + info->isDefault = false; + info->position = QCameraDevice::FrontFace; + f = new QCameraFormatPrivate{ + QSharedData(), + QVideoFrameFormat::Format_XRGB8888, + QSize(1280, 720), + 0, + 30 + }; + info->videoFormats << f->create(); + m_cameraDevices.append(info->create()); + info = new QCameraDevicePrivate; + info->description = QStringLiteral("backCamera"); + info->id = "back"; + info->isDefault = false; + info->position = QCameraDevice::BackFace; + m_cameraDevices.append(info->create()); + } + + void addNewCamera() + { + auto info = new QCameraDevicePrivate; + info->description = QLatin1String("newCamera") + QString::number(m_cameraDevices.size()); + info->id = + QString(QLatin1String("camera") + QString::number(m_cameraDevices.size())).toUtf8(); + info->isDefault = false; + m_cameraDevices.append(info->create()); + + emit videoInputsChanged(); + } + + QList<QCameraDevice> videoDevices() const override + { + return m_cameraDevices; + } + +private: + QList<QCameraDevice> m_cameraDevices; +}; + +QMockIntegration::QMockIntegration() : QPlatformMediaIntegration(QLatin1String("mock")) { } +QMockIntegration::~QMockIntegration() = default; + +QPlatformVideoDevices *QMockIntegration::createVideoDevices() +{ + return new QMockVideoDevices(this); +} + +std::unique_ptr<QPlatformMediaDevices> QMockIntegration::createMediaDevices() +{ + return std::make_unique<QMockMediaDevices>(); +} + +QMaybe<QPlatformAudioDecoder *> QMockIntegration::createAudioDecoder(QAudioDecoder *decoder) +{ + if (m_flags & NoAudioDecoderInterface) + m_lastAudioDecoderControl = nullptr; + else + m_lastAudioDecoderControl = new QMockAudioDecoder(decoder); + return m_lastAudioDecoderControl; +} + +QMaybe<QPlatformMediaPlayer *> QMockIntegration::createPlayer(QMediaPlayer *parent) +{ + if (m_flags & NoPlayerInterface) + m_lastPlayer = nullptr; + else + m_lastPlayer = new QMockMediaPlayer(parent); + return m_lastPlayer; +} + +QMaybe<QPlatformCamera *> QMockIntegration::createCamera(QCamera *parent) +{ + if (m_flags & NoCaptureInterface) + m_lastCamera = nullptr; + else + m_lastCamera = new QMockCamera(parent); + return m_lastCamera; +} + +QMaybe<QPlatformImageCapture *> QMockIntegration::createImageCapture(QImageCapture *capture) +{ + return new QMockImageCapture(capture); +} + +QMaybe<QPlatformMediaRecorder *> QMockIntegration::createRecorder(QMediaRecorder *recorder) +{ + return new QMockMediaEncoder(recorder); +} + +QPlatformSurfaceCapture *QMockIntegration::createScreenCapture(QScreenCapture * /*capture*/) +{ + if (m_flags & NoCaptureInterface) + m_lastScreenCapture = nullptr; + else + m_lastScreenCapture = new QMockSurfaceCapture(QPlatformSurfaceCapture::ScreenSource{}); + + return m_lastScreenCapture; +} + +QPlatformSurfaceCapture *QMockIntegration::createWindowCapture(QWindowCapture *) +{ + if (m_flags & NoCaptureInterface) + m_lastWindowCapture = nullptr; + else + m_lastWindowCapture = new QMockSurfaceCapture(QPlatformSurfaceCapture::WindowSource{}); + + return m_lastWindowCapture; +} + +QMaybe<QPlatformMediaCaptureSession *> QMockIntegration::createCaptureSession() +{ + if (m_flags & NoCaptureInterface) + m_lastCaptureService = nullptr; + else + m_lastCaptureService = new QMockMediaCaptureSession(); + return m_lastCaptureService; +} + +QMaybe<QPlatformVideoSink *> QMockIntegration::createVideoSink(QVideoSink *sink) +{ + m_lastVideoSink = new QMockVideoSink(sink); + return m_lastVideoSink; +} + +QMaybe<QPlatformAudioOutput *> QMockIntegration::createAudioOutput(QAudioOutput *q) +{ + return new QMockAudioOutput(q); +} + +void QMockIntegration::addNewCamera() +{ + static_cast<QMockVideoDevices *>(videoDevices())->addNewCamera(); +} + +bool QMockCamera::simpleCamera = false; + +QT_END_NAMESPACE + +#include "qmockintegration.moc" diff --git a/tests/auto/unit/mockbackend/qmockintegration.h b/tests/auto/unit/mockbackend/qmockintegration.h new file mode 100644 index 000000000..20b61721c --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockintegration.h @@ -0,0 +1,103 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKINTEGRATION_H +#define QMOCKINTEGRATION_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qplatformmediaintegration_p.h> + +QT_BEGIN_NAMESPACE + +class QMockMediaPlayer; +class QMockAudioDecoder; +class QMockCamera; +class QMockMediaCaptureSession; +class QMockVideoSink; +class QMockSurfaceCapture; + +class QMockIntegration : public QPlatformMediaIntegration +{ +public: + QMockIntegration(); + ~QMockIntegration(); + + static QMockIntegration *instance() + { + return static_cast<QMockIntegration *>(QPlatformMediaIntegration::instance()); + } + + QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *decoder) override; + QMaybe<QPlatformMediaPlayer *> createPlayer(QMediaPlayer *) override; + QMaybe<QPlatformCamera *> createCamera(QCamera *) override; + QMaybe<QPlatformMediaRecorder *> createRecorder(QMediaRecorder *) override; + QMaybe<QPlatformImageCapture *> createImageCapture(QImageCapture *) override; + QMaybe<QPlatformMediaCaptureSession *> createCaptureSession() override; + QMaybe<QPlatformVideoSink *> createVideoSink(QVideoSink *) override; + + QMaybe<QPlatformAudioOutput *> createAudioOutput(QAudioOutput *) override; + + QPlatformSurfaceCapture *createScreenCapture(QScreenCapture *) override; + QPlatformSurfaceCapture *createWindowCapture(QWindowCapture *) override; + + void addNewCamera(); + + enum Flag { NoPlayerInterface = 0x1, NoAudioDecoderInterface = 0x2, NoCaptureInterface = 0x4 }; + Q_DECLARE_FLAGS(Flags, Flag); + + void setFlags(Flags f) { m_flags = f; } + Flags flags() const { return m_flags; } + + QMockMediaPlayer *lastPlayer() const { return m_lastPlayer; } + QMockAudioDecoder *lastAudioDecoder() const { return m_lastAudioDecoderControl; } + QMockCamera *lastCamera() const { return m_lastCamera; } + // QMockMediaEncoder *lastEncoder const { return m_lastEncoder; } + QMockMediaCaptureSession *lastCaptureService() const { return m_lastCaptureService; } + QMockVideoSink *lastVideoSink() const { return m_lastVideoSink; } + QMockSurfaceCapture *lastScreenCapture() { return m_lastScreenCapture; } + QMockSurfaceCapture *lastWindowCapture() { return m_lastWindowCapture; } + +protected: + QPlatformVideoDevices *createVideoDevices() override; + std::unique_ptr<QPlatformMediaDevices> createMediaDevices() override; + +private: + + Flags m_flags = {}; + QMockMediaPlayer *m_lastPlayer = nullptr; + QMockAudioDecoder *m_lastAudioDecoderControl = nullptr; + QMockCamera *m_lastCamera = nullptr; + // QMockMediaEncoder *m_lastEncoder = nullptr; + QMockMediaCaptureSession *m_lastCaptureService = nullptr; + QMockVideoSink *m_lastVideoSink = nullptr; + QMockSurfaceCapture *m_lastScreenCapture = nullptr; + QMockSurfaceCapture *m_lastWindowCapture = nullptr; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QMockIntegration::Flags); + +#define Q_ENABLE_MOCK_MULTIMEDIA_PLUGIN \ + Q_IMPORT_PLUGIN(MockMultimediaPlugin) \ + struct EnableMockPlugin \ + { \ + EnableMockPlugin() \ + { \ + qputenv("QT_MEDIA_BACKEND", "mock"); \ + } \ + }; \ + static EnableMockPlugin s_mockMultimediaPluginEnabler; + + +QT_END_NAMESPACE + +#endif diff --git a/tests/auto/unit/mockbackend/qmockmediacapturesession.h b/tests/auto/unit/mockbackend/qmockmediacapturesession.h new file mode 100644 index 000000000..0a2d3fb60 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockmediacapturesession.h @@ -0,0 +1,86 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKMEDIACAPTURESESSION_H +#define QMOCKMEDIACAPTURESESSION_H + +#include "qmockmediaencoder.h" +#include "qmockimagecapture.h" +#include "qmockcamera.h" +#include "qmockimagecapture.h" +#include "qmocksurfacecapture.h" +#include <private/qplatformmediacapture_p.h> + +QT_BEGIN_NAMESPACE + +class QMockMediaCaptureSession : public QPlatformMediaCaptureSession +{ +public: + QMockMediaCaptureSession() + : hasControls(true) + { + } + ~QMockMediaCaptureSession() + { + } + + QPlatformCamera *camera() override { return hasControls ? mockCameraControl : nullptr; } + + void setCamera(QPlatformCamera *camera) override + { + QMockCamera *control = static_cast<QMockCamera *>(camera); + if (mockCameraControl == control) + return; + + mockCameraControl = control; + } + + void setImageCapture(QPlatformImageCapture *imageCapture) override + { + mockImageCapture = imageCapture; + } + QPlatformImageCapture *imageCapture() override { return hasControls ? mockImageCapture : nullptr; } + + QPlatformMediaRecorder *mediaRecorder() override { return hasControls ? mockControl : nullptr; } + void setMediaRecorder(QPlatformMediaRecorder *recorder) override + { + if (!hasControls) { + mockControl = nullptr; + return; + } + QMockMediaEncoder *control = static_cast<QMockMediaEncoder *>(recorder); + if (mockControl == control) + return; + + mockControl = control; + } + + void setVideoPreview(QVideoSink *) override {} + + void setAudioInput(QPlatformAudioInput *input) override + { + m_audioInput = input; + } + + QPlatformSurfaceCapture *screenCapture() override { return m_screenCapture; } + void setScreenCapture(QPlatformSurfaceCapture *capture) override { m_screenCapture = capture; } + + QPlatformSurfaceCapture *windowCapture() override { return m_windowCapture; } + void setWindowCapture(QPlatformSurfaceCapture *capture) override { m_windowCapture = capture; } + + QPlatformVideoFrameInput *videoFrameInput() override { return m_videoFrameInput; } + void setVideoFrameInput(QPlatformVideoFrameInput *input) override { m_videoFrameInput = input; } + + QMockCamera *mockCameraControl = nullptr; + QPlatformImageCapture *mockImageCapture = nullptr; + QMockMediaEncoder *mockControl = nullptr; + QPlatformAudioInput *m_audioInput = nullptr; + QPlatformSurfaceCapture *m_screenCapture = nullptr; + QPlatformSurfaceCapture *m_windowCapture = nullptr; + QPlatformVideoFrameInput *m_videoFrameInput = nullptr; + bool hasControls; +}; + +QT_END_NAMESPACE + +#endif // QMOCKMEDIACAPTURESESSION_H diff --git a/tests/auto/unit/mockbackend/qmockmediadevices.cpp b/tests/auto/unit/mockbackend/qmockmediadevices.cpp new file mode 100644 index 000000000..7f2478741 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockmediadevices.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "qmockmediadevices.h" +#include "private/qcameradevice_p.h" + +QT_BEGIN_NAMESPACE + +QMockMediaDevices::QMockMediaDevices() + : QPlatformMediaDevices() +{ +} + +QMockMediaDevices::~QMockMediaDevices() = default; + +QList<QAudioDevice> QMockMediaDevices::audioInputs() const +{ + return m_inputDevices; +} + +QList<QAudioDevice> QMockMediaDevices::audioOutputs() const +{ + return m_outputDevices; +} + +QPlatformAudioSource *QMockMediaDevices::createAudioSource(const QAudioDevice &info, + QObject *parent) +{ + Q_UNUSED(info); + Q_UNUSED(parent); + return nullptr;// ### +} + +QPlatformAudioSink *QMockMediaDevices::createAudioSink(const QAudioDevice &info, + QObject *parent) +{ + Q_UNUSED(info); + Q_UNUSED(parent); + return nullptr; //### +} + + +QT_END_NAMESPACE diff --git a/tests/auto/unit/mockbackend/qmockmediadevices.h b/tests/auto/unit/mockbackend/qmockmediadevices.h new file mode 100644 index 000000000..e9e823194 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockmediadevices.h @@ -0,0 +1,45 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKMEDIADEVICES_H +#define QMOCKMEDIADEVICES_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qplatformmediadevices_p.h> +#include <qelapsedtimer.h> +#include <qaudiodevice.h> +#include <qcameradevice.h> + +QT_BEGIN_NAMESPACE + +class QCameraDevice; + +class QMockMediaDevices : public QPlatformMediaDevices +{ +public: + QMockMediaDevices(); + ~QMockMediaDevices(); + + QList<QAudioDevice> audioInputs() const override; + QList<QAudioDevice> audioOutputs() const override; + QPlatformAudioSource *createAudioSource(const QAudioDevice &info, QObject *parent) override; + QPlatformAudioSink *createAudioSink(const QAudioDevice &info, QObject *parent) override; + +private: + QList<QAudioDevice> m_inputDevices; + QList<QAudioDevice> m_outputDevices; +}; + +QT_END_NAMESPACE + +#endif diff --git a/tests/auto/unit/mockbackend/qmockmediaencoder.h b/tests/auto/unit/mockbackend/qmockmediaencoder.h new file mode 100644 index 000000000..cf855488b --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockmediaencoder.h @@ -0,0 +1,95 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef MOCKRECORDERCONTROL_H +#define MOCKRECORDERCONTROL_H + +#include <QUrl> +#include <qaudiodevice.h> + +#include "private/qplatformmediarecorder_p.h" + +class QMockMediaEncoder : public QPlatformMediaRecorder +{ +public: + QMockMediaEncoder(QMediaRecorder *parent): + QPlatformMediaRecorder(parent), + m_state(QMediaRecorder::StoppedState), + m_position(0) + { + } + + bool isLocationWritable(const QUrl &) const override + { + return true; + } + + QMediaRecorder::RecorderState state() const override + { + return m_state; + } + + qint64 duration() const override + { + return m_position; + } + + virtual void setMetaData(const QMediaMetaData &m) override + { + m_metaData = m; + metaDataChanged(); + } + virtual QMediaMetaData metaData() const override { return m_metaData; } + + using QPlatformMediaRecorder::updateError; + +public: + void record(QMediaEncoderSettings &settings) override + { + m_state = QMediaRecorder::RecordingState; + m_settings = settings; + m_position=1; + stateChanged(m_state); + durationChanged(m_position); + + QUrl actualLocation = outputLocation().isEmpty() ? QUrl::fromLocalFile("default_name.mp4") : outputLocation(); + actualLocationChanged(actualLocation); + } + + void pause() override + { + m_state = QMediaRecorder::PausedState; + stateChanged(m_state); + } + + void resume() override + { + m_state = QMediaRecorder::RecordingState; + stateChanged(m_state); + } + + void stop() override + { + m_position=0; + m_state = QMediaRecorder::StoppedState; + stateChanged(m_state); + } + + void reset() + { + m_state = QMediaRecorder::StoppedState; + m_settings = QMediaEncoderSettings(); + m_position = 0; + stateChanged(m_state); + durationChanged(m_position); + clearActualLocation(); + } + +public: + QMediaMetaData m_metaData; + QMediaRecorder::RecorderState m_state; + QMediaEncoderSettings m_settings; + qint64 m_position; +}; + +#endif // MOCKRECORDERCONTROL_H diff --git a/tests/auto/unit/mockbackend/qmockmediaplayer.h b/tests/auto/unit/mockbackend/qmockmediaplayer.h new file mode 100644 index 000000000..a3ba76beb --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockmediaplayer.h @@ -0,0 +1,175 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKMEDIAPLAYER_H +#define QMOCKMEDIAPLAYER_H + +#include "private/qplatformmediaplayer_p.h" +#include <qurl.h> + +QT_BEGIN_NAMESPACE + +class QMockMediaPlayer : public QPlatformMediaPlayer +{ + friend class QMockMediaPlayerService; + +public: + QMockMediaPlayer(QMediaPlayer *parent) + : QPlatformMediaPlayer(parent) + , _state(QMediaPlayer::StoppedState) + , _error(QMediaPlayer::NoError) + , _duration(0) + , _position(0) + , _bufferProgress(0) + , _audioAvailable(false) + , _videoAvailable(false) + , _isSeekable(true) + , _playbackRate(qreal(1.0)) + , _stream(0) + , _isValid(false) + { + } + ~QMockMediaPlayer() + { + } + + QMediaPlayer::PlaybackState state() const override { return _state; } + void updateState(QMediaPlayer::PlaybackState state) { setState(state); } + void updateMediaStatus(QMediaPlayer::MediaStatus status, QMediaPlayer::PlaybackState state) + { + _state = state; + + mediaStatusChanged(status); + stateChanged(_state); + } + + qint64 duration() const override { return _duration; } + void setDuration(qint64 duration) { durationChanged(_duration = duration); } + + qint64 position() const override { return _position; } + + void setPosition(qint64 position) override + { + if (position != _position) + positionChanged(_position = position); + } + + float bufferProgress() const override { return _bufferProgress; } + void setBufferStatus(float status) + { + if (_bufferProgress == status) + return; + _bufferProgress = status; + bufferProgressChanged(status); + } + + bool isAudioAvailable() const override { return _audioAvailable; } + bool isVideoAvailable() const override { return _videoAvailable; } + + bool isSeekable() const override { return _isSeekable; } + void setSeekable(bool seekable) { seekableChanged(_isSeekable = seekable); } + + QMediaTimeRange availablePlaybackRanges() const override { return QMediaTimeRange(_seekRange.first, _seekRange.second); } + void setSeekRange(qint64 minimum, qint64 maximum) { _seekRange = qMakePair(minimum, maximum); } + + qreal playbackRate() const override { return _playbackRate; } + void setPlaybackRate(qreal rate) override + { + if (rate != _playbackRate) + playbackRateChanged(_playbackRate = rate); + } + + QUrl media() const override { return _media; } + void setMedia(const QUrl &content, QIODevice *stream) override + { + _stream = stream; + _media = content; + setState(QMediaPlayer::StoppedState); + mediaStatusChanged(_media.isEmpty() ? QMediaPlayer::NoMedia : QMediaPlayer::LoadingMedia); + } + QIODevice *mediaStream() const override { return _stream; } + + bool streamPlaybackSupported() const override { return m_supportsStreamPlayback; } + void setStreamPlaybackSupported(bool b) { m_supportsStreamPlayback = b; } + + void play() override { if (_isValid && !_media.isEmpty()) setState(QMediaPlayer::PlayingState); } + void pause() override { if (_isValid && !_media.isEmpty()) setState(QMediaPlayer::PausedState); } + void stop() override { if (_state != QMediaPlayer::StoppedState) setState(QMediaPlayer::StoppedState); } + + void setVideoSink(QVideoSink *) override {} + + void setAudioOutput(QPlatformAudioOutput *output) override { m_audioOutput = output; } + + void emitError(QMediaPlayer::Error err, const QString &errorString) { error(err, errorString); } + + void setState(QMediaPlayer::PlaybackState state) + { + if (_state == state) + return; + _state = state; + stateChanged(state); + } + void setState(QMediaPlayer::PlaybackState state, QMediaPlayer::MediaStatus status) + { + _state = state; + mediaStatusChanged(status); + stateChanged(state); + } + void setMediaStatus(QMediaPlayer::MediaStatus status) + { + if (status == QMediaPlayer::StalledMedia || status == QMediaPlayer::BufferingMedia) + bufferProgressChanged(_bufferProgress); + mediaStatusChanged(status); + } + void setIsValid(bool isValid) { _isValid = isValid; } + void setMedia(QUrl media) { _media = media; } + void setVideoAvailable(bool videoAvailable) { _videoAvailable = videoAvailable; } + void setError(QMediaPlayer::Error err) + { + _error = err; + error(_error, _errorString); + } + void setErrorString(QString errorString) + { + _errorString = errorString; + error(_error, _errorString); + } + + void reset() + { + _state = QMediaPlayer::StoppedState; + _error = QMediaPlayer::NoError; + _duration = 0; + _position = 0; + _bufferProgress = 0; + _videoAvailable = false; + _isSeekable = false; + _playbackRate = 0.0; + _media = QUrl(); + _stream = 0; + _isValid = false; + _errorString = QString(); + } + + + QMediaPlayer::PlaybackState _state; + QMediaPlayer::Error _error; + qint64 _duration; + qint64 _position; + float _bufferProgress; + bool _audioAvailable; + bool _videoAvailable; + bool _isSeekable; + QPair<qint64, qint64> _seekRange; + qreal _playbackRate; + QUrl _media; + QIODevice *_stream; + bool _isValid; + QString _errorString; + bool m_supportsStreamPlayback = false; + QPlatformAudioOutput *m_audioOutput = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QMOCKMEDIAPLAYER_H diff --git a/tests/auto/unit/mockbackend/qmocksurfacecapture.h b/tests/auto/unit/mockbackend/qmocksurfacecapture.h new file mode 100644 index 000000000..00ce80ebb --- /dev/null +++ b/tests/auto/unit/mockbackend/qmocksurfacecapture.h @@ -0,0 +1,88 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKSURFACECAPTURE_H +#define QMOCKSURFACECAPTURE_H + +#include "private/qplatformsurfacecapture_p.h" +#include "private/qvideoframe_p.h" + +#include "qmockvideobuffer.h" +#include "qthread.h" + +QT_BEGIN_NAMESPACE + +class QMockSurfaceCapture : public QPlatformSurfaceCapture +{ + class Grabber : public QThread + { + public: + Grabber(QMockSurfaceCapture &capture) : QThread(&capture), m_capture(capture) { } + + void run() override + { + for (int i = 0; !isInterruptionRequested(); ++i) { + QImage image(m_capture.m_imageSize, QImage::Format_ARGB32); + + image.fill(i % 2 ? Qt::red : Qt::blue); + + QVideoFrame frame = QVideoFramePrivate::createFrame( + std::make_unique<QMockVideoBuffer>(image), + QVideoFrameFormat(m_capture.m_imageSize, + QVideoFrameFormat::pixelFormatFromImageFormat( + m_capture.m_imageFormat))); + + emit m_capture.newVideoFrame(frame); + } + } + + private: + QMockSurfaceCapture &m_capture; + }; + +public: + using QPlatformSurfaceCapture::QPlatformSurfaceCapture; + + ~QMockSurfaceCapture() { resetGrabber(); } + + bool setActiveInternal(bool active) override + { + if (active) { + m_grabber = std::make_unique<Grabber>(*this); + m_grabber->start(); + } else { + resetGrabber(); + } + + return true; + } + + bool isActive() const override { return bool(m_grabber); } + + QVideoFrameFormat frameFormat() const override + { + return m_grabber ? QVideoFrameFormat( + m_imageSize, QVideoFrameFormat::pixelFormatFromImageFormat(m_imageFormat)) + : QVideoFrameFormat{}; + } + +private: + void resetGrabber() + { + if (m_grabber) { + m_grabber->requestInterruption(); + m_grabber->quit(); + m_grabber->wait(); + m_grabber.reset(); + } + } + +private: + std::unique_ptr<Grabber> m_grabber; + const QImage::Format m_imageFormat = QImage::Format_ARGB32; + const QSize m_imageSize = QSize(2, 3); +}; + +QT_END_NAMESPACE + +#endif // QMOCKSURFACECAPTURE_H diff --git a/tests/auto/unit/mockbackend/qmockvideobuffer.h b/tests/auto/unit/mockbackend/qmockvideobuffer.h new file mode 100644 index 000000000..0ee32416c --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockvideobuffer.h @@ -0,0 +1,38 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKVIDEOBUFFER_H +#define QMOCKVIDEOBUFFER_H + +#include "qimage.h" +#include "private/qhwvideobuffer_p.h" + +class QMockVideoBuffer : public QHwVideoBuffer +{ +public: + QMockVideoBuffer(QImage image) : QHwVideoBuffer(QVideoFrame::NoHandle), m_image(image) { } + + MapData map(QtVideo::MapMode mode) override + { + MapData mapData; + if (m_mapMode == QtVideo::MapMode::NotMapped && !m_image.isNull() + && mode != QtVideo::MapMode::NotMapped) { + m_mapMode = mode; + + mapData.planeCount = 1; + mapData.bytesPerLine[0] = m_image.bytesPerLine(); + mapData.data[0] = m_image.bits(); + mapData.dataSize[0] = m_image.sizeInBytes(); + } + + return mapData; + } + + void unmap() override { m_mapMode = QtVideo::MapMode::NotMapped; } + +private: + QtVideo::MapMode m_mapMode = QtVideo::MapMode::NotMapped; + QImage m_image; +}; + +#endif // QMOCKVIDEOBUFFER_H diff --git a/tests/auto/unit/mockbackend/qmockvideosink.h b/tests/auto/unit/mockbackend/qmockvideosink.h new file mode 100644 index 000000000..d93178668 --- /dev/null +++ b/tests/auto/unit/mockbackend/qmockvideosink.h @@ -0,0 +1,33 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef QMOCKVIDEOSINK_H +#define QMOCKVIDEOSINK_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qplatformvideosink_p.h> + +QT_BEGIN_NAMESPACE + +class QMockVideoSink : public QPlatformVideoSink +{ +public: + explicit QMockVideoSink(QVideoSink *parent) + : QPlatformVideoSink(parent) + {} + void setRhi(QRhi * /*rhi*/) override {} +}; + +QT_END_NAMESPACE + +#endif |