diff options
19 files changed, 246 insertions, 569 deletions
diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index db236093e..02805469b 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -680,27 +680,7 @@ void QMediaPlayer::setActiveSubtitleTrack(int index) d->control->setActiveTrack(QPlatformMediaPlayer::SubtitleStream, index); } -/*! - Attach a video \a output to the media player. - - If the media player has already video output attached, - it will be replaced with a new one. -*/ -void QMediaPlayer::setVideoOutput(const QVariant &output) -{ - QVideoSink *s = output.value<QVideoSink *>(); - if (s) { - setVideoOutput(s); - return; - } - QObject *o = output.value<QObject *>(); - if (o) { - setVideoOutput(o); - return; - } -} - -QVariant QMediaPlayer::videoOutput() const +QObject *QMediaPlayer::videoOutput() const { Q_D(const QMediaPlayer); return d->videoOutput; @@ -717,35 +697,37 @@ void QMediaPlayer::setVideoOutput(QObject *output) Q_D(QMediaPlayer); if (!d->control) return; + if (d->videoOutput == output) + return; - QVideoSink *sink = nullptr; - if (output) { + QVideoSink *sink = qobject_cast<QVideoSink *>(output); + if (!sink && output) { auto *mo = output->metaObject(); if (output) mo->invokeMethod(output, "videoSink", Q_RETURN_ARG(QVideoSink *, sink)); } - QVariant out = QVariant::fromValue(output); - if (d->videoOutput == out) - return; - d->videoOutput = out; - d->control->setVideoSink(sink); - emit videoOutputChanged(); + d->videoOutput = output; + d->setVideoSink(sink); } -void QMediaPlayer::setVideoOutput(QVideoSink *sink) +void QMediaPlayer::setVideoSink(QVideoSink *sink) { Q_D(QMediaPlayer); if (!d->control) return; - QVariant out = QVariant::fromValue(sink); - if (d->videoOutput == out) - return; - d->videoOutput = out; - d->control->setVideoSink(sink); - emit videoOutputChanged(); + d->videoOutput = nullptr; + d->setVideoSink(sink); } +QVideoSink *QMediaPlayer::videoSink() const +{ + Q_D(const QMediaPlayer); + return d->videoSink; +} + + +#if 0 /*! \since 5.15 Sets multiple video sinks as the video output of a media player. @@ -760,6 +742,7 @@ void QMediaPlayer::setVideoOutput(const QList<QVideoSink *> &sinks) Q_UNUSED(sinks); // setVideoOutput(!surfaces.empty() ? new QVideoSurfaces(surfaces, this) : nullptr); } +#endif /*! Returns true if the media player is supported on this platform. diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h index 746725ebb..4ee762fed 100644 --- a/src/multimedia/playback/qmediaplayer.h +++ b/src/multimedia/playback/qmediaplayer.h @@ -73,7 +73,7 @@ class Q_MULTIMEDIA_EXPORT QMediaPlayer : public QObject Q_PROPERTY(QMediaMetaData metaData READ metaData NOTIFY metaDataChanged) Q_PROPERTY(Error error READ error NOTIFY errorChanged) Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged) - Q_PROPERTY(QVariant videoOutput READ videoOutput WRITE setVideoOutput NOTIFY videoOutputChanged) + Q_PROPERTY(QObject *videoOutput READ videoOutput WRITE setVideoOutput NOTIFY videoOutputChanged) Q_ENUMS(PlaybackState) Q_ENUMS(MediaStatus) Q_ENUMS(Error) @@ -129,12 +129,14 @@ public: void setActiveVideoTrack(int index); void setActiveSubtitleTrack(int index); - void setVideoOutput(const QVariant &output); - QVariant videoOutput() const; - void setVideoOutput(QObject *); + QObject *videoOutput() const; +#if 0 void setVideoOutput(const QList<QVideoSink *> &sinks); - void setVideoOutput(QVideoSink *sink); +#endif + + void setVideoSink(QVideoSink *sink); + QVideoSink *videoSink() const; QUrl source() const; const QIODevice *sourceStream() const; diff --git a/src/multimedia/playback/qmediaplayer_p.h b/src/multimedia/playback/qmediaplayer_p.h index 9c609de28..ee519fb86 100644 --- a/src/multimedia/playback/qmediaplayer_p.h +++ b/src/multimedia/playback/qmediaplayer_p.h @@ -53,6 +53,7 @@ #include "qmediaplayer.h" #include "qmediametadata.h" +#include "qvideosink.h" #include <private/qplatformmediaplayer_p.h> #include "private/qobject_p.h" @@ -76,7 +77,8 @@ public: QPlatformMediaPlayer* control = nullptr; QString errorString; - QVariant videoOutput; + QVideoSink *videoSink = nullptr; + QPointer<QObject> videoOutput; QUrl qrcMedia; QScopedPointer<QFile> qrcFile; QUrl source; @@ -95,6 +97,20 @@ public: void setState(QMediaPlayer::PlaybackState state); void setStatus(QMediaPlayer::MediaStatus status); void setError(int error, const QString &errorString); + + void setVideoSink(QVideoSink *sink) + { + Q_Q(QMediaPlayer); + if (sink == videoSink) + return; + if (videoSink) + videoSink->setSource(nullptr); + videoSink = sink; + if (sink) + sink->setSource(q); + control->setVideoSink(sink); + emit q->videoOutputChanged(); + } }; QT_END_NAMESPACE diff --git a/src/multimedia/recording/qmediacapturesession.cpp b/src/multimedia/recording/qmediacapturesession.cpp index 727f5bac6..6e9df9c8d 100644 --- a/src/multimedia/recording/qmediacapturesession.cpp +++ b/src/multimedia/recording/qmediacapturesession.cpp @@ -44,6 +44,8 @@ #include "qcameraimagecapture.h" #include "qvideosink.h" +#include <qpointer.h> + #include "qplatformmediaintegration_p.h" #include "qplatformmediacapture_p.h" @@ -58,28 +60,18 @@ public: QCamera *camera = nullptr; QCameraImageCapture *imageCapture = nullptr; QMediaEncoder *encoder = nullptr; - QVariant videoOutput; QVideoSink *videoSink = nullptr; - - void _q_sinkDestroyed(QObject *sink) - { - if (sink == videoSink) { - captureSession->setVideoPreview(nullptr); - videoOutput = {}; - videoSink = nullptr; - } - } + QPointer<QObject> videoOutput; void setVideoSink(QVideoSink *sink) { + if (sink == videoSink) + return; if (videoSink) - QObject::disconnect(videoSink, SIGNAL(destroyed(QObject *)), q, SLOT(_q_sinkDestroyed(QObject *))); + videoSink->setSource(nullptr); videoSink = sink; - if (videoSink) - QObject::connect(videoSink, SIGNAL(destroyed(QObject *)), q, SLOT(_q_sinkDestroyed(QObject *))); - else - videoOutput = {}; - + if (sink) + sink->setSource(q); captureSession->setVideoPreview(sink); emit q->videoOutputChanged(); } @@ -286,27 +278,7 @@ void QMediaCaptureSession::setEncoder(QMediaEncoder *encoder) emit encoderChanged(); } -/*! - Attach a video \a output to the media player. - - If the media player has already video output attached, - it will be replaced with a new one. -*/ -void QMediaCaptureSession::setVideoOutput(const QVariant &output) -{ - QVideoSink *s = output.value<QVideoSink *>(); - if (s) { - setVideoOutput(s); - return; - } - QObject *o = output.value<QObject *>(); - if (o) { - setVideoOutput(o); - return; - } -} - -QVariant QMediaCaptureSession::videoOutput() const +QObject *QMediaCaptureSession::videoOutput() const { Q_D(const QMediaCaptureSession); return d->videoOutput; @@ -323,28 +295,30 @@ QVariant QMediaCaptureSession::videoOutput() const void QMediaCaptureSession::setVideoOutput(QObject *output) { Q_D(QMediaCaptureSession); - QVariant out = QVariant::fromValue(output); - if (d->videoOutput == out) + if (d->videoOutput == output) return; - d->videoOutput = out; - QVideoSink *sink = nullptr; - if (output) { + QVideoSink *sink = qobject_cast<QVideoSink *>(output); + if (!sink && output) { auto *mo = output->metaObject(); mo->invokeMethod(output, "videoSink", Q_RETURN_ARG(QVideoSink *, sink)); } + d->videoOutput = output; d->setVideoSink(sink); } -void QMediaCaptureSession::setVideoOutput(QVideoSink *sink) +void QMediaCaptureSession::setVideoSink(QVideoSink *sink) { Q_D(QMediaCaptureSession); - QVariant out = QVariant::fromValue(sink); - if (d->videoOutput == out) - return; - d->videoOutput = out; + d->videoOutput = nullptr; d->setVideoSink(sink); } +QVideoSink *QMediaCaptureSession::videoSink() const +{ + Q_D(const QMediaCaptureSession); + return d->videoSink; +} + /*! \internal */ diff --git a/src/multimedia/recording/qmediacapturesession.h b/src/multimedia/recording/qmediacapturesession.h index 9b6178579..23701a938 100644 --- a/src/multimedia/recording/qmediacapturesession.h +++ b/src/multimedia/recording/qmediacapturesession.h @@ -63,7 +63,7 @@ class Q_MULTIMEDIA_EXPORT QMediaCaptureSession : public QObject Q_PROPERTY(QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged) Q_PROPERTY(QCameraImageCapture *imageCapture READ imageCapture WRITE setImageCapture NOTIFY imageCaptureChanged) Q_PROPERTY(QMediaEncoder *encoder READ encoder WRITE setEncoder NOTIFY encoderChanged) - Q_PROPERTY(QVariant videoOutput READ videoOutput WRITE setVideoOutput NOTIFY videoOutputChanged) + Q_PROPERTY(QObject *videoOutput READ videoOutput WRITE setVideoOutput NOTIFY videoOutputChanged) public: explicit QMediaCaptureSession(QObject *parent = nullptr); ~QMediaCaptureSession(); @@ -87,11 +87,11 @@ public: QMediaEncoder *encoder(); void setEncoder(QMediaEncoder *recorder); - void setVideoOutput(const QVariant &output); - QVariant videoOutput() const; - void setVideoOutput(QObject *preview); - void setVideoOutput(QVideoSink *preview); + QObject *videoOutput() const; + + void setVideoSink(QVideoSink *preview); + QVideoSink *videoSink() const; QPlatformMediaCaptureSession *platformSession() const; @@ -108,7 +108,6 @@ private: QMediaCaptureSessionPrivate *d_ptr; Q_DISABLE_COPY(QMediaCaptureSession) Q_DECLARE_PRIVATE(QMediaCaptureSession) - Q_PRIVATE_SLOT(d_func(), void _q_sinkDestroyed(QObject *)) }; QT_END_NAMESPACE diff --git a/src/multimedia/recording/qmediarecorder.cpp b/src/multimedia/recording/qmediarecorder.cpp index 3a2fe5315..72e9b199b 100644 --- a/src/multimedia/recording/qmediarecorder.cpp +++ b/src/multimedia/recording/qmediarecorder.cpp @@ -460,12 +460,7 @@ QMediaCaptureSession *QMediaRecorder::captureSession() const return d->captureSession; } -void QMediaRecorder::setVideoOutput(const QVariant &output) -{ - d_ptr->captureSession->setVideoOutput(output); -} - -QVariant QMediaRecorder::videoOutput() const +QObject *QMediaRecorder::videoOutput() const { return d_ptr->captureSession->videoOutput(); } @@ -475,11 +470,17 @@ void QMediaRecorder::setVideoOutput(QObject *output) d_ptr->captureSession->setVideoOutput(output); } -void QMediaRecorder::setVideoOutput(QVideoSink *output) +void QMediaRecorder::setVideoSink(QVideoSink *output) { - d_ptr->captureSession->setVideoOutput(output); + d_ptr->captureSession->setVideoSink(output); } +QVideoSink *QMediaRecorder::videoSink() const +{ + return d_ptr->captureSession->videoSink(); +} + + /*! \fn QMediaRecorder::videoOutputChanged() diff --git a/src/multimedia/recording/qmediarecorder.h b/src/multimedia/recording/qmediarecorder.h index b6ea41c36..e887f58c5 100644 --- a/src/multimedia/recording/qmediarecorder.h +++ b/src/multimedia/recording/qmediarecorder.h @@ -58,7 +58,7 @@ class Q_MULTIMEDIA_EXPORT QMediaRecorder : public QMediaEncoderBase Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged) Q_PROPERTY(QMediaMetaData metaData READ metaData WRITE setMetaData NOTIFY metaDataChanged) Q_PROPERTY(CaptureMode captureMode READ captureMode WRITE setCaptureMode NOTIFY captureModeChanged) - Q_PROPERTY(QVariant videoOutput READ videoOutput WRITE setVideoOutput NOTIFY videoOutputChanged) + Q_PROPERTY(QObject *videoOutput READ videoOutput WRITE setVideoOutput NOTIFY videoOutputChanged) Q_PROPERTY(QCamera camera READ camera) public: @@ -101,11 +101,11 @@ public: QMediaCaptureSession *captureSession() const; - void setVideoOutput(const QVariant &output); - QVariant videoOutput() const; - void setVideoOutput(QObject *output); - void setVideoOutput(QVideoSink *output); + QObject *videoOutput() const; + + void setVideoSink(QVideoSink *output); + QVideoSink *videoSink() const; public Q_SLOTS: void record(); diff --git a/src/multimedia/video/qvideosink.cpp b/src/multimedia/video/qvideosink.cpp index 22692ddd7..3776b603b 100644 --- a/src/multimedia/video/qvideosink.cpp +++ b/src/multimedia/video/qvideosink.cpp @@ -41,6 +41,8 @@ #include "qvideoframeformat.h" #include "qvideoframe.h" +#include "qmediaplayer.h" +#include "qmediacapturesession.h" #include <qvariant.h> #include <qpainter.h> @@ -62,8 +64,21 @@ public: { delete videoSink; } + void unregisterSource() + { + if (!source) + return; + auto *old = source; + source = nullptr; + if (auto *player = qobject_cast<QMediaPlayer *>(old)) + player->setVideoSink(nullptr); + else if (auto *capture = qobject_cast<QMediaCaptureSession *>(old)) + capture->setVideoSink(nullptr); + } + QVideoSink *q_ptr = nullptr; QPlatformVideoSink *videoSink = nullptr; + QObject *source = nullptr; bool fullScreen = false; WId window = 0; QRhi *rhi = nullptr; @@ -117,6 +132,7 @@ QVideoSink::QVideoSink(QObject *parent) */ QVideoSink::~QVideoSink() { + d->unregisterSource(); delete d; } @@ -386,6 +402,15 @@ QSize QVideoSink::videoSize() const return d->videoSink->nativeSize(); } +void QVideoSink::setSource(QObject *source) +{ + if (d->source == source) + return; + if (source) + d->unregisterSource(); + d->source = source; +} + QT_END_NAMESPACE #include "moc_qvideosink.cpp" diff --git a/src/multimedia/video/qvideosink.h b/src/multimedia/video/qvideosink.h index 7802c32ed..93506db37 100644 --- a/src/multimedia/video/qvideosink.h +++ b/src/multimedia/video/qvideosink.h @@ -109,6 +109,10 @@ Q_SIGNALS: void aspectRatioModeChanged(Qt::AspectRatioMode mode); private: + friend class QMediaPlayerPrivate; + friend class QMediaCaptureSessionPrivate; + void setSource(QObject *source); + QVideoSinkPrivate *d = nullptr; }; diff --git a/src/multimediaquick/qquickvideooutput.cpp b/src/multimediaquick/qquickvideooutput.cpp index 14eb2cd68..14b9e43d2 100644 --- a/src/multimediaquick/qquickvideooutput.cpp +++ b/src/multimediaquick/qquickvideooutput.cpp @@ -125,7 +125,6 @@ Q_LOGGING_CATEGORY(qLcVideo, "qt.multimedia.video") QQuickVideoOutput::QQuickVideoOutput(QQuickItem *parent) : QQuickItem(parent), - m_fillMode(PreserveAspectFit), m_geometryDirty(true), m_orientation(0), m_autoOrientation(false), @@ -183,15 +182,16 @@ bool QQuickVideoOutput::createBackend() QQuickVideoOutput::FillMode QQuickVideoOutput::fillMode() const { - return m_fillMode; + return FillMode(videoSink()->aspectRatioMode()); } void QQuickVideoOutput::setFillMode(FillMode mode) { - if (mode == m_fillMode) + if (mode == fillMode()) return; - m_fillMode = mode; + videoSink()->setAspectRatioMode(Qt::AspectRatioMode(mode)); + m_geometryDirty = true; update(); @@ -235,15 +235,16 @@ void QQuickVideoOutput::_q_updateGeometry() m_geometryDirty = false; m_lastRect = absoluteRect; + const auto fill = fillMode(); if (m_nativeSize.isEmpty()) { //this is necessary for item to receive the //first paint event and configure video surface. m_contentRect = rect; - } else if (m_fillMode == Stretch) { + } else if (fill == Stretch) { m_contentRect = rect; - } else if (m_fillMode == PreserveAspectFit || m_fillMode == PreserveAspectCrop) { + } else if (fill == PreserveAspectFit || fill == PreserveAspectCrop) { QSizeF scaled = m_nativeSize; - scaled.scale(rect.size(), m_fillMode == PreserveAspectFit ? + scaled.scale(rect.size(), fill == PreserveAspectFit ? Qt::KeepAspectRatio : Qt::KeepAspectRatioByExpanding); m_contentRect = QRectF(QPointF(), scaled); diff --git a/src/multimediaquick/qquickvideooutput_p.h b/src/multimediaquick/qquickvideooutput_p.h index 453ef9b63..fc9199fe3 100644 --- a/src/multimediaquick/qquickvideooutput_p.h +++ b/src/multimediaquick/qquickvideooutput_p.h @@ -143,7 +143,6 @@ private Q_SLOTS: private: bool createBackend(); - FillMode m_fillMode; QSize m_nativeSize; bool m_geometryDirty; diff --git a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp index af26ac2e0..2a91da3d4 100644 --- a/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp +++ b/tests/auto/integration/qmediaplayerbackend/tst_qmediaplayerbackend.cpp @@ -73,7 +73,7 @@ private slots: void seekInStoppedState(); void subsequentPlayback(); void surfaceTest(); - void multipleSurfaces(); +// void multipleSurfaces(); void metadata(); void playerStateAtEOS(); void playFromBuffer(); @@ -968,6 +968,7 @@ void tst_QMediaPlayerBackend::surfaceTest() QVERIFY2(surface.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface.m_totalFrames))); } +#if 0 void tst_QMediaPlayerBackend::multipleSurfaces() { if (localVideoFile.isEmpty()) @@ -985,6 +986,7 @@ void tst_QMediaPlayerBackend::multipleSurfaces() // QVERIFY2(surface2.m_totalFrames >= 25, qPrintable(QString("Expected >= 25, got %1").arg(surface2.m_totalFrames))); // QCOMPARE(surface1.m_totalFrames, surface2.m_totalFrames); } +#endif void tst_QMediaPlayerBackend::metadata() { diff --git a/tests/auto/integration/qquickvideooutput/CMakeLists.txt b/tests/auto/integration/qquickvideooutput/CMakeLists.txt index b539b2f46..a7dba4296 100644 --- a/tests/auto/integration/qquickvideooutput/CMakeLists.txt +++ b/tests/auto/integration/qquickvideooutput/CMakeLists.txt @@ -4,7 +4,7 @@ ## tst_qdeclarativevideooutput Test: ##################################################################### -qt_add_test(tst_qdeclarativevideooutput +qt_add_test(tst_qquickvideooutput SOURCES tst_qquickvideooutput.cpp INCLUDE_DIRECTORIES @@ -22,7 +22,7 @@ set(qml_resource_files "main.qml" ) -qt_add_resource(tst_qdeclarativevideooutput "qml" +qt_add_resource(tst_qquickvideooutput "qml" PREFIX "/" FILES diff --git a/tests/auto/integration/qquickvideooutput/tst_qquickvideooutput.cpp b/tests/auto/integration/qquickvideooutput/tst_qquickvideooutput.cpp index d9f9eb689..83b0d4c81 100644 --- a/tests/auto/integration/qquickvideooutput/tst_qquickvideooutput.cpp +++ b/tests/auto/integration/qquickvideooutput/tst_qquickvideooutput.cpp @@ -34,6 +34,7 @@ #include <QtQml/qqmlcomponent.h> #include <QQuickView> #include <QVideoSink> +#include <QMediaPlayer> #include "private/qquickvideooutput_p.h" @@ -41,41 +42,13 @@ #include <qvideoframeformat.h> #include <qvideoframe.h> -class SurfaceHolder : public QObject +void presentDummyFrame(QVideoSink *sink, const QSize &size) { - Q_OBJECT - Q_PROPERTY(QVideoSink *videoSurface READ videoSurface WRITE setVideoSurface) -public: - SurfaceHolder(QObject *parent) - : QObject(parent) - , m_surface(nullptr) - { - } - - [[nodiscard]] QVideoSink *videoSurface() const - { - return m_surface; - } - void setVideoSurface(QVideoSink *surface) - { - m_surface = surface; - } - - void presentDummyFrame(const QSize &size); - -private: - QVideoSink *m_surface; - -}; - -// Starts the surface and puts a frame -void SurfaceHolder::presentDummyFrame(const QSize &size) -{ - if (m_surface) { + if (sink) { QVideoFrameFormat format(size, QVideoFrameFormat::Format_ARGB32_Premultiplied); QVideoFrame frame(format); - m_surface->newVideoFrame(frame); + sink->newVideoFrame(frame); // Have to spin an event loop or two for the surfaceFormatChanged() signal qApp->processEvents(); @@ -91,7 +64,6 @@ public: ~tst_QQuickVideoOutput() override { delete m_mappingOutput; - delete m_mappingSurface; delete m_mappingComponent; } @@ -109,26 +81,14 @@ private slots: void contentRect(); void contentRect_data(); - void mappingPoint(); - void mappingPoint_data(); - void mappingRect(); - void mappingRect_data(); - - // XXX May be worth adding tests that the surface activeChanged signals are sent appropriately - // to holder? - private: QQmlEngine m_engine; // Variables used for the mapping test QQmlComponent *m_mappingComponent = nullptr; - QObject *m_mappingOutput = nullptr; - SurfaceHolder *m_mappingSurface = nullptr; + QQuickVideoOutput *m_mappingOutput = nullptr; void updateOutputGeometry(QObject *output); - - QRectF invokeR2R(QObject *object, const char *signature, const QRectF &rect); - QPointF invokeP2P(QObject *object, const char *signature, const QPointF &point); }; void tst_QQuickVideoOutput::initTestCase() @@ -136,15 +96,17 @@ void tst_QQuickVideoOutput::initTestCase() // We initialize the mapping vars here m_mappingComponent = new QQmlComponent(&m_engine); m_mappingComponent->loadUrl(QUrl("qrc:/main.qml")); - m_mappingSurface = new SurfaceHolder(this); - m_mappingOutput = m_mappingComponent->create(); - QVERIFY(m_mappingOutput != nullptr); + auto *component = m_mappingComponent->create(); + QVERIFY(component != nullptr); - m_mappingOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(m_mappingSurface))); + m_mappingOutput = qobject_cast<QQuickVideoOutput *>(component); + QVERIFY(m_mappingOutput); - m_mappingSurface->presentDummyFrame(QSize(200,100)); // this should start m_surface + presentDummyFrame(m_mappingOutput->videoSink(), QSize(200,100)); updateOutputGeometry(m_mappingOutput); + // First make sure the component has processed the frame + QCOMPARE(m_mappingOutput->sourceRect(), QRectF(0, 0, 200,100)); } tst_QQuickVideoOutput::tst_QQuickVideoOutput() @@ -259,61 +221,63 @@ void tst_QQuickVideoOutput::surfaceSource() QObject *videoOutput = component.create(); QVERIFY(videoOutput != nullptr); - SurfaceHolder holder(this); + QMediaPlayer holder(this); - QCOMPARE(holder.videoSurface(), static_cast<QVideoSink *>(nullptr)); + QCOMPARE(holder.videoOutput(), nullptr); - videoOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); + holder.setVideoOutput(videoOutput); - QVERIFY(holder.videoSurface() != nullptr); + QVERIFY(holder.videoOutput() != nullptr); + QVERIFY(holder.videoSink() != nullptr); delete videoOutput; // This should clear the surface - QCOMPARE(holder.videoSurface(), static_cast<QVideoSink *>(nullptr)); + QVERIFY(holder.videoOutput() == nullptr); + QVERIFY(holder.videoSink() == nullptr); // Also, creating two sources, setting them in order, and destroying the first - // should not zero holder.videoSurface() + // should not zero holder.videoSink() videoOutput = component.create(); - videoOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); + holder.setVideoOutput(videoOutput); - QVideoSink *surface = holder.videoSurface(); - QVERIFY(holder.videoSurface()); + QObject *surface = holder.videoOutput(); + QVERIFY(surface != nullptr); QObject *videoOutput2 = component.create(); QVERIFY(videoOutput2); - videoOutput2->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); - QVERIFY(holder.videoSurface()); - QVERIFY(holder.videoSurface() != surface); // Surface should have changed - surface = holder.videoSurface(); + holder.setVideoOutput(videoOutput2); + QVERIFY(holder.videoOutput() != nullptr); + QVERIFY(holder.videoOutput() != surface); // Surface should have changed + surface = holder.videoOutput(); + QVERIFY(surface == videoOutput2); // Now delete first one delete videoOutput; - QVERIFY(holder.videoSurface()); - QVERIFY(holder.videoSurface() == surface); // Should not have changed surface + QVERIFY(holder.videoOutput() == surface); // Should not have changed surface // Now create a second surface and assign it as the source // The old surface holder should be zeroed - SurfaceHolder holder2(this); - videoOutput2->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder2))); + QMediaPlayer holder2(this); + holder2.setVideoOutput(videoOutput2); - QCOMPARE(holder.videoSurface(), static_cast<QVideoSink*>(nullptr)); - QVERIFY(holder2.videoSurface() != nullptr); + QVERIFY(holder.videoOutput() == nullptr); + QVERIFY(holder2.videoOutput() != nullptr); // Finally a combination - set the same source to two things, then assign a new source // to the first output - should not reset the first source videoOutput = component.create(); - videoOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder2))); + holder2.setVideoOutput(videoOutput); // Both vo and vo2 were pointed to holder2 - setting vo2 should not clear holder2 - QVERIFY(holder2.videoSurface() != nullptr); - QVERIFY(holder.videoSurface() == nullptr); - videoOutput2->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); - QVERIFY(holder2.videoSurface() != nullptr); - QVERIFY(holder.videoSurface() != nullptr); + QVERIFY(holder2.videoOutput() != nullptr); + QVERIFY(holder.videoOutput() == nullptr); + holder.setVideoOutput(videoOutput2); + QVERIFY(holder2.videoOutput() != nullptr); + QVERIFY(holder.videoOutput() != nullptr); // They should also be independent - QVERIFY(holder.videoSurface() != holder2.videoSurface()); + QVERIFY(holder.videoOutput() != holder2.videoOutput()); delete videoOutput; delete videoOutput2; @@ -322,6 +286,12 @@ void tst_QQuickVideoOutput::surfaceSource() static const uchar rgb32ImageData[] = {// B G R A 0x00, 0x01, 0x02, 0xff, 0x03, 0x04, 0x05, 0xff, + 0x06, 0x07, 0x08, 0xff, 0x09, 0x0a, 0x0b, 0xff, + 0x00, 0x01, 0x02, 0xff, 0x03, 0x04, 0x05, 0xff, + 0x06, 0x07, 0x08, 0xff, 0x09, 0x0a, 0x0b, 0xff, + 0x00, 0x01, 0x02, 0xff, 0x03, 0x04, 0x05, 0xff, + 0x06, 0x07, 0x08, 0xff, 0x09, 0x0a, 0x0b, 0xff, + 0x00, 0x01, 0x02, 0xff, 0x03, 0x04, 0x05, 0xff, 0x06, 0x07, 0x08, 0xff, 0x09, 0x0a, 0x0b, 0xff }; @@ -335,14 +305,14 @@ void tst_QQuickVideoOutput::paintSurface() auto videoOutput = qobject_cast<QQuickVideoOutput *>(window.rootObject()); QVERIFY(videoOutput); - auto surface = videoOutput->property("videoSurface").value<QVideoSink *>(); + auto surface = videoOutput->videoSink(); QVERIFY(surface); videoOutput->setSize(QSize(2, 2)); - QVideoFrame frame(QVideoFrameFormat(QSize(2, 2), QVideoFrameFormat::Format_ARGB32)); + QVideoFrame frame(QVideoFrameFormat(QSize(4, 4), QVideoFrameFormat::Format_ARGB32)); frame.map(QVideoFrame::ReadWrite); - QCOMPARE(frame.mappedBytes(), 16); - memcpy(frame.bits(), rgb32ImageData, 16); + QCOMPARE(frame.mappedBytes(), 64); + memcpy(frame.bits(), rgb32ImageData, 64); frame.unmap(); surface->newVideoFrame(frame); } @@ -355,23 +325,23 @@ void tst_QQuickVideoOutput::sourceRect() QObject *videoOutput = component.create(); QVERIFY(videoOutput != nullptr); - SurfaceHolder holder(this); + QMediaPlayer holder(this); QSignalSpy propSpy(videoOutput, SIGNAL(sourceRectChanged())); - videoOutput->setProperty("source", QVariant::fromValue(static_cast<QObject*>(&holder))); + holder.setVideoOutput(videoOutput); QRectF invalid(0,0,-1,-1); QCOMPARE(videoOutput->property("sourceRect").toRectF(), invalid); - holder.presentDummyFrame(QSize(200,100)); + presentDummyFrame(holder.videoSink(), QSize(200,100)); QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); QCOMPARE(propSpy.count(), 1); // Another frame shouldn't cause a source rect change - holder.presentDummyFrame(QSize(200,100)); + presentDummyFrame(holder.videoSink(), QSize(200,100)); QCOMPARE(propSpy.count(), 1); QCOMPARE(videoOutput->property("sourceRect").toRectF(), QRectF(0, 0, 200, 100)); @@ -407,226 +377,6 @@ void tst_QQuickVideoOutput::sourceRect() delete videoOutput; } -void tst_QQuickVideoOutput::mappingPoint() -{ - QFETCH(QPointF, point); - QFETCH(int, orientation); - QFETCH(QQuickVideoOutput::FillMode, fillMode); - QFETCH(QPointF, expected); - - QVERIFY(m_mappingOutput); - m_mappingOutput->setProperty("orientation", QVariant(orientation)); - m_mappingOutput->setProperty("fillMode", QVariant::fromValue(fillMode)); - - updateOutputGeometry(m_mappingOutput); - - QPointF output = invokeP2P(m_mappingOutput, "mapPointToItem", point); - QPointF reverse = invokeP2P(m_mappingOutput, "mapPointToSource", output); - - QCOMPARE(output, expected); - QCOMPARE(reverse, point); - - // Now the normalized versions - // Source rectangle is 200x100 - QPointF normal(point.x() / 200, point.y() / 100); - - output = invokeP2P(m_mappingOutput, "mapNormalizedPointToItem", normal); - reverse = invokeP2P(m_mappingOutput, "mapPointToSourceNormalized", output); - - QCOMPARE(output, expected); - QCOMPARE(reverse, normal); -} - -void tst_QQuickVideoOutput::mappingPoint_data() -{ - QTest::addColumn<QPointF>("point"); - QTest::addColumn<int>("orientation"); - QTest::addColumn<QQuickVideoOutput::FillMode>("fillMode"); - QTest::addColumn<QPointF>("expected"); - - QQuickVideoOutput::FillMode stretch = QQuickVideoOutput::Stretch; - QQuickVideoOutput::FillMode fit = QQuickVideoOutput::PreserveAspectFit; - QQuickVideoOutput::FillMode crop = QQuickVideoOutput::PreserveAspectCrop; - - // First make sure the component has processed the frame - QCOMPARE(m_mappingOutput->property("sourceRect").toRectF(), QRectF(0,0,200,100)); - - // 200x100 -> 150,100 stretch, 150x75 fit @ 12.5f, 200x100 @-25,0 crop - - // Corners, then the center, then a point in the middle somewhere - QTest::newRow("s0-0") << QPointF(0,0) << 0 << stretch << QPointF(0,0); - QTest::newRow("s1-0") << QPointF(200,0) << 0 << stretch << QPointF(150,0); - QTest::newRow("s2-0") << QPointF(0,100) << 0 << stretch << QPointF(0,100); - QTest::newRow("s3-0") << QPointF(200,100) << 0 << stretch << QPointF(150,100); - QTest::newRow("s4-0") << QPointF(100,50) << 0 << stretch << QPointF(75,50); - QTest::newRow("s5-0") << QPointF(40,80) << 0 << stretch << QPointF(30,80); - - QTest::newRow("f0-0") << QPointF(0,0) << 0 << fit << QPointF(0,12.5f); - QTest::newRow("f1-0") << QPointF(200,0) << 0 << fit << QPointF(150,12.5f); - QTest::newRow("f2-0") << QPointF(0,100) << 0 << fit << QPointF(0,87.5f); - QTest::newRow("f3-0") << QPointF(200,100) << 0 << fit << QPointF(150,87.5f); - QTest::newRow("f4-0") << QPointF(100,50) << 0 << stretch << QPointF(75,50); - QTest::newRow("f5-0") << QPointF(40,80) << 0 << stretch << QPointF(30,80); - - QTest::newRow("c0-0") << QPointF(0,0) << 0 << crop << QPointF(-25,0); - QTest::newRow("c1-0") << QPointF(200,0) << 0 << crop << QPointF(175,0); - QTest::newRow("c2-0") << QPointF(0,100) << 0 << crop << QPointF(-25,100); - QTest::newRow("c3-0") << QPointF(200,100) << 0 << crop << QPointF(175,100); - QTest::newRow("c4-0") << QPointF(100,50) << 0 << stretch << QPointF(75,50); - QTest::newRow("c5-0") << QPointF(40,80) << 0 << stretch << QPointF(30,80); - - // 90 degrees (anti clockwise) - QTest::newRow("s0-90") << QPointF(0,0) << 90 << stretch << QPointF(0,100); - QTest::newRow("s1-90") << QPointF(200,0) << 90 << stretch << QPointF(0,0); - QTest::newRow("s2-90") << QPointF(0,100) << 90 << stretch << QPointF(150,100); - QTest::newRow("s3-90") << QPointF(200,100) << 90 << stretch << QPointF(150,0); - QTest::newRow("s4-90") << QPointF(100,50) << 90 << stretch << QPointF(75,50); - QTest::newRow("s5-90") << QPointF(40,80) << 90 << stretch << QPointF(120,80); - - QTest::newRow("f0-90") << QPointF(0,0) << 90 << fit << QPointF(50,100); - QTest::newRow("f1-90") << QPointF(200,0) << 90 << fit << QPointF(50,0); - QTest::newRow("f2-90") << QPointF(0,100) << 90 << fit << QPointF(100,100); - QTest::newRow("f3-90") << QPointF(200,100) << 90 << fit << QPointF(100,0); - QTest::newRow("f4-90") << QPointF(100,50) << 90 << fit << QPointF(75,50); - QTest::newRow("f5-90") << QPointF(40,80) << 90 << fit << QPointF(90,80); - - QTest::newRow("c0-90") << QPointF(0,0) << 90 << crop << QPointF(0,200); - QTest::newRow("c1-90") << QPointF(200,0) << 90 << crop << QPointF(0,-100); - QTest::newRow("c2-90") << QPointF(0,100) << 90 << crop << QPointF(150,200); - QTest::newRow("c3-90") << QPointF(200,100) << 90 << crop << QPointF(150,-100); - QTest::newRow("c4-90") << QPointF(100,50) << 90 << crop << QPointF(75,50); - QTest::newRow("c5-90") << QPointF(40,80) << 90 << crop << QPointF(120,140); - - // 180 - QTest::newRow("s0-180") << QPointF(0,0) << 180 << stretch << QPointF(150,100); - QTest::newRow("s1-180") << QPointF(200,0) << 180 << stretch << QPointF(0,100); - QTest::newRow("s2-180") << QPointF(0,100) << 180 << stretch << QPointF(150,0); - QTest::newRow("s3-180") << QPointF(200,100) << 180 << stretch << QPointF(0,0); - QTest::newRow("s4-180") << QPointF(100,50) << 180 << stretch << QPointF(75,50); - QTest::newRow("s5-180") << QPointF(40,80) << 180 << stretch << QPointF(120,20); - - QTest::newRow("f0-180") << QPointF(0,0) << 180 << fit << QPointF(150,87.5f); - QTest::newRow("f1-180") << QPointF(200,0) << 180 << fit << QPointF(0,87.5f); - QTest::newRow("f2-180") << QPointF(0,100) << 180 << fit << QPointF(150,12.5f); - QTest::newRow("f3-180") << QPointF(200,100) << 180 << fit << QPointF(0,12.5f); - QTest::newRow("f4-180") << QPointF(100,50) << 180 << fit << QPointF(75,50); - QTest::newRow("f5-180") << QPointF(40,80) << 180 << fit << QPointF(120,27.5f); - - QTest::newRow("c0-180") << QPointF(0,0) << 180 << crop << QPointF(175,100); - QTest::newRow("c1-180") << QPointF(200,0) << 180 << crop << QPointF(-25,100); - QTest::newRow("c2-180") << QPointF(0,100) << 180 << crop << QPointF(175,0); - QTest::newRow("c3-180") << QPointF(200,100) << 180 << crop << QPointF(-25,0); - QTest::newRow("c4-180") << QPointF(100,50) << 180 << crop << QPointF(75,50); - QTest::newRow("c5-180") << QPointF(40,80) << 180 << crop << QPointF(135,20); - - // 270 - QTest::newRow("s0-270") << QPointF(0,0) << 270 << stretch << QPointF(150,0); - QTest::newRow("s1-270") << QPointF(200,0) << 270 << stretch << QPointF(150,100); - QTest::newRow("s2-270") << QPointF(0,100) << 270 << stretch << QPointF(0,0); - QTest::newRow("s3-270") << QPointF(200,100) << 270 << stretch << QPointF(0,100); - QTest::newRow("s4-270") << QPointF(100,50) << 270 << stretch << QPointF(75,50); - QTest::newRow("s5-270") << QPointF(40,80) << 270 << stretch << QPointF(30,20); - - QTest::newRow("f0-270") << QPointF(0,0) << 270 << fit << QPointF(100,0); - QTest::newRow("f1-270") << QPointF(200,0) << 270 << fit << QPointF(100,100); - QTest::newRow("f2-270") << QPointF(0,100) << 270 << fit << QPointF(50,0); - QTest::newRow("f3-270") << QPointF(200,100) << 270 << fit << QPointF(50,100); - QTest::newRow("f4-270") << QPointF(100,50) << 270 << fit << QPointF(75,50); - QTest::newRow("f5-270") << QPointF(40,80) << 270 << fit << QPointF(60,20); - - QTest::newRow("c0-270") << QPointF(0,0) << 270 << crop << QPointF(150,-100); - QTest::newRow("c1-270") << QPointF(200,0) << 270 << crop << QPointF(150,200); - QTest::newRow("c2-270") << QPointF(0,100) << 270 << crop << QPointF(0,-100); - QTest::newRow("c3-270") << QPointF(200,100) << 270 << crop << QPointF(0,200); - QTest::newRow("c4-270") << QPointF(100,50) << 270 << crop << QPointF(75,50); - QTest::newRow("c5-270") << QPointF(40,80) << 270 << crop << QPointF(30,-40); -} - -/* Test all rectangle mapping */ -void tst_QQuickVideoOutput::mappingRect() -{ - QFETCH(QRectF, rect); - QFETCH(int, orientation); - QFETCH(QQuickVideoOutput::FillMode, fillMode); - QFETCH(QRectF, expected); - - QVERIFY(m_mappingOutput); - m_mappingOutput->setProperty("orientation", QVariant(orientation)); - m_mappingOutput->setProperty("fillMode", QVariant::fromValue(fillMode)); - - updateOutputGeometry(m_mappingOutput); - - QRectF output = invokeR2R(m_mappingOutput, "mapRectToItem", rect); - QRectF reverse = invokeR2R(m_mappingOutput, "mapRectToSource", output); - - QCOMPARE(output, expected); - QCOMPARE(reverse, rect); - - // Now the normalized versions - // Source rectangle is 200x100 - QRectF normal(rect.x() / 200, rect.y() / 100, rect.width() / 200, rect.height() / 100); - - output = invokeR2R(m_mappingOutput, "mapNormalizedRectToItem", normal); - reverse = invokeR2R(m_mappingOutput, "mapRectToSourceNormalized", output); - - QCOMPARE(output, expected); - QCOMPARE(reverse, normal); -} - -void tst_QQuickVideoOutput::mappingRect_data() -{ - QTest::addColumn<QRectF>("rect"); - QTest::addColumn<int>("orientation"); - QTest::addColumn<QQuickVideoOutput::FillMode>("fillMode"); - QTest::addColumn<QRectF>("expected"); - - // First make sure the component has processed the frame - QCOMPARE(m_mappingOutput->property("sourceRect").toRectF(), QRectF(0,0,200,100)); - - QQuickVideoOutput::FillMode stretch = QQuickVideoOutput::Stretch; - QQuickVideoOutput::FillMode fit = QQuickVideoOutput::PreserveAspectFit; - QQuickVideoOutput::FillMode crop = QQuickVideoOutput::PreserveAspectCrop; - - // Full rectangle mapping - // Stretch - QTest::newRow("s0") << QRectF(0,0, 200, 100) << 0 << stretch << QRectF(0,0,150,100); - QTest::newRow("s90") << QRectF(0,0, 200, 100) << 90 << stretch << QRectF(0,0,150,100); - QTest::newRow("s180") << QRectF(0,0, 200, 100) << 180 << stretch << QRectF(0,0,150,100); - QTest::newRow("s270") << QRectF(0,0, 200, 100) << 270 << stretch << QRectF(0,0,150,100); - - // Fit - QTest::newRow("f0") << QRectF(0,0, 200, 100) << 0 << fit << QRectF(0,12.5f,150,75); - QTest::newRow("f90") << QRectF(0,0, 200, 100) << 90 << fit << QRectF(50,0,50,100); - QTest::newRow("f180") << QRectF(0,0, 200, 100) << 180 << fit << QRectF(0,12.5f,150,75); - QTest::newRow("f270") << QRectF(0,0, 200, 100) << 270 << fit << QRectF(50,0,50,100); - - // Crop - QTest::newRow("c0") << QRectF(0,0, 200, 100) << 0 << crop << QRectF(-25,0,200,100); - QTest::newRow("c90") << QRectF(0,0, 200, 100) << 90 << crop << QRectF(0,-100,150,300); - QTest::newRow("c180") << QRectF(0,0, 200, 100) << 180 << crop << QRectF(-25,0,200,100); - QTest::newRow("c270") << QRectF(0,0, 200, 100) << 270 << crop << QRectF(0,-100,150,300); - - // Partial rectangle mapping - // Stretch - // 50-130 in x (0.25 - 0.65), 25-50 (0.25 - 0.5) in y (out of 200, 100) -> 150x100 - QTest::newRow("p-s0") << QRectF(50, 25, 80, 25) << 0 << stretch << QRectF(37.5f,25,60,25); - QTest::newRow("p-s90") << QRectF(50, 25, 80, 25) << 90 << stretch << QRectF(37.5f,35,37.5f,40); - QTest::newRow("p-s180") << QRectF(50, 25, 80, 25) << 180 << stretch << QRectF(52.5f,50,60,25); - QTest::newRow("p-s270") << QRectF(50, 25, 80, 25) << 270 << stretch << QRectF(75,25,37.5f,40); - - // Fit - QTest::newRow("p-f0") << QRectF(50, 25, 80, 25) << 0 << fit << QRectF(37.5f,31.25f,60,18.75f); - QTest::newRow("p-f90") << QRectF(50, 25, 80, 25) << 90 << fit << QRectF(62.5f,35,12.5f,40); - QTest::newRow("p-f180") << QRectF(50, 25, 80, 25) << 180 << fit << QRectF(52.5f,50,60,18.75f); - QTest::newRow("p-f270") << QRectF(50, 25, 80, 25) << 270 << fit << QRectF(75,25,12.5f,40); - - // Crop - QTest::newRow("p-c0") << QRectF(50, 25, 80, 25) << 0 << crop << QRectF(25,25,80,25); - QTest::newRow("p-c90") << QRectF(50, 25, 80, 25) << 90 << crop << QRectF(37.5f,5,37.5f,120); - QTest::newRow("p-c180") << QRectF(50, 25, 80, 25) << 180 << crop << QRectF(45,50,80,25); - QTest::newRow("p-c270") << QRectF(50, 25, 80, 25) << 270 << crop << QRectF(75,-25,37.5f,120); -} - void tst_QQuickVideoOutput::updateOutputGeometry(QObject *output) { // Since the object isn't visible, update() doesn't do anything @@ -656,9 +406,6 @@ void tst_QQuickVideoOutput::contentRect_data() QTest::addColumn<QQuickVideoOutput::FillMode>("fillMode"); QTest::addColumn<QRectF>("expected"); - // First make sure the component has processed the frame - QCOMPARE(m_mappingOutput->property("sourceRect").toRectF(), QRectF(0,0,200,100)); - QQuickVideoOutput::FillMode stretch = QQuickVideoOutput::Stretch; QQuickVideoOutput::FillMode fit = QQuickVideoOutput::PreserveAspectFit; QQuickVideoOutput::FillMode crop = QQuickVideoOutput::PreserveAspectCrop; @@ -686,22 +433,6 @@ void tst_QQuickVideoOutput::contentRect_data() QTest::newRow("c270") << 270 << crop << QRectF(0,-100,150,300); } - -QRectF tst_QQuickVideoOutput::invokeR2R(QObject *object, const char *signature, const QRectF &rect) -{ - QRectF r; - QMetaObject::invokeMethod(object, signature, Q_RETURN_ARG(QRectF, r), Q_ARG(QRectF, rect)); - return r; -} - -QPointF tst_QQuickVideoOutput::invokeP2P(QObject *object, const char *signature, const QPointF &point) -{ - QPointF p; - QMetaObject::invokeMethod(object, signature, Q_RETURN_ARG(QPointF, p), Q_ARG(QPointF, point)); - return p; -} - - QTEST_MAIN(tst_QQuickVideoOutput) #include "tst_qquickvideooutput.moc" diff --git a/tests/auto/integration/qquickvideooutput_window/CMakeLists.txt b/tests/auto/integration/qquickvideooutput_window/CMakeLists.txt index c0fc0db43..bda77ce88 100644 --- a/tests/auto/integration/qquickvideooutput_window/CMakeLists.txt +++ b/tests/auto/integration/qquickvideooutput_window/CMakeLists.txt @@ -4,7 +4,7 @@ ## tst_qdeclarativevideooutput_window Test: ##################################################################### -qt_add_test(tst_qdeclarativevideooutput_window +qt_add_test(tst_qquickvideooutput_window SOURCES tst_qquickvideooutput_window.cpp INCLUDE_DIRECTORIES @@ -22,7 +22,7 @@ set(qml_resource_files "main.qml" ) -qt_add_resource(tst_qdeclarativevideooutput_window "qml" +qt_add_resource(tst_qquickvideooutput_window "qml" PREFIX "/" FILES diff --git a/tests/auto/integration/qquickvideooutput_window/tst_qquickvideooutput_window.cpp b/tests/auto/integration/qquickvideooutput_window/tst_qquickvideooutput_window.cpp index d9f8e5304..ec824a61e 100644 --- a/tests/auto/integration/qquickvideooutput_window/tst_qquickvideooutput_window.cpp +++ b/tests/auto/integration/qquickvideooutput_window/tst_qquickvideooutput_window.cpp @@ -37,69 +37,7 @@ #include <QtQuick/qquickitem.h> #include <QtQuick/qquickview.h> #include <private/qplatformvideosink_p.h> - -class SourceObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(QObject *mediaSource READ mediaSource CONSTANT) -public: - explicit SourceObject(QObject *mediaSource, QObject *parent = nullptr) - : QObject(parent), m_mediaSource(mediaSource) - {} - - [[nodiscard]] QObject *mediaSource() const - { return m_mediaSource; } - -private: - QObject *m_mediaSource; -}; - -class QtTestWindowControl : public QPlatformVideoSink -{ -public: - QtTestWindowControl(QVideoSink *parent = nullptr) - : QPlatformVideoSink(parent) - {} - void setWinId(WId id) override { m_winId = id; } - - void setDisplayRect(const QRect &rect) override { m_displayRect = rect; } - - void setFullScreen(bool fullScreen) override { m_fullScreen = fullScreen; } - - [[nodiscard]] QSize nativeSize() const override { return m_nativeSize; } - void setNativeSize(const QSize &size) { m_nativeSize = size; emit nativeSizeChanged(); } - - void setAspectRatioMode(Qt::AspectRatioMode mode) override { m_aspectRatioMode = mode; } - - void setBrightness(float brightness) override { m_brightness = brightness; } - void setContrast(float contrast) override { m_contrast = contrast; } - void setHue(float hue) override { m_hue = hue; } - void setSaturation(float saturation) override { m_saturation = saturation; } - - [[nodiscard]] WId winId() const { return m_winId; } - - [[nodiscard]] QRect displayRect() const { return m_displayRect; } - - [[nodiscard]] bool isFullScreen() const { return m_fullScreen; } - - [[nodiscard]] Qt::AspectRatioMode aspectRatioMode() const { return m_aspectRatioMode; } - - [[nodiscard]] float brightness() const { return m_brightness; } - [[nodiscard]] float contrast() const { return m_contrast; } - [[nodiscard]] float hue() const { return m_hue; } - [[nodiscard]] float saturation() const { return m_saturation; } - -private: - WId m_winId = 0; - float m_brightness = 0; - float m_contrast = 0; - float m_hue = 0; - float m_saturation = 0; - Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio; - QRect m_displayRect; - QSize m_nativeSize; - bool m_fullScreen = false; -}; +#include <qmediaplayer.h> class QtTestVideoObject : public QObject { @@ -130,19 +68,16 @@ public slots: private slots: void winId(); - void nativeSize(); void aspectRatio(); - void geometryChange(); - void resetCanvas(); private: QQmlEngine m_engine; - QQuickItem *m_videoItem; + QQuickVideoOutput *m_videoItem; QScopedPointer<QQuickItem> m_rootItem; - QtTestWindowControl m_windowControl; QtTestVideoObject m_videoObject; - SourceObject m_sourceObject; + QMediaPlayer m_sourceObject; QQuickView m_view; + QVideoSink *m_sink; }; void tst_QQuickVideoOutputWindow::initTestCase() @@ -151,12 +86,12 @@ void tst_QQuickVideoOutputWindow::initTestCase() component.loadUrl(QUrl("qrc:/main.qml")); m_rootItem.reset(qobject_cast<QQuickItem *>(component.create())); - m_videoItem = m_rootItem->findChild<QQuickItem *>("videoOutput"); + m_videoItem = qobject_cast<QQuickVideoOutput *>(m_rootItem->findChild<QQuickItem *>("videoOutput")); QVERIFY(m_videoItem); + m_sink = m_videoItem->videoSink(); m_rootItem->setParentItem(m_view.contentItem()); - m_videoItem->setProperty("source", QVariant::fromValue<QObject *>(&m_sourceObject)); + m_sourceObject.setVideoOutput(m_videoItem); - m_windowControl.setNativeSize(QSize(400, 200)); m_view.resize(200, 200); m_view.show(); } @@ -171,47 +106,21 @@ void tst_QQuickVideoOutputWindow::cleanupTestCase() void tst_QQuickVideoOutputWindow::winId() { - QCOMPARE(m_windowControl.winId(), m_view.winId()); -} - -void tst_QQuickVideoOutputWindow::nativeSize() -{ - QCOMPARE(m_videoItem->implicitWidth(), qreal(400.0f)); - QCOMPARE(m_videoItem->implicitHeight(), qreal(200.0f)); + QCOMPARE(m_sink->nativeWindowId(), 0); } void tst_QQuickVideoOutputWindow::aspectRatio() { - const QRect expectedDisplayRect(25, 50, 150, 100); m_videoItem->setProperty("fillMode", QQuickVideoOutput::Stretch); - QTRY_COMPARE(m_windowControl.aspectRatioMode(), Qt::IgnoreAspectRatio); - QCOMPARE(m_windowControl.displayRect(), expectedDisplayRect); + QTRY_COMPARE(m_sink->aspectRatioMode(), Qt::IgnoreAspectRatio); m_videoItem->setProperty("fillMode", QQuickVideoOutput::PreserveAspectFit); - QTRY_COMPARE(m_windowControl.aspectRatioMode(), Qt::KeepAspectRatio); - QCOMPARE(m_windowControl.displayRect(), expectedDisplayRect); + QTRY_COMPARE(m_sink->aspectRatioMode(), Qt::KeepAspectRatio); m_videoItem->setProperty("fillMode", QQuickVideoOutput::PreserveAspectCrop); - QTRY_COMPARE(m_windowControl.aspectRatioMode(), Qt::KeepAspectRatioByExpanding); - QCOMPARE(m_windowControl.displayRect(), expectedDisplayRect); + QTRY_COMPARE(m_sink->aspectRatioMode(), Qt::KeepAspectRatioByExpanding); } -void tst_QQuickVideoOutputWindow::geometryChange() -{ - m_videoItem->setWidth(50); - QTRY_COMPARE(m_windowControl.displayRect(), QRect(25, 50, 50, 100)); - - m_videoItem->setX(30); - QTRY_COMPARE(m_windowControl.displayRect(), QRect(30, 50, 50, 100)); -} - -void tst_QQuickVideoOutputWindow::resetCanvas() -{ - m_rootItem->setParentItem(nullptr); - QCOMPARE((int)m_windowControl.winId(), 0); -} - - QTEST_MAIN(tst_QQuickVideoOutputWindow) #include "tst_qquickvideooutput_window.moc" diff --git a/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp b/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp index 9265f0799..fa2410ae2 100644 --- a/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp +++ b/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp @@ -555,15 +555,35 @@ void tst_QCamera::testSetVideoOutput() QCamera camera; session.setCamera(&camera); - QVERIFY(session.videoOutput().isNull()); - session.setVideoOutput(&surface); + QVERIFY(!session.videoOutput()); - QVERIFY(session.videoOutput().value<QVideoSink *>() == &surface); + session.setVideoOutput(&surface); + QVERIFY(session.videoOutput() == &surface); + QVERIFY(session.videoSink() == &surface); session.setVideoOutput(static_cast<QVideoSink *>(nullptr)); - QVERIFY(session.videoOutput().isNull()); + QVERIFY(session.videoOutput() == nullptr); + QVERIFY(session.videoSink() == nullptr); + + session.setVideoOutput(&surface); + QVERIFY(session.videoOutput() == &surface); + QVERIFY(session.videoSink() == &surface); + + session.setVideoSink(&surface); + QVERIFY(session.videoOutput() == nullptr); + QVERIFY(session.videoSink() == &surface); + + session.setVideoOutput(&surface); + QVERIFY(session.videoOutput() == &surface); + QVERIFY(session.videoSink() == &surface); + + session.setVideoSink(nullptr); + QVERIFY(session.videoOutput() == nullptr); + QVERIFY(session.videoSink() == nullptr); } + + void tst_QCamera::testSetVideoOutputDestruction() { { @@ -573,7 +593,7 @@ void tst_QCamera::testSetVideoOutputDestruction() QCamera camera; session.setCamera(&camera); - QVERIFY(session.videoOutput().isNull()); + QVERIFY(session.videoOutput() == nullptr); session.setVideoOutput(&surface); } } @@ -585,7 +605,7 @@ void tst_QCamera::testSetVideoOutputDestruction() QCamera camera; session.setCamera(&camera); - QVERIFY(session.videoOutput().isNull()); + QVERIFY(session.videoOutput() == nullptr); session.setVideoOutput(&surface); } } @@ -597,7 +617,7 @@ void tst_QCamera::testSetVideoOutputDestruction() QVideoSink surface; session.setCamera(&camera); - QVERIFY(session.videoOutput().isNull()); + QVERIFY(session.videoOutput() == nullptr); session.setVideoOutput(&surface); } } @@ -608,7 +628,7 @@ void tst_QCamera::testSetVideoOutputDestruction() QCamera camera; session.setCamera(&camera); - QVERIFY(session.videoOutput().isNull()); + QVERIFY(session.videoOutput() == nullptr); session.setVideoOutput(&surface); } } diff --git a/tests/auto/unit/multimedia/qsamplecache/tst_qsamplecache.cpp b/tests/auto/unit/multimedia/qsamplecache/tst_qsamplecache.cpp index fdb3d93e6..5baea0278 100644 --- a/tests/auto/unit/multimedia/qsamplecache/tst_qsamplecache.cpp +++ b/tests/auto/unit/multimedia/qsamplecache/tst_qsamplecache.cpp @@ -116,8 +116,7 @@ void tst_QSampleCache::testEnoughCapacity() QCOMPARE(sample, sampleCached); // sample is cached QVERIFY(cache.isCached(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test.wav")))); QVERIFY(cache.isCached(QUrl::fromLocalFile(QFINDTESTDATA("testdata/test2.wav")))); - QVERIFY(cache.isLoading()); - QTRY_VERIFY(!cache.isLoading()); + QVERIFY(!cache.isLoading()); sampleCached->release(); } diff --git a/tests/auto/unit/multimediawidgets/qcamerawidgets/tst_qcamerawidgets.cpp b/tests/auto/unit/multimediawidgets/qcamerawidgets/tst_qcamerawidgets.cpp index 757a8c805..3314ad547 100644 --- a/tests/auto/unit/multimediawidgets/qcamerawidgets/tst_qcamerawidgets.cpp +++ b/tests/auto/unit/multimediawidgets/qcamerawidgets/tst_qcamerawidgets.cpp @@ -97,34 +97,46 @@ void tst_QCameraWidgets::testSetVideoOutput() QMediaCaptureSession session; session.setVideoOutput(&widget); - QVERIFY(session.videoOutput() == QVariant::fromValue(&widget)); + QVERIFY(session.videoSink() == widget.videoSink()); + QVERIFY(session.videoOutput() == &widget); session.setVideoOutput(&item); - QVERIFY(session.videoOutput() == QVariant::fromValue(&item)); + QVERIFY(session.videoSink() == item.videoSink()); + QVERIFY(session.videoOutput() == &item); - session.setVideoOutput(static_cast<QVideoWidget *>(nullptr)); - QVERIFY(session.videoOutput() == QVariant()); + session.setVideoOutput(nullptr); + QVERIFY(session.videoSink() == nullptr); + QVERIFY(session.videoOutput() == nullptr); session.setVideoOutput(&widget); - QVERIFY(session.videoOutput() == QVariant::fromValue(&widget)); + QVERIFY(session.videoSink() == widget.videoSink()); + QVERIFY(session.videoOutput() == &widget); - session.setVideoOutput(static_cast<QGraphicsVideoItem *>(nullptr)); - QVERIFY(session.videoOutput() == QVariant()); + session.setVideoOutput(nullptr); + QVERIFY(session.videoOutput() == nullptr); session.setVideoOutput(&surface); - QVERIFY(session.videoOutput() == QVariant::fromValue(&surface)); + QVERIFY(session.videoSink() == &surface); + QVERIFY(session.videoOutput() == &surface); - session.setVideoOutput(static_cast<QVideoSink *>(nullptr)); - QVERIFY(session.videoOutput() == QVariant()); + session.setVideoSink(nullptr); + QVERIFY(session.videoSink() == nullptr); + QVERIFY(session.videoOutput() == nullptr); session.setVideoOutput(&surface); - QVERIFY(session.videoOutput() == QVariant::fromValue(&surface)); + QVERIFY(session.videoSink() == &surface); + QVERIFY(session.videoOutput() == &surface); + + session.setVideoSink(&surface); + QVERIFY(session.videoSink() == &surface); + QVERIFY(session.videoOutput() == nullptr); session.setVideoOutput(&widget); - QVERIFY(session.videoOutput() == QVariant::fromValue(&widget)); + QVERIFY(session.videoSink() == widget.videoSink()); + QVERIFY(session.videoOutput() == &widget); session.setVideoOutput(&surface); - QVERIFY(session.videoOutput() == QVariant::fromValue(&surface)); + QVERIFY(session.videoOutput() == &surface); } QTEST_MAIN(tst_QCameraWidgets) |