From 3c54acb6f7ab082e3c7881701b84593c6372ef6c Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Wed, 3 Jun 2015 14:19:10 +0200 Subject: Add new property to QVideoSurfaceFormat. The 'mirrored' property indicates the QVideoFrames need to be mirrored along their vertical axis. This is typically needed for video frames coming from a front camera on a mobile device. This is implemented as a string-based property. In Qt 5.6, this should be replaced by a new public function. Change-Id: Ideb7de81e83f66826f4efb5f2951c4beec13546b Reviewed-by: Christian Stromme --- src/multimediawidgets/qpaintervideosurface.cpp | 42 ++++++++++++++++++-------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'src/multimediawidgets/qpaintervideosurface.cpp') diff --git a/src/multimediawidgets/qpaintervideosurface.cpp b/src/multimediawidgets/qpaintervideosurface.cpp index c9fa206a2..5a8857b78 100644 --- a/src/multimediawidgets/qpaintervideosurface.cpp +++ b/src/multimediawidgets/qpaintervideosurface.cpp @@ -86,11 +86,13 @@ private: QSize m_imageSize; QImage::Format m_imageFormat; QVideoSurfaceFormat::Direction m_scanLineDirection; + bool m_mirrored; }; QVideoSurfaceGenericPainter::QVideoSurfaceGenericPainter() : m_imageFormat(QImage::Format_Invalid) , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom) + , m_mirrored(false) { m_imagePixelFormats << QVideoFrame::Format_RGB32; @@ -137,6 +139,7 @@ QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::start(const QVideoSurf m_imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat()); m_imageSize = format.frameSize(); m_scanLineDirection = format.scanLineDirection(); + m_mirrored = format.property("mirrored").toBool(); const QAbstractVideoBuffer::HandleType t = format.handleType(); if (t == QAbstractVideoBuffer::NoHandle) { @@ -183,17 +186,22 @@ QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::paint( m_frame.bytesPerLine(), m_imageFormat); + const QTransform oldTransform = painter->transform(); + QTransform transform = oldTransform; + QRectF targetRect = target; if (m_scanLineDirection == QVideoSurfaceFormat::BottomToTop) { - const QTransform oldTransform = painter->transform(); - - painter->scale(1, -1); - painter->translate(0, -target.bottom()); - painter->drawImage( - QRectF(target.x(), 0, target.width(), target.height()), image, source); - painter->setTransform(oldTransform); - } else { - painter->drawImage(target, image, source); + transform.scale(1, -1); + transform.translate(0, -target.bottom()); + targetRect.setY(0); + } + if (m_mirrored) { + transform.scale(-1, 1); + transform.translate(-target.right(), 0); + targetRect.setX(0); } + painter->setTransform(transform); + painter->drawImage(targetRect, image, source); + painter->setTransform(oldTransform); m_frame.unmap(); } else if (m_frame.isValid()) { @@ -281,6 +289,7 @@ protected: QGLContext *m_context; QAbstractVideoBuffer::HandleType m_handleType; QVideoSurfaceFormat::Direction m_scanLineDirection; + bool m_mirrored; QVideoSurfaceFormat::YCbCrColorSpace m_colorSpace; GLenum m_textureFormat; GLuint m_textureInternalFormat; @@ -299,6 +308,7 @@ QVideoSurfaceGLPainter::QVideoSurfaceGLPainter(QGLContext *context) : m_context(context) , m_handleType(QAbstractVideoBuffer::NoHandle) , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom) + , m_mirrored(false) , m_colorSpace(QVideoSurfaceFormat::YCbCr_BT601) , m_textureFormat(0) , m_textureInternalFormat(0) @@ -829,6 +839,7 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfac } else { m_handleType = format.handleType(); m_scanLineDirection = format.scanLineDirection(); + m_mirrored = format.property("mirrored").toBool(); m_frameSize = format.frameSize(); m_colorSpace = format.yCbCrColorSpace(); @@ -878,8 +889,10 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint( if (scissorTestEnabled) glEnable(GL_SCISSOR_TEST); - const float txLeft = source.left() / m_frameSize.width(); - const float txRight = source.right() / m_frameSize.width(); + const float txLeft = m_mirrored ? source.right() / m_frameSize.width() + : source.left() / m_frameSize.width(); + const float txRight = m_mirrored ? source.left() / m_frameSize.width() + : source.right() / m_frameSize.width(); const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom ? source.top() / m_frameSize.height() : source.bottom() / m_frameSize.height(); @@ -1188,6 +1201,7 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurface } else { m_handleType = format.handleType(); m_scanLineDirection = format.scanLineDirection(); + m_mirrored = format.property("mirrored").toBool(); m_frameSize = format.frameSize(); m_colorSpace = format.yCbCrColorSpace(); @@ -1276,8 +1290,10 @@ QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint( GLfloat(target.right() + 1), GLfloat(target.top()) }; - const GLfloat txLeft = source.left() / m_frameSize.width(); - const GLfloat txRight = source.right() / m_frameSize.width(); + const GLfloat txLeft = m_mirrored ? source.right() / m_frameSize.width() + : source.left() / m_frameSize.width(); + const GLfloat txRight = m_mirrored ? source.left() / m_frameSize.width() + : source.right() / m_frameSize.width(); const GLfloat txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom ? source.top() / m_frameSize.height() : source.bottom() / m_frameSize.height(); -- cgit v1.2.3