static GstFlowReturn gst_wayland_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, GstBufferPoolAcquireParams * params) { GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL_CAST (pool); gint width, height, stride; gsize size; enum wl_shm_format format; gint offset; void *data; GstWlMeta *meta; width = GST_VIDEO_INFO_WIDTH (&self->info); height = GST_VIDEO_INFO_HEIGHT (&self->info); stride = GST_VIDEO_INFO_PLANE_STRIDE (&self->info, 0); size = GST_VIDEO_INFO_SIZE (&self->info); format = gst_video_format_to_wayland_format (GST_VIDEO_INFO_FORMAT (&self->info)); GST_DEBUG_OBJECT (self, "Allocating buffer of size %" G_GSSIZE_FORMAT " (%d x %d, stride %d), format %s", size, width, height, stride, gst_wayland_format_to_string (format)); /* try to reserve another memory block from the shm pool */ if (self->used + size > self->size) goto no_buffer; offset = self->used; self->used += size; data = ((gchar *) self->data) + offset; /* create buffer and its metadata object */ *buffer = gst_buffer_new (); meta = (GstWlMeta *) gst_buffer_add_meta (*buffer, GST_WL_META_INFO, NULL); meta->pool = self; meta->wbuffer = wl_shm_pool_create_buffer (self->wl_pool, offset, width, height, stride, format); meta->used_by_compositor = FALSE; /* configure listening to wl_buffer.release */ g_mutex_lock (&self->buffers_map_mutex); g_hash_table_insert (self->buffers_map, meta->wbuffer, *buffer); g_mutex_unlock (&self->buffers_map_mutex); wl_buffer_add_listener (meta->wbuffer, &buffer_listener, self); /* add the allocated memory on the GstBuffer */ gst_buffer_append_memory (*buffer, gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, data, size, 0, size, NULL, NULL)); return GST_FLOW_OK; /* ERROR */ no_buffer: { GST_WARNING_OBJECT (pool, "can't create buffer"); return GST_FLOW_ERROR; } }
static GstFlowReturn wayland_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer, GstBufferPoolAcquireParams * params) { GstWaylandBufferPool *w_pool = GST_WAYLAND_BUFFER_POOL_CAST (pool); GstBuffer *w_buffer; GstWlMeta *meta; w_buffer = gst_buffer_new (); meta = gst_buffer_add_wayland_meta (w_buffer, w_pool); if (meta == NULL) { gst_buffer_unref (w_buffer); goto no_buffer; } *buffer = w_buffer; return GST_FLOW_OK; /* ERROR */ no_buffer: { GST_WARNING_OBJECT (pool, "can't create buffer"); return GST_FLOW_ERROR; } }
static void gst_wayland_buffer_pool_finalize (GObject * object) { GstWaylandBufferPool *pool = GST_WAYLAND_BUFFER_POOL_CAST (object); gst_object_unref (pool->sink); G_OBJECT_CLASS (gst_wayland_buffer_pool_parent_class)->finalize (object); }
static void gst_wayland_buffer_pool_finalize (GObject * object) { GstWaylandBufferPool *pool = GST_WAYLAND_BUFFER_POOL_CAST (object); if (pool->wl_pool) gst_wayland_buffer_pool_stop (GST_BUFFER_POOL (pool)); g_mutex_clear (&pool->buffers_map_mutex); g_hash_table_unref (pool->buffers_map); g_object_unref (pool->display); G_OBJECT_CLASS (gst_wayland_buffer_pool_parent_class)->finalize (object); }
static gboolean wayland_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { GstWaylandBufferPool *wpool = GST_WAYLAND_BUFFER_POOL_CAST (pool); GstVideoInfo info; GstCaps *caps; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) goto wrong_config; if (caps == NULL) goto no_caps; /* now parse the caps from the config */ if (!gst_video_info_from_caps (&info, caps)) goto wrong_caps; GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, info.height, caps); /*Fixme: Enable metadata checking handling based on the config of pool */ wpool->caps = gst_caps_ref (caps); wpool->info = info; wpool->width = info.width; wpool->height = info.height; return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); /* ERRORS */ wrong_config: { GST_WARNING_OBJECT (pool, "invalid config"); return FALSE; } no_caps: { GST_WARNING_OBJECT (pool, "no caps in config"); return FALSE; } wrong_caps: { GST_WARNING_OBJECT (pool, "failed getting geometry from caps %" GST_PTR_FORMAT, caps); return FALSE; } }
static gboolean gst_wayland_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL_CAST (pool); GstCaps *caps; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) goto wrong_config; if (caps == NULL) goto no_caps; /* now parse the caps from the config */ if (!gst_video_info_from_caps (&self->info, caps)) goto wrong_caps; GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, GST_VIDEO_INFO_WIDTH (&self->info), GST_VIDEO_INFO_HEIGHT (&self->info), caps); /*Fixme: Enable metadata checking handling based on the config of pool */ return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); /* ERRORS */ wrong_config: { GST_WARNING_OBJECT (pool, "invalid config"); return FALSE; } no_caps: { GST_WARNING_OBJECT (pool, "no caps in config"); return FALSE; } wrong_caps: { GST_WARNING_OBJECT (pool, "failed getting geometry from caps %" GST_PTR_FORMAT, caps); return FALSE; } }