mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +00:00
[518/906] GstGLImageSink: add propose_allocation impl and use GstGLMeta
make use of GstGLMeta and GstGLMemory
This commit is contained in:
parent
69997e311f
commit
4d7bb47b75
2 changed files with 115 additions and 28 deletions
|
@ -106,6 +106,8 @@ static void gst_glimage_sink_get_times (GstBaseSink * bsink, GstBuffer * buf,
|
||||||
static gboolean gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
|
static gboolean gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
|
||||||
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink,
|
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink,
|
||||||
GstBuffer * buf);
|
GstBuffer * buf);
|
||||||
|
static gboolean gst_glimage_sink_propose_allocation (GstBaseSink * bsink,
|
||||||
|
GstQuery * query);
|
||||||
|
|
||||||
static void gst_glimage_sink_video_overlay_init (GstVideoOverlayInterface *
|
static void gst_glimage_sink_video_overlay_init (GstVideoOverlayInterface *
|
||||||
iface);
|
iface);
|
||||||
|
@ -201,6 +203,7 @@ gst_glimage_sink_class_init (GstGLImageSinkClass * klass)
|
||||||
gstbasesink_class->get_times = gst_glimage_sink_get_times;
|
gstbasesink_class->get_times = gst_glimage_sink_get_times;
|
||||||
gstbasesink_class->preroll = gst_glimage_sink_render;
|
gstbasesink_class->preroll = gst_glimage_sink_render;
|
||||||
gstbasesink_class->render = gst_glimage_sink_render;
|
gstbasesink_class->render = gst_glimage_sink_render;
|
||||||
|
gstbasesink_class->propose_allocation = gst_glimage_sink_propose_allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -556,28 +559,17 @@ static GstFlowReturn
|
||||||
gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstGLImageSink *glimage_sink;
|
GstGLImageSink *glimage_sink;
|
||||||
|
GstGLMeta *gl_meta;
|
||||||
|
GstVideoMeta *v_meta;
|
||||||
|
|
||||||
glimage_sink = GST_GLIMAGE_SINK (bsink);
|
glimage_sink = GST_GLIMAGE_SINK (bsink);
|
||||||
|
|
||||||
/* FIXME: implement using GstGLMeta */
|
if (!(v_meta = gst_buffer_get_video_meta (buf)))
|
||||||
//is gl
|
goto no_video_meta;
|
||||||
/*if (glimage_sink->is_gl) {
|
|
||||||
//increment gl buffer ref before storage
|
|
||||||
gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf));
|
|
||||||
}
|
|
||||||
//is not gl
|
|
||||||
else {
|
|
||||||
//blocking call
|
|
||||||
gl_buffer = gst_gl_buffer_new (glimage_sink->display,
|
|
||||||
glimage_sink->width, glimage_sink->height);
|
|
||||||
|
|
||||||
//blocking call
|
if (!(gl_meta = gst_buffer_get_gl_meta (buf)))
|
||||||
gst_gl_display_do_upload (glimage_sink->display, gl_buffer->texture,
|
goto no_gl_meta;
|
||||||
glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf));
|
|
||||||
|
|
||||||
//gl_buffer is created in this block, so the gl buffer is already referenced
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (glimage_sink->window_id != glimage_sink->new_window_id) {
|
if (glimage_sink->window_id != glimage_sink->new_window_id) {
|
||||||
glimage_sink->window_id = glimage_sink->new_window_id;
|
glimage_sink->window_id = glimage_sink->new_window_id;
|
||||||
gst_gl_display_set_window_id (glimage_sink->display,
|
gst_gl_display_set_window_id (glimage_sink->display,
|
||||||
|
@ -588,21 +580,36 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
|
||||||
gst_buffer_unref (glimage_sink->stored_buffer);
|
gst_buffer_unref (glimage_sink->stored_buffer);
|
||||||
}
|
}
|
||||||
//store current buffer
|
//store current buffer
|
||||||
glimage_sink->stored_buffer = buf;
|
glimage_sink->stored_buffer = gst_buffer_ref (buf);
|
||||||
/*
|
|
||||||
//redisplay opengl scene
|
//redisplay opengl scene
|
||||||
if (gl_buffer->texture &&
|
if (!gst_gl_display_redisplay (glimage_sink->display,
|
||||||
gst_gl_display_redisplay (glimage_sink->display,
|
gl_meta->memory->tex_id, v_meta->width, v_meta->height,
|
||||||
gl_buffer->texture, gl_buffer->width, gl_buffer->height,
|
|
||||||
glimage_sink->window_width, glimage_sink->window_height,
|
glimage_sink->window_width, glimage_sink->window_height,
|
||||||
glimage_sink->keep_aspect_ratio))
|
glimage_sink->keep_aspect_ratio))
|
||||||
return GST_FLOW_OK;
|
goto redisplay_failed;
|
||||||
else {
|
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_video_meta:
|
||||||
|
{
|
||||||
|
GST_ERROR ("Buffer %" GST_PTR_FORMAT " is missing required GstVideoMeta");
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
no_gl_meta:
|
||||||
|
{
|
||||||
|
GST_ERROR ("Buffer %" GST_PTR_FORMAT " is missing required GstGLMeta");
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
redisplay_failed:
|
||||||
|
{
|
||||||
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
|
GST_ELEMENT_ERROR (glimage_sink, RESOURCE, NOT_FOUND,
|
||||||
GST_GL_DISPLAY_ERR_MSG (glimage_sink->display), (NULL));
|
GST_GL_DISPLAY_ERR_MSG (glimage_sink->display), (NULL));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}*/
|
}
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -646,3 +653,82 @@ gst_glimage_sink_expose (GstVideoOverlay * overlay)
|
||||||
glimage_sink->keep_aspect_ratio);
|
glimage_sink->keep_aspect_ratio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_glimage_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
||||||
|
{
|
||||||
|
GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (bsink);
|
||||||
|
GstBufferPool *pool;
|
||||||
|
GstStructure *config;
|
||||||
|
GstCaps *caps;
|
||||||
|
guint size;
|
||||||
|
gboolean need_pool;
|
||||||
|
|
||||||
|
gst_query_parse_allocation (query, &caps, &need_pool);
|
||||||
|
|
||||||
|
if (caps == NULL)
|
||||||
|
goto no_caps;
|
||||||
|
|
||||||
|
if ((pool = glimage_sink->pool))
|
||||||
|
gst_object_ref (pool);
|
||||||
|
|
||||||
|
if (pool != NULL) {
|
||||||
|
GstCaps *pcaps;
|
||||||
|
|
||||||
|
/* we had a pool, check caps */
|
||||||
|
GST_DEBUG_OBJECT (glimage_sink, "check existing pool caps");
|
||||||
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL);
|
||||||
|
|
||||||
|
if (!gst_caps_is_equal (caps, pcaps)) {
|
||||||
|
GST_DEBUG_OBJECT (glimage_sink, "pool has different caps");
|
||||||
|
/* different caps, we can't use this pool */
|
||||||
|
gst_object_unref (pool);
|
||||||
|
pool = NULL;
|
||||||
|
}
|
||||||
|
gst_structure_free (config);
|
||||||
|
}
|
||||||
|
if (pool == NULL && need_pool) {
|
||||||
|
GstVideoInfo info;
|
||||||
|
|
||||||
|
if (!gst_video_info_from_caps (&info, caps))
|
||||||
|
goto invalid_caps;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (glimage_sink, "create new pool");
|
||||||
|
pool = gst_gl_buffer_pool_new (glimage_sink->display);
|
||||||
|
|
||||||
|
/* the normal size of a frame */
|
||||||
|
size = info.size;
|
||||||
|
|
||||||
|
config = gst_buffer_pool_get_config (pool);
|
||||||
|
gst_buffer_pool_config_set_params (config, caps, size, 0, 0);
|
||||||
|
if (!gst_buffer_pool_set_config (pool, config))
|
||||||
|
goto config_failed;
|
||||||
|
}
|
||||||
|
/* we need at least 2 buffer because we hold on to the last one */
|
||||||
|
gst_query_add_allocation_pool (query, pool, size, 2, 0);
|
||||||
|
|
||||||
|
/* we also support various metadata */
|
||||||
|
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE);
|
||||||
|
|
||||||
|
gst_object_unref (pool);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
no_caps:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (bsink, "no caps specified");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
invalid_caps:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (bsink, "invalid caps specified");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
config_failed:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (bsink, "failed setting config");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <gst/video/gstvideosink.h>
|
#include <gst/video/gstvideosink.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
|
||||||
#include "gstglmeta.h"
|
#include "gstglbufferpool.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
@ -63,7 +63,6 @@ struct _GstGLImageSink
|
||||||
gint height;
|
gint height;
|
||||||
gint window_width;
|
gint window_width;
|
||||||
gint window_height;
|
gint window_height;
|
||||||
gboolean is_gl;
|
|
||||||
gint fps_n, fps_d;
|
gint fps_n, fps_d;
|
||||||
gint par_n, par_d;
|
gint par_n, par_d;
|
||||||
|
|
||||||
|
@ -76,6 +75,8 @@ struct _GstGLImageSink
|
||||||
|
|
||||||
gboolean keep_aspect_ratio;
|
gboolean keep_aspect_ratio;
|
||||||
GValue *par;
|
GValue *par;
|
||||||
|
|
||||||
|
GstBufferPool *pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGLImageSinkClass
|
struct _GstGLImageSinkClass
|
||||||
|
|
Loading…
Reference in a new issue