diff options
author | VaL Doroshchuk <valentyn.doroshchuk@qt.io> | 2019-10-22 14:29:44 +0200 |
---|---|---|
committer | VaL Doroshchuk <valentyn.doroshchuk@qt.io> | 2020-01-05 16:05:47 +0100 |
commit | 8c9676fb0bb145704b7e8bdaf7832c03f14b47de (patch) | |
tree | 427519b54a43ab063531c9a7d3d1f8181e9ca0de /src/multimediawidgets/qvideowidget.cpp | |
parent | e530c303d8d9164888f8d6e1a935b81cda8bf426 (diff) |
Expose video surfaces in rendering components
* Currently QVideoWidget, QGraphicsVideoItem and QML Video Output
tightly depend on QMediaPlayer, QMediaService etc.
Since QMediaService is deprecated and will be removed from Qt6,
its usage must be removed from rendering components.
* Also it is a part of a task to make all components independent,
e.g. without dependencies to another components, like the media player,
or video producer.
These video consumer components should be reusable without QMediaPlayer too,
which today is not possible,
and should have responsibility for a single part of the functionality.
* It is a part of a task to allow users to decide how to render video,
using either video surface or native windows.
Introducing
QVideoWidget::videoSurface()
QGraphicsVideoItem::videoSurface()
QDeclarativeVideoOutput::videoSurface()
that create a surface, if necessary, and returns the underlying video surface
which provides a possibility to render video frames without knowledge of any services and controls.
Can be used like:
QMediaPlayer->setVideoOutput(QVideoWidget->videoSurface());
or
QMediaPlayer->setVideoOutput(QGraphicsVideoItem->videoSurface());
This allows QMediaPlayer to get video frames from a backend,
without using QVideoWidget/QGraphicsVideoItem, and to present these frames to provided surface.
Moreover, now it is possible to render video frames without QMediaPlayer:
QVideoSurfaceFormat format(img.size(), QVideoFrame::Format_ARGB32);
videoWidget->videoSurface()->start(format);
videoWidget->videoSurface()->present(img);
[ChangeLog] Introduced videoSurface property to QVideoWidget, QGraphicsVideoItem and
QDeclarativeVideoOutput.
Task-number: QTBUG-80431
Change-Id: I49641750537160832e29c297279e72b8288e974c
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Diffstat (limited to 'src/multimediawidgets/qvideowidget.cpp')
-rw-r--r-- | src/multimediawidgets/qvideowidget.cpp | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/src/multimediawidgets/qvideowidget.cpp b/src/multimediawidgets/qvideowidget.cpp index 5adc6c359..723a9bbb3 100644 --- a/src/multimediawidgets/qvideowidget.cpp +++ b/src/multimediawidgets/qvideowidget.cpp @@ -145,7 +145,8 @@ QRendererVideoWidgetBackend::QRendererVideoWidgetBackend( connect(m_surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)), this, SLOT(formatChanged(QVideoSurfaceFormat))); - m_rendererControl->setSurface(m_surface); + if (m_rendererControl) + m_rendererControl->setSurface(m_surface); } QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend() @@ -153,14 +154,21 @@ QRendererVideoWidgetBackend::~QRendererVideoWidgetBackend() delete m_surface; } +QAbstractVideoSurface *QRendererVideoWidgetBackend::videoSurface() const +{ + return m_surface; +} + void QRendererVideoWidgetBackend::releaseControl() { - m_service->releaseControl(m_rendererControl); + if (m_service && m_rendererControl) + m_service->releaseControl(m_rendererControl); } void QRendererVideoWidgetBackend::clearSurface() { - m_rendererControl->setSurface(0); + if (m_rendererControl) + m_rendererControl->setSurface(0); } void QRendererVideoWidgetBackend::setBrightness(int brightness) @@ -469,7 +477,7 @@ void QVideoWidgetPrivate::clearService() delete rendererBackend; rendererBackend = 0; - } else { + } else if (windowBackend) { windowBackend->releaseControl(); delete windowBackend; @@ -515,18 +523,15 @@ bool QVideoWidgetPrivate::createWindowBackend() bool QVideoWidgetPrivate::createRendererBackend() { - if (QMediaControl *control = service->requestControl(QVideoRendererControl_iid)) { - if (QVideoRendererControl *rendererControl = qobject_cast<QVideoRendererControl *>(control)) { - rendererBackend = new QRendererVideoWidgetBackend(service, rendererControl, q_func()); - currentBackend = rendererBackend; - - setCurrentControl(rendererBackend); + QMediaControl *control = service + ? service->requestControl(QVideoRendererControl_iid) + : nullptr; + rendererBackend = new QRendererVideoWidgetBackend(service, + qobject_cast<QVideoRendererControl *>(control), q_func()); + currentBackend = rendererBackend; + setCurrentControl(rendererBackend); - return true; - } - service->releaseControl(control); - } - return false; + return !service || (service && control); } void QVideoWidgetPrivate::_q_serviceDestroyed() @@ -696,6 +701,29 @@ bool QVideoWidget::setMediaObject(QMediaObject *object) } /*! + \since 5.15 + \property QVideoWidget::videoSurface + \brief Returns the underlaying video surface that can render video frames + to the current widget. + This property is never \c nullptr. + Example of how to render video frames to QVideoWidget: + \snippet multimedia-snippets/video.cpp Widget Surface + \sa QMediaPlayer::setVideoOutput +*/ + +QAbstractVideoSurface *QVideoWidget::videoSurface() const +{ + auto d = const_cast<QVideoWidgetPrivate *>(d_func()); + + if (!d->rendererBackend) { + d->clearService(); + d->createRendererBackend(); + } + + return d->rendererBackend->videoSurface(); +} + +/*! \property QVideoWidget::aspectRatioMode \brief how video is scaled with respect to its aspect ratio. */ |