mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-11 16:55:23 +00:00
qt(6)/material: ensure that we always update the context in setBuffer()
Scenario is that there are two (or more) GstGLContext's wrapping Qt's GL context from either multiple qml(6)glsink or qml(6)glsrc elements. Call flow is this: 1. material 1 setBuffer() 2. material 1 bind() 3. material 2 setBuffer() 4. material 2 bind() If the call to setBuffer() reuses the same buffer as previous call, then the qt context is not updated in the material. If however the previously used qt context by the material had been deactivated or freed, then bind() would fail and could result in a critical like so: gst_gl_context_thread_add: assertion 'context->priv->active_thread == g_thread_self ()' failed Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7970>
This commit is contained in:
parent
3540b33597
commit
e2d388000c
2 changed files with 34 additions and 19 deletions
|
@ -451,16 +451,23 @@ GstQSGMaterial::setCaps (GstCaps * caps)
|
||||||
gboolean
|
gboolean
|
||||||
GstQSGMaterial::setBuffer (GstBuffer * buffer)
|
GstQSGMaterial::setBuffer (GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GST_LOG ("%p setBuffer %" GST_PTR_FORMAT, this, buffer);
|
GstGLContext *qt_context;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
/* FIXME: update more state here */
|
/* FIXME: update more state here */
|
||||||
if (!gst_buffer_replace (&this->buffer_, buffer))
|
if (gst_buffer_replace (&this->buffer_, buffer)) {
|
||||||
return FALSE;
|
GST_LOG ("%p setBuffer new buffer %" GST_PTR_FORMAT, this, buffer);
|
||||||
|
|
||||||
this->buffer_was_bound = FALSE;
|
this->buffer_was_bound = FALSE;
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
g_weak_ref_set (&this->qt_context_ref_, gst_gl_context_get_current ());
|
qt_context = gst_gl_context_get_current ();
|
||||||
|
GST_DEBUG ("%p setBuffer with qt context %" GST_PTR_FORMAT, this, qt_context);
|
||||||
|
|
||||||
return TRUE;
|
g_weak_ref_set (&this->qt_context_ref_, qt_context);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only called from the streaming thread with scene graph thread blocked */
|
/* only called from the streaming thread with scene graph thread blocked */
|
||||||
|
@ -481,7 +488,7 @@ void
|
||||||
GstQSGMaterial::bind(GstQSGMaterialShader *shader, GstVideoFormat v_format)
|
GstQSGMaterial::bind(GstQSGMaterialShader *shader, GstVideoFormat v_format)
|
||||||
{
|
{
|
||||||
const GstGLFuncs *gl;
|
const GstGLFuncs *gl;
|
||||||
GstGLContext *context, *qt_context;
|
GstGLContext *context, *qt_context = NULL;
|
||||||
GstGLSyncMeta *sync_meta;
|
GstGLSyncMeta *sync_meta;
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
GstGLMemory *gl_mem;
|
GstGLMemory *gl_mem;
|
||||||
|
@ -492,10 +499,6 @@ GstQSGMaterial::bind(GstQSGMaterialShader *shader, GstVideoFormat v_format)
|
||||||
memset (&this->v_frame, 0, sizeof (this->v_frame));
|
memset (&this->v_frame, 0, sizeof (this->v_frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
qt_context = GST_GL_CONTEXT (g_weak_ref_get (&this->qt_context_ref_));
|
|
||||||
if (!qt_context)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!this->buffer_)
|
if (!this->buffer_)
|
||||||
goto out;
|
goto out;
|
||||||
if (GST_VIDEO_INFO_FORMAT (&this->v_info) == GST_VIDEO_FORMAT_UNKNOWN)
|
if (GST_VIDEO_INFO_FORMAT (&this->v_info) == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
|
@ -505,6 +508,10 @@ GstQSGMaterial::bind(GstQSGMaterialShader *shader, GstVideoFormat v_format)
|
||||||
if (!this->mem_)
|
if (!this->mem_)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
qt_context = GST_GL_CONTEXT (g_weak_ref_get (&this->qt_context_ref_));
|
||||||
|
if (!qt_context)
|
||||||
|
goto out;
|
||||||
|
|
||||||
gl = qt_context->gl_vtable;
|
gl = qt_context->gl_vtable;
|
||||||
|
|
||||||
/* FIXME: should really lock the memory to prevent write access */
|
/* FIXME: should really lock the memory to prevent write access */
|
||||||
|
@ -514,6 +521,8 @@ GstQSGMaterial::bind(GstQSGMaterialShader *shader, GstVideoFormat v_format)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_DEBUG ("%p attempting to bind with context %" GST_PTR_FORMAT, this, qt_context);
|
||||||
|
|
||||||
mem = gst_buffer_peek_memory (this->buffer_, 0);
|
mem = gst_buffer_peek_memory (this->buffer_, 0);
|
||||||
g_assert (gst_is_gl_memory (mem));
|
g_assert (gst_is_gl_memory (mem));
|
||||||
gl_mem = (GstGLMemory *)mem;
|
gl_mem = (GstGLMemory *)mem;
|
||||||
|
|
|
@ -473,15 +473,19 @@ GstQSG6Material::setCaps (GstCaps * caps)
|
||||||
gboolean
|
gboolean
|
||||||
GstQSG6Material::setBuffer (GstBuffer * buffer)
|
GstQSG6Material::setBuffer (GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GST_LOG ("%p setBuffer %" GST_PTR_FORMAT, this, buffer);
|
GstGLContext *qt_context = gst_gl_context_get_current ();
|
||||||
|
|
||||||
|
GST_LOG ("%p setBuffer %" GST_PTR_FORMAT " with qt context %" GST_PTR_FORMAT,
|
||||||
|
this, buffer, qt_context);
|
||||||
/* FIXME: update more state here */
|
/* FIXME: update more state here */
|
||||||
|
|
||||||
|
g_weak_ref_set (&this->qt_context_ref_, qt_context);
|
||||||
|
|
||||||
if (!gst_buffer_replace (&this->buffer_, buffer))
|
if (!gst_buffer_replace (&this->buffer_, buffer))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
this->buffer_was_bound = false;
|
this->buffer_was_bound = false;
|
||||||
|
|
||||||
g_weak_ref_set (&this->qt_context_ref_, gst_gl_context_get_current ());
|
|
||||||
|
|
||||||
if (this->v_frame.buffer) {
|
if (this->v_frame.buffer) {
|
||||||
gst_video_frame_unmap (&this->v_frame);
|
gst_video_frame_unmap (&this->v_frame);
|
||||||
memset (&this->v_frame, 0, sizeof (this->v_frame));
|
memset (&this->v_frame, 0, sizeof (this->v_frame));
|
||||||
|
@ -567,7 +571,7 @@ video_format_to_texel_size (GstVideoFormat format, guint plane)
|
||||||
QSGTexture *
|
QSGTexture *
|
||||||
GstQSG6Material::bind(GstQSG6MaterialShader *shader, QRhi * rhi, QRhiResourceUpdateBatch *res_updates, guint plane, GstVideoFormat v_format)
|
GstQSG6Material::bind(GstQSG6MaterialShader *shader, QRhi * rhi, QRhiResourceUpdateBatch *res_updates, guint plane, GstVideoFormat v_format)
|
||||||
{
|
{
|
||||||
GstGLContext *qt_context, *context;
|
GstGLContext *qt_context = NULL, *context;
|
||||||
GstMemory *mem;
|
GstMemory *mem;
|
||||||
GstGLMemory *gl_mem;
|
GstGLMemory *gl_mem;
|
||||||
GstGLSyncMeta *sync_meta;
|
GstGLSyncMeta *sync_meta;
|
||||||
|
@ -578,15 +582,17 @@ GstQSG6Material::bind(GstQSG6MaterialShader *shader, QRhi * rhi, QRhiResourceUpd
|
||||||
QSize tex_size;
|
QSize tex_size;
|
||||||
QRhiTexture::Flags flags = {};
|
QRhiTexture::Flags flags = {};
|
||||||
|
|
||||||
qt_context = GST_GL_CONTEXT (g_weak_ref_get (&this->qt_context_ref_));
|
|
||||||
if (!qt_context)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!this->buffer_)
|
if (!this->buffer_)
|
||||||
goto out;
|
goto out;
|
||||||
if (GST_VIDEO_INFO_FORMAT (&this->v_info) == GST_VIDEO_FORMAT_UNKNOWN)
|
if (GST_VIDEO_INFO_FORMAT (&this->v_info) == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
qt_context = GST_GL_CONTEXT (g_weak_ref_get (&this->qt_context_ref_));
|
||||||
|
if (!qt_context)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
GST_DEBUG ("%p attempting to bind with context %" GST_PTR_FORMAT, this, qt_context);
|
||||||
|
|
||||||
mem = gst_buffer_peek_memory (this->buffer_, plane);
|
mem = gst_buffer_peek_memory (this->buffer_, plane);
|
||||||
g_assert (gst_is_gl_memory (mem));
|
g_assert (gst_is_gl_memory (mem));
|
||||||
gl_mem = (GstGLMemory *) mem;
|
gl_mem = (GstGLMemory *) mem;
|
||||||
|
|
Loading…
Reference in a new issue