basesrc: negotiate allocation
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 13 Jun 2011 08:19:30 +0000 (10:19 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 13 Jun 2011 08:21:53 +0000 (10:21 +0200)
Add vmethod to configure allocation methods.
Remove some unused variables

libs/gst/base/gstbasesrc.c
libs/gst/base/gstbasesrc.h

index 58e28bd..745d925 100644 (file)
@@ -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;
 }
 
index c44b38b..529c797 100644 (file)
@@ -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);