diff options
author | Lars Knoll <lars.knoll@qt.io> | 2021-02-11 09:20:08 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2021-02-17 08:26:34 +0000 |
commit | a8eb585f239c2e5c0a5fed8a1a279fbd076c8446 (patch) | |
tree | 8edab7e7e297bc42e3ee214bf803e03a393e8ad8 | |
parent | 5b08bbc4a244416ee961e9793cc12a652994573b (diff) |
Rework how to set a video output surface
Setting a video output should not require QMediaService
anymore.
Reverse the logic, by making QAbstractVideoSurface the primary
interface. Use runtime method lookup to get a pointer to the
video surface from QVideoWidget/QGraphicsVideoItem.
QAbstractVideoSurface is now the primary interface for setting
up a video output. We will need to add some API there to allow for
windows/fullscreen rendering.
With this change, QVideoRendererControl/QVideoWindowControl can
also be retired as an abstraction layer in the longer term.
Change-Id: Iedff18c6b95fedc7cb914075a8c84081080deab1
Reviewed-by: Doris Verria <doris.verria@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
57 files changed, 201 insertions, 434 deletions
diff --git a/src/multimedia/camera/qcamera.cpp b/src/multimedia/camera/qcamera.cpp index 3f43c03a2..4ca99b2c7 100644 --- a/src/multimedia/camera/qcamera.cpp +++ b/src/multimedia/camera/qcamera.cpp @@ -46,6 +46,7 @@ #include <qcamerafocuscontrol.h> #include <qcameraimageprocessingcontrol.h> #include <qcameraimagecapturecontrol.h> +#include <qvideorenderercontrol.h> #include <private/qmediaplatformintegration_p.h> #include <private/qmediaplatformcaptureinterface_p.h> #include <qmediadevicemanager.h> @@ -304,20 +305,15 @@ QCameraImageProcessing *QCamera::imageProcessing() const Sets the QMediaSink based camera \a viewfinder. The previously set viewfinder is detached. */ -void QCamera::setViewfinder(QMediaSink *viewfinder) +void QCamera::setViewfinder(QObject *viewfinder) { - Q_D(QCamera); - d->_q_preparePropertyChange(QCameraControl::Viewfinder); - - if (d->viewfinder) - unbind(d->viewfinder); - - if (!viewfinder) { - d->viewfinder = nullptr; + auto *mo = viewfinder->metaObject(); + QAbstractVideoSurface *surface = nullptr; + if (viewfinder && !mo->invokeMethod(viewfinder, "videoSurface", Q_RETURN_ARG(QAbstractVideoSurface *, surface))) { + qWarning() << "QCamera::setViewFinder: Object" << viewfinder->metaObject()->className() << "does not have a videoSurface()"; return; } - - d->viewfinder = bind(viewfinder) ? viewfinder : nullptr; + setViewfinder(surface); } /*! @@ -330,9 +326,7 @@ void QCamera::setViewfinder(QMediaSink *viewfinder) void QCamera::setViewfinder(QAbstractVideoSurface *surface) { Q_D(QCamera); - - d->surfaceViewfinder.setVideoSurface(surface); - setViewfinder(surface ? &d->surfaceViewfinder : nullptr); + d->control->setVideoSurface(surface); } /*! diff --git a/src/multimedia/camera/qcamera.h b/src/multimedia/camera/qcamera.h index f31083812..49c0d900d 100644 --- a/src/multimedia/camera/qcamera.h +++ b/src/multimedia/camera/qcamera.h @@ -126,7 +126,7 @@ public: QCameraFocus *focus() const; QCameraImageProcessing *imageProcessing() const; - void setViewfinder(QMediaSink *viewfinder); + void setViewfinder(QObject *viewfinder); void setViewfinder(QAbstractVideoSurface *surface); Error error() const; diff --git a/src/multimedia/camera/qcamera_p.h b/src/multimedia/camera/qcamera_p.h index 5f1795f3e..946fc3ccc 100644 --- a/src/multimedia/camera/qcamera_p.h +++ b/src/multimedia/camera/qcamera_p.h @@ -52,7 +52,6 @@ // #include "qmediasource_p.h" -#include "qvideosurfaceoutput_p.h" #include "qcamera.h" #include "qcamerainfo.h" @@ -104,8 +103,6 @@ public: bool restartPending; - QVideoSurfaceOutput surfaceViewfinder; - void _q_error(int error, const QString &errorString); void unsetError() { error = QCamera::NoError; errorString.clear(); } diff --git a/src/multimedia/controls/qcameracontrol.h b/src/multimedia/controls/qcameracontrol.h index bfe33b363..68e049d30 100644 --- a/src/multimedia/controls/qcameracontrol.h +++ b/src/multimedia/controls/qcameracontrol.h @@ -52,6 +52,7 @@ class QString; class QCameraFocusControl; class QCameraExposureControl; class QCameraImageProcessingControl; +class QVideoRendererControl; class Q_MULTIMEDIA_EXPORT QCameraControl : public QObject { @@ -82,6 +83,8 @@ public: virtual QCameraExposureControl *exposureControl() { return nullptr; } virtual QCameraImageProcessingControl *imageProcessingControl() { return nullptr; } + virtual void setVideoSurface(QAbstractVideoSurface *surface) = 0; + Q_SIGNALS: void stateChanged(QCamera::State); void statusChanged(QCamera::Status); diff --git a/src/multimedia/controls/qmediaplayercontrol.h b/src/multimedia/controls/qmediaplayercontrol.h index 234e43bd4..886311917 100644 --- a/src/multimedia/controls/qmediaplayercontrol.h +++ b/src/multimedia/controls/qmediaplayercontrol.h @@ -103,6 +103,8 @@ public: virtual QMediaMetaData metaData() const { return {}; } + virtual void setVideoSurface(QAbstractVideoSurface *surface) = 0; + Q_SIGNALS: void audioRoleChanged(QAudio::Role role); void customAudioRoleChanged(const QString &role); diff --git a/src/multimedia/platform/android/mediacapture/qandroidcameracontrol.cpp b/src/multimedia/platform/android/mediacapture/qandroidcameracontrol.cpp index d1160d274..0b17f17b9 100644 --- a/src/multimedia/platform/android/mediacapture/qandroidcameracontrol.cpp +++ b/src/multimedia/platform/android/mediacapture/qandroidcameracontrol.cpp @@ -42,6 +42,7 @@ #include "qandroidcameraexposurecontrol_p.h" #include "qandroidcamerafocuscontrol_p.h" #include "qandroidcameraimageprocessingcontrol_p.h" +#include "qandroidcameravideorenderercontrol_p.h" #include <qmediadevicemanager.h> #include <qcamerainfo.h> #include <qtimer.h> @@ -72,6 +73,7 @@ QAndroidCameraControl::QAndroidCameraControl(QAndroidCameraSession *session) QAndroidCameraControl::~QAndroidCameraControl() { + delete m_renderer; } QCamera::CaptureModes QAndroidCameraControl::captureMode() const @@ -148,4 +150,11 @@ QCameraImageProcessingControl *QAndroidCameraControl::imageProcessingControl() return m_cameraSession->imageProcessingControl(); } +void QAndroidCameraControl::setVideoSurface(QAbstractVideoSurface *surface) +{ + if (!m_renderer) + m_renderer = new QAndroidCameraVideoRendererControl(m_cameraSession); + m_renderer->setSurface(surface); +} + QT_END_NAMESPACE diff --git a/src/multimedia/platform/android/mediacapture/qandroidcameracontrol_p.h b/src/multimedia/platform/android/mediacapture/qandroidcameracontrol_p.h index 02b197616..6118d0fa8 100644 --- a/src/multimedia/platform/android/mediacapture/qandroidcameracontrol_p.h +++ b/src/multimedia/platform/android/mediacapture/qandroidcameracontrol_p.h @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE class QAndroidCameraSession; +class QAndroidCameraVideoRendererControl; class QAndroidCameraControl : public QCameraControl { @@ -82,8 +83,11 @@ public: QCameraExposureControl *exposureControl() override; QCameraImageProcessingControl *imageProcessingControl() override; + void setVideoSurface(QAbstractVideoSurface *surface) override; + private: QAndroidCameraSession *m_cameraSession; + QAndroidCameraVideoRendererControl *m_renderer = nullptr; QTimer *m_recalculateTimer; }; diff --git a/src/multimedia/platform/android/mediacapture/qandroidcaptureservice.cpp b/src/multimedia/platform/android/mediacapture/qandroidcaptureservice.cpp index f6d242cd7..7e2ff8ac8 100644 --- a/src/multimedia/platform/android/mediacapture/qandroidcaptureservice.cpp +++ b/src/multimedia/platform/android/mediacapture/qandroidcaptureservice.cpp @@ -51,7 +51,6 @@ QT_BEGIN_NAMESPACE QAndroidCaptureService::QAndroidCaptureService(QMediaRecorder::CaptureMode mode) : m_videoEnabled(mode == QMediaRecorder::AudioAndVideo) - , m_videoRendererControl(0) { if (m_videoEnabled) { m_cameraSession = new QAndroidCameraSession; @@ -72,7 +71,6 @@ QAndroidCaptureService::~QAndroidCaptureService() delete m_recorderControl; delete m_captureSession; delete m_cameraControl; - delete m_videoRendererControl; delete m_imageCaptureControl; delete m_cameraSession; } @@ -88,26 +86,11 @@ QObject *QAndroidCaptureService::requestControl(const char *name) if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) return m_imageCaptureControl; - if (qstrcmp(name, QVideoRendererControl_iid) == 0 - && m_videoEnabled - && !m_videoRendererControl) { - m_videoRendererControl = new QAndroidCameraVideoRendererControl(m_cameraSession); - return m_videoRendererControl; - } - return 0; } -void QAndroidCaptureService::releaseControl(QObject *control) +void QAndroidCaptureService::releaseControl(QObject *) { - if (control) { - if (control == m_videoRendererControl) { - delete m_videoRendererControl; - m_videoRendererControl = 0; - return; - } - } - } QT_END_NAMESPACE diff --git a/src/multimedia/platform/android/mediacapture/qandroidcaptureservice_p.h b/src/multimedia/platform/android/mediacapture/qandroidcaptureservice_p.h index 55d4f845e..e10646a82 100644 --- a/src/multimedia/platform/android/mediacapture/qandroidcaptureservice_p.h +++ b/src/multimedia/platform/android/mediacapture/qandroidcaptureservice_p.h @@ -62,7 +62,6 @@ class QAndroidMediaRecorderControl; class QAndroidCaptureSession; class QAndroidCameraControl; class QAndroidCameraSession; -class QAndroidCameraVideoRendererControl; class QAndroidCameraImageCaptureControl; class QAndroidCaptureService : public QMediaPlatformCaptureInterface @@ -82,7 +81,6 @@ public: QAndroidCaptureSession *m_captureSession; QAndroidCameraControl *m_cameraControl; QAndroidCameraSession *m_cameraSession; - QAndroidCameraVideoRendererControl *m_videoRendererControl; QAndroidCameraImageCaptureControl *m_imageCaptureControl; }; diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol.cpp index 11d18d362..c613722bd 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol.cpp @@ -41,6 +41,7 @@ #include "androidmediaplayer_p.h" #include "qandroidvideooutput_p.h" #include "qandroidmetadata_p.h" +#include "qandroidmediaplayervideorenderercontrol_p.h" QT_BEGIN_NAMESPACE @@ -456,6 +457,13 @@ void QAndroidMediaPlayerControl::setVideoOutput(QAndroidVideoOutput *videoOutput connect(videoOutput, SIGNAL(readyChanged(bool)), this, SLOT(onVideoOutputReady(bool))); } +void QAndroidMediaPlayerControl::setVideoSurface(QAbstractVideoSurface *surface) +{ + if (!mVideoRendererControl) + mVideoRendererControl = new QAndroidMediaPlayerVideoRendererControl(this); + mVideoRendererControl->setSurface(surface); +} + void QAndroidMediaPlayerControl::play() { StateChangeNotifier notifier(this); diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol_p.h index b8a5f9884..0cdc99688 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol_p.h +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaplayercontrol_p.h @@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE class AndroidMediaPlayer; class QAndroidVideoOutput; +class QAndroidMediaPlayerVideoRendererControl; class QAndroidMediaPlayerControl : public QMediaPlayerControl { @@ -93,6 +94,7 @@ public: QMediaMetaData metaData() const override; void setVideoOutput(QAndroidVideoOutput *videoOutput); + void setVideoSurface(QAbstractVideoSurface *surface) override; Q_SIGNALS: void audioRoleChanged(QAudio::Role role); @@ -116,6 +118,7 @@ private Q_SLOTS: private: AndroidMediaPlayer *mMediaPlayer; + QAndroidMediaPlayerVideoRendererControl *mVideoRendererControl = nullptr; QMediaPlayer::State mCurrentState; QMediaPlayer::MediaStatus mCurrentMediaStatus; QUrl mMediaContent; diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaservice.cpp b/src/multimedia/platform/android/mediaplayer/qandroidmediaservice.cpp index aa00dedce..722d37335 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaservice.cpp +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaservice.cpp @@ -51,7 +51,6 @@ QAndroidMediaService::QAndroidMediaService() QAndroidMediaService::~QAndroidMediaService() { - delete mVideoRendererControl; delete mMediaControl; } @@ -60,13 +59,4 @@ QMediaPlayerControl *QAndroidMediaService::player() return mMediaControl; } -QVideoRendererControl *QAndroidMediaService::createVideoRenderer() -{ - if (!mVideoRendererControl) { - mVideoRendererControl = new QAndroidMediaPlayerVideoRendererControl(mMediaControl); - return mVideoRendererControl; - } - return nullptr; -} - QT_END_NAMESPACE diff --git a/src/multimedia/platform/android/mediaplayer/qandroidmediaservice_p.h b/src/multimedia/platform/android/mediaplayer/qandroidmediaservice_p.h index d01cf59fe..6973f7fa5 100644 --- a/src/multimedia/platform/android/mediaplayer/qandroidmediaservice_p.h +++ b/src/multimedia/platform/android/mediaplayer/qandroidmediaservice_p.h @@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE class QAndroidMediaPlayerControl; -class QAndroidMediaPlayerVideoRendererControl; class QAndroidMediaService : public QMediaPlatformPlayerInterface { @@ -69,12 +68,8 @@ public: QMediaPlayerControl *player() override; // QMediaStreamsControl *streams() override; - QVideoRendererControl *createVideoRenderer() override; -// QVideoWindowControl *createVideoWindow() override;; - private: QAndroidMediaPlayerControl *mMediaControl = nullptr; - QAndroidMediaPlayerVideoRendererControl *mVideoRendererControl = nullptr; }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/camera/avfcameracontrol.mm b/src/multimedia/platform/darwin/camera/avfcameracontrol.mm index 77f394221..b4cc9116a 100644 --- a/src/multimedia/platform/darwin/camera/avfcameracontrol.mm +++ b/src/multimedia/platform/darwin/camera/avfcameracontrol.mm @@ -128,6 +128,11 @@ bool AVFCameraControl::isCaptureModeSupported(QCamera::CaptureModes /*mode*/) co return true; } +void AVFCameraControl::setVideoSurface(QAbstractVideoSurface *surface) +{ + m_session->setVideoSurface(surface); +} + bool AVFCameraControl::canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const { Q_UNUSED(changeType); @@ -206,10 +211,10 @@ bool AVFCameraControl::CVPixelFormatFromQtFormat(QVideoFrame::PixelFormat qtForm AVCaptureConnection *AVFCameraControl::videoConnection() const { - if (!m_service->videoOutput() || !m_service->videoOutput()->videoDataOutput()) + if (!m_session->videoOutput() || !m_session->videoOutput()->videoDataOutput()) return nil; - return [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo]; + return [m_session->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo]; } diff --git a/src/multimedia/platform/darwin/camera/avfcameracontrol_p.h b/src/multimedia/platform/darwin/camera/avfcameracontrol_p.h index 8c78a367c..423afa724 100644 --- a/src/multimedia/platform/darwin/camera/avfcameracontrol_p.h +++ b/src/multimedia/platform/darwin/camera/avfcameracontrol_p.h @@ -90,6 +90,8 @@ public: static QVideoFrame::PixelFormat QtPixelFormatFromCVFormat(unsigned avPixelFormat); static bool CVPixelFormatFromQtFormat(QVideoFrame::PixelFormat qtFormat, unsigned &conv); + void setVideoSurface(QAbstractVideoSurface *surface) override; + AVCaptureConnection *videoConnection() const; private Q_SLOTS: diff --git a/src/multimedia/platform/darwin/camera/avfcameradebug_p.h b/src/multimedia/platform/darwin/camera/avfcameradebug_p.h index cbb64b316..616e53d99 100644 --- a/src/multimedia/platform/darwin/camera/avfcameradebug_p.h +++ b/src/multimedia/platform/darwin/camera/avfcameradebug_p.h @@ -57,7 +57,7 @@ QT_USE_NAMESPACE -#define AVF_DEBUG_CAMERA +//#define AVF_DEBUG_CAMERA #ifdef AVF_DEBUG_CAMERA #define qDebugCamera qDebug diff --git a/src/multimedia/platform/darwin/camera/avfcameraservice.mm b/src/multimedia/platform/darwin/camera/avfcameraservice.mm index 0ed6b74ce..3e9f6b873 100644 --- a/src/multimedia/platform/darwin/camera/avfcameraservice.mm +++ b/src/multimedia/platform/darwin/camera/avfcameraservice.mm @@ -59,8 +59,6 @@ QT_USE_NAMESPACE AVFCameraService::AVFCameraService() - : m_videoOutput(nullptr), - m_captureWindowControl(nullptr) { m_session = new AVFCameraSession(this); m_cameraControl = new AVFCameraControl(this); @@ -90,18 +88,6 @@ AVFCameraService::~AVFCameraService() delete m_recorderControl; #endif - if (m_captureWindowControl) { - m_session->setCapturePreviewOutput(nullptr); - delete m_captureWindowControl; - m_captureWindowControl = nullptr; - } - - if (m_videoOutput) { - m_session->setVideoOutput(nullptr); - delete m_videoOutput; - m_videoOutput = nullptr; - } - //delete controls before session, //so they have a chance to do deinitialization delete m_imageCaptureControl; @@ -124,39 +110,11 @@ QObject *AVFCameraService::requestControl(const char *name) if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) return m_imageCaptureControl; - if (!m_captureWindowControl) { - if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - m_captureWindowControl = new AVFCameraWindowControl(this); - m_session->setCapturePreviewOutput(m_captureWindowControl); - return m_captureWindowControl; - } - } - - if (!m_videoOutput) { - if (qstrcmp(name, QVideoRendererControl_iid) == 0) - m_videoOutput = new AVFCameraRendererControl(this); - - if (m_videoOutput) { - m_session->setVideoOutput(m_videoOutput); - return m_videoOutput; - } - } - return nullptr; } -void AVFCameraService::releaseControl(QObject *control) +void AVFCameraService::releaseControl(QObject *) { - if (m_videoOutput == control) { - m_session->setVideoOutput(nullptr); - delete m_videoOutput; - m_videoOutput = nullptr; - } - else if (m_captureWindowControl == control) { - m_session->setCapturePreviewOutput(nullptr); - delete m_captureWindowControl; - m_captureWindowControl = nullptr; - } } diff --git a/src/multimedia/platform/darwin/camera/avfcameraservice_p.h b/src/multimedia/platform/darwin/camera/avfcameraservice_p.h index faa39fc21..a84a5bed2 100644 --- a/src/multimedia/platform/darwin/camera/avfcameraservice_p.h +++ b/src/multimedia/platform/darwin/camera/avfcameraservice_p.h @@ -60,16 +60,12 @@ QT_BEGIN_NAMESPACE class QCameraControl; class QMediaRecorderControl; class AVFCameraControl; -class AVFVideoWindowControl; -class AVFVideoWidgetControl; -class AVFCameraRendererControl; class AVFImageCaptureControl; class AVFCameraSession; class AVFCameraFocusControl; class AVFCameraExposureControl; class AVFMediaRecorderControl; class AVFMediaRecorderControlIOS; -class AVFCameraWindowControl; class AVFCameraService : public QMediaPlatformCaptureInterface { @@ -87,17 +83,14 @@ public: AVFImageCaptureControl *imageCaptureControl() const { return m_imageCaptureControl; } AVFCameraFocusControl *cameraFocusControl() const { return m_cameraFocusControl; } AVFCameraExposureControl *cameraExposureControl() const { return m_cameraExposureControl; } - AVFCameraRendererControl *videoOutput() const { return m_videoOutput; } private: AVFCameraSession *m_session; AVFCameraControl *m_cameraControl; - AVFCameraRendererControl *m_videoOutput; QMediaRecorderControl *m_recorderControl; AVFImageCaptureControl *m_imageCaptureControl; AVFCameraFocusControl *m_cameraFocusControl; AVFCameraExposureControl *m_cameraExposureControl; - AVFCameraWindowControl *m_captureWindowControl; }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/camera/avfcamerasession.mm b/src/multimedia/platform/darwin/camera/avfcamerasession.mm index ceee3412b..1d76e672e 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerasession.mm +++ b/src/multimedia/platform/darwin/camera/avfcamerasession.mm @@ -153,6 +153,7 @@ AVFCameraSession::AVFCameraSession(AVFCameraService *service, QObject *parent) //configuration is commited during transition to Active state [m_captureSession beginConfiguration]; + setVideoOutput(new AVFCameraRendererControl(this)); } AVFCameraSession::~AVFCameraSession() @@ -370,4 +371,9 @@ FourCharCode AVFCameraSession::defaultCodec() return m_defaultCodec; } +void AVFCameraSession::setVideoSurface(QAbstractVideoSurface *surface) +{ + m_videoOutput->setSurface(surface); +} + #include "moc_avfcamerasession_p.cpp" diff --git a/src/multimedia/platform/darwin/camera/avfcamerasession_p.h b/src/multimedia/platform/darwin/camera/avfcamerasession_p.h index 079866ffa..0ca3c01f1 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerasession_p.h +++ b/src/multimedia/platform/darwin/camera/avfcamerasession_p.h @@ -78,6 +78,7 @@ public: void setActiveCamera(const QCameraInfo &info); void setVideoOutput(AVFCameraRendererControl *output); + AVFCameraRendererControl *videoOutput() const { return m_videoOutput; } void setCapturePreviewOutput(AVFCameraWindowControl *output); AVCaptureSession *captureSession() const { return m_captureSession; } AVCaptureDevice *videoCaptureDevice() const; @@ -90,6 +91,8 @@ public: AVCaptureDeviceInput *videoInput() const {return m_videoInput;} + void setVideoSurface(QAbstractVideoSurface *surface); + public Q_SLOTS: void setState(QCamera::State state); diff --git a/src/multimedia/platform/darwin/camera/avfimagecapturecontrol.mm b/src/multimedia/platform/darwin/camera/avfimagecapturecontrol.mm index 79576b779..3ff4a4eb9 100644 --- a/src/multimedia/platform/darwin/camera/avfimagecapturecontrol.mm +++ b/src/multimedia/platform/darwin/camera/avfimagecapturecontrol.mm @@ -156,7 +156,7 @@ int AVFImageCaptureControl::capture(const QString &fileName) // not the same thread that initiated a capture and stopped the camera), // so we cannot reliably check the camera's status. Instead, we wait // with a timeout and treat a failure to acquire a semaphore as an error. - if (!m_service->videoOutput() || request.previewReady->tryAcquire(1, 1000)) { + if (!m_session->videoOutput() || request.previewReady->tryAcquire(1, 1000)) { qDebugCamera() << "Image capture completed"; NSData *nsJpgData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer]; diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol.mm b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol.mm index 1e55fb770..301eb6790 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol.mm +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol.mm @@ -217,3 +217,8 @@ void AVFMediaPlayerControl::setMuted(bool muted) { m_session->setMuted(muted); } + +void AVFMediaPlayerControl::setVideoSurface(QAbstractVideoSurface *surface) +{ + m_session->setVideoSurface(surface); +} diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol_p.h b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol_p.h index 9b8018ecb..10a592972 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol_p.h +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayercontrol_p.h @@ -97,6 +97,8 @@ public: QMediaMetaData metaData() const override; void setMetaData(const QMediaMetaData &metaData); + void setVideoSurface(QAbstractVideoSurface *surface) override; + public Q_SLOTS: void setPosition(qint64 pos) override; diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice.mm b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice.mm index 5d6422530..660332695 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice.mm +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice.mm @@ -70,27 +70,3 @@ QMediaPlayerControl *AVFMediaPlayerService::player() { return m_control; } - -QVideoRendererControl *AVFMediaPlayerService::createVideoRenderer() -{ - if (m_videoOutput) - return nullptr; - - auto *control = new AVFVideoRendererControl(this); - m_videoOutput = control; - - m_session->setVideoOutput(control); - return control; -} - -QVideoWindowControl *AVFMediaPlayerService::createVideoWindow() -{ - if (m_videoOutput) - return nullptr; - - auto *control = new AVFVideoWindowControl(this); - m_videoOutput = control; - - m_session->setVideoOutput(control); - return control; -} diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice_p.h b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice_p.h index 185f1d805..5755f87c9 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice_p.h +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayerservice_p.h @@ -69,14 +69,9 @@ public: QMediaPlayerControl *player() override; // QMediaStreamsControl *streams() override; - QVideoRendererControl *createVideoRenderer() override; - QVideoWindowControl *createVideoWindow() override;; - - private: AVFMediaPlayerSession *m_session = nullptr; AVFMediaPlayerControl *m_control = nullptr; - QObject *m_videoOutput = nullptr; }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession.mm b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession.mm index 386e66ecd..1bc8a675b 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession.mm +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession.mm @@ -40,6 +40,7 @@ #include "avfmediaplayersession_p.h" #include "avfmediaplayerservice_p.h" #include "avfmediaplayercontrol_p.h" +#include "avfvideorenderercontrol_p.h" #include "avfvideooutput_p.h" #include "avfmetadata_p.h" @@ -483,6 +484,7 @@ AVFMediaPlayerSession::AVFMediaPlayerSession(AVFMediaPlayerService *service, QOb , m_seekable(false) { m_observer = [[AVFMediaPlayerSessionObserver alloc] initWithMediaPlayerSession:this]; + setVideoOutput(new AVFVideoRendererControl(this)); } AVFMediaPlayerSession::~AVFMediaPlayerSession() @@ -495,7 +497,12 @@ AVFMediaPlayerSession::~AVFMediaPlayerSession() [static_cast<AVFMediaPlayerSessionObserver*>(m_observer) release]; } -void AVFMediaPlayerSession::setVideoOutput(AVFVideoOutput *output) +void AVFMediaPlayerSession::setVideoSurface(QAbstractVideoSurface *surface) +{ + m_videoOutput->setSurface(surface); +} + +void AVFMediaPlayerSession::setVideoOutput(AVFVideoRendererControl *output) { #ifdef QT_DEBUG_AVF qDebug() << Q_FUNC_INFO << output; diff --git a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession_p.h b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession_p.h index 206d12163..ec364b29d 100644 --- a/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession_p.h +++ b/src/multimedia/platform/darwin/mediaplayer/avfmediaplayersession_p.h @@ -67,6 +67,7 @@ QT_BEGIN_NAMESPACE class AVFMediaPlayerService; class AVFVideoOutput; +class AVFVideoRendererControl; class AVFMediaPlayerSession : public QObject { @@ -75,7 +76,8 @@ public: AVFMediaPlayerSession(AVFMediaPlayerService *service, QObject *parent = nullptr); virtual ~AVFMediaPlayerSession(); - void setVideoOutput(AVFVideoOutput *output); + void setVideoSurface(QAbstractVideoSurface *surface); + void setVideoOutput(AVFVideoRendererControl *output); AVAsset *currentAssetHandle(); QMediaPlayer::State state() const; @@ -155,7 +157,7 @@ private: void resetStream(QIODevice *stream = nullptr); AVFMediaPlayerService *m_service; - AVFVideoOutput *m_videoOutput; + AVFVideoRendererControl *m_videoOutput; QMediaPlayer::State m_state; QMediaPlayer::MediaStatus m_mediaStatus; diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol.cpp b/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol.cpp index c8fdd00a3..f856bc3d8 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol.cpp @@ -385,9 +385,9 @@ QMediaMetaData QGstreamerPlayerControl::metaData() const return m_session->metaData(); } -void QGstreamerPlayerControl::setVideoOutput(QObject *output) +void QGstreamerPlayerControl::setVideoSurface(QAbstractVideoSurface *surface) { - m_session->setVideoRenderer(output); + m_session->setVideoRenderer(surface); } bool QGstreamerPlayerControl::isAudioAvailable() const diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol_p.h b/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol_p.h index 1c4321663..a73ea1b94 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreamerplayercontrol_p.h @@ -82,7 +82,6 @@ public: bool isAudioAvailable() const override; bool isVideoAvailable() const override; - void setVideoOutput(QObject *output); bool isSeekable() const override; QMediaTimeRange availablePlaybackRanges() const override; @@ -101,6 +100,8 @@ public: QMediaMetaData metaData() const override; + void setVideoSurface(QAbstractVideoSurface *surface) override; + public Q_SLOTS: void setPosition(qint64 pos) override; diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerplayersession.cpp b/src/multimedia/platform/gstreamer/common/qgstreamerplayersession.cpp index 6f4bb61d5..d63d7be89 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamerplayersession.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstreamerplayersession.cpp @@ -40,7 +40,7 @@ #include <private/qgstreamerplayersession_p.h> #include <private/qgstreamerbushelper_p.h> -#include <private/qgstreamervideorendererinterface_p.h> +#include <private/qgstreamervideorenderer_p.h> #include <private/qgstutils_p.h> #include <private/qgstvideorenderersink_p.h> #include <private/qgstreamermetadata_p.h> @@ -552,42 +552,8 @@ void QGstreamerPlayerSession::updateVideoRenderer() qDebug() << "Video sink has chaged, reload video output"; #endif - if (m_videoOutput) - setVideoRenderer(m_videoOutput); -} - -void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) -{ -#ifdef DEBUG_PLAYBIN - qDebug() << Q_FUNC_INFO; -#endif - if (m_videoOutput != videoOutput) { - if (m_videoOutput) { - disconnect(m_videoOutput, SIGNAL(sinkChanged()), - this, SLOT(updateVideoRenderer())); - disconnect(m_videoOutput, SIGNAL(readyChanged(bool)), - this, SLOT(updateVideoRenderer())); - - m_busHelper->removeMessageFilter(m_videoOutput); - } - - m_videoOutput = videoOutput; - - if (m_videoOutput) { - connect(m_videoOutput, SIGNAL(sinkChanged()), - this, SLOT(updateVideoRenderer())); - connect(m_videoOutput, SIGNAL(readyChanged(bool)), - this, SLOT(updateVideoRenderer())); - - m_busHelper->installMessageFilter(m_videoOutput); - } - } - - m_renderer = qobject_cast<QGstreamerVideoRendererInterface*>(videoOutput); - emit rendererChanged(); - // No sense to continue if custom pipeline requested. - if (!m_playbin) + if (!m_playbin || !m_videoOutput) return; GstElement *videoSink = 0; @@ -683,6 +649,27 @@ void QGstreamerPlayerSession::setVideoRenderer(QObject *videoOutput) } } +void QGstreamerPlayerSession::setVideoRenderer(QAbstractVideoSurface *videoOutput) +{ + if (!m_videoOutput) { + m_videoOutput = new QGstreamerVideoRenderer; +#ifdef DEBUG_PLAYBIN + qDebug() << Q_FUNC_INFO; +#endif + connect(m_videoOutput, SIGNAL(sinkChanged()), + this, SLOT(updateVideoRenderer())); + connect(m_videoOutput, SIGNAL(readyChanged(bool)), + this, SLOT(updateVideoRenderer())); + + m_busHelper->installMessageFilter(m_videoOutput); + m_renderer = qobject_cast<QGstreamerVideoRendererInterface*>(m_videoOutput); + emit rendererChanged(); + } + + m_videoOutput->setSurface(videoOutput); + updateVideoRenderer(); +} + void QGstreamerPlayerSession::finishVideoOutputChange() { if (!m_playbin || !m_pendingVideoSink) diff --git a/src/multimedia/platform/gstreamer/common/qgstreamerplayersession_p.h b/src/multimedia/platform/gstreamer/common/qgstreamerplayersession_p.h index 1a3b329a7..80594e36a 100644 --- a/src/multimedia/platform/gstreamer/common/qgstreamerplayersession_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstreamerplayersession_p.h @@ -73,6 +73,7 @@ class QGstreamerBusHelper; class QGstreamerMessage; class QGstreamerVideoRendererInterface; +class QGstreamerVideoRenderer; typedef enum { GST_AUTOPLUG_SELECT_TRY, @@ -108,7 +109,7 @@ public: bool isAudioAvailable() const; - void setVideoRenderer(QObject *renderer); + void setVideoRenderer(QAbstractVideoSurface *renderer); QGstreamerVideoRendererInterface *renderer() const { return m_renderer; } bool isVideoAvailable() const; @@ -223,7 +224,7 @@ private: GstElement *m_volumeElement = nullptr; GstBus *m_bus = nullptr; - QObject *m_videoOutput = nullptr; + QGstreamerVideoRenderer *m_videoOutput = nullptr; QGstreamerVideoRendererInterface *m_renderer = nullptr; #if QT_CONFIG(gstreamer_app) diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercameracontrol.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercameracontrol.cpp index 93e4f77ed..abee759e9 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercameracontrol.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercameracontrol.cpp @@ -39,6 +39,7 @@ #include "qgstreamercameracontrol_p.h" #include "qgstreamerimagecapturecontrol_p.h" +#include <qvideorenderercontrol.h> #include <qcamerainfo.h> @@ -200,3 +201,8 @@ bool QGstreamerCameraControl::canChangeProperty(PropertyChangeType changeType, Q return false; } } + +void QGstreamerCameraControl::setVideoSurface(QAbstractVideoSurface *surface) +{ + m_session->setVideoPreview(surface); +} diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercameracontrol_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercameracontrol_p.h index 6a41aabc4..43a3d3adc 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercameracontrol_p.h +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercameracontrol_p.h @@ -81,6 +81,8 @@ public: bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const override; + void setVideoSurface(QAbstractVideoSurface *surface) override; + public slots: void reloadLater(); diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercaptureservice.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercaptureservice.cpp index 6a8815e66..cf381a141 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercaptureservice.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercaptureservice.cpp @@ -58,15 +58,15 @@ QGstreamerCaptureService::QGstreamerCaptureService(QMediaRecorder::CaptureMode m m_captureSession = new QGstreamerCaptureSession(QGstreamerCaptureSession::AudioAndVideo, this); m_cameraControl = new QGstreamerCameraControl(m_captureSession); - m_videoRenderer = new QGstreamerVideoRenderer(this); - - m_videoWindow = new QGstreamerVideoWindow(this); - // If the GStreamer video sink is not available, don't provide the video window control since - // it won't work anyway. - if (!m_videoWindow->videoSink()) { - delete m_videoWindow; - m_videoWindow = 0; - } +// m_videoRenderer = new QGstreamerVideoRenderer(this); + +// m_videoWindow = new QGstreamerVideoWindow(this); +// // If the GStreamer video sink is not available, don't provide the video window control since +// // it won't work anyway. +// if (!m_videoWindow->videoSink()) { +// delete m_videoWindow; +// m_videoWindow = 0; +// } } } @@ -88,30 +88,11 @@ QObject *QGstreamerCaptureService::requestControl(const char *name) if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) return m_captureSession->imageCaptureControl(); - if (!m_videoOutput) { - if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - m_videoOutput = m_videoRenderer; - } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - m_videoOutput = m_videoWindow; - } - - if (m_videoOutput) { - m_captureSession->setVideoPreview(m_videoOutput); - return m_videoOutput; - } - } - return 0; } -void QGstreamerCaptureService::releaseControl(QObject *control) +void QGstreamerCaptureService::releaseControl(QObject *) { - if (!control) { - return; - } else if (control == m_videoOutput) { - m_videoOutput = 0; - m_captureSession->setVideoPreview(0); - } } QT_END_NAMESPACE diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession.cpp b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession.cpp index f8eb1c5c8..e6ed85f9d 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession.cpp +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession.cpp @@ -43,7 +43,7 @@ #include "private/qgstreamerdevicemanager_p.h" #include <qmediarecorder.h> #include <qmediadevicemanager.h> -#include <private/qgstreamervideorendererinterface_p.h> +#include <private/qgstreamervideorenderer_p.h> #include <private/qgstreamerbushelper_p.h> #include <private/qaudiodeviceinfo_gstreamer_p.h> #include <private/qgstutils_p.h> @@ -702,40 +702,24 @@ bool QGstreamerCaptureSession::setOutputLocation(const QUrl& sink) return true; } -void QGstreamerCaptureSession::setVideoPreview(QObject *viewfinder) +void QGstreamerCaptureSession::setVideoPreview(QAbstractVideoSurface *surface) { - m_viewfinderInterface = qobject_cast<QGstreamerVideoRendererInterface*>(viewfinder); - if (!m_viewfinderInterface) - viewfinder = 0; - - if (m_viewfinder != viewfinder) { + if (!m_viewfinderInterface) { + m_viewfinderInterface = new QGstreamerVideoRenderer; bool oldReady = isReady(); - if (m_viewfinder) { - disconnect(m_viewfinder, SIGNAL(sinkChanged()), - this, SIGNAL(viewfinderChanged())); - disconnect(m_viewfinder, SIGNAL(readyChanged(bool)), - this, SIGNAL(readyChanged(bool))); - - m_busHelper->removeMessageFilter(m_viewfinder); - } - - m_viewfinder = viewfinder; - //m_viewfinderHasChanged = true; - - if (m_viewfinder) { - connect(m_viewfinder, SIGNAL(sinkChanged()), - this, SIGNAL(viewfinderChanged())); - connect(m_viewfinder, SIGNAL(readyChanged(bool)), - this, SIGNAL(readyChanged(bool))); + connect(m_viewfinder, SIGNAL(sinkChanged()), + this, SIGNAL(viewfinderChanged())); + connect(m_viewfinder, SIGNAL(readyChanged(bool)), + this, SIGNAL(readyChanged(bool))); - m_busHelper->installMessageFilter(m_viewfinder); - } + m_busHelper->installMessageFilter(m_viewfinder); emit viewfinderChanged(); if (oldReady != isReady()) emit readyChanged(isReady()); } + m_viewfinderInterface->setSurface(surface); } bool QGstreamerCaptureSession::isReady() const diff --git a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession_p.h b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession_p.h index bcb786ab2..50a43268c 100644 --- a/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession_p.h +++ b/src/multimedia/platform/gstreamer/mediacapture/qgstreamercapturesession_p.h @@ -72,9 +72,10 @@ class QGstreamerMessage; class QGstreamerBusHelper; class QGstreamerImageCaptureControl; class QGstreamerRecorderControl; -class QGstreamerVideoRendererInterface; +class QGstreamerVideoRenderer; class QCameraInfo; class QGstreamerVideoInput; +class QAbstractVideoSurface; class QGstreamerCaptureSession : public QObject @@ -113,7 +114,7 @@ public: void setVideoDevice(const QCameraInfo &camera) { m_camera = camera; } QObject *videoPreview() const { return m_viewfinder; } - void setVideoPreview(QObject *viewfinder); + void setVideoPreview(QAbstractVideoSurface *viewfinder); void captureImage(int requestId, const QString &fileName); @@ -179,7 +180,7 @@ private: QGstreamerMetaData m_metaData; QObject *m_viewfinder; - QGstreamerVideoRendererInterface *m_viewfinderInterface; + QGstreamerVideoRenderer *m_viewfinderInterface; QGstreamerImageCaptureControl *m_imageCaptureControl; QGstreamerRecorderControl *m_recorderControl; diff --git a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice.cpp b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice.cpp index 3608ff868..1cbe5675e 100644 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice.cpp +++ b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice.cpp @@ -44,9 +44,6 @@ #include "qgstreamerplayerservice_p.h" -#include <private/qgstreamervideowindow_p.h> -#include <private/qgstreamervideorenderer_p.h> - #include "qgstreamerstreamscontrol_p.h" #include <private/qgstreamerplayersession_p.h> #include <private/qgstreamerplayercontrol_p.h> @@ -59,14 +56,6 @@ QGstreamerPlayerService::QGstreamerPlayerService() m_session = new QGstreamerPlayerSession(this); m_control = new QGstreamerPlayerControl(m_session, this); m_streamsControl = new QGstreamerStreamsControl(m_session,this); - m_videoRenderer = new QGstreamerVideoRenderer(this); - m_videoWindow = new QGstreamerVideoWindow(this); - // If the GStreamer video sink is not available, don't provide the video window control since - // it won't work anyway. - if (!m_videoWindow->videoSink()) { - delete m_videoWindow; - m_videoWindow = 0; - } } QGstreamerPlayerService::~QGstreamerPlayerService() @@ -88,38 +77,4 @@ QMediaStreamsControl *QGstreamerPlayerService::streams() return m_streamsControl; } -QVideoRendererControl *QGstreamerPlayerService::createVideoRenderer() -{ - if (!m_videoOutput) { - m_videoOutput = m_videoRenderer; - - increaseVideoRef(); - m_control->setVideoOutput(m_videoOutput); - return m_videoRenderer; - } - return nullptr; -} - -QVideoWindowControl *QGstreamerPlayerService::createVideoWindow() -{ - if (!m_videoOutput) { - m_videoOutput = m_videoWindow; - - increaseVideoRef(); - m_control->setVideoOutput(m_videoOutput); - return m_videoWindow; - } - return nullptr; -} - -void QGstreamerPlayerService::increaseVideoRef() -{ - m_videoReferenceCount++; -} - -void QGstreamerPlayerService::decreaseVideoRef() -{ - m_videoReferenceCount--; -} - QT_END_NAMESPACE diff --git a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice_p.h b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice_p.h index e3f9862b4..1c42775d2 100644 --- a/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice_p.h +++ b/src/multimedia/platform/gstreamer/mediaplayer/qgstreamerplayerservice_p.h @@ -63,8 +63,6 @@ class QGstreamerMetaData; class QGstreamerPlayerControl; class QGstreamerPlayerSession; class QGstreamerStreamsControl; -class QGstreamerVideoRenderer; -class QGstreamerVideoWindow; class QGStreamerAvailabilityControl; class QGstreamerPlayerService : public QMediaPlatformPlayerInterface @@ -78,21 +76,10 @@ public: QMediaPlayerControl *player() override; QMediaStreamsControl *streams() override; - QVideoRendererControl *createVideoRenderer() override; - QVideoWindowControl *createVideoWindow() override;; - private: QGstreamerPlayerControl *m_control = nullptr; QGstreamerPlayerSession *m_session = nullptr; QGstreamerStreamsControl *m_streamsControl = nullptr; - - QObject *m_videoOutput = nullptr; - QVideoRendererControl *m_videoRenderer = nullptr; - QGstreamerVideoWindow *m_videoWindow = nullptr; - - void increaseVideoRef(); - void decreaseVideoRef(); - int m_videoReferenceCount = 0; }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/gstreamer/qgstreamerintegration.cpp b/src/multimedia/platform/gstreamer/qgstreamerintegration.cpp index 1140f12e8..c6ad99411 100644 --- a/src/multimedia/platform/gstreamer/qgstreamerintegration.cpp +++ b/src/multimedia/platform/gstreamer/qgstreamerintegration.cpp @@ -44,6 +44,7 @@ #include "private/qgstreamercaptureservice_p.h" #include "private/qgstreameraudiodecodercontrol_p.h" #include "private/qgstreamerformatsinfo_p.h" +#include "private/qgstreamervideorenderer_p.h" QT_BEGIN_NAMESPACE diff --git a/src/multimedia/platform/qmediaplatformintegration_p.h b/src/multimedia/platform/qmediaplatformintegration_p.h index 4d46ac39b..b154b41aa 100644 --- a/src/multimedia/platform/qmediaplatformintegration_p.h +++ b/src/multimedia/platform/qmediaplatformintegration_p.h @@ -61,6 +61,7 @@ class QMediaPlatformCaptureInterface; class QMediaPlatformPlayerInterface; class QAudioDecoderControl; class QMediaPlatformFormatInfo; +class QVideoRendererControl; class Q_MULTIMEDIA_EXPORT QMediaPlatformIntegration { @@ -77,7 +78,6 @@ public: virtual QAudioDecoderControl *createAudioDecoder() { return nullptr; } virtual QMediaPlatformCaptureInterface *createCaptureInterface(QMediaRecorder::CaptureMode /*mode*/) { return nullptr; } virtual QMediaPlatformPlayerInterface *createPlayerInterface() { return nullptr; } - }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/qmediaplatformplayerinterface_p.h b/src/multimedia/platform/qmediaplatformplayerinterface_p.h index c086f637e..21e762131 100644 --- a/src/multimedia/platform/qmediaplatformplayerinterface_p.h +++ b/src/multimedia/platform/qmediaplatformplayerinterface_p.h @@ -70,9 +70,6 @@ public: // ### nothing in the frontend uses the stream info currently. Needs implementation in QMediaPlayer virtual QMediaStreamsControl *streams() { return nullptr; } - - virtual QVideoRendererControl *createVideoRenderer() = 0; - virtual QVideoWindowControl *createVideoWindow() { return nullptr; }; }; QT_END_NAMESPACE diff --git a/src/multimedia/platform/windows/player/mfplayercontrol.cpp b/src/multimedia/platform/windows/player/mfplayercontrol.cpp index 64e73e0ba..7381b3c3f 100644 --- a/src/multimedia/platform/windows/player/mfplayercontrol.cpp +++ b/src/multimedia/platform/windows/player/mfplayercontrol.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "mfplayercontrol_p.h" +#include "mfvideorenderercontrol_p.h" #include <qtcore/qdebug.h> //#define DEBUG_MEDIAFOUNDATION @@ -139,6 +140,11 @@ QAudioDeviceInfo MFPlayerControl::audioOutput() const return m_session->audioOutput(); } +void MFPlayerControl::setVideoSurface(QAbstractVideoSurface *surface) +{ + m_session->setVideoSurface(surface); +} + void MFPlayerControl::changeState(QMediaPlayer::State state) { if (m_state == state) diff --git a/src/multimedia/platform/windows/player/mfplayercontrol_p.h b/src/multimedia/platform/windows/player/mfplayercontrol_p.h index 54c9f949c..3b9ae083e 100644 --- a/src/multimedia/platform/windows/player/mfplayercontrol_p.h +++ b/src/multimedia/platform/windows/player/mfplayercontrol_p.h @@ -107,6 +107,8 @@ public: bool setAudioOutput(const QAudioDeviceInfo &) override; QAudioDeviceInfo audioOutput() const override; + void setVideoSurface(QAbstractVideoSurface *surface) override; + private Q_SLOTS: void handleStatusChanged(); void handleVideoAvailable(); diff --git a/src/multimedia/platform/windows/player/mfplayerservice.cpp b/src/multimedia/platform/windows/player/mfplayerservice.cpp index d5d461082..43c22beeb 100644 --- a/src/multimedia/platform/windows/player/mfplayerservice.cpp +++ b/src/multimedia/platform/windows/player/mfplayerservice.cpp @@ -57,12 +57,6 @@ MFPlayerService::~MFPlayerService() { m_session->close(); - if (m_videoWindowControl) - delete m_videoWindowControl; - - if (m_videoRendererControl) - delete m_videoRendererControl; - m_session->Release(); //delete m_player; @@ -72,31 +66,3 @@ QMediaPlayerControl *MFPlayerService::player() { return m_player; } - -QVideoRendererControl *MFPlayerService::createVideoRenderer() -{ - if (!m_videoRendererControl && !m_videoWindowControl) { - m_videoRendererControl = new MFVideoRendererControl; - return m_videoRendererControl; - } - return nullptr; -} - -QVideoWindowControl *MFPlayerService::createVideoWindow() -{ - if (!m_videoRendererControl && !m_videoWindowControl) { - m_videoWindowControl = new MFEvrVideoWindowControl; - return m_videoWindowControl; - } - return nullptr; -} - -MFVideoRendererControl* MFPlayerService::videoRendererControl() const -{ - return m_videoRendererControl; -} - -MFEvrVideoWindowControl* MFPlayerService::videoWindowControl() const -{ - return m_videoWindowControl; -} diff --git a/src/multimedia/platform/windows/player/mfplayerservice_p.h b/src/multimedia/platform/windows/player/mfplayerservice_p.h index 1170d7be9..938218cbb 100644 --- a/src/multimedia/platform/windows/player/mfplayerservice_p.h +++ b/src/multimedia/platform/windows/player/mfplayerservice_p.h @@ -80,17 +80,9 @@ public: QMediaPlayerControl *player() override; // ### QMediaStreamsControl *streams() override; - virtual QVideoRendererControl *createVideoRenderer() override; - virtual QVideoWindowControl *createVideoWindow() override; - - MFVideoRendererControl* videoRendererControl() const; - MFEvrVideoWindowControl* videoWindowControl() const; - private: MFPlayerSession *m_session = nullptr; - MFVideoRendererControl *m_videoRendererControl = nullptr; - MFEvrVideoWindowControl *m_videoWindowControl = nullptr; - MFPlayerControl *m_player = nullptr; + MFPlayerControl *m_player = nullptr; }; #endif diff --git a/src/multimedia/platform/windows/player/mfplayersession.cpp b/src/multimedia/platform/windows/player/mfplayersession.cpp index 7972ffd5b..e0abfbd61 100644 --- a/src/multimedia/platform/windows/player/mfplayersession.cpp +++ b/src/multimedia/platform/windows/player/mfplayersession.cpp @@ -103,6 +103,7 @@ MFPlayerSession::MFPlayerSession(MFPlayerService *playerService) m_request.rate = 1.0f; m_audioSampleGrabber = new AudioSampleGrabberCallback; + m_videoRendererControl = new MFVideoRendererControl; } void MFPlayerSession::close() @@ -143,11 +144,10 @@ void MFPlayerSession::close() m_videoProbeMFT = 0; } - if (m_playerService->videoRendererControl()) { - m_playerService->videoRendererControl()->releaseActivate(); - } else if (m_playerService->videoWindowControl()) { - m_playerService->videoWindowControl()->releaseActivate(); - } + m_videoRendererControl->releaseActivate(); +// } else if (m_playerService->videoWindowControl()) { +// m_playerService->videoWindowControl()->releaseActivate(); +// } if (m_session) m_session->Release(); @@ -406,13 +406,9 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(MediaType mediaType, IMFTopology setAudioOutput(QAudioDeviceInfo()); activate = m_currentAudioActivate; } else if (mediaType == Video) { - if (m_playerService->videoRendererControl()) { - activate = m_playerService->videoRendererControl()->createActivate(); - } else if (m_playerService->videoWindowControl()) { - activate = m_playerService->videoWindowControl()->createActivate(); - } else { - qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data"; - } + activate = m_videoRendererControl->createActivate(); +// } else if (m_playerService->videoWindowControl()) { +// activate = m_playerService->videoWindowControl()->createActivate(); } else { // Unknown stream type. emit error(QMediaPlayer::FormatError, tr("Unknown stream type."), false); @@ -1563,9 +1559,9 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent) updatePendingCommands(CmdStart); // playback started, we can now set again the procAmpValues if they have been // changed previously (these are lost when loading a new media) - if (m_playerService->videoWindowControl()) { - m_playerService->videoWindowControl()->applyImageControls(); - } +// if (m_playerService->videoWindowControl()) { +// m_playerService->videoWindowControl()->applyImageControls(); +// } break; case MESessionStopped: if (m_status != QMediaPlayer::EndOfMedia) { @@ -1833,3 +1829,8 @@ bool MFPlayerSession::setAudioOutput(const QAudioDeviceInfo &device) m_audioOutput = device; return true; } + +void MFPlayerSession::setVideoSurface(QAbstractVideoSurface *surface) +{ + m_videoRendererControl->setSurface(surface); +} diff --git a/src/multimedia/platform/windows/player/mfplayersession_p.h b/src/multimedia/platform/windows/player/mfplayersession_p.h index adc3c392b..90f17adfb 100644 --- a/src/multimedia/platform/windows/player/mfplayersession_p.h +++ b/src/multimedia/platform/windows/player/mfplayersession_p.h @@ -128,6 +128,8 @@ public: QMediaMetaData metaData() const { return m_metaData; } + void setVideoSurface(QAbstractVideoSurface *surface); + Q_SIGNALS: void error(QMediaPlayer::Error error, QString errorString, bool isFatal); void sessionEvent(IMFMediaEvent *sessionEvent); @@ -151,6 +153,7 @@ private Q_SLOTS: private: long m_cRef; MFPlayerService *m_playerService; + MFVideoRendererControl *m_videoRendererControl = nullptr; IMFMediaSession *m_session; IMFPresentationClock *m_presentationClock; IMFRateControl *m_rateControl; diff --git a/src/multimedia/playback/qmediaplayer.cpp b/src/multimedia/playback/qmediaplayer.cpp index dc639c2c4..1892c0aaf 100644 --- a/src/multimedia/playback/qmediaplayer.cpp +++ b/src/multimedia/playback/qmediaplayer.cpp @@ -722,22 +722,15 @@ QAudioDeviceInfo QMediaPlayer::audioOutput() const If the media player has already video output attached, it will be replaced with a new one. */ -void QMediaPlayer::setVideoOutput(QMediaSink *output) +void QMediaPlayer::setVideoOutput(QObject *output) { - Q_D(QMediaPlayer); - - if (d->videoOutput) - unbind(qobject_cast<QMediaSink *>(d->videoOutput)); - - if (!output) { - d->videoOutput = nullptr; + auto *mo = output->metaObject(); + QAbstractVideoSurface *surface = nullptr; + if (output && !mo->invokeMethod(output, "videoSurface", Q_RETURN_ARG(QAbstractVideoSurface *, surface))) { + qWarning() << "QMediaPlayer::setVideoOutput: Object" << output->metaObject()->className() << "does not have a videoSurface()"; return; } - - QObject *outputObject = output->asObject(); - Q_ASSERT(outputObject); - - d->videoOutput = bind(output) ? outputObject : nullptr; + setVideoOutput(surface); } /*! @@ -751,8 +744,10 @@ void QMediaPlayer::setVideoOutput(QAbstractVideoSurface *surface) { Q_D(QMediaPlayer); - d->surfaceOutput.setVideoSurface(surface); - setVideoOutput(surface ? &d->surfaceOutput : nullptr); + if (!d->control) + return; + + d->control->setVideoSurface(surface); } /*! diff --git a/src/multimedia/playback/qmediaplayer.h b/src/multimedia/playback/qmediaplayer.h index 791580253..97995f096 100644 --- a/src/multimedia/playback/qmediaplayer.h +++ b/src/multimedia/playback/qmediaplayer.h @@ -135,8 +135,7 @@ public: // void setVideoStream(int index) const; // void setSubtitleStream(int index) const; - // ### should be QVideoSink - void setVideoOutput(QMediaSink *); + void setVideoOutput(QObject *); void setVideoOutput(QAbstractVideoSurface *surface); void setVideoOutput(const QList<QAbstractVideoSurface *> &surfaces); diff --git a/src/multimediawidgets/qgraphicsvideoitem.cpp b/src/multimediawidgets/qgraphicsvideoitem.cpp index 91c157d62..af45d930d 100644 --- a/src/multimediawidgets/qgraphicsvideoitem.cpp +++ b/src/multimediawidgets/qgraphicsvideoitem.cpp @@ -67,9 +67,7 @@ public: QPainterVideoSurface *surface = nullptr; QPointer<QMediaSource> mediaSource; QMediaService *service = nullptr; - QVideoRendererControl *rendererControl = nullptr; Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio; - bool updatePaintDevice = true; QRectF rect; QRectF boundingRect; QRectF sourceRect; @@ -86,12 +84,6 @@ public: void QGraphicsVideoItemPrivate::clearService() { - if (rendererControl) { - surface->stop(); - rendererControl->setSurface(nullptr); - service->releaseControl(rendererControl); - rendererControl = nullptr; - } if (service) { QObject::disconnect(service, SIGNAL(destroyed()), q_ptr, SLOT(_q_serviceDestroyed())); service = nullptr; @@ -152,7 +144,6 @@ void QGraphicsVideoItemPrivate::_q_updateNativeSize() void QGraphicsVideoItemPrivate::_q_serviceDestroyed() { - rendererControl = nullptr; service = nullptr; surface->stop(); @@ -204,11 +195,6 @@ QGraphicsVideoItem::QGraphicsVideoItem(QGraphicsItem *parent) */ QGraphicsVideoItem::~QGraphicsVideoItem() { - if (d_ptr->rendererControl) { - d_ptr->rendererControl->setSurface(nullptr); - d_ptr->service->releaseControl(d_ptr->rendererControl); - } - delete d_ptr->surface; delete d_ptr; } @@ -256,28 +242,6 @@ bool QGraphicsVideoItem::setMediaSource(QMediaSource *object) if (d->mediaSource) { d->service = d->mediaSource->service(); - - if (d->service) { - QObject *control = d->service->requestControl(QVideoRendererControl_iid); - if (control) { - d->rendererControl = qobject_cast<QVideoRendererControl *>(control); - - if (d->rendererControl) { - //don't set the surface until the item is painted - //at least once and the surface is configured - if (!d->updatePaintDevice) - d->rendererControl->setSurface(d->surface); - else - update(boundingRect()); - - connect(d->service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed())); - - return true; - } - if (control) - d->service->releaseControl(control); - } - } } d->mediaSource = nullptr; @@ -379,8 +343,7 @@ void QGraphicsVideoItem::paint( Q_UNUSED(option); Q_UNUSED(widget); - if (d->surface && d->updatePaintDevice) { - d->updatePaintDevice = false; + if (d->surface) { #if QT_CONFIG(opengl) if (widget) connect(widget, SIGNAL(destroyed()), d->surface, SLOT(viewportDestroyed())); @@ -396,8 +359,6 @@ void QGraphicsVideoItem::paint( } } #endif - if (d->rendererControl && d->rendererControl->surface() != d->surface) - d->rendererControl->setSurface(d->surface); } if (d->surface && d->surface->isActive()) { diff --git a/src/multimediawidgets/qgraphicsvideoitem.h b/src/multimediawidgets/qgraphicsvideoitem.h index 0a51269a2..65915a573 100644 --- a/src/multimediawidgets/qgraphicsvideoitem.h +++ b/src/multimediawidgets/qgraphicsvideoitem.h @@ -67,7 +67,7 @@ public: QMediaSource *mediaSource() const override; QObject *asObject() override { return this; } - QAbstractVideoSurface *videoSurface() const; + Q_INVOKABLE QAbstractVideoSurface *videoSurface() const; Qt::AspectRatioMode aspectRatioMode() const; void setAspectRatioMode(Qt::AspectRatioMode mode); diff --git a/src/multimediawidgets/qpaintervideosurface.cpp b/src/multimediawidgets/qpaintervideosurface.cpp index 8a3567d01..9e6d8fa8a 100644 --- a/src/multimediawidgets/qpaintervideosurface.cpp +++ b/src/multimediawidgets/qpaintervideosurface.cpp @@ -150,12 +150,12 @@ QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::start(const QVideoSurf const QAbstractVideoBuffer::HandleType t = format.handleType(); if (t == QAbstractVideoBuffer::NoHandle) { - bool ok = m_imageFormat != QImage::Format_Invalid && !m_imageSize.isEmpty(); -#ifndef QT_NO_OPENGL - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) - ok &= format.pixelFormat() != QVideoFrame::Format_RGB24; -#endif - if (ok) +// bool ok = m_imageFormat != QImage::Format_Invalid && !m_imageSize.isEmpty(); +//#ifndef QT_NO_OPENGL +// if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) +// ok &= format.pixelFormat() != QVideoFrame::Format_RGB24; +//#endif +// if (ok) return QAbstractVideoSurface::NoError; } else if (t == QAbstractVideoBuffer::QPixmapHandle) { return QAbstractVideoSurface::NoError; @@ -186,12 +186,7 @@ QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::paint( if (m_frame.handleType() == QAbstractVideoBuffer::QPixmapHandle) { painter->drawPixmap(target, m_frame.handle().value<QPixmap>(), source); } else if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) { - QImage image( - m_frame.bits(), - m_imageSize.width(), - m_imageSize.height(), - m_frame.bytesPerLine(), - m_imageFormat); + QImage image = m_frame.image(); const QTransform oldTransform = painter->transform(); QTransform transform = oldTransform; diff --git a/src/multimediawidgets/qvideowidget.h b/src/multimediawidgets/qvideowidget.h index 3073033ae..3a858077c 100644 --- a/src/multimediawidgets/qvideowidget.h +++ b/src/multimediawidgets/qvideowidget.h @@ -71,7 +71,7 @@ public: QMediaSource *mediaSource() const override; QObject *asObject() override { return this; } - QAbstractVideoSurface *videoSurface() const; + Q_INVOKABLE QAbstractVideoSurface *videoSurface() const; #ifdef Q_QDOC bool isFullScreen() const; diff --git a/tests/auto/unit/mockbackend/mockcameracontrol.h b/tests/auto/unit/mockbackend/mockcameracontrol.h index c79aa9f9f..25262e23b 100644 --- a/tests/auto/unit/mockbackend/mockcameracontrol.h +++ b/tests/auto/unit/mockbackend/mockcameracontrol.h @@ -120,6 +120,7 @@ public: m_camera = camera; } + void setVideoSurface(QAbstractVideoSurface *) {} QCamera::State m_state; QCamera::CaptureModes m_captureMode; diff --git a/tests/auto/unit/mockbackend/mockmediaplayercontrol.h b/tests/auto/unit/mockbackend/mockmediaplayercontrol.h index 924358095..12532f826 100644 --- a/tests/auto/unit/mockbackend/mockmediaplayercontrol.h +++ b/tests/auto/unit/mockbackend/mockmediaplayercontrol.h @@ -144,6 +144,9 @@ public: << QStringLiteral("customRole2"); } + void setVideoSurface(QAbstractVideoSurface *) {} + + void emitError(QMediaPlayer::Error err, const QString &errorString) { emit error(err, errorString); diff --git a/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp b/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp index 4d3d6ab98..f280389db 100644 --- a/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp +++ b/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp @@ -800,7 +800,7 @@ void tst_QCamera::testSetVideoOutput() QCamera camera; auto *mockCameraService = integration->lastCaptureService(); - camera.setViewfinder(static_cast<QMediaSink *>(nullptr)); + camera.setViewfinder(static_cast<QAbstractVideoSurface *>(nullptr)); QCOMPARE(mockCameraService->rendererRef, 0); @@ -808,7 +808,7 @@ void tst_QCamera::testSetVideoOutput() QVERIFY(mockCameraService->rendererControl->surface() == &surface); QCOMPARE(mockCameraService->rendererRef, 1); - camera.setViewfinder(reinterpret_cast<QAbstractVideoSurface *>(0)); + camera.setViewfinder(static_cast<QAbstractVideoSurface *>(nullptr)); QVERIFY(mockCameraService->rendererControl->surface() == nullptr); //rendererControl is released @@ -818,7 +818,7 @@ void tst_QCamera::testSetVideoOutput() QVERIFY(mockCameraService->rendererControl->surface() == &surface); QCOMPARE(mockCameraService->rendererRef, 1); - camera.setViewfinder(static_cast<QMediaSink *>(nullptr)); + camera.setViewfinder(static_cast<QAbstractVideoSurface *>(nullptr)); QVERIFY(mockCameraService->rendererControl->surface() == nullptr); //rendererControl is released QCOMPARE(mockCameraService->rendererRef, 0); diff --git a/tests/auto/unit/multimedia/qmediaplayer/tst_qmediaplayer.cpp b/tests/auto/unit/multimedia/qmediaplayer/tst_qmediaplayer.cpp index 9c778fe11..321847683 100644 --- a/tests/auto/unit/multimedia/qmediaplayer/tst_qmediaplayer.cpp +++ b/tests/auto/unit/multimedia/qmediaplayer/tst_qmediaplayer.cpp @@ -977,7 +977,7 @@ void tst_QMediaPlayer::testSetVideoOutput() { MockVideoSurface surface; - player->setVideoOutput(static_cast<QMediaSink *>(nullptr)); + player->setVideoOutput(static_cast<QObject *>(nullptr)); QCOMPARE(mockService->rendererRef, 0); @@ -995,7 +995,7 @@ void tst_QMediaPlayer::testSetVideoOutput() QVERIFY(mockService->rendererControl->surface() == &surface); QCOMPARE(mockService->rendererRef, 1); - player->setVideoOutput(static_cast<QMediaSink *>(nullptr)); + player->setVideoOutput(static_cast<QObject *>(nullptr)); QVERIFY(mockService->rendererControl->surface() == nullptr); //rendererControl is released QCOMPARE(mockService->rendererRef, 0); |