summaryrefslogtreecommitdiffstats
path: root/src/imports
diff options
context:
space:
mode:
authorThomas McGuire <thomas.mcguire.qnx@kdab.com>2013-04-25 16:06:08 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-07 15:02:15 +0200
commit0d9526b5c9740d3d77d9c4d8403a6f9e7370643f (patch)
treebefde05e75607014919cadf2243ef36fa39346c1 /src/imports
parent2eac932747682e4fcc374843e764a377a84e8a3c (diff)
VideoOutput: Take the surface's viewport into account
Task-Number: QTBUG-30410 Change-Id: I480ce0bcd7ec136e54b5bfc5fec0e901141b72d8 Reviewed-by: Josh Faust <jfaust@suitabletech.com> Reviewed-by: Yoann Lopes <yoann.lopes@digia.com>
Diffstat (limited to 'src/imports')
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput.cpp23
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput_backend_p.h3
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput_render.cpp53
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput_render_p.h1
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput_window.cpp7
-rw-r--r--src/imports/multimedia/qdeclarativevideooutput_window_p.h1
6 files changed, 74 insertions, 14 deletions
diff --git a/src/imports/multimedia/qdeclarativevideooutput.cpp b/src/imports/multimedia/qdeclarativevideooutput.cpp
index 1b4b9cd5b..653d45b6d 100644
--- a/src/imports/multimedia/qdeclarativevideooutput.cpp
+++ b/src/imports/multimedia/qdeclarativevideooutput.cpp
@@ -436,13 +436,18 @@ QRectF QDeclarativeVideoOutput::contentRect() const
This property holds the area of the source video
content that is considered for rendering. The
- values are in source pixel coordinates.
+ values are in source pixel coordinates, adjusted for
+ the source's pixel aspect ratio.
Note that typically the top left corner of this rectangle
will be \c {0,0} while the width and height will be the
- width and height of the input content.
+ width and height of the input content. Only when the video
+ source has a viewport set, these values will differ.
The orientation setting does not affect this rectangle.
+
+ \sa QVideoSurfaceFormat::pixelAspectRatio()
+ \sa QVideoSurfaceFormat::viewport()
*/
QRectF QDeclarativeVideoOutput::sourceRect() const
{
@@ -451,7 +456,19 @@ QRectF QDeclarativeVideoOutput::sourceRect() const
if (!qIsDefaultAspect(m_orientation)) {
size.transpose();
}
- return QRectF(QPointF(), size); // XXX ignores viewport
+
+ // No backend? Just assume no viewport.
+ if (!m_nativeSize.isValid() || !m_backend) {
+ return QRectF(QPointF(), size);
+ }
+
+ // Take the viewport into account for the top left position.
+ // m_nativeSize is already adjusted to the viewport, as it originats
+ // from QVideoSurfaceFormat::sizeHint(), which includes pixel aspect
+ // ratio and viewport.
+ const QRectF viewport = m_backend->adjustedViewport();
+ Q_ASSERT(viewport.size() == size);
+ return QRectF(viewport.topLeft(), size);
}
/*!
diff --git a/src/imports/multimedia/qdeclarativevideooutput_backend_p.h b/src/imports/multimedia/qdeclarativevideooutput_backend_p.h
index 7f2284bb4..f731b77f1 100644
--- a/src/imports/multimedia/qdeclarativevideooutput_backend_p.h
+++ b/src/imports/multimedia/qdeclarativevideooutput_backend_p.h
@@ -74,6 +74,9 @@ public:
virtual QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data) = 0;
virtual QAbstractVideoSurface *videoSurface() const = 0;
+ // The viewport, adjusted for the pixel aspect ratio
+ virtual QRectF adjustedViewport() const = 0;
+
protected:
QDeclarativeVideoOutput *q;
QPointer<QMediaService> m_service;
diff --git a/src/imports/multimedia/qdeclarativevideooutput_render.cpp b/src/imports/multimedia/qdeclarativevideooutput_render.cpp
index e9bcf4b26..96b979bc5 100644
--- a/src/imports/multimedia/qdeclarativevideooutput_render.cpp
+++ b/src/imports/multimedia/qdeclarativevideooutput_render.cpp
@@ -133,30 +133,45 @@ QSize QDeclarativeVideoRendererBackend::nativeSize() const
void QDeclarativeVideoRendererBackend::updateGeometry()
{
+ const QRectF viewport = videoSurface()->surfaceFormat().viewport();
+ const QSizeF frameSize = videoSurface()->surfaceFormat().frameSize();
+ const QRectF normalizedViewport(viewport.x() / frameSize.width(),
+ viewport.y() / frameSize.height(),
+ viewport.width() / frameSize.width(),
+ viewport.height() / frameSize.height());
const QRectF rect(0, 0, q->width(), q->height());
if (nativeSize().isEmpty()) {
m_renderedRect = rect;
- m_sourceTextureRect = QRectF(0, 0, 1, 1);
+ m_sourceTextureRect = normalizedViewport;
} else if (q->fillMode() == QDeclarativeVideoOutput::Stretch) {
m_renderedRect = rect;
- m_sourceTextureRect = QRectF(0, 0, 1, 1);
+ m_sourceTextureRect = normalizedViewport;
} else if (q->fillMode() == QDeclarativeVideoOutput::PreserveAspectFit) {
- m_sourceTextureRect = QRectF(0, 0, 1, 1);
+ m_sourceTextureRect = normalizedViewport;
m_renderedRect = q->contentRect();
} else if (q->fillMode() == QDeclarativeVideoOutput::PreserveAspectCrop) {
m_renderedRect = rect;
const qreal contentHeight = q->contentRect().height();
const qreal contentWidth = q->contentRect().width();
+
+ // Calculate the size of the source rectangle without taking the viewport into account
+ const qreal relativeOffsetLeft = -q->contentRect().left() / contentWidth;
+ const qreal relativeOffsetTop = -q->contentRect().top() / contentHeight;
+ const qreal relativeWidth = rect.width() / contentWidth;
+ const qreal relativeHeight = rect.height() / contentHeight;
+
+ // Now take the viewport size into account
+ const qreal totalOffsetLeft = normalizedViewport.x() + relativeOffsetLeft * normalizedViewport.width();
+ const qreal totalOffsetTop = normalizedViewport.y() + relativeOffsetTop * normalizedViewport.height();
+ const qreal totalWidth = normalizedViewport.width() * relativeWidth;
+ const qreal totalHeight = normalizedViewport.height() * relativeHeight;
+
if (qIsDefaultAspect(q->orientation())) {
- m_sourceTextureRect = QRectF(-q->contentRect().left() / contentWidth,
- -q->contentRect().top() / contentHeight,
- rect.width() / contentWidth,
- rect.height() / contentHeight);
+ m_sourceTextureRect = QRectF(totalOffsetLeft, totalOffsetTop,
+ totalWidth, totalHeight);
} else {
- m_sourceTextureRect = QRectF(-q->contentRect().top() / contentHeight,
- -q->contentRect().left() / contentWidth,
- rect.height() / contentHeight,
- rect.width() / contentWidth);
+ m_sourceTextureRect = QRectF(totalOffsetTop, totalOffsetLeft,
+ totalHeight, totalWidth);
}
}
}
@@ -223,6 +238,22 @@ QAbstractVideoSurface *QDeclarativeVideoRendererBackend::videoSurface() const
return m_surface;
}
+QRectF QDeclarativeVideoRendererBackend::adjustedViewport() const
+{
+ const QRectF viewport = m_surface->surfaceFormat().viewport();
+ const QSize pixelAspectRatio = m_surface->surfaceFormat().pixelAspectRatio();
+
+ if (pixelAspectRatio.height() != 0) {
+ const qreal ratio = pixelAspectRatio.width() / pixelAspectRatio.height();
+ QRectF result = viewport;
+ result.setX(result.x() * ratio);
+ result.setWidth(result.width() * ratio);
+ return result;
+ }
+
+ return viewport;
+}
+
QOpenGLContext *QDeclarativeVideoRendererBackend::glContext() const
{
return m_glContext;
diff --git a/src/imports/multimedia/qdeclarativevideooutput_render_p.h b/src/imports/multimedia/qdeclarativevideooutput_render_p.h
index 2a706b339..3682c15a6 100644
--- a/src/imports/multimedia/qdeclarativevideooutput_render_p.h
+++ b/src/imports/multimedia/qdeclarativevideooutput_render_p.h
@@ -71,6 +71,7 @@ public:
void updateGeometry();
QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data);
QAbstractVideoSurface *videoSurface() const;
+ QRectF adjustedViewport() const Q_DECL_OVERRIDE;
QOpenGLContext *glContext() const;
friend class QSGVideoItemSurface;
diff --git a/src/imports/multimedia/qdeclarativevideooutput_window.cpp b/src/imports/multimedia/qdeclarativevideooutput_window.cpp
index 527c08908..2da63c107 100644
--- a/src/imports/multimedia/qdeclarativevideooutput_window.cpp
+++ b/src/imports/multimedia/qdeclarativevideooutput_window.cpp
@@ -143,4 +143,11 @@ QAbstractVideoSurface *QDeclarativeVideoWindowBackend::videoSurface() const
return 0;
}
+QRectF QDeclarativeVideoWindowBackend::adjustedViewport() const
+{
+ // No viewport supported by QVideoWindowControl, so make the viewport the same size
+ // as the source
+ return QRectF(QPointF(0, 0), nativeSize());
+}
+
QT_END_NAMESPACE
diff --git a/src/imports/multimedia/qdeclarativevideooutput_window_p.h b/src/imports/multimedia/qdeclarativevideooutput_window_p.h
index f09b08c42..eb7b35b85 100644
--- a/src/imports/multimedia/qdeclarativevideooutput_window_p.h
+++ b/src/imports/multimedia/qdeclarativevideooutput_window_p.h
@@ -62,6 +62,7 @@ public:
void updateGeometry();
QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *data);
QAbstractVideoSurface *videoSurface() const;
+ QRectF adjustedViewport() const Q_DECL_OVERRIDE;
private:
QPointer<QVideoWindowControl> m_videoWindowControl;