summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin McPherson <justin.mcpherson@nokia.com>2010-01-28 07:31:52 (GMT)
committerJustin McPherson <justin.mcpherson@nokia.com>2010-01-28 07:31:52 (GMT)
commitb4402915aab8a13ec6a085dd2e3a1e13a59ade98 (patch)
treea60fce623a1d8987b2deb58ebd7757dce6bc36a9
parentb220901d125b6c440426577b10d5c7463bf49964 (diff)
downloadQt-b4402915aab8a13ec6a085dd2e3a1e13a59ade98.zip
Qt-b4402915aab8a13ec6a085dd2e3a1e13a59ade98.tar.gz
Qt-b4402915aab8a13ec6a085dd2e3a1e13a59ade98.tar.bz2
Add size, offset and fillMode properties to QGraphicsVideoItem.
From: Andrew den Exter committed 9fb251df to qtmobility/qtm-multimedia
-rw-r--r--src/multimedia/base/qgraphicsvideoitem.cpp169
-rw-r--r--src/multimedia/base/qgraphicsvideoitem.h32
-rw-r--r--src/multimedia/base/qpaintervideosurface.cpp16
-rw-r--r--src/multimedia/base/qpaintervideosurface_p.h2
4 files changed, 185 insertions, 34 deletions
diff --git a/src/multimedia/base/qgraphicsvideoitem.cpp b/src/multimedia/base/qgraphicsvideoitem.cpp
index 7fa2e7d..1a5ccd7 100644
--- a/src/multimedia/base/qgraphicsvideoitem.cpp
+++ b/src/multimedia/base/qgraphicsvideoitem.cpp
@@ -43,15 +43,15 @@
#include <QtMultimedia/qmediaobject.h>
#include <QtMultimedia/qmediaservice.h>
-#include "qpaintervideosurface_p.h"
+#include <QtMultimedia/private/qpaintervideosurface_p.h>
#include <QtMultimedia/qvideooutputcontrol.h>
#include <QtMultimedia/qvideorenderercontrol.h>
-
#include <QtMultimedia/qvideosurfaceformat.h>
QT_BEGIN_NAMESPACE
+
class QGraphicsVideoItemPrivate
{
public:
@@ -62,6 +62,8 @@ public:
, service(0)
, outputControl(0)
, rendererControl(0)
+ , aspectRatioMode(Qt::KeepAspectRatio)
+ , updatePaintDevice(true)
{
}
@@ -72,9 +74,14 @@ public:
QMediaService *service;
QVideoOutputControl *outputControl;
QVideoRendererControl *rendererControl;
- QRect boundingRect;
+ Qt::AspectRatioMode aspectRatioMode;
+ bool updatePaintDevice;
+ QRectF rect;
+ QRectF boundingRect;
+ QSizeF nativeSize;
void clearService();
+ void updateBoundingRect();
void _q_present();
void _q_formatChanged(const QVideoSurfaceFormat &format);
@@ -99,17 +106,40 @@ void QGraphicsVideoItemPrivate::clearService()
}
}
+void QGraphicsVideoItemPrivate::updateBoundingRect()
+{
+ q_ptr->prepareGeometryChange();
+
+ if (nativeSize.isEmpty()) {
+ boundingRect = QRectF();
+ } else {
+ if (aspectRatioMode == Qt::IgnoreAspectRatio) {
+ boundingRect = rect;
+ } else {
+ QSizeF size = nativeSize;
+ size.scale(rect.size(), aspectRatioMode);
+
+ boundingRect = QRectF(QPointF(), size);
+ boundingRect.moveCenter(rect.center());
+ }
+ }
+}
+
void QGraphicsVideoItemPrivate::_q_present()
{
- q_ptr->update(boundingRect);
+ if (q_ptr->isObscured()) {
+ q_ptr->update(boundingRect);
+ surface->setReady(true);
+ } else {
+ q_ptr->update(boundingRect);
+ }
}
void QGraphicsVideoItemPrivate::_q_formatChanged(const QVideoSurfaceFormat &format)
{
- q_ptr->prepareGeometryChange();
+ nativeSize = format.sizeHint();
- boundingRect = QRect(QPoint(0, 0), format.sizeHint());
- boundingRect.moveCenter(QPoint(0, 0));
+ updateBoundingRect();
}
void QGraphicsVideoItemPrivate::_q_serviceDestroyed()
@@ -152,22 +182,39 @@ void QGraphicsVideoItemPrivate::_q_mediaObjectDestroyed()
player->play();
\endcode
- \bold {Note}: Only a single display output can be attached to a media object at one time.
+ \bold {Note}: Only a single display output can be attached to a media
+ object at one time.
\sa QMediaObject, QMediaPlayer, QVideoWidget
*/
/*!
+ \enum QGraphicsVideoItem::FillMode
+
+ Enumerates the methods of scaling a video to fit a graphics item.
+
+ \value Stretch The video is stretched to fit the item's size.
+ \value PreserveAspectFit The video is uniformly scaled to fix the item's
+ size without cropping.
+ \value PreserveAspectCrop The video is uniformly scaled to fill the item's
+ size, cropping if necessary.
+*/
+
+/*!
Constructs a graphics item that displays video.
The \a parent is passed to QGraphicsItem.
*/
QGraphicsVideoItem::QGraphicsVideoItem(QGraphicsItem *parent)
- : QGraphicsItem(parent)
+ : QGraphicsObject(parent)
, d_ptr(new QGraphicsVideoItemPrivate)
{
d_ptr->q_ptr = this;
d_ptr->surface = new QPainterVideoSurface;
+
+ connect(d_ptr->surface, SIGNAL(frameChanged()), this, SLOT(_q_present()));
+ connect(d_ptr->surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
+ this, SLOT(_q_formatChanged(QVideoSurfaceFormat)));
}
/*!
@@ -187,7 +234,8 @@ QGraphicsVideoItem::~QGraphicsVideoItem()
/*!
\property QGraphicsVideoItem::mediaObject
- \brief the media object which provides the video displayed by a graphics item.
+ \brief the media object which provides the video displayed by a graphics
+ item.
*/
QMediaObject *QGraphicsVideoItem::mediaObject() const
@@ -227,15 +275,6 @@ void QGraphicsVideoItem::setMediaObject(QMediaObject *object)
d->service->control(QVideoRendererControl_iid));
if (d->outputControl != 0 && d->rendererControl != 0) {
- if (!d->surface) {
- d->surface = new QPainterVideoSurface;
-
- connect(d->surface, SIGNAL(frameChanged()), this, SLOT(_q_present()));
- connect(d->surface, SIGNAL(surfaceFormatChanged(QVideoSurfaceFormat)),
- this, SLOT(_q_formatChanged(QVideoSurfaceFormat)));
- connect(d->service, SIGNAL(destroyed()), this, SLOT(_q_serviceDestroyed()));
- }
-
d->rendererControl->setSurface(d->surface);
if (isVisible())
@@ -246,6 +285,82 @@ void QGraphicsVideoItem::setMediaObject(QMediaObject *object)
}
/*!
+ \property QGraphicsVideoItem::aspectRatioMode
+ \brief how a video is scaled to fit the graphics item's size.
+*/
+
+Qt::AspectRatioMode QGraphicsVideoItem::aspectRatioMode() const
+{
+ return d_func()->aspectRatioMode;
+}
+
+void QGraphicsVideoItem::setAspectRatioMode(Qt::AspectRatioMode mode)
+{
+ Q_D(QGraphicsVideoItem);
+
+ d->aspectRatioMode = mode;
+ d->updateBoundingRect();
+}
+
+/*!
+ \property QGraphicsVideoItem::offset
+ \brief the video item's offset.
+
+ QGraphicsVideoItem will draw video using the offset for its top left
+ corner.
+*/
+
+QPointF QGraphicsVideoItem::offset() const
+{
+ return d_func()->rect.topLeft();
+}
+
+void QGraphicsVideoItem::setOffset(const QPointF &offset)
+{
+ Q_D(QGraphicsVideoItem);
+
+ d->rect.moveTo(offset);
+ d->updateBoundingRect();
+}
+
+/*!
+ \property QGraphicsVideoItem::size
+ \brief the video item's size.
+
+ QGraphicsVideoItem will draw video scaled to fit size according to its
+ fillMode.
+*/
+
+QSizeF QGraphicsVideoItem::size() const
+{
+ return d_func()->rect.size();
+}
+
+void QGraphicsVideoItem::setSize(const QSizeF &size)
+{
+ Q_D(QGraphicsVideoItem);
+
+ d->rect.setSize(size);
+ d->updateBoundingRect();
+}
+
+/*!
+ \property QGraphicsVideoItem::nativeSize
+ \brief the native size of the video.
+*/
+
+QSizeF QGraphicsVideoItem::nativeSize() const
+{
+ return d_func()->nativeSize;
+}
+
+/*!
+ \fn QGraphicsVideoItem::nativeSizeChanged(const QSizeF &size)
+
+ Signals that the native \a size of the video has changed.
+*/
+
+/*!
\reimp
*/
QRectF QGraphicsVideoItem::boundingRect() const
@@ -264,10 +379,24 @@ void QGraphicsVideoItem::paint(
Q_UNUSED(option);
Q_UNUSED(widget);
- if (d->surface != 0) {
+ if (d->surface && d->surface->isActive()) {
d->surface->paint(painter, d->boundingRect);
d->surface->setReady(true);
+#ifndef QGRAPHICSVIDEOITEM_SHADERS // Flickers
+ }
+#else
+ } else if (d->updatePaintDevice && (painter->paintEngine()->type() == QPaintEngine::OpenGL
+ || painter->paintEngine()->type() == QPaintEngine::OpenGL2)) {
+ d->updatePaintDevice = false;
+
+ d->surface->setGLContext(const_cast<QGLContext *>(QGLContext::currentContext()));
+ if (d->surface->supportedShaderTypes() & QPainterVideoSurface::GlslShader) {
+ d->surface->setShaderType(QPainterVideoSurface::GlslShader);
+ } else {
+ d->surface->setShaderType(QPainterVideoSurface::FragmentProgramShader);
+ }
}
+#endif
}
/*!
diff --git a/src/multimedia/base/qgraphicsvideoitem.h b/src/multimedia/base/qgraphicsvideoitem.h
index 0cd5d46..ac215ea 100644
--- a/src/multimedia/base/qgraphicsvideoitem.h
+++ b/src/multimedia/base/qgraphicsvideoitem.h
@@ -46,32 +46,54 @@
#include <QtMultimedia/qvideowidget.h>
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
-QT_MODULE(Multimedia)
-
class QVideoSurfaceFormat;
class QGraphicsVideoItemPrivate;
-class Q_MULTIMEDIA_EXPORT QGraphicsVideoItem : public QObject, public QGraphicsItem
+class Q_MULTIMEDIA_EXPORT QGraphicsVideoItem : public QGraphicsObject
{
Q_OBJECT
- Q_INTERFACES(QGraphicsItem)
Q_PROPERTY(QMediaObject* mediaObject READ mediaObject WRITE setMediaObject)
-
+ Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode)
+ Q_PROPERTY(QPointF offset READ offset WRITE setOffset)
+ Q_PROPERTY(QSizeF size READ size WRITE setSize)
+ Q_PROPERTY(QSizeF nativeSize READ nativeSize NOTIFY nativeSizeChanged)
public:
+ enum FillMode
+ {
+ Stretch,
+ PreserveAspectFit,
+ PreserveAspectCrop
+ };
+
QGraphicsVideoItem(QGraphicsItem *parent = 0);
~QGraphicsVideoItem();
QMediaObject *mediaObject() const;
void setMediaObject(QMediaObject *object);
+ Qt::AspectRatioMode aspectRatioMode() const;
+ void setAspectRatioMode(Qt::AspectRatioMode mode);
+
+ QPointF offset() const;
+ void setOffset(const QPointF &offset);
+
+ QSizeF size() const;
+ void setSize(const QSizeF &size);
+
+ QSizeF nativeSize() const;
+
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+Q_SIGNALS:
+ void nativeSizeChanged(const QSizeF &size) const;
+
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
diff --git a/src/multimedia/base/qpaintervideosurface.cpp b/src/multimedia/base/qpaintervideosurface.cpp
index feeb42f..9953ae8 100644
--- a/src/multimedia/base/qpaintervideosurface.cpp
+++ b/src/multimedia/base/qpaintervideosurface.cpp
@@ -73,7 +73,7 @@ public:
virtual QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame) = 0;
virtual QAbstractVideoSurface::Error paint(
- const QRect &target, QPainter *painter, const QRect &source) = 0;
+ const QRectF &target, QPainter *painter, const QRect &source) = 0;
virtual void updateColors(int brightness, int contrast, int hue, int saturation) = 0;
};
@@ -99,7 +99,7 @@ public:
QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame);
QAbstractVideoSurface::Error paint(
- const QRect &target, QPainter *painter, const QRect &source);
+ const QRectF &target, QPainter *painter, const QRect &source);
void updateColors(int brightness, int contrast, int hue, int saturation);
@@ -167,7 +167,7 @@ QAbstractVideoSurface::Error QVideoSurfaceRasterPainter::setCurrentFrame(const Q
}
QAbstractVideoSurface::Error QVideoSurfaceRasterPainter::paint(
- const QRect &target, QPainter *painter, const QRect &source)
+ const QRectF &target, QPainter *painter, const QRect &source)
{
if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
QImage image(
@@ -540,7 +540,7 @@ public:
QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format);
void stop();
- QAbstractVideoSurface::Error paint(const QRect &target, QPainter *painter, const QRect &source);
+ QAbstractVideoSurface::Error paint(const QRectF &target, QPainter *painter, const QRect &source);
private:
typedef void (APIENTRY *_glProgramStringARB) (GLenum, GLenum, GLsizei, const GLvoid *);
@@ -700,7 +700,7 @@ void QVideoSurfaceArbFpPainter::stop()
}
QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint(
- const QRect &target, QPainter *painter, const QRect &source)
+ const QRectF &target, QPainter *painter, const QRect &source)
{
if (m_frame.isValid()) {
painter->beginNativePainting();
@@ -857,7 +857,7 @@ public:
QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format);
void stop();
- QAbstractVideoSurface::Error paint(const QRect &target, QPainter *painter, const QRect &source);
+ QAbstractVideoSurface::Error paint(const QRectF &target, QPainter *painter, const QRect &source);
private:
QGLShaderProgram m_program;
@@ -975,7 +975,7 @@ void QVideoSurfaceGlslPainter::stop()
}
QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint(
- const QRect &target, QPainter *painter, const QRect &source)
+ const QRectF &target, QPainter *painter, const QRect &source)
{
if (m_frame.isValid()) {
painter->beginNativePainting();
@@ -1289,7 +1289,7 @@ void QPainterVideoSurface::setReady(bool ready)
/*!
*/
-void QPainterVideoSurface::paint(QPainter *painter, const QRect &rect)
+void QPainterVideoSurface::paint(QPainter *painter, const QRectF &rect)
{
if (!isActive()) {
painter->fillRect(rect, QBrush(Qt::black));
diff --git a/src/multimedia/base/qpaintervideosurface_p.h b/src/multimedia/base/qpaintervideosurface_p.h
index a7d3e3a..67b514f 100644
--- a/src/multimedia/base/qpaintervideosurface_p.h
+++ b/src/multimedia/base/qpaintervideosurface_p.h
@@ -102,7 +102,7 @@ public:
bool isReady() const;
void setReady(bool ready);
- void paint(QPainter *painter, const QRect &rect);
+ void paint(QPainter *painter, const QRectF &rect);
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_1_CL) && !defined(QT_OPENGL_ES_1)
const QGLContext *glContext() const;