From 3977991c9d3dc390a6a38903e965c312bc20c2c6 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 13 Jun 2011 10:19:30 +0200 Subject: [PATCH] basesrc: negotiate allocation Add vmethod to configure allocation methods. Remove some unused variables --- libs/gst/base/gstbasesrc.c | 74 ++++++++++++++++++++++++++++++++++++-- libs/gst/base/gstbasesrc.h | 16 ++++----- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/libs/gst/base/gstbasesrc.c b/libs/gst/base/gstbasesrc.c index 58e28bd2de..745d925f31 100644 --- a/libs/gst/base/gstbasesrc.c +++ b/libs/gst/base/gstbasesrc.c @@ -238,6 +238,9 @@ struct _GstBaseSrcPrivate gboolean qos_enabled; gdouble proportion; GstClockTime earliest_time; + + GstBufferPool *pool; + const GstMemoryAllocator *allocator; }; static GstElementClass *parent_class = NULL; @@ -393,7 +396,6 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class) basesrc->num_buffers_left = -1; basesrc->can_activate_push = TRUE; - basesrc->pad_mode = GST_ACTIVATE_NONE; pad_template = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src"); @@ -2567,6 +2569,67 @@ null_buffer: } } +static void +gst_base_src_set_allocation (GstBaseSrc * basesrc, GstBufferPool * pool, + const GstMemoryAllocator * allocator) +{ + if (basesrc->priv->pool) + gst_object_unref (basesrc->priv->pool); + basesrc->priv->pool = pool; + + basesrc->priv->allocator = allocator; +} + +static gboolean +gst_base_src_prepare_allocation (GstBaseSrc * basesrc, GstCaps * caps) +{ + GstBaseSrcClass *bclass; + gboolean result = TRUE; + GstQuery *query; + GstBufferPool *pool = NULL; + const GstMemoryAllocator *allocator = NULL; + guint size, min, max, prefix, alignment; + + bclass = GST_BASE_SRC_GET_CLASS (basesrc); + + /* make query and let peer pad answer, we don't really care if it worked or + * not, if it failed, the allocation query would contain defaults and the + * subclass would then set better values if needed */ + query = gst_query_new_allocation (caps, TRUE); + gst_pad_peer_query (basesrc->srcpad, query); + + if (G_LIKELY (bclass->setup_allocation)) + result = bclass->setup_allocation (basesrc, query); + + gst_query_parse_allocation_params (query, &size, &min, &max, &prefix, + &alignment, &pool); + + if (size == 0) { + const gchar *mem = NULL; + + /* no size, we have variable size buffers */ + if (gst_query_get_n_allocation_memories (query) > 0) { + mem = gst_query_parse_nth_allocation_memory (query, 0); + } + allocator = gst_memory_allocator_find (mem); + } else if (pool == NULL) { + /* fixed size, we can use a bufferpool */ + GstStructure *config; + + /* we did not get a pool, make one ourselves then */ + pool = gst_buffer_pool_new (); + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set (config, caps, size, min, max, prefix, + alignment); + gst_buffer_pool_set_config (pool, config); + } + + gst_base_src_set_allocation (basesrc, pool, allocator); + + return result; +} + /* default negotiation code. * * Take intersection between src and sink pads, take first @@ -2654,9 +2717,16 @@ gst_base_src_negotiate (GstBaseSrc * basesrc) bclass = GST_BASE_SRC_GET_CLASS (basesrc); - if (bclass->negotiate) + if (G_LIKELY (bclass->negotiate)) result = bclass->negotiate (basesrc); + if (G_LIKELY (result)) { + GstCaps *caps; + + caps = gst_pad_get_current_caps (basesrc->srcpad); + + result = gst_base_src_prepare_allocation (basesrc, caps); + } return result; } diff --git a/libs/gst/base/gstbasesrc.h b/libs/gst/base/gstbasesrc.h index c44b38ba57..529c79712f 100644 --- a/libs/gst/base/gstbasesrc.h +++ b/libs/gst/base/gstbasesrc.h @@ -83,21 +83,15 @@ struct _GstBaseSrc { /* MT-protected (with LOCK) */ guint blocksize; /* size of buffers when operating push based */ gboolean can_activate_push; /* some scheduling properties */ - GstActivateMode pad_mode; - gboolean seekable; /* not used anymore */ gboolean random_access; GstClockID clock_id; /* for syncing */ - GstClockTime end_time; /* MT-protected (with STREAM_LOCK *and* OBJECT_LOCK) */ GstSegment segment; /* MT-protected (with STREAM_LOCK) */ gboolean need_newsegment; - guint64 offset; /* current offset in the resource, unused */ - guint64 size; /* total size of the resource, unused */ - gint num_buffers; gint num_buffers_left; @@ -115,10 +109,10 @@ struct _GstBaseSrc { * GstBaseSrcClass: * @parent_class: Element parent class * @get_caps: Called to get the caps to report - * @set_caps: Notify subclass of changed output caps * @negotiate: Negotiated the caps with the peer. * @fixate: Called during negotiation if caps need fixating. Implement instead of * setting a fixate function on the source pad. + * @set_caps: Notify subclass of changed output caps * @start: Start processing. Subclasses should open resources and prepare * to produce data. * @stop: Stop processing. Subclasses should use this to close resources. @@ -165,13 +159,15 @@ struct _GstBaseSrcClass { /* get caps from subclass */ GstCaps* (*get_caps) (GstBaseSrc *src, GstCaps *filter); - /* notify the subclass of new caps */ - gboolean (*set_caps) (GstBaseSrc *src, GstCaps *caps); - /* decide on caps */ gboolean (*negotiate) (GstBaseSrc *src); /* called if, in negotiation, caps need fixating */ void (*fixate) (GstBaseSrc *src, GstCaps *caps); + /* notify the subclass of new caps */ + gboolean (*set_caps) (GstBaseSrc *src, GstCaps *caps); + + /* setup allocation query */ + gboolean (*setup_allocation) (GstBaseSrc *src, GstQuery *query); /* start and stop processing, ideal for opening/closing the resource */ gboolean (*start) (GstBaseSrc *src);