diff options
4 files changed, 49 insertions, 15 deletions
diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp index 4c616b898..df6cbcfc1 100644 --- a/src/multimedia/video/qvideosurfaceformat.cpp +++ b/src/multimedia/video/qvideosurfaceformat.cpp @@ -61,6 +61,7 @@ public: , pixelAspectRatio(1, 1) , ycbcrColorSpace(QVideoSurfaceFormat::YCbCr_Undefined) , frameRate(0.0) + , mirrored(false) { } @@ -76,6 +77,7 @@ public: , ycbcrColorSpace(QVideoSurfaceFormat::YCbCr_Undefined) , viewport(QPoint(0, 0), size) , frameRate(0.0) + , mirrored(false) { } @@ -89,6 +91,7 @@ public: , ycbcrColorSpace(other.ycbcrColorSpace) , viewport(other.viewport) , frameRate(other.frameRate) + , mirrored(other.mirrored) , propertyNames(other.propertyNames) , propertyValues(other.propertyValues) { @@ -104,6 +107,7 @@ public: && viewport == other.viewport && frameRatesEqual(frameRate, other.frameRate) && ycbcrColorSpace == other.ycbcrColorSpace + && mirrored == other.mirrored && propertyNames.count() == other.propertyNames.count()) { for (int i = 0; i < propertyNames.count(); ++i) { int j = other.propertyNames.indexOf(propertyNames.at(i)); @@ -130,6 +134,7 @@ public: QVideoSurfaceFormat::YCbCrColorSpace ycbcrColorSpace; QRect viewport; qreal frameRate; + bool mirrored; QList<QByteArray> propertyNames; QList<QVariant> propertyValues; }; @@ -468,7 +473,8 @@ QList<QByteArray> QVideoSurfaceFormat::propertyNames() const << "frameRate" << "pixelAspectRatio" << "sizeHint" - << "yCbCrColorSpace") + << "yCbCrColorSpace" + << "mirrored") + d->propertyNames; } @@ -499,6 +505,8 @@ QVariant QVideoSurfaceFormat::property(const char *name) const return sizeHint(); } else if (qstrcmp(name, "yCbCrColorSpace") == 0) { return qVariantFromValue(d->ycbcrColorSpace); + } else if (qstrcmp(name, "mirrored") == 0) { + return d->mirrored; } else { int id = 0; for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {} @@ -547,6 +555,9 @@ void QVideoSurfaceFormat::setProperty(const char *name, const QVariant &value) } else if (qstrcmp(name, "yCbCrColorSpace") == 0) { if (value.canConvert<YCbCrColorSpace>()) d->ycbcrColorSpace = qvariant_cast<YCbCrColorSpace>(value); + } else if (qstrcmp(name, "mirrored") == 0) { + if (value.canConvert<bool>()) + d->mirrored = qvariant_cast<bool>(value); } else { int id = 0; for (; id < d->propertyNames.count() && d->propertyNames.at(id) != name; ++id) {} 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(); diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp index de4cabfaf..70d48dd97 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp @@ -255,6 +255,12 @@ void QDeclarativeVideoRendererBackend::updateGeometry() m_sourceTextureRect.setTop(m_sourceTextureRect.bottom()); m_sourceTextureRect.setBottom(top); } + + if (videoSurface()->surfaceFormat().property("mirrored").toBool()) { + qreal left = m_sourceTextureRect.left(); + m_sourceTextureRect.setLeft(m_sourceTextureRect.right()); + m_sourceTextureRect.setRight(left); + } } QSGNode *QDeclarativeVideoRendererBackend::updatePaintNode(QSGNode *oldNode, diff --git a/tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp b/tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp index 8e548d64c..6ad875972 100644 --- a/tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp +++ b/tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp @@ -521,7 +521,8 @@ void tst_QVideoSurfaceFormat::staticPropertyNames() QVERIFY(propertyNames.contains("pixelAspectRatio")); QVERIFY(propertyNames.contains("yCbCrColorSpace")); QVERIFY(propertyNames.contains("sizeHint")); - QCOMPARE(propertyNames.count(), 10); + QVERIFY(propertyNames.contains("mirrored")); + QCOMPARE(propertyNames.count(), 11); } void tst_QVideoSurfaceFormat::dynamicProperty() |