diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c index 59355a2401..943f46e8df 100644 --- a/ext/gl/gstglimagesink.c +++ b/ext/gl/gstglimagesink.c @@ -646,6 +646,7 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition) glimage_sink->stored_buffer = NULL; } GST_GLIMAGE_SINK_UNLOCK (glimage_sink); + gst_buffer_replace (&glimage_sink->next_buffer, NULL); if (glimage_sink->upload) { gst_object_unref (glimage_sink->upload); @@ -822,6 +823,7 @@ static GstFlowReturn gst_glimage_sink_prepare (GstBaseSink * bsink, GstBuffer * buf) { GstGLImageSink *glimage_sink; + GstBuffer *next_buffer = NULL; glimage_sink = GST_GLIMAGE_SINK (bsink); @@ -836,9 +838,12 @@ gst_glimage_sink_prepare (GstBaseSink * bsink, GstBuffer * buf) return GST_FLOW_NOT_NEGOTIATED; if (!gst_gl_upload_perform_with_buffer (glimage_sink->upload, buf, - &glimage_sink->next_tex)) + &glimage_sink->next_tex, &next_buffer)) goto upload_failed; + gst_buffer_replace (&glimage_sink->next_buffer, next_buffer); + gst_buffer_unref (next_buffer); + if (glimage_sink->window_id != glimage_sink->new_window_id) { GstGLWindow *window = gst_gl_context_get_window (glimage_sink->context); @@ -878,10 +883,8 @@ gst_glimage_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf) GST_GLIMAGE_SINK_LOCK (glimage_sink); glimage_sink->redisplay_texture = glimage_sink->next_tex; stored_buffer = glimage_sink->stored_buffer; - glimage_sink->stored_buffer = gst_buffer_ref (buf); + glimage_sink->stored_buffer = gst_buffer_ref (glimage_sink->next_buffer); GST_GLIMAGE_SINK_UNLOCK (glimage_sink); - if (stored_buffer) - gst_buffer_unref (stored_buffer); /* Ask the underlying window to redraw its content */ if (!gst_glimage_sink_redisplay (glimage_sink)) @@ -889,6 +892,9 @@ gst_glimage_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf) GST_TRACE ("post redisplay"); + if (stored_buffer) + gst_buffer_unref (stored_buffer); + if (g_atomic_int_get (&glimage_sink->to_quit) != 0) { GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND, ("%s", gst_gl_context_get_error ()), (NULL)); diff --git a/ext/gl/gstglimagesink.h b/ext/gl/gstglimagesink.h index f9cf66a78d..c5bc2ecc54 100644 --- a/ext/gl/gstglimagesink.h +++ b/ext/gl/gstglimagesink.h @@ -68,6 +68,7 @@ struct _GstGLImageSink GstGLUpload *upload; guint next_tex; + GstBuffer *next_buffer; volatile gint to_quit; gboolean keep_aspect_ratio; diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c index 72291a8bad..3fcd728f17 100644 --- a/ext/gl/gstglmixer.c +++ b/ext/gl/gstglmixer.c @@ -882,7 +882,7 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) } if (!gst_gl_upload_perform_with_buffer (pad->upload, - vaggpad->buffer, &in_tex)) { + vaggpad->buffer, &in_tex, NULL)) { ++array_index; pad->mapped = FALSE; continue; diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c index e8c8710c13..c29a08f6f7 100644 --- a/gst-libs/gst/gl/gstglfilter.c +++ b/gst-libs/gst/gl/gstglfilter.c @@ -1175,7 +1175,7 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf, filter_class = GST_GL_FILTER_GET_CLASS (filter); - if (!gst_gl_upload_perform_with_buffer (filter->upload, inbuf, &in_tex)) + if (!gst_gl_upload_perform_with_buffer (filter->upload, inbuf, &in_tex, NULL)) return FALSE; if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf, diff --git a/gst-libs/gst/gl/gstglupload.c b/gst-libs/gst/gl/gstglupload.c index cc696bd7ea..2a80647775 100644 --- a/gst-libs/gst/gl/gstglupload.c +++ b/gst-libs/gst/gl/gstglupload.c @@ -50,7 +50,8 @@ static gboolean _upload_memory (GstGLUpload * upload); static gboolean _init_upload (GstGLUpload * upload); static gboolean _gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, - GLuint * texture_id, gpointer data[GST_VIDEO_MAX_PLANES]); + GLuint * texture_id, gpointer data[GST_VIDEO_MAX_PLANES], + GstBuffer ** outbuf); static void _do_upload_with_meta (GstGLContext * context, GstGLUpload * upload); static void gst_gl_upload_reset (GstGLUpload * upload); @@ -223,6 +224,7 @@ gst_gl_upload_get_format (GstGLUpload * upload) * @upload: a #GstGLUpload * @buffer: a #GstBuffer * @tex_id: resulting texture + * @outbuf: (allow-none): resulting buffer * * Uploads @buffer to the texture given by @tex_id. @tex_id is valid * until gst_gl_upload_release_buffer() is called. @@ -231,7 +233,7 @@ gst_gl_upload_get_format (GstGLUpload * upload) */ gboolean gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, - guint * tex_id) + guint * tex_id, GstBuffer ** outbuf) { GstMemory *mem; GstVideoGLTextureUploadMeta *gl_tex_upload_meta; @@ -257,6 +259,10 @@ gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, gst_memory_unmap (mem, &map_info); *tex_id = ((GstGLMemory *) mem)->tex_id; + + if (outbuf) + *outbuf = gst_buffer_ref (buffer); + return TRUE; } @@ -271,6 +277,10 @@ gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) { upload->in_tex[i] = NULL; } + + if (ret && outbuf != NULL) + *outbuf = gst_buffer_ref (upload->priv->outbuf); + return ret; } #if GST_GL_HAVE_PLATFORM_EGL @@ -292,7 +302,7 @@ gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, texture_ids[0] = upload->priv->tex_id; if (!gst_gl_upload_perform_with_gl_texture_upload_meta (upload, - gl_tex_upload_meta, texture_ids)) { + gl_tex_upload_meta, texture_ids, outbuf)) { GST_DEBUG_OBJECT (upload, "Upload with GstVideoGLTextureUploadMeta " "failed"); } else { @@ -315,7 +325,7 @@ gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, gst_gl_upload_set_format (upload, &upload->priv->frame.info); if (!gst_gl_upload_perform_with_data (upload, tex_id, - upload->priv->frame.data)) { + upload->priv->frame.data, outbuf)) { return FALSE; } @@ -364,6 +374,7 @@ error: * @upload: a #GstGLUpload * @meta: a #GstVideoGLTextureUploadMeta * @texture_id: resulting GL textures to place the data into. + * @outbuf: (allow-none): resulting buffer * * Uploads @meta into @texture_id. * @@ -371,7 +382,8 @@ error: */ gboolean gst_gl_upload_perform_with_gl_texture_upload_meta (GstGLUpload * upload, - GstVideoGLTextureUploadMeta * meta, guint texture_id[4]) + GstVideoGLTextureUploadMeta * meta, guint texture_id[4], + GstBuffer ** outbuf) { gboolean ret; @@ -403,6 +415,9 @@ gst_gl_upload_perform_with_gl_texture_upload_meta (GstGLUpload * upload, ret = upload->priv->result; + if (ret && outbuf != NULL) + *outbuf = gst_buffer_ref (upload->priv->outbuf); + GST_OBJECT_UNLOCK (upload); return ret; @@ -413,6 +428,7 @@ gst_gl_upload_perform_with_gl_texture_upload_meta (GstGLUpload * upload, * @upload: a #GstGLUpload * @texture_id: (out): the texture id to upload into * @data: where the downloaded data should go + * @outbuf: (allow-none): resulting buffer * * Uploads @data into @texture_id. data size and format is specified by * the #GstVideoInfos passed to gst_gl_upload_set_format() @@ -421,14 +437,16 @@ gst_gl_upload_perform_with_gl_texture_upload_meta (GstGLUpload * upload, */ gboolean gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint * texture_id, - gpointer data[GST_VIDEO_MAX_PLANES]) + gpointer data[GST_VIDEO_MAX_PLANES], GstBuffer ** outbuf) { gboolean ret; g_return_val_if_fail (upload != NULL, FALSE); GST_OBJECT_LOCK (upload); - ret = _gst_gl_upload_perform_with_data_unlocked (upload, texture_id, data); + ret = + _gst_gl_upload_perform_with_data_unlocked (upload, texture_id, data, + outbuf); GST_OBJECT_UNLOCK (upload); return ret; @@ -436,7 +454,8 @@ gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint * texture_id, static gboolean _gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, - GLuint * texture_id, gpointer data[GST_VIDEO_MAX_PLANES]) + GLuint * texture_id, gpointer data[GST_VIDEO_MAX_PLANES], + GstBuffer ** outbuf) { gboolean ret; guint i; @@ -459,6 +478,9 @@ _gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload, ret = _upload_memory (upload); *texture_id = upload->out_tex->tex_id; + if (ret && outbuf != NULL) + *outbuf = gst_buffer_ref (upload->priv->outbuf); + return ret; } diff --git a/gst-libs/gst/gl/gstglupload.h b/gst-libs/gst/gl/gstglupload.h index 21943b9d9f..5c357c1b84 100644 --- a/gst-libs/gst/gl/gstglupload.h +++ b/gst-libs/gst/gl/gstglupload.h @@ -78,12 +78,12 @@ GstGLUpload * gst_gl_upload_new (GstGLContext * context); void gst_gl_upload_set_format (GstGLUpload * upload, GstVideoInfo * in_info); GstVideoInfo * gst_gl_upload_get_format (GstGLUpload * upload); -gboolean gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, guint * tex_id); +gboolean gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer, guint * tex_id, GstBuffer ** outbuf); void gst_gl_upload_release_buffer (GstGLUpload * upload); gboolean gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint * texture_id, - gpointer data[GST_VIDEO_MAX_PLANES]); + gpointer data[GST_VIDEO_MAX_PLANES], GstBuffer ** outbuf); -gboolean gst_gl_upload_perform_with_gl_texture_upload_meta (GstGLUpload *upload, GstVideoGLTextureUploadMeta *meta, guint texture_id[4]); +gboolean gst_gl_upload_perform_with_gl_texture_upload_meta (GstGLUpload *upload, GstVideoGLTextureUploadMeta *meta, guint texture_id[4], GstBuffer ** outbuf); G_END_DECLS