mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-25 16:48:11 +00:00
qt: Use a proxy object for access to the QML widget
QML can destroy the video widget at any time, leaving us with a dangling pointer. Use a lock and a proxy object to cope with that, and block in the widget destructor if there are ongoing calls into the widget.
This commit is contained in:
parent
6083ad6287
commit
b7fc75c883
4 changed files with 174 additions and 70 deletions
|
@ -143,6 +143,7 @@ gst_qt_sink_class_init (GstQtSinkClass * klass)
|
||||||
static void
|
static void
|
||||||
gst_qt_sink_init (GstQtSink * qt_sink)
|
gst_qt_sink_init (GstQtSink * qt_sink)
|
||||||
{
|
{
|
||||||
|
qt_sink->widget = QSharedPointer<QtGLVideoItemInterface>();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -152,9 +153,14 @@ gst_qt_sink_set_property (GObject * object, guint prop_id,
|
||||||
GstQtSink *qt_sink = GST_QT_SINK (object);
|
GstQtSink *qt_sink = GST_QT_SINK (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_WIDGET:
|
case PROP_WIDGET: {
|
||||||
qt_sink->widget = static_cast<QtGLVideoItem *> (g_value_get_pointer (value));
|
QtGLVideoItem *qt_item = static_cast<QtGLVideoItem *> (g_value_get_pointer (value));
|
||||||
|
if (qt_item)
|
||||||
|
qt_sink->widget = qt_item->getInterface();
|
||||||
|
else
|
||||||
|
qt_sink->widget.clear();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PROP_FORCE_ASPECT_RATIO:
|
case PROP_FORCE_ASPECT_RATIO:
|
||||||
g_return_if_fail (qt_sink->widget);
|
g_return_if_fail (qt_sink->widget);
|
||||||
qt_sink->widget->setForceAspectRatio (g_value_get_boolean (value));
|
qt_sink->widget->setForceAspectRatio (g_value_get_boolean (value));
|
||||||
|
@ -196,6 +202,8 @@ gst_qt_sink_finalize (GObject * object)
|
||||||
|
|
||||||
_reset (qt_sink);
|
_reset (qt_sink);
|
||||||
|
|
||||||
|
qt_sink->widget.clear();
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +215,13 @@ gst_qt_sink_get_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_WIDGET:
|
case PROP_WIDGET:
|
||||||
g_value_set_pointer (value, qt_sink->widget);
|
/* This is not really safe - the app needs to be
|
||||||
|
* sure the widget is going to be kept alive or
|
||||||
|
* this can crash */
|
||||||
|
if (qt_sink->widget)
|
||||||
|
g_value_set_pointer (value, qt_sink->widget->videoItem());
|
||||||
|
else
|
||||||
|
g_value_set_pointer (value, NULL);
|
||||||
break;
|
break;
|
||||||
case PROP_FORCE_ASPECT_RATIO:
|
case PROP_FORCE_ASPECT_RATIO:
|
||||||
if (qt_sink->widget)
|
if (qt_sink->widget)
|
||||||
|
@ -287,16 +301,16 @@ gst_qt_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
return GST_STATE_CHANGE_FAILURE;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!qt_item_init_winsys (qt_sink->widget)) {
|
if (!qt_sink->widget->initWinSys()) {
|
||||||
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
||||||
("%s", "Could not initialize window system"),
|
("%s", "Could not initialize window system"),
|
||||||
(NULL));
|
(NULL));
|
||||||
return GST_STATE_CHANGE_FAILURE;
|
return GST_STATE_CHANGE_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
qt_sink->display = qt_item_get_display (qt_sink->widget);
|
qt_sink->display = qt_sink->widget->getDisplay();
|
||||||
qt_sink->context = qt_item_get_context (qt_sink->widget);
|
qt_sink->context = qt_sink->widget->getContext();
|
||||||
qt_sink->qt_context = qt_item_get_qt_context (qt_sink->widget);
|
qt_sink->qt_context = qt_sink->widget->getQtContext();
|
||||||
|
|
||||||
if (!qt_sink->display || !qt_sink->context || !qt_sink->qt_context) {
|
if (!qt_sink->display || !qt_sink->context || !qt_sink->qt_context) {
|
||||||
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (element, RESOURCE, NOT_FOUND,
|
||||||
|
@ -321,7 +335,8 @@ gst_qt_sink_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
qt_item_set_buffer (qt_sink->widget, NULL);
|
if (qt_sink->widget)
|
||||||
|
qt_sink->widget->setBuffer(NULL);
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||||
break;
|
break;
|
||||||
|
@ -365,10 +380,10 @@ gst_qt_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
if (!gst_video_info_from_caps (&qt_sink->v_info, caps))
|
if (!gst_video_info_from_caps (&qt_sink->v_info, caps))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!qt_item_set_caps (qt_sink->widget, caps))
|
if (!qt_sink->widget)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return qt_sink->widget->setCaps(caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -380,7 +395,8 @@ gst_qt_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
|
||||||
|
|
||||||
qt_sink = GST_QT_SINK (vsink);
|
qt_sink = GST_QT_SINK (vsink);
|
||||||
|
|
||||||
qt_item_set_buffer (qt_sink->widget, buf);
|
if (qt_sink->widget)
|
||||||
|
qt_sink->widget->setBuffer(buf);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,8 +51,6 @@ struct _GstQtSink
|
||||||
/* <private> */
|
/* <private> */
|
||||||
GstVideoSink parent;
|
GstVideoSink parent;
|
||||||
|
|
||||||
QtGLVideoItem *widget;
|
|
||||||
|
|
||||||
GstVideoInfo v_info;
|
GstVideoInfo v_info;
|
||||||
GstBufferPool *pool;
|
GstBufferPool *pool;
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ struct _GstQtSink
|
||||||
GstGLContext *context;
|
GstGLContext *context;
|
||||||
GstGLContext *qt_context;
|
GstGLContext *qt_context;
|
||||||
|
|
||||||
GstQtSinkPrivate *priv;
|
QSharedPointer<QtGLVideoItemInterface> widget;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
160
ext/qt/qtitem.cc
160
ext/qt/qtitem.cc
|
@ -30,6 +30,7 @@
|
||||||
#include "gstqtglutility.h"
|
#include "gstqtglutility.h"
|
||||||
|
|
||||||
#include <QtCore/QRunnable>
|
#include <QtCore/QRunnable>
|
||||||
|
#include <QtCore/QMutexLocker>
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QtGui/QGuiApplication>
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
#include <QtQuick/QSGSimpleTextureNode>
|
#include <QtQuick/QSGSimpleTextureNode>
|
||||||
|
@ -123,11 +124,21 @@ QtGLVideoItem::QtGLVideoItem()
|
||||||
connect(this, SIGNAL(windowChanged(QQuickWindow*)), this,
|
connect(this, SIGNAL(windowChanged(QQuickWindow*)), this,
|
||||||
SLOT(handleWindowChanged(QQuickWindow*)));
|
SLOT(handleWindowChanged(QQuickWindow*)));
|
||||||
|
|
||||||
|
this->proxy = QSharedPointer<QtGLVideoItemInterface>(new QtGLVideoItemInterface(this));
|
||||||
|
|
||||||
GST_DEBUG ("%p init Qt Video Item", this);
|
GST_DEBUG ("%p init Qt Video Item", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QtGLVideoItem::~QtGLVideoItem()
|
QtGLVideoItem::~QtGLVideoItem()
|
||||||
{
|
{
|
||||||
|
/* Before destroying the priv info, make sure
|
||||||
|
* no qmlglsink's will call in again, and that
|
||||||
|
* any ongoing calls are done by invalidating the proxy
|
||||||
|
* pointer */
|
||||||
|
GST_INFO ("Destroying QtGLVideoItem and invalidating the proxy");
|
||||||
|
proxy->invalidateRef();
|
||||||
|
proxy.clear();
|
||||||
|
|
||||||
g_mutex_clear (&this->priv->lock);
|
g_mutex_clear (&this->priv->lock);
|
||||||
if (this->priv->context)
|
if (this->priv->context)
|
||||||
gst_object_unref(this->priv->context);
|
gst_object_unref(this->priv->context);
|
||||||
|
@ -237,18 +248,25 @@ _reset (QtGLVideoItem * qt_item)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
qt_item_set_buffer (QtGLVideoItem * widget, GstBuffer * buffer)
|
QtGLVideoItemInterface::setBuffer (GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
g_return_if_fail (widget != NULL);
|
QMutexLocker locker(&lock);
|
||||||
g_return_if_fail (widget->priv->negotiated);
|
|
||||||
|
|
||||||
g_mutex_lock (&widget->priv->lock);
|
if (qt_item == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
gst_buffer_replace (&widget->priv->buffer, buffer);
|
if (!qt_item->priv->negotiated) {
|
||||||
|
GST_WARNING ("Got buffer on unnegotiated QtGLVideoItem. Dropping");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QMetaObject::invokeMethod(widget, "update", Qt::QueuedConnection);
|
g_mutex_lock (&qt_item->priv->lock);
|
||||||
|
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
gst_buffer_replace (&qt_item->priv->buffer, buffer);
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(qt_item, "update", Qt::QueuedConnection);
|
||||||
|
|
||||||
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -280,50 +298,53 @@ QtGLVideoItem::onSceneGraphInvalidated ()
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
qt_item_init_winsys (QtGLVideoItem * widget)
|
QtGLVideoItemInterface::initWinSys ()
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
if (qt_item == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
g_mutex_lock (&widget->priv->lock);
|
g_mutex_lock (&qt_item->priv->lock);
|
||||||
|
|
||||||
if (widget->priv->display && widget->priv->qt_context
|
if (qt_item->priv->display && qt_item->priv->qt_context
|
||||||
&& widget->priv->other_context && widget->priv->context) {
|
&& qt_item->priv->other_context && qt_item->priv->context) {
|
||||||
/* already have the necessary state */
|
/* already have the necessary state */
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GST_IS_GL_DISPLAY (widget->priv->display)) {
|
if (!GST_IS_GL_DISPLAY (qt_item->priv->display)) {
|
||||||
GST_ERROR ("%p failed to retrieve display connection %" GST_PTR_FORMAT,
|
GST_ERROR ("%p failed to retrieve display connection %" GST_PTR_FORMAT,
|
||||||
widget, widget->priv->display);
|
qt_item, qt_item->priv->display);
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GST_IS_GL_CONTEXT (widget->priv->other_context)) {
|
if (!GST_IS_GL_CONTEXT (qt_item->priv->other_context)) {
|
||||||
GST_ERROR ("%p failed to retrieve wrapped context %" GST_PTR_FORMAT, widget,
|
GST_ERROR ("%p failed to retrieve wrapped context %" GST_PTR_FORMAT, qt_item,
|
||||||
widget->priv->other_context);
|
qt_item->priv->other_context);
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
widget->priv->context = gst_gl_context_new (widget->priv->display);
|
qt_item->priv->context = gst_gl_context_new (qt_item->priv->display);
|
||||||
|
|
||||||
if (!widget->priv->context) {
|
if (!qt_item->priv->context) {
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_gl_context_create (widget->priv->context, widget->priv->other_context,
|
if (!gst_gl_context_create (qt_item->priv->context, qt_item->priv->other_context,
|
||||||
&error)) {
|
&error)) {
|
||||||
GST_ERROR ("%s", error->message);
|
GST_ERROR ("%s", error->message);
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,68 +424,115 @@ _calculate_par (QtGLVideoItem * widget, GstVideoInfo * info)
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
qt_item_set_caps (QtGLVideoItem * widget, GstCaps * caps)
|
QtGLVideoItemInterface::setCaps (GstCaps * caps)
|
||||||
{
|
{
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
GstVideoInfo v_info;
|
GstVideoInfo v_info;
|
||||||
|
|
||||||
g_return_val_if_fail (widget != NULL, FALSE);
|
|
||||||
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
|
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
|
||||||
g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
|
g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
|
||||||
|
|
||||||
if (widget->priv->caps && gst_caps_is_equal_fixed (widget->priv->caps, caps))
|
if (qt_item == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (qt_item->priv->caps && gst_caps_is_equal_fixed (qt_item->priv->caps, caps))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (!gst_video_info_from_caps (&v_info, caps))
|
if (!gst_video_info_from_caps (&v_info, caps))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
g_mutex_lock (&widget->priv->lock);
|
g_mutex_lock (&qt_item->priv->lock);
|
||||||
|
|
||||||
_reset (widget);
|
_reset (qt_item);
|
||||||
|
|
||||||
gst_caps_replace (&widget->priv->caps, caps);
|
gst_caps_replace (&qt_item->priv->caps, caps);
|
||||||
|
|
||||||
if (!_calculate_par (widget, &v_info)) {
|
if (!_calculate_par (qt_item, &v_info)) {
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
widget->priv->v_info = v_info;
|
qt_item->priv->v_info = v_info;
|
||||||
widget->priv->negotiated = TRUE;
|
qt_item->priv->negotiated = TRUE;
|
||||||
|
|
||||||
g_mutex_unlock (&widget->priv->lock);
|
g_mutex_unlock (&qt_item->priv->lock);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstGLContext *
|
GstGLContext *
|
||||||
qt_item_get_qt_context (QtGLVideoItem * qt_item)
|
QtGLVideoItemInterface::getQtContext ()
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (qt_item != NULL, NULL);
|
QMutexLocker locker(&lock);
|
||||||
|
|
||||||
if (!qt_item->priv->other_context)
|
if (!qt_item || !qt_item->priv->other_context)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return (GstGLContext *) gst_object_ref (qt_item->priv->other_context);
|
return (GstGLContext *) gst_object_ref (qt_item->priv->other_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
GstGLContext *
|
GstGLContext *
|
||||||
qt_item_get_context (QtGLVideoItem * qt_item)
|
QtGLVideoItemInterface::getContext ()
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (qt_item != NULL, NULL);
|
QMutexLocker locker(&lock);
|
||||||
|
|
||||||
if (!qt_item->priv->context)
|
if (!qt_item || !qt_item->priv->context)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return (GstGLContext *) gst_object_ref (qt_item->priv->context);
|
return (GstGLContext *) gst_object_ref (qt_item->priv->context);
|
||||||
}
|
}
|
||||||
|
|
||||||
GstGLDisplay *
|
GstGLDisplay *
|
||||||
qt_item_get_display (QtGLVideoItem * qt_item)
|
QtGLVideoItemInterface::getDisplay()
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (qt_item != NULL, NULL);
|
QMutexLocker locker(&lock);
|
||||||
|
|
||||||
if (!qt_item->priv->display)
|
if (!qt_item || !qt_item->priv->display)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return (GstGLDisplay *) gst_object_ref (qt_item->priv->display);
|
return (GstGLDisplay *) gst_object_ref (qt_item->priv->display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QtGLVideoItemInterface::setDAR(gint num, gint den)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
if (!qt_item)
|
||||||
|
return;
|
||||||
|
qt_item->setDAR(num, den);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QtGLVideoItemInterface::getDAR(gint * num, gint * den)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
if (!qt_item)
|
||||||
|
return;
|
||||||
|
qt_item->getDAR (num, den);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QtGLVideoItemInterface::setForceAspectRatio(bool force_aspect_ratio)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
if (!qt_item)
|
||||||
|
return;
|
||||||
|
qt_item->setForceAspectRatio(force_aspect_ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
QtGLVideoItemInterface::getForceAspectRatio()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
if (!qt_item)
|
||||||
|
return FALSE;
|
||||||
|
return qt_item->getForceAspectRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
QtGLVideoItemInterface::invalidateRef()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&lock);
|
||||||
|
qt_item = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,40 @@
|
||||||
#include <gst/gl/gl.h>
|
#include <gst/gl/gl.h>
|
||||||
|
|
||||||
#include "gstqtgl.h"
|
#include "gstqtgl.h"
|
||||||
|
#include <QtCore/QMutex>
|
||||||
#include <QtQuick/QQuickItem>
|
#include <QtQuick/QQuickItem>
|
||||||
#include <QtGui/QOpenGLContext>
|
#include <QtGui/QOpenGLContext>
|
||||||
#include <QtGui/QOpenGLFunctions>
|
#include <QtGui/QOpenGLFunctions>
|
||||||
|
|
||||||
typedef struct _QtGLVideoItemPrivate QtGLVideoItemPrivate;
|
typedef struct _QtGLVideoItemPrivate QtGLVideoItemPrivate;
|
||||||
|
|
||||||
|
class QtGLVideoItem;
|
||||||
|
|
||||||
|
class QtGLVideoItemInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QtGLVideoItemInterface (QtGLVideoItem *w) : qt_item (w), lock() {};
|
||||||
|
|
||||||
|
void invalidateRef();
|
||||||
|
|
||||||
|
void setBuffer (GstBuffer * buffer);
|
||||||
|
gboolean setCaps (GstCaps *caps);
|
||||||
|
gboolean initWinSys ();
|
||||||
|
GstGLContext *getQtContext();
|
||||||
|
GstGLContext *getContext();
|
||||||
|
GstGLDisplay *getDisplay();
|
||||||
|
QtGLVideoItem *videoItem () { return qt_item; };
|
||||||
|
|
||||||
|
void setDAR(gint, gint);
|
||||||
|
void getDAR(gint *, gint *);
|
||||||
|
void setForceAspectRatio(bool);
|
||||||
|
bool getForceAspectRatio();
|
||||||
|
private:
|
||||||
|
QtGLVideoItem *qt_item;
|
||||||
|
QMutex lock;
|
||||||
|
};
|
||||||
|
|
||||||
class InitializeSceneGraph;
|
class InitializeSceneGraph;
|
||||||
|
|
||||||
class QtGLVideoItem : public QQuickItem, protected QOpenGLFunctions
|
class QtGLVideoItem : public QQuickItem, protected QOpenGLFunctions
|
||||||
|
@ -45,6 +73,7 @@ public:
|
||||||
void setForceAspectRatio(bool);
|
void setForceAspectRatio(bool);
|
||||||
bool getForceAspectRatio();
|
bool getForceAspectRatio();
|
||||||
|
|
||||||
|
QSharedPointer<QtGLVideoItemInterface> getInterface() { return proxy; };
|
||||||
/* private for C interface ... */
|
/* private for C interface ... */
|
||||||
QtGLVideoItemPrivate *priv;
|
QtGLVideoItemPrivate *priv;
|
||||||
|
|
||||||
|
@ -57,22 +86,15 @@ protected:
|
||||||
QSGNode * updatePaintNode (QSGNode * oldNode, UpdatePaintNodeData * updatePaintNodeData);
|
QSGNode * updatePaintNode (QSGNode * oldNode, UpdatePaintNodeData * updatePaintNodeData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend class InitializeSceneGraph;
|
friend class InitializeSceneGraph;
|
||||||
void setViewportSize(const QSize &size);
|
void setViewportSize(const QSize &size);
|
||||||
void shareContext();
|
void shareContext();
|
||||||
|
|
||||||
QSize m_viewportSize;
|
QSize m_viewportSize;
|
||||||
bool m_openGlContextInitialized;
|
bool m_openGlContextInitialized;
|
||||||
|
|
||||||
|
QSharedPointer<QtGLVideoItemInterface> proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
void qt_item_set_buffer (QtGLVideoItem * widget, GstBuffer * buffer);
|
|
||||||
gboolean qt_item_set_caps (QtGLVideoItem * widget, GstCaps * caps);
|
|
||||||
gboolean qt_item_init_winsys (QtGLVideoItem * widget);
|
|
||||||
GstGLContext * qt_item_get_qt_context (QtGLVideoItem * qt_item);
|
|
||||||
GstGLContext * qt_item_get_context (QtGLVideoItem * qt_item);
|
|
||||||
GstGLDisplay * qt_item_get_display (QtGLVideoItem * qt_item);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* __QT_ITEM_H__ */
|
#endif /* __QT_ITEM_H__ */
|
||||||
|
|
Loading…
Reference in a new issue