summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@theqtcompany.com>2015-06-03 14:19:10 +0200
committerYoann Lopes <yoann.lopes@theqtcompany.com>2015-08-07 17:35:12 +0000
commit3c54acb6f7ab082e3c7881701b84593c6372ef6c (patch)
tree2524d35b8733e7ffa86143c66635a21a3e38a999
parentbc9cfcd08acd439c85fee5ffa1a768f8aebeff6f (diff)
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>
-rw-r--r--src/multimedia/video/qvideosurfaceformat.cpp13
-rw-r--r--src/multimediawidgets/qpaintervideosurface.cpp42
-rw-r--r--src/qtmultimediaquicktools/qdeclarativevideooutput_render.cpp6
-rw-r--r--tests/auto/unit/qvideosurfaceformat/tst_qvideosurfaceformat.cpp3
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()