Skip to content
Snippets Groups Projects
VideoItem.cc 3.22 KiB
Newer Older
  • Learn to ignore specific revisions
  • /****************************************************************************
     *
     *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
     *
     * QGroundControl is licensed according to the terms in the file
     * COPYING.md in the root of the source code directory.
     *
     ****************************************************************************/
    
    Gus Grubba's avatar
    Gus Grubba committed
    
    
    /**
     * @file
     *   @brief QGC Video Item
     *   @author Gus Grubba <mavlink@grubba.com>
     */
    
    #include <QtCore/QPointer>
    #include <QtQuick/QSGNode>
    #include <QtQuick/QSGFlatColorMaterial>
    
    
    Gus Grubba's avatar
    Gus Grubba committed
    #include "VideoItem.h"
    
    #if defined(QGC_GST_STREAMING)
    
    Gus Grubba's avatar
    Gus Grubba committed
    #include "VideoSurface_p.h"
    
    Gus Grubba's avatar
    Gus Grubba committed
    
    
    #if defined(QGC_GST_STREAMING)
    
    Gus Grubba's avatar
    Gus Grubba committed
    struct VideoItem::Private
    {
        QPointer<VideoSurface> surface;
        bool surfaceDirty;
        QRectF targetArea;
    };
    
    Gus Grubba's avatar
    Gus Grubba committed
    
    VideoItem::VideoItem(QQuickItem *parent)
    
        : QQuickItem(parent)
    #if defined(QGC_GST_STREAMING)
        , _data(new Private)
    #endif
    
    Gus Grubba's avatar
    Gus Grubba committed
    {
    
    #if defined(QGC_GST_STREAMING)
    
    Gus Grubba's avatar
    Gus Grubba committed
        _data->surfaceDirty = true;
        setFlag(QQuickItem::ItemHasContents, true);
    
    Gus Grubba's avatar
    Gus Grubba committed
    }
    
    VideoItem::~VideoItem()
    {
    
    #if defined(QGC_GST_STREAMING)
    
    Gus Grubba's avatar
    Gus Grubba committed
        setSurface(0);
        delete _data;
    
    Gus Grubba's avatar
    Gus Grubba committed
    }
    
    VideoSurface *VideoItem::surface() const
    {
    
    #if defined(QGC_GST_STREAMING)
    
    Gus Grubba's avatar
    Gus Grubba committed
        return _data->surface.data();
    
    Gus Grubba's avatar
    Gus Grubba committed
    }
    
    void VideoItem::setSurface(VideoSurface *surface)
    {
    
    #if defined(QGC_GST_STREAMING)
    
    Gus Grubba's avatar
    Gus Grubba committed
        if (_data->surface) {
            _data->surface.data()->_data->items.remove(this);
        }
        _data->surface = surface;
        _data->surfaceDirty = true;
        if (_data->surface) {
            _data->surface.data()->_data->items.insert(this);
        }
    
    dogmaphobic's avatar
    dogmaphobic committed
    #else
        Q_UNUSED(surface)
    
    Gus Grubba's avatar
    Gus Grubba committed
    }
    
    
    #if defined(QGC_GST_STREAMING)
    
    Gus Grubba's avatar
    Gus Grubba committed
    QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*)
    {
        QRectF r = boundingRect();
        QSGNode* newNode = 0;
    
        if (_data->surfaceDirty) {
            delete oldNode;
            oldNode = 0;
            _data->surfaceDirty = false;
        }
    
        if (!_data->surface || _data->surface.data()->_data->videoSink == NULL) {
            if (!oldNode) {
                QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
                material->setColor(Qt::black);
                QSGGeometryNode *node = new QSGGeometryNode;
                node->setMaterial(material);
                node->setFlag(QSGNode::OwnsMaterial);
                node->setFlag(QSGNode::OwnsGeometry);
                newNode = node;
                _data->targetArea = QRectF(); //force geometry to be set
            } else {
                newNode = oldNode;
            }
            if (r != _data->targetArea) {
                QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
                geometry->vertexDataAsPoint2D()[0].set(r.x(), r.y());
                geometry->vertexDataAsPoint2D()[1].set(r.x(), r.height());
                geometry->vertexDataAsPoint2D()[2].set(r.width(), r.y());
                geometry->vertexDataAsPoint2D()[3].set(r.width(), r.height());
                QSGGeometryNode *node = static_cast<QSGGeometryNode*>(newNode);
                node->setGeometry(geometry);
                _data->targetArea = r;
            }
        } else {
            g_signal_emit_by_name(_data->surface.data()->_data->videoSink, "update-node", (void*)oldNode, r.x(), r.y(), r.width(), r.height(), (void**)&newNode);
        }
    
        return newNode;
    }