diff --git a/ChangeLog.md b/ChangeLog.md index aeccabeabebb535e35ca4c28d7f1c9ebddaad80e..cdb34dbfee30255b4d3b806798b3b45890cc9a27 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -9,6 +9,7 @@ Note: This file only contains high level features or important fixes. * Major rewrite and bug fix pass through Structure Scan. Previous version had such bad problems that it can no longer be supported. Plans with Structure Scan will need to be recreated. New QGC will not load old Structure Scan plans. ### 3.5.4 - Not yet released +* Guard against null geometry coming from gstreamer which can cause crashes * Add .apj file selection support to custom firmware flash ### 3.5.3 - Stable diff --git a/src/VideoStreaming/VideoItem.cc b/src/VideoStreaming/VideoItem.cc index 2a138cf6dac80b821ebad26bd6f6479f7f0f1970..8a872c6545beb09cece89c11c2dd99cd97be46ed 100644 --- a/src/VideoStreaming/VideoItem.cc +++ b/src/VideoStreaming/VideoItem.cc @@ -78,6 +78,17 @@ void VideoItem::setSurface(VideoSurface *surface) } #if defined(QGC_GST_STREAMING) +QSGGeometry* VideoItem::_createDefaultGeometry(QRectF& rectBound) +{ + QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); + geometry->vertexDataAsPoint2D()[0].set(rectBound.x(), rectBound.y()); + geometry->vertexDataAsPoint2D()[1].set(rectBound.x(), rectBound.height()); + geometry->vertexDataAsPoint2D()[2].set(rectBound.width(), rectBound.y()); + geometry->vertexDataAsPoint2D()[3].set(rectBound.width(), rectBound.height()); + + return geometry; +} + QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) { QRectF r = boundingRect(); @@ -103,19 +114,22 @@ QSGNode* VideoItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData*) 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(newNode); - node->setGeometry(geometry); + node->setGeometry(_createDefaultGeometry(r)); _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); } + // Sometimes we can still end up here with no geometry when gstreamer fails to create it for whatever reason. If that happens it can + // cause crashes. + QSGGeometryNode *node = static_cast(newNode); + if (node->geometry() == nullptr) { + qDebug() << "Creating default geom"; + node->setGeometry(_createDefaultGeometry(r)); + } + return newNode; } #endif diff --git a/src/VideoStreaming/VideoItem.h b/src/VideoStreaming/VideoItem.h index eeb1caa670107471f08bb2d6b52f56a8731b9f17..504460409b4b0134ff432824407241914c6da198 100644 --- a/src/VideoStreaming/VideoItem.h +++ b/src/VideoStreaming/VideoItem.h @@ -19,6 +19,8 @@ #include #include "VideoSurface.h" +class QSGGeometry; + class VideoItem : public QQuickItem { Q_OBJECT @@ -40,6 +42,8 @@ protected: private: #if defined(QGC_GST_STREAMING) + QSGGeometry* _createDefaultGeometry(QRectF& rectBound); + struct Private; Private* const _data; #endif