diff options
author | Artem Dyomin <artem.dyomin@qt.io> | 2023-09-05 18:20:20 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-09-06 18:10:48 +0000 |
commit | 2f6afb0b25d3d5785e8d68910b3fd98fd5117969 (patch) | |
tree | 292ba936b7f1f9ac62b714b1e275797128f29151 | |
parent | 3c8138e3d32347d22e7c09bec606dfa617677c10 (diff) |
Fix potential thread-safety on lazy media format initialization
Let's have a common approach of lazy media format initialization
for all platforms.
The approach was introduced in some recent CR, but it hasn't been
integrated due to other reasons.
Change-Id: I0fff558463753149d2381a2435f8ba300243f0a8
Reviewed-by: Pavel Dubsky <pavel.dubsky@qt.io>
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
(cherry picked from commit 13c9472acc761f772b0a14b80b24321b924d69e1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
18 files changed, 70 insertions, 114 deletions
diff --git a/src/multimedia/platform/qplatformmediaintegration.cpp b/src/multimedia/platform/qplatformmediaintegration.cpp index b094d549c..1fe5e1cd1 100644 --- a/src/multimedia/platform/qplatformmediaintegration.cpp +++ b/src/multimedia/platform/qplatformmediaintegration.cpp @@ -14,6 +14,7 @@ #include "qplatformcapturablewindows_p.h" #include "QtCore/private/qfactoryloader_p.h" +#include "private/qplatformmediaformatinfo_p.h" #include "qplatformmediaplugin_p.h" class QDummyIntegration : public QPlatformMediaIntegration @@ -23,7 +24,6 @@ public: { qCritical("QtMultimedia is not currently supported on this platform or compiler."); } - QPlatformMediaFormatInfo *formatInfo() override { return nullptr; } }; static Q_LOGGING_CATEGORY(qLcMediaPlugin, "qt.multimedia.plugin") @@ -144,6 +144,20 @@ bool QPlatformMediaIntegration::isCapturableWindowValid(const QCapturableWindowP return m_capturableWindows && m_capturableWindows->isWindowValid(window); } +const QPlatformMediaFormatInfo *QPlatformMediaIntegration::formatInfo() +{ + std::call_once(m_formatInfoOnceFlg, [this]() { + m_formatInfo.reset(createFormatInfo()); + Q_ASSERT(m_formatInfo); + }); + return m_formatInfo.get(); +} + +QPlatformMediaFormatInfo *QPlatformMediaIntegration::createFormatInfo() +{ + return new QPlatformMediaFormatInfo; +} + QPlatformMediaIntegration::QPlatformMediaIntegration() = default; QPlatformMediaIntegration::~QPlatformMediaIntegration() = default; diff --git a/src/multimedia/platform/qplatformmediaintegration_p.h b/src/multimedia/platform/qplatformmediaintegration_p.h index 728425355..3fc97a1ce 100644 --- a/src/multimedia/platform/qplatformmediaintegration_p.h +++ b/src/multimedia/platform/qplatformmediaintegration_p.h @@ -21,6 +21,7 @@ #include <qstring.h> #include <memory> +#include <mutex> QT_BEGIN_NAMESPACE @@ -60,7 +61,7 @@ public: QPlatformMediaIntegration(); virtual ~QPlatformMediaIntegration(); - virtual QPlatformMediaFormatInfo *formatInfo() = 0; + const QPlatformMediaFormatInfo *formatInfo(); virtual QList<QCameraDevice> videoInputs(); virtual QMaybe<QPlatformCamera *> createCamera(QCamera *) { return notAvailable; } @@ -83,6 +84,9 @@ public: QPlatformVideoDevices *videoDevices() { return m_videoDevices.get(); } +protected: + virtual QPlatformMediaFormatInfo *createFormatInfo(); + private: friend class QMockIntegrationFactory; // API to be able to test with a mock backend @@ -93,6 +97,9 @@ private: protected: std::unique_ptr<QPlatformVideoDevices> m_videoDevices; std::unique_ptr<QPlatformCapturableWindows> m_capturableWindows; + + mutable std::unique_ptr<QPlatformMediaFormatInfo> m_formatInfo; + mutable std::once_flag m_formatInfoOnceFlg; }; QT_END_NAMESPACE diff --git a/src/multimedia/qmediaformat.cpp b/src/multimedia/qmediaformat.cpp index 275cdf8b8..a05648636 100644 --- a/src/multimedia/qmediaformat.cpp +++ b/src/multimedia/qmediaformat.cpp @@ -455,14 +455,6 @@ QMimeType QMediaFormat::mimeType() const return QMimeDatabase().mimeTypeForName(QString::fromLatin1(mimeTypeForFormat[fmt + 1])); } -static QPlatformMediaFormatInfo *formatInfo() -{ - QPlatformMediaFormatInfo *result = nullptr; - if (auto *pi = QPlatformMediaIntegration::instance()) - result = pi->formatInfo(); - return result; -} - /*! \enum QMediaFormat::ConversionMode @@ -501,8 +493,7 @@ static QPlatformMediaFormatInfo *formatInfo() */ QList<QMediaFormat::FileFormat> QMediaFormat::supportedFileFormats(QMediaFormat::ConversionMode m) { - auto *fi = formatInfo(); - return fi != nullptr ? fi->supportedFileFormats(*this, m) : QList<QMediaFormat::FileFormat>{}; + return QPlatformMediaIntegration::instance()->formatInfo()->supportedFileFormats(*this, m); } /*! @@ -528,8 +519,7 @@ QList<QMediaFormat::FileFormat> QMediaFormat::supportedFileFormats(QMediaFormat: */ QList<QMediaFormat::VideoCodec> QMediaFormat::supportedVideoCodecs(QMediaFormat::ConversionMode m) { - auto *fi = formatInfo(); - return fi != nullptr ? fi->supportedVideoCodecs(*this, m) : QList<QMediaFormat::VideoCodec>{}; + return QPlatformMediaIntegration::instance()->formatInfo()->supportedVideoCodecs(*this, m); } /*! @@ -555,8 +545,7 @@ QList<QMediaFormat::VideoCodec> QMediaFormat::supportedVideoCodecs(QMediaFormat: */ QList<QMediaFormat::AudioCodec> QMediaFormat::supportedAudioCodecs(QMediaFormat::ConversionMode m) { - auto *fi = formatInfo(); - return fi != nullptr ? fi->supportedAudioCodecs(*this, m) : QList<QMediaFormat::AudioCodec>{}; + return QPlatformMediaIntegration::instance()->formatInfo()->supportedAudioCodecs(*this, m); } /*! diff --git a/src/plugins/multimedia/android/qandroidintegration.cpp b/src/plugins/multimedia/android/qandroidintegration.cpp index b33717341..c1bb98568 100644 --- a/src/plugins/multimedia/android/qandroidintegration.cpp +++ b/src/plugins/multimedia/android/qandroidintegration.cpp @@ -49,22 +49,14 @@ QAndroidIntegration::QAndroidIntegration() } -QAndroidIntegration::~QAndroidIntegration() -{ - delete m_formatInfo; -} - QMaybe<QPlatformAudioDecoder *> QAndroidIntegration::createAudioDecoder(QAudioDecoder *decoder) { return new QAndroidAudioDecoder(decoder); } -QPlatformMediaFormatInfo *QAndroidIntegration::formatInfo() +QPlatformMediaFormatInfo *QAndroidIntegration::createFormatInfo() { - if (!m_formatInfo) - m_formatInfo = new QAndroidFormatInfo(); - return m_formatInfo; - + return new QAndroidFormatInfo; } QMaybe<QPlatformMediaCaptureSession *> QAndroidIntegration::createCaptureSession() diff --git a/src/plugins/multimedia/android/qandroidintegration_p.h b/src/plugins/multimedia/android/qandroidintegration_p.h index d6df4dbef..9ef5a3267 100644 --- a/src/plugins/multimedia/android/qandroidintegration_p.h +++ b/src/plugins/multimedia/android/qandroidintegration_p.h @@ -25,9 +25,6 @@ class QAndroidIntegration : public QPlatformMediaIntegration { public: QAndroidIntegration(); - ~QAndroidIntegration(); - - QPlatformMediaFormatInfo *formatInfo() override; QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *decoder) override; QMaybe<QPlatformMediaCaptureSession *> createCaptureSession() override; @@ -42,7 +39,8 @@ public: QMaybe<QPlatformVideoSink *> createVideoSink(QVideoSink *) override; QList<QCameraDevice> videoInputs() override; - QPlatformMediaFormatInfo *m_formatInfo = nullptr; +protected: + QPlatformMediaFormatInfo *createFormatInfo() override; }; QT_END_NAMESPACE diff --git a/src/plugins/multimedia/darwin/qdarwinintegration.mm b/src/plugins/multimedia/darwin/qdarwinintegration.mm index 1a3e41d7e..6491f1952 100644 --- a/src/plugins/multimedia/darwin/qdarwinintegration.mm +++ b/src/plugins/multimedia/darwin/qdarwinintegration.mm @@ -45,16 +45,9 @@ QDarwinIntegration::QDarwinIntegration() m_videoDevices = std::make_unique<QAVFVideoDevices>(this); } -QDarwinIntegration::~QDarwinIntegration() +QPlatformMediaFormatInfo *QDarwinIntegration::createFormatInfo() { - delete m_formatInfo; -} - -QPlatformMediaFormatInfo *QDarwinIntegration::formatInfo() -{ - if (!m_formatInfo) - m_formatInfo = new QDarwinFormatInfo(); - return m_formatInfo; + return new QDarwinFormatInfo(); } QMaybe<QPlatformAudioDecoder *> QDarwinIntegration::createAudioDecoder(QAudioDecoder *decoder) diff --git a/src/plugins/multimedia/darwin/qdarwinintegration_p.h b/src/plugins/multimedia/darwin/qdarwinintegration_p.h index f8f897c51..533b5a441 100644 --- a/src/plugins/multimedia/darwin/qdarwinintegration_p.h +++ b/src/plugins/multimedia/darwin/qdarwinintegration_p.h @@ -25,9 +25,6 @@ class QDarwinIntegration : public QPlatformMediaIntegration { public: QDarwinIntegration(); - ~QDarwinIntegration(); - - QPlatformMediaFormatInfo *formatInfo() override; QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *) override; QMaybe<QPlatformMediaCaptureSession *> createCaptureSession() override; @@ -38,7 +35,8 @@ public: QMaybe<QPlatformVideoSink *> createVideoSink(QVideoSink *) override; - QPlatformMediaFormatInfo *m_formatInfo = nullptr; +protected: + QPlatformMediaFormatInfo *createFormatInfo() override; }; QT_END_NAMESPACE diff --git a/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp b/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp index 60910f66b..1425fe8a8 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp +++ b/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration.cpp @@ -144,8 +144,6 @@ QFFmpegMediaIntegration::QFFmpegMediaIntegration() setupFFmpegLogger(); - m_formatsInfo = new QFFmpegMediaFormatInfo(); - #if defined(Q_OS_ANDROID) m_videoDevices = std::make_unique<QAndroidVideoDevices>(this); #elif QT_CONFIG(linux_v4l) @@ -176,16 +174,6 @@ QFFmpegMediaIntegration::QFFmpegMediaIntegration() #endif } -QFFmpegMediaIntegration::~QFFmpegMediaIntegration() -{ - delete m_formatsInfo; -} - -QPlatformMediaFormatInfo *QFFmpegMediaIntegration::formatInfo() -{ - return m_formatsInfo; -} - QMaybe<QPlatformAudioDecoder *> QFFmpegMediaIntegration::createAudioDecoder(QAudioDecoder *decoder) { return new QFFmpegAudioDecoder(decoder); @@ -287,6 +275,11 @@ QMaybe<QPlatformAudioInput *> QFFmpegMediaIntegration::createAudioInput(QAudioIn return new QFFmpegAudioInput(input); } +QPlatformMediaFormatInfo *QFFmpegMediaIntegration::createFormatInfo() +{ + return new QFFmpegMediaFormatInfo; +} + #ifdef Q_OS_ANDROID Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) diff --git a/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration_p.h b/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration_p.h index aaa643705..b68431ba6 100644 --- a/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration_p.h +++ b/src/plugins/multimedia/ffmpeg/qffmpegmediaintegration_p.h @@ -25,10 +25,11 @@ class QFFmpegMediaIntegration : public QPlatformMediaIntegration { public: QFFmpegMediaIntegration(); - ~QFFmpegMediaIntegration(); - static QFFmpegMediaIntegration *instance() { return static_cast<QFFmpegMediaIntegration *>(QPlatformMediaIntegration::instance()); } - QPlatformMediaFormatInfo *formatInfo() override; + static QFFmpegMediaIntegration *instance() + { + return static_cast<QFFmpegMediaIntegration *>(QPlatformMediaIntegration::instance()); + } QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *decoder) override; QMaybe<QPlatformMediaCaptureSession *> createCaptureSession() override; @@ -44,7 +45,8 @@ public: QMaybe<QPlatformAudioInput *> createAudioInput(QAudioInput *input) override; // QPlatformAudioOutput *createAudioOutput(QAudioOutput *) override; - QFFmpegMediaFormatInfo *m_formatsInfo = nullptr; +protected: + QPlatformMediaFormatInfo *createFormatInfo() override; }; QT_END_NAMESPACE diff --git a/src/plugins/multimedia/gstreamer/qgstreamerintegration.cpp b/src/plugins/multimedia/gstreamer/qgstreamerintegration.cpp index 264d71d3f..9c3e92c37 100644 --- a/src/plugins/multimedia/gstreamer/qgstreamerintegration.cpp +++ b/src/plugins/multimedia/gstreamer/qgstreamerintegration.cpp @@ -41,22 +41,16 @@ QGstreamerIntegration::QGstreamerIntegration() { gst_init(nullptr, nullptr); m_videoDevices = std::make_unique<QGstreamerVideoDevices>(this); - m_formatsInfo = new QGstreamerFormatInfo(); } -QGstreamerIntegration::~QGstreamerIntegration() +QPlatformMediaFormatInfo *QGstreamerIntegration::createFormatInfo() { - delete m_formatsInfo; + return new QGstreamerFormatInfo(); } -QPlatformMediaFormatInfo *QGstreamerIntegration::formatInfo() +const QGstreamerFormatInfo *QGstreamerIntegration::gstFormatsInfo() { - return m_formatsInfo; -} - -const QGstreamerFormatInfo *QGstreamerIntegration::gstFormatsInfo() const -{ - return m_formatsInfo; + return static_cast<const QGstreamerFormatInfo *>(formatInfo()); } QMaybe<QPlatformAudioDecoder *> QGstreamerIntegration::createAudioDecoder(QAudioDecoder *decoder) diff --git a/src/plugins/multimedia/gstreamer/qgstreamerintegration_p.h b/src/plugins/multimedia/gstreamer/qgstreamerintegration_p.h index 387909b2e..d6e7271ff 100644 --- a/src/plugins/multimedia/gstreamer/qgstreamerintegration_p.h +++ b/src/plugins/multimedia/gstreamer/qgstreamerintegration_p.h @@ -26,10 +26,11 @@ class QGstreamerIntegration : public QPlatformMediaIntegration { public: QGstreamerIntegration(); - ~QGstreamerIntegration(); - static QGstreamerIntegration *instance() { return static_cast<QGstreamerIntegration *>(QPlatformMediaIntegration::instance()); } - QPlatformMediaFormatInfo *formatInfo() override; + static QGstreamerIntegration *instance() + { + return static_cast<QGstreamerIntegration *>(QPlatformMediaIntegration::instance()); + } QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *decoder) override; QMaybe<QPlatformMediaCaptureSession *> createCaptureSession() override; @@ -43,11 +44,11 @@ public: QMaybe<QPlatformAudioInput *> createAudioInput(QAudioInput *) override; QMaybe<QPlatformAudioOutput *> createAudioOutput(QAudioOutput *) override; - const QGstreamerFormatInfo *gstFormatsInfo() const; + const QGstreamerFormatInfo *gstFormatsInfo(); GstDevice *videoDevice(const QByteArray &id) const; -private: - QGstreamerFormatInfo *m_formatsInfo; +protected: + QPlatformMediaFormatInfo *createFormatInfo() override; }; QT_END_NAMESPACE diff --git a/src/plugins/multimedia/qnx/qqnxmediaintegration.cpp b/src/plugins/multimedia/qnx/qqnxmediaintegration.cpp index 2e19cc032..a3348579b 100644 --- a/src/plugins/multimedia/qnx/qqnxmediaintegration.cpp +++ b/src/plugins/multimedia/qnx/qqnxmediaintegration.cpp @@ -37,16 +37,9 @@ QQnxMediaIntegration::QQnxMediaIntegration() m_videoDevices = std::make_unique<QQnxVideoDevices>(this); } -QQnxMediaIntegration::~QQnxMediaIntegration() +QPlatformMediaFormatInfo *QQnxMediaIntegration::createFormatInfo() { - delete m_formatInfo; -} - -QPlatformMediaFormatInfo *QQnxMediaIntegration::formatInfo() -{ - if (!m_formatInfo) - m_formatInfo = new QQnxFormatInfo(); - return m_formatInfo; + return new QQnxFormatInfo; } QMaybe<QPlatformVideoSink *> QQnxMediaIntegration::createVideoSink(QVideoSink *sink) diff --git a/src/plugins/multimedia/qnx/qqnxmediaintegration_p.h b/src/plugins/multimedia/qnx/qqnxmediaintegration_p.h index 1cb7c0219..21ad0d81f 100644 --- a/src/plugins/multimedia/qnx/qqnxmediaintegration_p.h +++ b/src/plugins/multimedia/qnx/qqnxmediaintegration_p.h @@ -26,9 +26,6 @@ class QQnxMediaIntegration : public QPlatformMediaIntegration { public: QQnxMediaIntegration(); - ~QQnxMediaIntegration(); - - QPlatformMediaFormatInfo *formatInfo() override; QMaybe<QPlatformVideoSink *> createVideoSink(QVideoSink *sink) override; @@ -42,7 +39,8 @@ public: QMaybe<QPlatformImageCapture *> createImageCapture(QImageCapture *parent) override; - QQnxFormatInfo *m_formatInfo = nullptr; +protected: + QPlatformMediaFormatInfo *createFormatInfo() override; }; QT_END_NAMESPACE diff --git a/src/plugins/multimedia/wasm/qwasmmediaintegration.cpp b/src/plugins/multimedia/wasm/qwasmmediaintegration.cpp index 2458bdc7c..c1f9810ce 100644 --- a/src/plugins/multimedia/wasm/qwasmmediaintegration.cpp +++ b/src/plugins/multimedia/wasm/qwasmmediaintegration.cpp @@ -51,11 +51,6 @@ QWasmMediaIntegration::QWasmMediaIntegration() m_videoDevices = std::make_unique<QWasmCameraDevices>(this); } -QWasmMediaIntegration::~QWasmMediaIntegration() -{ - delete m_formatInfo; -} - QMaybe<QPlatformMediaPlayer *> QWasmMediaIntegration::createPlayer(QMediaPlayer *player) { return new QWasmMediaPlayer(player); @@ -76,12 +71,10 @@ QMaybe<QPlatformAudioOutput *> QWasmMediaIntegration::createAudioOutput(QAudioOu return new QWasmAudioOutput(q); } -QPlatformMediaFormatInfo *QWasmMediaIntegration::formatInfo() +QPlatformMediaFormatInfo *QWasmMediaIntegration::createFormatInfo() { - if (!m_formatInfo) { - m_formatInfo = new QPlatformMediaFormatInfo(); - } - return m_formatInfo; + // TODO: create custom implementation + return new QPlatformMediaFormatInfo; } QMaybe<QPlatformMediaCaptureSession *> QWasmMediaIntegration::createCaptureSession() diff --git a/src/plugins/multimedia/wasm/qwasmmediaintegration_p.h b/src/plugins/multimedia/wasm/qwasmmediaintegration_p.h index 75af8a731..ca5dce34f 100644 --- a/src/plugins/multimedia/wasm/qwasmmediaintegration_p.h +++ b/src/plugins/multimedia/wasm/qwasmmediaintegration_p.h @@ -27,11 +27,6 @@ class QWasmMediaIntegration : public QPlatformMediaIntegration { public: QWasmMediaIntegration(); - ~QWasmMediaIntegration() override; - - QPlatformMediaFormatInfo *formatInfo() override; - - QPlatformMediaFormatInfo *m_formatInfo = nullptr; QMaybe<QPlatformMediaPlayer *> createPlayer(QMediaPlayer *player) override; QMaybe<QPlatformVideoSink *> createVideoSink(QVideoSink *sink) override; @@ -44,6 +39,9 @@ public: QMaybe<QPlatformMediaRecorder *> createRecorder(QMediaRecorder *recorder) override; QMaybe<QPlatformImageCapture *> createImageCapture(QImageCapture *imageCapture) override; QList<QCameraDevice> videoInputs() override; + +protected: + QPlatformMediaFormatInfo *createFormatInfo() override; }; QT_END_NAMESPACE diff --git a/src/plugins/multimedia/windows/qwindowsintegration.cpp b/src/plugins/multimedia/windows/qwindowsintegration.cpp index aff3dd9a4..279c0992b 100644 --- a/src/plugins/multimedia/windows/qwindowsintegration.cpp +++ b/src/plugins/multimedia/windows/qwindowsintegration.cpp @@ -43,17 +43,13 @@ QWindowsMediaIntegration::QWindowsMediaIntegration() QWindowsMediaIntegration::~QWindowsMediaIntegration() { - delete m_formatInfo; - MFShutdown(); CoUninitialize(); } -QPlatformMediaFormatInfo *QWindowsMediaIntegration::formatInfo() +QPlatformMediaFormatInfo *QWindowsMediaIntegration::createFormatInfo() { - if (!m_formatInfo) - m_formatInfo = new QWindowsFormatInfo(); - return m_formatInfo; + return new QWindowsFormatInfo(); } QMaybe<QPlatformMediaCaptureSession *> QWindowsMediaIntegration::createCaptureSession() diff --git a/src/plugins/multimedia/windows/qwindowsintegration_p.h b/src/plugins/multimedia/windows/qwindowsintegration_p.h index 81f5b4572..cc6aa4825 100644 --- a/src/plugins/multimedia/windows/qwindowsintegration_p.h +++ b/src/plugins/multimedia/windows/qwindowsintegration_p.h @@ -29,8 +29,6 @@ public: QWindowsMediaIntegration(); ~QWindowsMediaIntegration(); - QPlatformMediaFormatInfo *formatInfo() override; - QMaybe<QPlatformMediaCaptureSession *> createCaptureSession() override; QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *decoder) override; @@ -41,7 +39,8 @@ public: QMaybe<QPlatformVideoSink *> createVideoSink(QVideoSink *sink) override; - QWindowsFormatInfo *m_formatInfo = nullptr; +protected: + QPlatformMediaFormatInfo *createFormatInfo() override; }; QT_END_NAMESPACE diff --git a/tests/auto/unit/mockbackend/qmockintegration.h b/tests/auto/unit/mockbackend/qmockintegration.h index bc2d31ec1..f361f685f 100644 --- a/tests/auto/unit/mockbackend/qmockintegration.h +++ b/tests/auto/unit/mockbackend/qmockintegration.h @@ -36,8 +36,6 @@ public: return static_cast<QMockIntegration *>(QPlatformMediaIntegration::instance()); } - QPlatformMediaFormatInfo *formatInfo() override { return nullptr; } - QMaybe<QPlatformAudioDecoder *> createAudioDecoder(QAudioDecoder *decoder) override; QMaybe<QPlatformMediaPlayer *> createPlayer(QMediaPlayer *) override; QMaybe<QPlatformCamera *> createCamera(QCamera *) override; |