1 /*
2 Copyright (C) 2012-2013 Collabora Ltd. <info@collabora.com>
3 @author George Kiagiadakis <george.kiagiadakis@collabora.com>
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published
7 by the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "videoitem.h"
20 #include "videosurface_p.h"
21 #include <QtQuick/QSGNode>
22 #include <QtQuick/QSGFlatColorMaterial>
23 #include "../../QGlib/Signal"
24
25 namespace QGst {
26 namespace Quick {
27
28 struct VideoItem::Private
29 {
30 QPointer<VideoSurface> surface;
31 bool surfaceDirty;
32 QRectF targetArea;
33 };
34
VideoItem(QQuickItem * parent)35 VideoItem::VideoItem(QQuickItem *parent)
36 : QQuickItem(parent), d(new Private)
37 {
38 d->surfaceDirty = true;
39 setFlag(QQuickItem::ItemHasContents, true);
40 }
41
~VideoItem()42 VideoItem::~VideoItem()
43 {
44 setSurface(0);
45 delete d;
46 }
47
surface() const48 VideoSurface *VideoItem::surface() const
49 {
50 return d->surface.data();
51 }
52
setSurface(VideoSurface * surface)53 void VideoItem::setSurface(VideoSurface *surface)
54 {
55 if (d->surface) {
56 d->surface.data()->d->items.remove(this);
57 }
58
59 d->surface = surface;
60 d->surfaceDirty = true;
61
62 if (d->surface) {
63 d->surface.data()->d->items.insert(this);
64 }
65 }
66
updatePaintNode(QSGNode * oldNode,UpdatePaintNodeData * data)67 QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
68 {
69 Q_UNUSED(data)
70
71 QRectF r = boundingRect();
72 QSGNode *newNode = 0;
73
74 if (d->surfaceDirty) {
75 delete oldNode;
76 oldNode = 0;
77 d->surfaceDirty = false;
78 }
79
80 if (!d->surface || d->surface.data()->d->videoSink.isNull()) {
81 if (!oldNode) {
82 QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
83 material->setColor(Qt::black);
84
85 QSGGeometryNode *node = new QSGGeometryNode;
86 node->setMaterial(material);
87 node->setFlag(QSGNode::OwnsMaterial);
88 node->setFlag(QSGNode::OwnsGeometry);
89
90 newNode = node;
91 d->targetArea = QRectF(); //force geometry to be set
92 } else {
93 newNode = oldNode;
94 }
95
96 if (r != d->targetArea) {
97 QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
98 geometry->vertexDataAsPoint2D()[0].set(r.x(), r.y());
99 geometry->vertexDataAsPoint2D()[1].set(r.x(), r.height());
100 geometry->vertexDataAsPoint2D()[2].set(r.width(), r.y());
101 geometry->vertexDataAsPoint2D()[3].set(r.width(), r.height());
102
103 QSGGeometryNode *node = static_cast<QSGGeometryNode*>(newNode);
104 node->setGeometry(geometry);
105
106 d->targetArea = r;
107 }
108 } else {
109 newNode = (QSGNode*) QGlib::emit<void*>(d->surface.data()->d->videoSink,
110 "update-node", (void*)oldNode,
111 r.x(), r.y(), r.width(), r.height());
112 }
113
114 return newNode;
115 }
116
117 } // namespace Quick
118 } // namespace QGst
119