+static GstFlowReturn
+do_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
+ GstBufferPoolAcquireParams * params)
+{
+ GstBufferPoolPrivate *priv = pool->priv;
+ GstFlowReturn result;
+ gint cur_buffers, max_buffers;
+ GstBufferPoolClass *pclass;
+
+ pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+ if (G_UNLIKELY (!pclass->alloc_buffer))
+ goto no_function;
+
+ max_buffers = priv->max_buffers;
+
+ /* increment the allocation counter */
+ cur_buffers = g_atomic_int_add (&priv->cur_buffers, 1);
+ if (max_buffers && cur_buffers >= max_buffers)
+ goto max_reached;
+
+ result = pclass->alloc_buffer (pool, buffer, params);
+ if (G_UNLIKELY (result != GST_FLOW_OK))
+ goto alloc_failed;
+
+ /* lock all metadata and mark as pooled, we want this to remain on
+ * the buffer and we want to remove any other metadata that gets added
+ * later */
+ gst_buffer_foreach_meta (*buffer, mark_meta_pooled, pool);
+
+ /* un-tag memory, this is how we expect the buffer when it is
+ * released again */
+ GST_BUFFER_FLAG_UNSET (*buffer, GST_BUFFER_FLAG_TAG_MEMORY);
+
+ GST_LOG_OBJECT (pool, "allocated buffer %d/%d, %p", cur_buffers,
+ max_buffers, *buffer);
+
+ return result;
+
+ /* ERRORS */
+no_function:
+ {
+ GST_ERROR_OBJECT (pool, "no alloc function");
+ return GST_FLOW_NOT_SUPPORTED;
+ }
+max_reached:
+ {
+ GST_DEBUG_OBJECT (pool, "max buffers reached");
+ g_atomic_int_add (&priv->cur_buffers, -1);
+ return GST_FLOW_EOS;
+ }
+alloc_failed:
+ {
+ GST_WARNING_OBJECT (pool, "alloc function failed");
+ g_atomic_int_add (&priv->cur_buffers, -1);
+ return result;
+ }
+}
+
+/* the default implementation for preallocating the buffers in the pool */