eglglessink: add GstEGLImageBufferPoolSendBlockingAllocate callback

The goal here is to prepare GstEGLBufferPool to be moved into
gstegl lib. So it has to not depend on 'gst_eglglessink_queue_object'
This commit is contained in:
Julien Isorce 2013-09-04 10:52:51 +01:00
parent c0ca9bc422
commit d16583d771

View file

@ -213,8 +213,9 @@ static GstFlowReturn gst_eglglessink_render (GstEglGlesSink * sink);
static GstFlowReturn gst_eglglessink_queue_object (GstEglGlesSink * sink, static GstFlowReturn gst_eglglessink_queue_object (GstEglGlesSink * sink,
GstMiniObject * obj); GstMiniObject * obj);
static inline gboolean egl_init (GstEglGlesSink * eglglessink); static inline gboolean egl_init (GstEglGlesSink * eglglessink);
static GstBufferPool *gst_egl_image_buffer_pool_new (GstEglGlesSink *
eglglessink, GstEGLDisplay * display); typedef GstBuffer *(*GstEGLImageBufferPoolSendBlockingAllocate) (GstBufferPool *
pool, gpointer data);
/* EGLImage memory, buffer pool, etc */ /* EGLImage memory, buffer pool, etc */
typedef struct typedef struct
@ -228,6 +229,10 @@ typedef struct
gboolean add_metavideo; gboolean add_metavideo;
gboolean want_eglimage; gboolean want_eglimage;
GstEGLDisplay *display; GstEGLDisplay *display;
GstEGLImageBufferPoolSendBlockingAllocate send_blocking_allocate_func;
gpointer send_blocking_allocate_data;
GDestroyNotify send_blocking_allocate_destroy;
} GstEGLImageBufferPool; } GstEGLImageBufferPool;
typedef GstVideoBufferPoolClass GstEGLImageBufferPoolClass; typedef GstVideoBufferPoolClass GstEGLImageBufferPoolClass;
@ -239,6 +244,70 @@ GType gst_egl_image_buffer_pool_get_type (void);
G_DEFINE_TYPE (GstEGLImageBufferPool, gst_egl_image_buffer_pool, G_DEFINE_TYPE (GstEGLImageBufferPool, gst_egl_image_buffer_pool,
GST_TYPE_VIDEO_BUFFER_POOL); GST_TYPE_VIDEO_BUFFER_POOL);
static GstBufferPool *gst_egl_image_buffer_pool_new (GstEglGlesSink *
eglglessink, GstEGLDisplay * display,
GstEGLImageBufferPoolSendBlockingAllocate blocking_allocate_func,
gpointer blocking_allocate_data, GDestroyNotify destroy_func);
static void
gst_egl_image_buffer_pool_get_video_infos (GstEGLImageBufferPool * pool,
GstVideoFormat * format, gint * width, gint * height)
{
g_return_if_fail (pool != NULL);
if (format)
*format = pool->info.finfo->format;
if (width)
*width = pool->info.width;
if (height)
*height = pool->info.height;
}
static GstBuffer *
gst_eglglessink_egl_image_buffer_pool_send_blocking (GstBufferPool * bpool,
gpointer data)
{
GstFlowReturn ret = GST_FLOW_OK;
GstQuery *query = NULL;
GstStructure *s = NULL;
const GValue *v = NULL;
GstBuffer *buffer = NULL;
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
gint width = 0;
gint height = 0;
GstEGLImageBufferPool *pool = GST_EGL_IMAGE_BUFFER_POOL (bpool);
GstEglGlesSink *eglglessink = GST_EGLGLESSINK (data);
gst_egl_image_buffer_pool_get_video_infos (pool, &format, &width, &height);
s = gst_structure_new ("eglglessink-allocate-eglimage",
"format", GST_TYPE_VIDEO_FORMAT, format,
"width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL);
query = gst_query_new_custom (GST_QUERY_CUSTOM, s);
ret =
gst_eglglessink_queue_object (eglglessink, GST_MINI_OBJECT_CAST (query));
if (ret == GST_FLOW_OK && gst_structure_has_field (s, "buffer")) {
v = gst_structure_get_value (s, "buffer");
buffer = GST_BUFFER_CAST (g_value_get_pointer (v));
}
gst_query_unref (query);
return buffer;
}
static void
gst_eglglessink_egl_image_buffer_pool_on_destroy (gpointer data)
{
GstEglGlesSink *eglglessink = GST_EGLGLESSINK (data);
gst_object_unref (eglglessink);
}
static const gchar ** static const gchar **
gst_egl_image_buffer_pool_get_options (GstBufferPool * bpool) gst_egl_image_buffer_pool_get_options (GstBufferPool * bpool)
{ {
@ -326,33 +395,10 @@ gst_egl_image_buffer_pool_alloc_buffer (GstBufferPool * bpool,
case GST_VIDEO_FORMAT_Y444: case GST_VIDEO_FORMAT_Y444:
case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_Y42B:
case GST_VIDEO_FORMAT_Y41B:{ case GST_VIDEO_FORMAT_Y41B:{
GstFlowReturn ret;
GstQuery *query;
GstStructure *s;
const GValue *v;
s = gst_structure_new ("eglglessink-allocate-eglimage", if (pool->send_blocking_allocate_func)
"format", GST_TYPE_VIDEO_FORMAT, pool->info.finfo->format, *buffer = pool->send_blocking_allocate_func (bpool,
"width", G_TYPE_INT, pool->info.width, pool->send_blocking_allocate_data);
"height", G_TYPE_INT, pool->info.height, NULL);
query = gst_query_new_custom (GST_QUERY_CUSTOM, s);
ret =
gst_eglglessink_queue_object (pool->sink,
GST_MINI_OBJECT_CAST (query));
if (ret != GST_FLOW_OK || !gst_structure_has_field (s, "buffer")) {
GST_WARNING ("Fallback memory allocation");
gst_query_unref (query);
return
GST_BUFFER_POOL_CLASS
(gst_egl_image_buffer_pool_parent_class)->alloc_buffer (bpool,
buffer, params);
}
v = gst_structure_get_value (s, "buffer");
*buffer = GST_BUFFER_CAST (g_value_get_pointer (v));
gst_query_unref (query);
if (!*buffer) { if (!*buffer) {
GST_WARNING ("Fallback memory allocation"); GST_WARNING ("Fallback memory allocation");
@ -426,6 +472,11 @@ gst_egl_image_buffer_pool_finalize (GObject * object)
gst_egl_display_unref (pool->display); gst_egl_display_unref (pool->display);
pool->display = NULL; pool->display = NULL;
if (pool->send_blocking_allocate_destroy)
pool->send_blocking_allocate_destroy (pool->send_blocking_allocate_data);
pool->send_blocking_allocate_destroy = NULL;
pool->send_blocking_allocate_data = NULL;
G_OBJECT_CLASS (gst_egl_image_buffer_pool_parent_class)->finalize (object); G_OBJECT_CLASS (gst_egl_image_buffer_pool_parent_class)->finalize (object);
} }
@ -1996,7 +2047,10 @@ gst_eglglessink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
GST_DEBUG_OBJECT (eglglessink, "create new pool"); GST_DEBUG_OBJECT (eglglessink, "create new pool");
pool = pool =
gst_egl_image_buffer_pool_new (eglglessink, gst_egl_image_buffer_pool_new (eglglessink,
eglglessink->egl_context->display); eglglessink->egl_context->display,
gst_eglglessink_egl_image_buffer_pool_send_blocking,
gst_object_ref (eglglessink),
gst_eglglessink_egl_image_buffer_pool_on_destroy);
/* the normal size of a frame */ /* the normal size of a frame */
size = info.size; size = info.size;
@ -2148,7 +2202,10 @@ gst_eglglessink_setcaps (GstBaseSink * bsink, GstCaps * caps)
newpool = newpool =
gst_egl_image_buffer_pool_new (eglglessink, gst_egl_image_buffer_pool_new (eglglessink,
eglglessink->egl_context->display); eglglessink->egl_context->display,
gst_eglglessink_egl_image_buffer_pool_send_blocking,
gst_object_ref (eglglessink),
gst_eglglessink_egl_image_buffer_pool_on_destroy);
config = gst_buffer_pool_get_config (newpool); config = gst_buffer_pool_get_config (newpool);
/* we need at least 2 buffer because we hold on to the last one */ /* we need at least 2 buffer because we hold on to the last one */
gst_buffer_pool_config_set_params (config, caps, info.size, 2, 0); gst_buffer_pool_config_set_params (config, caps, info.size, 2, 0);
@ -2420,13 +2477,18 @@ gst_eglglessink_init (GstEglGlesSink * eglglessink)
static GstBufferPool * static GstBufferPool *
gst_egl_image_buffer_pool_new (GstEglGlesSink * gst_egl_image_buffer_pool_new (GstEglGlesSink *
eglglessink, GstEGLDisplay * display) eglglessink, GstEGLDisplay * display,
GstEGLImageBufferPoolSendBlockingAllocate blocking_allocate_func,
gpointer blocking_allocate_data, GDestroyNotify destroy_func)
{ {
GstEGLImageBufferPool *pool; GstEGLImageBufferPool *pool;
pool = g_object_new (gst_egl_image_buffer_pool_get_type (), NULL); pool = g_object_new (gst_egl_image_buffer_pool_get_type (), NULL);
pool->display = gst_egl_display_ref (display); pool->display = gst_egl_display_ref (display);
pool->sink = gst_object_ref (eglglessink); pool->sink = gst_object_ref (eglglessink);
pool->send_blocking_allocate_func = blocking_allocate_func;
pool->send_blocking_allocate_data = blocking_allocate_data;
pool->send_blocking_allocate_destroy = destroy_func;
return (GstBufferPool *) pool; return (GstBufferPool *) pool;
} }