mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
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:
parent
c0ca9bc422
commit
d16583d771
1 changed files with 93 additions and 31 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue