summaryrefslogtreecommitdiffstats
path: root/src/imports
diff options
context:
space:
mode:
authorMichael Goddard <michael.goddard@nokia.com>2011-11-25 15:25:22 +1000
committerQt by Nokia <qt-info@nokia.com>2011-11-25 08:30:55 +0100
commitbe7cc17cbfe2209c6da1ecd40f99df0149a2651d (patch)
treeea6a56215baee7a03e1e405eac07d09856e9d6f6 /src/imports
parent581564c9902702626a5dc89cb47632c6a624b514 (diff)
Add orientation support to VideoOutput.
Just uses an integer to represent the degrees rotation from standard. Only supports multiples of 90 - other rotation can be done with standard QML. Change-Id: Id4013169c5d9da473b6e5be94ba341da21c2f2a3 Reviewed-by: Dmytro Poplavskiy <dmytro.poplavskiy@nokia.com>
Diffstat (limited to 'src/imports')
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput.cpp57
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput_p.h6
-rw-r--r--src/imports/multimedia/qsgvideonode.cpp71
-rw-r--r--src/imports/multimedia/qsgvideonode_p.h3
4 files changed, 126 insertions, 11 deletions
diff --git a/src/imports/multimedia/qdeclarativevideooutput.cpp b/src/imports/multimedia/qdeclarativevideooutput.cpp
index 0d65becf3..b7667fddc 100644
--- a/src/imports/multimedia/qdeclarativevideooutput.cpp
+++ b/src/imports/multimedia/qdeclarativevideooutput.cpp
@@ -163,7 +163,8 @@ private:
QDeclarativeVideoOutput::QDeclarativeVideoOutput(QQuickItem *parent) :
QQuickItem(parent),
m_sourceType(NoSource),
- m_fillMode(PreserveAspectFit)
+ m_fillMode(PreserveAspectFit),
+ m_orientation(0)
{
setFlag(ItemHasContents, true);
m_surface = new QSGVideoItemSurface(this);
@@ -290,6 +291,14 @@ void QDeclarativeVideoOutput::stop()
present(QVideoFrame());
}
+/*
+ * Helper - returns true if the given orientation has the same aspect as the default (e.g. 180*n)
+ */
+static inline bool qIsDefaultAspect(int o)
+{
+ return (o % 180) == 0;
+}
+
/*!
\qmlproperty enumeration VideoOutput::fillMode
@@ -322,7 +331,11 @@ void QDeclarativeVideoOutput::setFillMode(FillMode mode)
void QDeclarativeVideoOutput::_q_updateNativeSize(const QVideoSurfaceFormat &format)
{
- const QSize &size = format.sizeHint();
+ QSize size = format.sizeHint();
+ if (!qIsDefaultAspect(m_orientation)) {
+ size.transpose();
+ }
+
if (m_nativeSize != size) {
m_nativeSize = size;
@@ -363,6 +376,43 @@ void QDeclarativeVideoOutput::_q_updateGeometry()
}
}
+int QDeclarativeVideoOutput::orientation() const
+{
+ return m_orientation;
+}
+
+void QDeclarativeVideoOutput::setOrientation(int orientation)
+{
+ // Make sure it's a multiple of 90.
+ if (orientation % 90)
+ return;
+
+ // If the new orientation is the same effect
+ // as the old one, don't update the video node stuff
+ if ((m_orientation % 360) == (orientation % 360)) {
+ m_orientation = orientation;
+ emit orientationChanged();
+ return;
+ }
+
+ // Otherwise, a new orientation
+ // See if we need to change aspect ratio orientation too
+ bool oldAspect = qIsDefaultAspect(m_orientation);
+ bool newAspect = qIsDefaultAspect(orientation);
+
+ m_orientation = orientation;
+
+ if (oldAspect != newAspect) {
+ m_nativeSize.transpose();
+
+ setImplicitWidth(m_nativeSize.width());
+ setImplicitHeight(m_nativeSize.height());
+ }
+
+ update();
+ emit orientationChanged();
+}
+
QSGNode *QDeclarativeVideoOutput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
QSGVideoNode *videoNode = static_cast<QSGVideoNode *>(oldNode);
@@ -396,7 +446,8 @@ QSGNode *QDeclarativeVideoOutput::updatePaintNode(QSGNode *oldNode, UpdatePaintN
return 0;
_q_updateGeometry();
- videoNode->setTexturedRectGeometry(m_boundingRect, m_sourceRect);
+ // Negative rotations need lots of %360
+ videoNode->setTexturedRectGeometry(m_boundingRect, m_sourceRect, (360 + (m_orientation % 360)) % 360);
videoNode->setCurrentFrame(m_frame);
return videoNode;
}
diff --git a/src/imports/multimedia/qdeclarativevideooutput_p.h b/src/imports/multimedia/qdeclarativevideooutput_p.h
index 2c63fc9e4..6b990f72f 100644
--- a/src/imports/multimedia/qdeclarativevideooutput_p.h
+++ b/src/imports/multimedia/qdeclarativevideooutput_p.h
@@ -65,6 +65,7 @@ class QDeclarativeVideoOutput : public QQuickItem
Q_DISABLE_COPY(QDeclarativeVideoOutput)
Q_PROPERTY(QObject* source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(FillMode fillMode READ fillMode WRITE setFillMode NOTIFY fillModeChanged)
+ Q_PROPERTY(int orientation READ orientation WRITE setOrientation NOTIFY orientationChanged)
Q_ENUMS(FillMode)
public:
@@ -84,9 +85,13 @@ public:
FillMode fillMode() const;
void setFillMode(FillMode mode);
+ int orientation() const;
+ void setOrientation(int);
+
Q_SIGNALS:
void sourceChanged();
void fillModeChanged(QDeclarativeVideoOutput::FillMode);
+ void orientationChanged();
protected:
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
@@ -122,6 +127,7 @@ private:
QSize m_nativeSize;
QRectF m_boundingRect;
QRectF m_sourceRect;
+ int m_orientation;
QMutex m_frameMutex;
};
diff --git a/src/imports/multimedia/qsgvideonode.cpp b/src/imports/multimedia/qsgvideonode.cpp
index 712caff65..14d55c118 100644
--- a/src/imports/multimedia/qsgvideonode.cpp
+++ b/src/imports/multimedia/qsgvideonode.cpp
@@ -42,26 +42,83 @@
#include "qsgvideonode_p.h"
QSGVideoNode::QSGVideoNode()
+ : m_orientation(-1)
{
}
-void QSGVideoNode::setTexturedRectGeometry(const QRectF &rect, const QRectF &textureRect)
+/* Helpers */
+static inline void qSetGeom(QSGGeometry::TexturedPoint2D *v, const QPointF &p)
{
- if (rect == m_rect && textureRect == m_textureRect)
+ v->x = p.x();
+ v->y = p.y();
+}
+
+static inline void qSetTex(QSGGeometry::TexturedPoint2D *v, const QPointF &p)
+{
+ v->tx = p.x();
+ v->ty = p.y();
+}
+
+/* Update the vertices and texture coordinates. Orientation must be in {0,90,180,270} */
+void QSGVideoNode::setTexturedRectGeometry(const QRectF &rect, const QRectF &textureRect, int orientation)
+{
+ if (rect == m_rect && textureRect == m_textureRect && orientation == m_orientation)
return;
m_rect = rect;
m_textureRect = textureRect;
+ m_orientation = orientation;
QSGGeometry *g = geometry();
- if (g == 0) {
+ if (g == 0)
g = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4);
- QSGGeometry::updateTexturedRectGeometry(g, rect, textureRect);
- setGeometry(g);
- } else {
- QSGGeometry::updateTexturedRectGeometry(g, rect, textureRect);
+
+ QSGGeometry::TexturedPoint2D *v = g->vertexDataAsTexturedPoint2D();
+
+ // Set geometry first
+ qSetGeom(v + 0, rect.topLeft());
+ qSetGeom(v + 1, rect.bottomLeft());
+ qSetGeom(v + 2, rect.topRight());
+ qSetGeom(v + 3, rect.bottomRight());
+
+ // and then texture coordinates
+ switch (orientation) {
+ default:
+ // tl, bl, tr, br
+ qSetTex(v + 0, textureRect.topLeft());
+ qSetTex(v + 1, textureRect.bottomLeft());
+ qSetTex(v + 2, textureRect.topRight());
+ qSetTex(v + 3, textureRect.bottomRight());
+ break;
+
+ case 90:
+ // tr, tl, br, bl
+ qSetTex(v + 0, textureRect.topRight());
+ qSetTex(v + 1, textureRect.topLeft());
+ qSetTex(v + 2, textureRect.bottomRight());
+ qSetTex(v + 3, textureRect.bottomLeft());
+ break;
+
+ case 180:
+ // br, tr, bl, tl
+ qSetTex(v + 0, textureRect.bottomRight());
+ qSetTex(v + 1, textureRect.topRight());
+ qSetTex(v + 2, textureRect.bottomLeft());
+ qSetTex(v + 3, textureRect.topLeft());
+ break;
+
+ case 270:
+ // bl, br, tl, tr
+ qSetTex(v + 0, textureRect.bottomLeft());
+ qSetTex(v + 1, textureRect.bottomRight());
+ qSetTex(v + 2, textureRect.topLeft());
+ qSetTex(v + 3, textureRect.topRight());
+ break;
}
+ if (!geometry())
+ setGeometry(g);
+
markDirty(DirtyGeometry);
}
diff --git a/src/imports/multimedia/qsgvideonode_p.h b/src/imports/multimedia/qsgvideonode_p.h
index 466b4566c..45087dd0d 100644
--- a/src/imports/multimedia/qsgvideonode_p.h
+++ b/src/imports/multimedia/qsgvideonode_p.h
@@ -56,11 +56,12 @@ public:
virtual void setCurrentFrame(const QVideoFrame &frame) = 0;
virtual QVideoFrame::PixelFormat pixelFormat() const = 0;
- void setTexturedRectGeometry(const QRectF &boundingRect, const QRectF &textureRect);
+ void setTexturedRectGeometry(const QRectF &boundingRect, const QRectF &textureRect, int orientation);
private:
QRectF m_rect;
QRectF m_textureRect;
+ int m_orientation;
};
class QSGVideoNodeFactory {