diff options
author | Dan Cape <dcape@qnx.com> | 2016-04-22 14:40:23 -0400 |
---|---|---|
committer | Yoann Lopes <yoann.lopes@qt.io> | 2016-04-27 10:58:11 +0000 |
commit | c1cfbd98d2c03a2aff305c4fc190424906d7f465 (patch) | |
tree | 56528f42875ef1d93881657ef3711119c5e4989e /src/plugins/qnx/mediaplayer | |
parent | 80deebcee3e9b14046a042cf6a66467ff078d57b (diff) |
QNX: Avoid reading frames faster than they're rendered
The previous code would capture frames with a 60Hz timer
into two pixmaps alternating pixmaps with each successive
frame. Rendering was somewhat disconnected from this, if
rendering was unable to occur at 60fps, multiple frames
might be copied for each frame rendered. This meant that
it might try copying a video frame into a pixmap that was
currently being used by the GPU with bad effects. The
primary effect being severe flicker on i.mx6 targets.
The change is to ensure that we don't read the window data
until we're just about to make use of it. This means we
don't ever get ahead of ourselves and read the video window
once for every frame rendered.
The code has been significantly refactored. There is now
a class that manages the pixmaps and egl images. This is
created on demand and the images are created and destroyed
when sizes change. Since this all now occurs in the proper
thread, much of the nonsense of setting _q_GLThreadCallback
to arrange a call from the render thread is avoided.
Remove BlackBerry ifdefs that are no longer used.
Change-Id: I4bf5efa4c39c8170e3f55499c167ee10e521e100
Reviewed-by: James McDonnell <jmcdonnell@qnx.com>
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
Diffstat (limited to 'src/plugins/qnx/mediaplayer')
-rw-r--r-- | src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp | 53 | ||||
-rw-r--r-- | src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h | 2 |
2 files changed, 23 insertions, 32 deletions
diff --git a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp index 9e83ba2b2..5483e1423 100644 --- a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp +++ b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.cpp @@ -52,7 +52,7 @@ MmRendererPlayerVideoRendererControl::MmRendererPlayerVideoRendererControl(QObje , m_context(0) , m_videoId(-1) { - connect(m_windowGrabber, SIGNAL(frameGrabbed(QImage, int)), SLOT(frameGrabbed(QImage, int))); + connect(m_windowGrabber, SIGNAL(updateScene(const QSize &)), SLOT(updateScene(const QSize &))); } MmRendererPlayerVideoRendererControl::~MmRendererPlayerVideoRendererControl() @@ -136,13 +136,14 @@ void MmRendererPlayerVideoRendererControl::resume() m_windowGrabber->resume(); } -class BBTextureBuffer : public QAbstractVideoBuffer +class QnxTextureBuffer : public QAbstractVideoBuffer { public: - BBTextureBuffer(int handle) : + QnxTextureBuffer(WindowGrabber *windowGrabber) : QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle) { - m_handle = handle; + m_windowGrabber = windowGrabber; + m_handle = 0; } MapMode mapMode() const { return QAbstractVideoBuffer::ReadWrite; @@ -157,54 +158,46 @@ public: return 0; } QVariant handle() const { + if (!m_handle) { + const_cast<QnxTextureBuffer*>(this)->m_handle = m_windowGrabber->getNextTextureId(); + } return m_handle; } private: + WindowGrabber *m_windowGrabber; int m_handle; }; -void MmRendererPlayerVideoRendererControl::frameGrabbed(const QImage &frame, int handle) +void MmRendererPlayerVideoRendererControl::updateScene(const QSize &size) { if (m_surface) { if (!m_surface->isActive()) { if (m_windowGrabber->eglImageSupported()) { - if (QOpenGLContext::currentContext()) - m_windowGrabber->createEglImages(); - else - m_surface->setProperty("_q_GLThreadCallback", QVariant::fromValue<QObject*>(this)); - - m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_BGR32, - QAbstractVideoBuffer::GLTextureHandle)); + m_surface->start(QVideoSurfaceFormat(size, QVideoFrame::Format_BGR32, + QAbstractVideoBuffer::GLTextureHandle)); } else { - m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32)); + m_surface->start(QVideoSurfaceFormat(size, QVideoFrame::Format_ARGB32)); } } else { - if (m_surface->surfaceFormat().frameSize() != frame.size()) { - QAbstractVideoBuffer::HandleType type = m_surface->surfaceFormat().handleType(); + if (m_surface->surfaceFormat().frameSize() != size) { m_surface->stop(); - if (type != QAbstractVideoBuffer::NoHandle) { - m_surface->setProperty("_q_GLThreadCallback", QVariant::fromValue<QObject*>(this)); - m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_BGR32, - QAbstractVideoBuffer::GLTextureHandle)); + if (m_windowGrabber->eglImageSupported()) { + m_surface->start(QVideoSurfaceFormat(size, QVideoFrame::Format_BGR32, + QAbstractVideoBuffer::GLTextureHandle)); } else { - m_surface->start(QVideoSurfaceFormat(frame.size(), QVideoFrame::Format_ARGB32)); + m_surface->start(QVideoSurfaceFormat(size, QVideoFrame::Format_ARGB32)); } } } // Depending on the support of EGL images on the current platform we either pass a texture // handle or a copy of the image data - if (m_surface->surfaceFormat().handleType() != QAbstractVideoBuffer::NoHandle) { - if (m_windowGrabber->eglImagesInitialized() && - m_surface->property("_q_GLThreadCallback") != 0) - m_surface->setProperty("_q_GLThreadCallback", 0); - - - BBTextureBuffer *textBuffer = new BBTextureBuffer(handle); - QVideoFrame actualFrame(textBuffer, frame.size(), QVideoFrame::Format_BGR32); + if (m_windowGrabber->eglImageSupported()) { + QnxTextureBuffer *textBuffer = new QnxTextureBuffer(m_windowGrabber); + QVideoFrame actualFrame(textBuffer, size, QVideoFrame::Format_BGR32); m_surface->present(actualFrame); } else { - m_surface->present(frame.copy()); + m_surface->present(m_windowGrabber->getNextImage().copy()); } } } @@ -214,8 +207,6 @@ void MmRendererPlayerVideoRendererControl::customEvent(QEvent *e) // This is running in the render thread (OpenGL enabled) if (e->type() == QEvent::User) m_windowGrabber->checkForEglImageExtension(); - else if (e->type() == QEvent::User + 1) - m_windowGrabber->createEglImages(); } QT_END_NAMESPACE diff --git a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h index 22833040c..c63d88f4d 100644 --- a/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h +++ b/src/plugins/qnx/mediaplayer/mmrendererplayervideorenderercontrol.h @@ -62,7 +62,7 @@ public: void customEvent(QEvent *) Q_DECL_OVERRIDE; private Q_SLOTS: - void frameGrabbed(const QImage &frame, int); + void updateScene(const QSize &size); private: QPointer<QAbstractVideoSurface> m_surface; |