diff options
author | Yoann Lopes <yoann.lopes@theqtcompany.com> | 2015-06-03 14:19:10 +0200 |
---|---|---|
committer | Yoann Lopes <yoann.lopes@theqtcompany.com> | 2015-08-07 17:35:12 +0000 |
commit | 3c54acb6f7ab082e3c7881701b84593c6372ef6c (patch) | |
tree | 2524d35b8733e7ffa86143c66635a21a3e38a999 | |
parent | bc9cfcd08acd439c85fee5ffa1a768f8aebeff6f (diff) | |
download | qtmultimedia-3c54acb6f7ab082e3c7881701b84593c6372ef6c.tar.gz qtmultimedia-3c54acb6f7ab082e3c7881701b84593c6372ef6c.tar.bz2 qtmultimedia-3c54acb6f7ab082e3c7881701b84593c6372ef6c.zip |
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 <christian.stromme@theqtcompany.com>
4 files changed, 49 insertions, 15 deletions
diff --git a/src/multimedia/video/qvideosurfaceformat.cpp b/src/multimedia/video/qvideosurfaceformat.cpp index 4c616b89..df6cbcfc 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 c9fa206a..5a8857b7 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 de4cabfa..70d48dd9 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 8e548d64..6ad87597 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() |