mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
gl: download whenever we have sysmem capsfeatures
Otherwise we could pass on a RGBA formatted buffer and downstream would misinterpret that as some other video format. Fixes pipelines of the form gleffects ! tee ! xvimagesink
This commit is contained in:
parent
462d27e60a
commit
c44352b11f
6 changed files with 61 additions and 29 deletions
|
@ -131,6 +131,8 @@ _negotiated_caps (GstVideoAggregator * vagg, GstCaps * caps)
|
||||||
|
|
||||||
mix->priv->negotiated = ret;
|
mix->priv->negotiated = ret;
|
||||||
|
|
||||||
|
gst_caps_replace (&mix->out_caps, caps);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -826,32 +828,37 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
gboolean res = TRUE;
|
gboolean res = TRUE;
|
||||||
guint array_index = 0;
|
guint array_index = 0;
|
||||||
GstVideoFrame out_frame;
|
GstVideoFrame out_frame;
|
||||||
gboolean out_gl_wrapped = FALSE;
|
|
||||||
GstElement *element = GST_ELEMENT (mix);
|
GstElement *element = GST_ELEMENT (mix);
|
||||||
GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
|
GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix);
|
||||||
GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix);
|
GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix);
|
||||||
GstGLMixerPrivate *priv = mix->priv;
|
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");
|
GST_TRACE ("Processing buffers");
|
||||||
|
|
||||||
if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf,
|
to_download |= !gst_is_gl_memory (gst_buffer_peek_memory (outbuf, 0));
|
||||||
GST_MAP_WRITE | GST_MAP_GL)) {
|
|
||||||
|
if (!to_download)
|
||||||
|
out_map_flags |= GST_MAP_GL;
|
||||||
|
|
||||||
|
if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf, out_map_flags)) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gst_is_gl_memory (out_frame.map[0].memory)) {
|
if (!to_download) {
|
||||||
out_tex = *(guint *) out_frame.data[0];
|
out_tex = *(guint *) out_frame.data[0];
|
||||||
} else {
|
} else {
|
||||||
GST_INFO ("Output Buffer does not contain correct memory, "
|
GST_INFO ("Output Buffer does not contain correct memory, "
|
||||||
"attempting to wrap for download");
|
"attempting to wrap for download");
|
||||||
|
|
||||||
out_tex = mix->out_tex_id;;
|
|
||||||
|
|
||||||
if (!mix->download)
|
if (!mix->download)
|
||||||
mix->download = gst_gl_download_new (mix->context);
|
mix->download = gst_gl_download_new (mix->context);
|
||||||
|
|
||||||
gst_gl_download_set_format (mix->download, &out_frame.info);
|
gst_gl_download_set_format (mix->download, &out_frame.info);
|
||||||
out_gl_wrapped = TRUE;
|
out_tex = mix->out_tex_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_OBJECT_LOCK (mix);
|
GST_OBJECT_LOCK (mix);
|
||||||
|
@ -910,7 +917,7 @@ gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf)
|
||||||
|
|
||||||
g_mutex_unlock (&priv->gl_resource_lock);
|
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,
|
if (!gst_gl_download_perform_with_data (mix->download, out_tex,
|
||||||
out_frame.data)) {
|
out_frame.data)) {
|
||||||
GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s",
|
GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s",
|
||||||
|
|
|
@ -69,6 +69,8 @@ struct _GstGLMixer
|
||||||
GstGLContext *context;
|
GstGLContext *context;
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
GLuint depthbuffer;
|
GLuint depthbuffer;
|
||||||
|
|
||||||
|
GstCaps *out_caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLMixerClass
|
struct _GstGLMixerClass
|
||||||
|
|
|
@ -415,6 +415,8 @@ gst_gl_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
|
||||||
|
|
||||||
gltestsrc->negotiated = TRUE;
|
gltestsrc->negotiated = TRUE;
|
||||||
|
|
||||||
|
gst_caps_replace (&gltestsrc->out_caps, caps);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -543,14 +545,20 @@ gst_gl_test_src_init_shader (GstGLTestSrc * gltestsrc)
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_gl_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer)
|
gst_gl_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstGLTestSrc *src;
|
GstGLTestSrc *src = GST_GL_TEST_SRC (psrc);
|
||||||
GstClockTime next_time;
|
GstClockTime next_time;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
GstVideoFrame out_frame;
|
GstVideoFrame out_frame;
|
||||||
gboolean out_gl_wrapped = FALSE;
|
|
||||||
guint out_tex;
|
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))
|
if (G_UNLIKELY (!src->negotiated || !src->context))
|
||||||
goto not_negotiated;
|
goto not_negotiated;
|
||||||
|
@ -570,29 +578,27 @@ gst_gl_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer)
|
||||||
src->make_image = gst_gl_test_src_black;
|
src->make_image = gst_gl_test_src_black;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_video_frame_map (&out_frame, &src->out_info, buffer,
|
if (!gst_video_frame_map (&out_frame, &src->out_info, buffer, out_map_flags)) {
|
||||||
GST_MAP_WRITE | GST_MAP_GL)) {
|
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
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];
|
out_tex = *(guint *) out_frame.data[0];
|
||||||
} else {
|
} else {
|
||||||
GST_INFO ("Output Buffer does not contain correct meta, "
|
GST_INFO ("Output Buffer does not contain correct meta, "
|
||||||
"attempting to wrap for download");
|
"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) {
|
if (!src->out_tex_id) {
|
||||||
gst_gl_context_gen_texture (src->context, &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_FORMAT_RGBA, GST_VIDEO_FRAME_WIDTH (&out_frame),
|
||||||
GST_VIDEO_FRAME_HEIGHT (&out_frame));
|
GST_VIDEO_FRAME_HEIGHT (&out_frame));
|
||||||
}
|
}
|
||||||
out_tex = src->out_tex_id;
|
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);
|
gst_buffer_replace (&src->buffer, buffer);
|
||||||
|
@ -604,7 +610,7 @@ gst_gl_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer)
|
||||||
goto not_negotiated;
|
goto not_negotiated;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out_gl_wrapped) {
|
if (to_download) {
|
||||||
if (!gst_gl_download_perform_with_data (src->download, out_tex,
|
if (!gst_gl_download_perform_with_data (src->download, out_tex,
|
||||||
out_frame.data)) {
|
out_frame.data)) {
|
||||||
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s",
|
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);
|
GstGLTestSrc *src = GST_GL_TEST_SRC (basesrc);
|
||||||
|
|
||||||
|
gst_caps_replace (&src->out_caps, NULL);
|
||||||
|
|
||||||
if (src->context) {
|
if (src->context) {
|
||||||
if (src->out_tex_id) {
|
if (src->out_tex_id) {
|
||||||
gst_gl_context_del_texture (src->context, &src->out_tex_id);
|
gst_gl_context_del_texture (src->context, &src->out_tex_id);
|
||||||
|
|
|
@ -118,6 +118,8 @@ struct _GstGLTestSrc {
|
||||||
const gchar *fragment_src;
|
const gchar *fragment_src;
|
||||||
|
|
||||||
void (*make_image) (GstGLTestSrc* v, GstBuffer* buffer, gint w, gint h);
|
void (*make_image) (GstGLTestSrc* v, GstBuffer* buffer, gint w, gint h);
|
||||||
|
|
||||||
|
GstCaps *out_caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLTestSrcClass {
|
struct _GstGLTestSrcClass {
|
||||||
|
|
|
@ -244,6 +244,8 @@ gst_gl_filter_reset (GstGLFilter * filter)
|
||||||
{
|
{
|
||||||
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
GstGLFilterClass *filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||||
|
|
||||||
|
gst_caps_replace (&filter->out_caps, NULL);
|
||||||
|
|
||||||
if (filter->upload) {
|
if (filter->upload) {
|
||||||
gst_object_unref (filter->upload);
|
gst_object_unref (filter->upload);
|
||||||
filter->upload = NULL;
|
filter->upload = NULL;
|
||||||
|
@ -822,6 +824,8 @@ gst_gl_filter_set_caps (GstBaseTransform * bt, GstCaps * incaps,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_caps_replace (&filter->out_caps, outcaps);
|
||||||
|
|
||||||
GST_DEBUG ("set_caps %dx%d", GST_VIDEO_INFO_WIDTH (&filter->out_info),
|
GST_DEBUG ("set_caps %dx%d", GST_VIDEO_INFO_WIDTH (&filter->out_info),
|
||||||
GST_VIDEO_INFO_HEIGHT (&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;
|
GstGLFilterClass *filter_class;
|
||||||
guint in_tex, out_tex;
|
guint in_tex, out_tex;
|
||||||
GstVideoFrame out_frame;
|
GstVideoFrame out_frame;
|
||||||
gboolean ret, out_gl_mem;
|
gboolean ret;
|
||||||
GstVideoGLTextureUploadMeta *out_tex_upload_meta;
|
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);
|
filter_class = GST_GL_FILTER_GET_CLASS (filter);
|
||||||
|
|
||||||
if (!gst_gl_upload_perform_with_buffer (filter->upload, inbuf, &in_tex, NULL))
|
if (!gst_gl_upload_perform_with_buffer (filter->upload, inbuf, &in_tex, NULL))
|
||||||
return FALSE;
|
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,
|
if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
|
||||||
GST_MAP_WRITE | GST_MAP_GL)) {
|
out_map_flags)) {
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
goto inbuf_error;
|
goto inbuf_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_gl_mem = gst_is_gl_memory (out_frame.map[0].memory);
|
if (!to_download) {
|
||||||
out_tex_upload_meta = gst_buffer_get_video_gl_texture_upload_meta (outbuf);
|
|
||||||
|
|
||||||
if (out_gl_mem) {
|
|
||||||
out_tex = *(guint *) out_frame.data[0];
|
out_tex = *(guint *) out_frame.data[0];
|
||||||
} else {
|
} else {
|
||||||
GST_LOG ("Output Buffer does not contain correct memory, "
|
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);
|
filter->download = gst_gl_download_new (filter->context);
|
||||||
|
|
||||||
gst_gl_download_set_format (filter->download, &out_frame.info);
|
gst_gl_download_set_format (filter->download, &out_frame.info);
|
||||||
|
|
||||||
out_tex = filter->out_tex_id;
|
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);
|
g_assert (filter_class->filter_texture);
|
||||||
ret = filter_class->filter_texture (filter, in_tex, out_tex);
|
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,
|
if (!gst_gl_download_perform_with_data (filter->download, out_tex,
|
||||||
out_frame.data)) {
|
out_frame.data)) {
|
||||||
GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (filter, RESOURCE, NOT_FOUND,
|
||||||
|
|
|
@ -68,6 +68,9 @@ struct _GstGLFilter
|
||||||
|
|
||||||
GstVideoInfo in_info;
|
GstVideoInfo in_info;
|
||||||
GstVideoInfo out_info;
|
GstVideoInfo out_info;
|
||||||
|
|
||||||
|
GstCaps *out_caps;
|
||||||
|
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
GLuint depthbuffer;
|
GLuint depthbuffer;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue