diff --git a/ext/gl/gstglmixer.c b/ext/gl/gstglmixer.c index 3fcd728f17..04c951fdb5 100644 --- a/ext/gl/gstglmixer.c +++ b/ext/gl/gstglmixer.c @@ -131,6 +131,8 @@ _negotiated_caps (GstVideoAggregator * vagg, GstCaps * caps) mix->priv->negotiated = ret; + gst_caps_replace (&mix->out_caps, caps); + return ret; } @@ -826,32 +828,37 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) gboolean res = TRUE; guint array_index = 0; GstVideoFrame out_frame; - gboolean out_gl_wrapped = FALSE; GstElement *element = GST_ELEMENT (mix); GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix); GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); GstGLMixerPrivate *priv = mix->priv; + gboolean to_download = + gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, + gst_caps_get_features (mix->out_caps, 0)); + GstMapFlags out_map_flags = GST_MAP_WRITE; GST_TRACE ("Processing buffers"); - if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf, - GST_MAP_WRITE | GST_MAP_GL)) { + to_download |= !gst_is_gl_memory (gst_buffer_peek_memory (outbuf, 0)); + + if (!to_download) + out_map_flags |= GST_MAP_GL; + + if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf, out_map_flags)) { return FALSE; } - if (gst_is_gl_memory (out_frame.map[0].memory)) { + if (!to_download) { out_tex = *(guint *) out_frame.data[0]; } else { GST_INFO ("Output Buffer does not contain correct memory, " "attempting to wrap for download"); - out_tex = mix->out_tex_id;; - if (!mix->download) mix->download = gst_gl_download_new (mix->context); gst_gl_download_set_format (mix->download, &out_frame.info); - out_gl_wrapped = TRUE; + out_tex = mix->out_tex_id; } GST_OBJECT_LOCK (mix); @@ -910,7 +917,7 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) g_mutex_unlock (&priv->gl_resource_lock); - if (out_gl_wrapped) { + if (to_download) { if (!gst_gl_download_perform_with_data (mix->download, out_tex, out_frame.data)) { GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s", diff --git a/ext/gl/gstglmixer.h b/ext/gl/gstglmixer.h index a9e3a3c6cb..d66ef30c18 100644 --- a/ext/gl/gstglmixer.h +++ b/ext/gl/gstglmixer.h @@ -69,6 +69,8 @@ struct _GstGLMixer GstGLContext *context; GLuint fbo; GLuint depthbuffer; + + GstCaps *out_caps; }; struct _GstGLMixerClass diff --git a/ext/gl/gstgltestsrc.c b/ext/gl/gstgltestsrc.c index 3b60f77e75..c154477c3d 100644 --- a/ext/gl/gstgltestsrc.c +++ b/ext/gl/gstgltestsrc.c @@ -415,6 +415,8 @@ gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps) gltestsrc->negotiated = TRUE; + gst_caps_replace (&gltestsrc->out_caps, caps); + return TRUE; /* ERRORS */ @@ -543,14 +545,20 @@ gst_gl_test_src_init_shader (GstGLTestSrc * gltestsrc) static GstFlowReturn gst_gl_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer) { - GstGLTestSrc *src; + GstGLTestSrc *src = GST_GL_TEST_SRC (psrc); GstClockTime next_time; gint width, height; GstVideoFrame out_frame; - gboolean out_gl_wrapped = FALSE; guint out_tex; + gboolean to_download = + gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, + gst_caps_get_features (src->out_caps, 0)); + GstMapFlags out_map_flags = GST_MAP_WRITE; - src = GST_GL_TEST_SRC (psrc); + to_download |= !gst_is_gl_memory (gst_buffer_peek_memory (buffer, 0)); + + if (!to_download) + out_map_flags |= GST_MAP_GL; if (G_UNLIKELY (!src->negotiated || !src->context)) goto not_negotiated; @@ -570,29 +578,27 @@ gst_gl_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer) src->make_image = gst_gl_test_src_black; } - if (!gst_video_frame_map (&out_frame, &src->out_info, buffer, - GST_MAP_WRITE | GST_MAP_GL)) { + if (!gst_video_frame_map (&out_frame, &src->out_info, buffer, out_map_flags)) { return GST_FLOW_NOT_NEGOTIATED; } - if (gst_is_gl_memory (out_frame.map[0].memory)) { + if (!to_download) { out_tex = *(guint *) out_frame.data[0]; } else { GST_INFO ("Output Buffer does not contain correct meta, " "attempting to wrap for download"); + if (!src->download) + src->download = gst_gl_download_new (src->context); + + gst_gl_download_set_format (src->download, &out_frame.info); + if (!src->out_tex_id) { gst_gl_context_gen_texture (src->context, &src->out_tex_id, GST_VIDEO_FORMAT_RGBA, GST_VIDEO_FRAME_WIDTH (&out_frame), GST_VIDEO_FRAME_HEIGHT (&out_frame)); } out_tex = src->out_tex_id; - - if (!src->download) - src->download = gst_gl_download_new (src->context); - - gst_gl_download_set_format (src->download, &out_frame.info); - out_gl_wrapped = TRUE; } gst_buffer_replace (&src->buffer, buffer); @@ -604,7 +610,7 @@ gst_gl_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer) goto not_negotiated; } - if (out_gl_wrapped) { + if (to_download) { if (!gst_gl_download_perform_with_data (src->download, out_tex, out_frame.data)) { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s", @@ -665,6 +671,8 @@ gst_gl_test_src_stop (GstBaseSrc * basesrc) { GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc); + gst_caps_replace (&src->out_caps, NULL); + if (src->context) { if (src->out_tex_id) { gst_gl_context_del_texture (src->context, &src->out_tex_id); diff --git a/ext/gl/gstgltestsrc.h b/ext/gl/gstgltestsrc.h index 3e854e8079..0e7d71bb3b 100644 --- a/ext/gl/gstgltestsrc.h +++ b/ext/gl/gstgltestsrc.h @@ -118,6 +118,8 @@ struct _GstGLTestSrc { const gchar *fragment_src; void (*make_image) (GstGLTestSrc* v, GstBuffer* buffer, gint w, gint h); + + GstCaps *out_caps; }; struct _GstGLTestSrcClass { diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c index 1b68e91e00..de4a1affc0 100644 --- a/gst-libs/gst/gl/gstglfilter.c +++ b/gst-libs/gst/gl/gstglfilter.c @@ -244,6 +244,8 @@ gst_gl_filter_reset (GstGLFilter * filter) { GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter); + gst_caps_replace (&filter->out_caps, NULL); + if (filter->upload) { gst_object_unref (filter->upload); filter->upload = NULL; @@ -822,6 +824,8 @@ gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps, goto error; } + gst_caps_replace (&filter->out_caps, outcaps); + GST_DEBUG ("set_caps %dx%d", GST_VIDEO_INFO_WIDTH (&filter->out_info), GST_VIDEO_INFO_HEIGHT (&filter->out_info)); @@ -1169,24 +1173,29 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf, GstGLFilterClass *filter_class; guint in_tex, out_tex; GstVideoFrame out_frame; - gboolean ret, out_gl_mem; - GstVideoGLTextureUploadMeta *out_tex_upload_meta; + gboolean ret; + gboolean to_download = + gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, + gst_caps_get_features (filter->out_caps, 0)); + GstMapFlags out_map_flags = GST_MAP_WRITE; filter_class = GST_GL_FILTER_GET_CLASS (filter); if (!gst_gl_upload_perform_with_buffer (filter->upload, inbuf, &in_tex, NULL)) return FALSE; + to_download |= !gst_is_gl_memory (gst_buffer_peek_memory (outbuf, 0)); + + if (!to_download) + out_map_flags |= GST_MAP_GL; + if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf, - GST_MAP_WRITE | GST_MAP_GL)) { + out_map_flags)) { ret = FALSE; goto inbuf_error; } - out_gl_mem = gst_is_gl_memory (out_frame.map[0].memory); - out_tex_upload_meta = gst_buffer_get_video_gl_texture_upload_meta (outbuf); - - if (out_gl_mem) { + if (!to_download) { out_tex = *(guint *) out_frame.data[0]; } else { GST_LOG ("Output Buffer does not contain correct memory, " @@ -1196,6 +1205,7 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf, filter->download = gst_gl_download_new (filter->context); gst_gl_download_set_format (filter->download, &out_frame.info); + out_tex = filter->out_tex_id; } @@ -1205,7 +1215,7 @@ gst_gl_filter_filter_texture (GstGLFilter * filter, GstBuffer * inbuf, g_assert (filter_class->filter_texture); ret = filter_class->filter_texture (filter, in_tex, out_tex); - if (!out_gl_mem && !out_tex_upload_meta) { + if (to_download) { if (!gst_gl_download_perform_with_data (filter->download, out_tex, out_frame.data)) { GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND, diff --git a/gst-libs/gst/gl/gstglfilter.h b/gst-libs/gst/gl/gstglfilter.h index 6e7702279e..c78649363a 100644 --- a/gst-libs/gst/gl/gstglfilter.h +++ b/gst-libs/gst/gl/gstglfilter.h @@ -68,6 +68,9 @@ struct _GstGLFilter GstVideoInfo in_info; GstVideoInfo out_info; + + GstCaps *out_caps; + GLuint fbo; GLuint depthbuffer;