diff options
author | Michael Goddard <michael.goddard@nokia.com> | 2011-11-25 15:25:22 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-25 08:30:55 +0100 |
commit | be7cc17cbfe2209c6da1ecd40f99df0149a2651d (patch) | |
tree | ea6a56215baee7a03e1e405eac07d09856e9d6f6 /src/imports | |
parent | 581564c9902702626a5dc89cb47632c6a624b514 (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.cpp | 57 | ||||
-rw-r--r-- | src/imports/multimedia/qdeclarativevideooutput_p.h | 6 | ||||
-rw-r--r-- | src/imports/multimedia/qsgvideonode.cpp | 71 | ||||
-rw-r--r-- | src/imports/multimedia/qsgvideonode_p.h | 3 |
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 { |