basetransform/basesrc: Do bufferpool configuration inside the default decide_allocati...
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Thu, 26 Apr 2012 15:26:50 +0000 (17:26 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 1 May 2012 11:32:41 +0000 (13:32 +0200)
This allows subclasses to override it, as is necessary for e.g. the
video-crop meta. It is now necessary that after decide_allocation()
there is always a allocator and a configured buffer pool inside the
query.

libs/gst/base/gstbasesrc.c
libs/gst/base/gstbasetransform.c

index fdd3a4d8d13bdb41e190725b152dea25355a8d1f..3bba3e65b5a9d173972014f08c7d25b044c7b2ea 100644 (file)
@@ -314,6 +314,8 @@ static GstFlowReturn gst_base_src_default_create (GstBaseSrc * basesrc,
     guint64 offset, guint size, GstBuffer ** buf);
 static GstFlowReturn gst_base_src_default_alloc (GstBaseSrc * basesrc,
     guint64 offset, guint size, GstBuffer ** buf);
+static gboolean gst_base_src_decide_allocation_default (GstBaseSrc * basesrc,
+    GstQuery * query);
 
 static gboolean gst_base_src_set_flushing (GstBaseSrc * basesrc,
     gboolean flushing, gboolean live_play, gboolean unlock, gboolean * playing);
@@ -385,6 +387,8 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
   klass->event = GST_DEBUG_FUNCPTR (gst_base_src_default_event);
   klass->create = GST_DEBUG_FUNCPTR (gst_base_src_default_create);
   klass->alloc = GST_DEBUG_FUNCPTR (gst_base_src_default_alloc);
+  klass->decide_allocation =
+      GST_DEBUG_FUNCPTR (gst_base_src_decide_allocation_default);
 
   /* Registering debug symbols for function pointers */
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_activate_mode);
@@ -2784,47 +2788,37 @@ gst_base_src_activate_pool (GstBaseSrc * basesrc, gboolean active)
   return res;
 }
 
+
 static gboolean
-gst_base_src_prepare_allocation (GstBaseSrc * basesrc, GstCaps * caps)
+gst_base_src_decide_allocation_default (GstBaseSrc * basesrc, GstQuery * query)
 {
-  GstBaseSrcClass *bclass;
-  gboolean result = TRUE;
-  GstQuery *query;
-  GstBufferPool *pool = NULL;
-  GstAllocator *allocator = NULL;
+  GstCaps *outcaps;
+  GstBufferPool *pool;
   guint size, min, max;
+  GstAllocator *allocator;
   GstAllocationParams params;
+  GstStructure *config;
+  gboolean update_allocator;
 
-  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);
-  if (!gst_pad_peer_query (basesrc->srcpad, query)) {
-    /* not a problem, just debug a little */
-    GST_DEBUG_OBJECT (basesrc, "peer ALLOCATION query failed");
-  }
-
-  if (G_LIKELY (bclass->decide_allocation))
-    result = bclass->decide_allocation (basesrc, query);
-
-  GST_DEBUG_OBJECT (basesrc, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, result,
-      query);
+  gst_query_parse_allocation (query, &outcaps, NULL);
 
+  /* we got configuration from our peer or the decide_allocation method,
+   * parse them */
   if (gst_query_get_n_allocation_params (query) > 0) {
     /* try the allocator */
     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
+    update_allocator = TRUE;
   } else {
     allocator = NULL;
     gst_allocation_params_init (&params);
+    update_allocator = FALSE;
   }
 
   if (gst_query_get_n_allocation_pools (query) > 0) {
     gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
 
     if (pool == NULL) {
-      /* no pool, just parameters, we can make our own */
+      /* no pool, we can make our own */
       GST_DEBUG_OBJECT (basesrc, "no pool, making new pool");
       pool = gst_buffer_pool_new ();
     }
@@ -2835,20 +2829,83 @@ gst_base_src_prepare_allocation (GstBaseSrc * basesrc, GstCaps * caps)
 
   /* now configure */
   if (pool) {
-    GstStructure *config;
-
     config = gst_buffer_pool_get_config (pool);
-    gst_buffer_pool_config_set_params (config, caps, size, min, max);
+    gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
     gst_buffer_pool_config_set_allocator (config, allocator, &params);
     gst_buffer_pool_set_config (pool, config);
   }
 
+  if (update_allocator)
+    gst_query_set_nth_allocation_param (query, 0, allocator, &params);
+  else
+    gst_query_add_allocation_param (query, allocator, &params);
+  if (allocator)
+    gst_allocator_unref (allocator);
+
+  if (pool) {
+    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
+    gst_object_unref (pool);
+  }
+
+  return TRUE;
+}
+
+static gboolean
+gst_base_src_prepare_allocation (GstBaseSrc * basesrc, GstCaps * caps)
+{
+  GstBaseSrcClass *bclass;
+  gboolean result = TRUE;
+  GstQuery *query;
+  GstBufferPool *pool = NULL;
+  GstAllocator *allocator = NULL;
+  GstAllocationParams params;
+
+  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);
+  if (!gst_pad_peer_query (basesrc->srcpad, query)) {
+    /* not a problem, just debug a little */
+    GST_DEBUG_OBJECT (basesrc, "peer ALLOCATION query failed");
+  }
+
+  g_assert (bclass->decide_allocation != NULL);
+  result = bclass->decide_allocation (basesrc, query);
+
+  GST_DEBUG_OBJECT (basesrc, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, result,
+      query);
+
+  if (!result)
+    goto no_decide_allocation;
+
+  /* we got configuration from our peer or the decide_allocation method,
+   * parse them */
+  if (gst_query_get_n_allocation_params (query) > 0) {
+    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
+  } else {
+    allocator = NULL;
+    gst_allocation_params_init (&params);
+  }
+
+  if (gst_query_get_n_allocation_pools (query) > 0)
+    gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
+
   result = gst_base_src_set_allocation (basesrc, pool, allocator, &params);
 
   gst_query_unref (query);
 
   return result;
 
+  /* Errors */
+no_decide_allocation:
+  {
+    GST_WARNING_OBJECT (basesrc, "Subclass failed to decide allocation");
+    gst_query_unref (query);
+
+    return result;
+  }
 }
 
 /* default negotiation code.
index b5e30e1a03734d93aeb89e05e631c3fa493cf96b..3941392decec439cb43e85d4e3fc5af0ddbe3276 100644 (file)
@@ -802,6 +802,13 @@ gst_base_transform_default_decide_allocation (GstBaseTransform * trans,
 {
   guint i, n_metas;
   GstBaseTransformClass *klass;
+  GstCaps *outcaps;
+  GstBufferPool *pool;
+  guint size, min, max;
+  GstAllocator *allocator;
+  GstAllocationParams params;
+  GstStructure *config;
+  gboolean update_allocator;
 
   klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
@@ -836,6 +843,54 @@ gst_base_transform_default_decide_allocation (GstBaseTransform * trans,
       n_metas--;
     }
   }
+
+  gst_query_parse_allocation (query, &outcaps, NULL);
+
+  /* we got configuration from our peer or the decide_allocation method,
+   * parse them */
+  if (gst_query_get_n_allocation_params (query) > 0) {
+    /* try the allocator */
+    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
+    update_allocator = TRUE;
+  } else {
+    allocator = NULL;
+    gst_allocation_params_init (&params);
+    update_allocator = FALSE;
+  }
+
+  if (gst_query_get_n_allocation_pools (query) > 0) {
+    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
+
+    if (pool == NULL) {
+      /* no pool, we can make our own */
+      GST_DEBUG_OBJECT (trans, "no pool, making new pool");
+      pool = gst_buffer_pool_new ();
+    }
+  } else {
+    pool = NULL;
+    size = min = max = 0;
+  }
+
+  /* now configure */
+  if (pool) {
+    config = gst_buffer_pool_get_config (pool);
+    gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
+    gst_buffer_pool_config_set_allocator (config, allocator, &params);
+    gst_buffer_pool_set_config (pool, config);
+  }
+
+  if (update_allocator)
+    gst_query_set_nth_allocation_param (query, 0, allocator, &params);
+  else
+    gst_query_add_allocation_param (query, allocator, &params);
+  if (allocator)
+    gst_allocator_unref (allocator);
+
+  if (pool) {
+    gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max);
+    gst_object_unref (pool);
+  }
+
   return TRUE;
 }
 
@@ -844,8 +899,7 @@ gst_base_transform_do_bufferpool (GstBaseTransform * trans, GstCaps * outcaps)
 {
   GstQuery *query;
   gboolean result = TRUE;
-  GstBufferPool *pool;
-  guint size, min, max;
+  GstBufferPool *pool = NULL;
   GstBaseTransformClass *klass;
   GstBaseTransformPrivate *priv = trans->priv;
   GstAllocator *allocator;
@@ -882,43 +936,28 @@ gst_base_transform_do_bufferpool (GstBaseTransform * trans, GstCaps * outcaps)
   klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   GST_DEBUG_OBJECT (trans, "calling decide_allocation");
-  if (G_LIKELY (klass->decide_allocation))
-    if ((result = klass->decide_allocation (trans, query)) == FALSE)
-      goto no_decide_allocation;
+  g_assert (klass->decide_allocation != NULL);
+  result = klass->decide_allocation (trans, query);
+
+  GST_DEBUG_OBJECT (trans, "ALLOCATION (%d) params: %" GST_PTR_FORMAT, result,
+      query);
+
+  if (!result)
+    goto no_decide_allocation;
 
   /* we got configuration from our peer or the decide_allocation method,
    * parse them */
   if (gst_query_get_n_allocation_params (query) > 0) {
-    /* try the allocator */
     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
   } else {
     allocator = NULL;
     gst_allocation_params_init (&params);
   }
 
-  if (gst_query_get_n_allocation_pools (query) > 0) {
-    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
+  if (gst_query_get_n_allocation_pools (query) > 0)
+    gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
 
-    if (pool == NULL) {
-      /* no pool, just parameters, we can make our own */
-      GST_DEBUG_OBJECT (trans, "no pool, making new pool");
-      pool = gst_buffer_pool_new ();
-    }
-  } else {
-    pool = NULL;
-    size = min = max = 0;
-  }
-
-  /* now configure */
-  if (pool) {
-    GstStructure *config;
-
-    config = gst_buffer_pool_get_config (pool);
-    gst_buffer_pool_config_set_params (config, outcaps, size, min, max);
-    gst_buffer_pool_config_set_allocator (config, allocator, &params);
-    gst_buffer_pool_set_config (pool, config);
-  }
-  /* and store */
+  /* now store */
   result =
       gst_base_transform_set_allocation (trans, pool, allocator, &params,
       query);