diff options
author | Justin McPherson <justin.mcpherson@nokia.com> | 2010-01-28 07:31:52 (GMT) |
---|---|---|
committer | Justin McPherson <justin.mcpherson@nokia.com> | 2010-01-28 07:31:52 (GMT) |
commit | b4402915aab8a13ec6a085dd2e3a1e13a59ade98 (patch) | |
tree | a60fce623a1d8987b2deb58ebd7757dce6bc36a9 /src/multimedia | |
parent | b220901d125b6c440426577b10d5c7463bf49964 (diff) | |
download | Qt-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
Diffstat (limited to 'src/multimedia')
-rw-r--r-- | src/multimedia/base/qgraphicsvideoitem.cpp | 169 | ||||
-rw-r--r-- | src/multimedia/base/qgraphicsvideoitem.h | 32 | ||||
-rw-r--r-- | src/multimedia/base/qpaintervideosurface.cpp | 16 | ||||
-rw-r--r-- | src/multimedia/base/qpaintervideosurface_p.h | 2 |
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; |