GstBufferPool *pool;
const GstMemoryAllocator *allocator;
+ guint prefix;
+ guint alignment;
};
static GstElementClass *parent_class = NULL;
static gboolean gst_base_src_query (GstPad * pad, GstQuery * query);
+static gboolean gst_base_src_activate_pool (GstBaseSrc * basesrc,
+ gboolean active);
static gboolean gst_base_src_default_negotiate (GstBaseSrc * basesrc);
static gboolean gst_base_src_default_do_seek (GstBaseSrc * src,
GstSegment * segment);
}
static GstFlowReturn
+gst_base_src_alloc_buffer (GstBaseSrc * src, guint64 offset,
+ guint size, GstBuffer ** buffer)
+{
+ GstFlowReturn ret;
+ GstBaseSrcPrivate *priv = src->priv;
+
+ if (priv->pool) {
+ ret = gst_buffer_pool_acquire_buffer (priv->pool, buffer, NULL);
+ } else {
+ *buffer = gst_buffer_new_allocate (priv->allocator, size, priv->alignment);
+ if (G_UNLIKELY (*buffer == NULL))
+ goto alloc_failed;
+
+ ret = GST_FLOW_OK;
+ }
+ return ret;
+
+ /* ERRORS */
+alloc_failed:
+ {
+ GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
+ return GST_FLOW_ERROR;
+ }
+}
+
+static GstFlowReturn
gst_base_src_default_create (GstBaseSrc * src, guint64 offset,
guint size, GstBuffer ** buffer)
{
GstBaseSrcClass *bclass;
GstFlowReturn ret;
- GstBuffer *buf;
bclass = GST_BASE_SRC_GET_CLASS (src);
if (G_UNLIKELY (!bclass->fill))
goto no_function;
- buf = gst_buffer_new_allocate (NULL, size, 0);
- if (G_UNLIKELY (buf == NULL))
+ ret = gst_base_src_alloc_buffer (src, offset, size, buffer);
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
goto alloc_failed;
if (G_LIKELY (size > 0)) {
/* only call fill when there is a size */
- ret = bclass->fill (src, offset, size, buf);
-
+ ret = bclass->fill (src, offset, size, *buffer);
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto not_ok;
}
- *buffer = buf;
-
return GST_FLOW_OK;
/* ERRORS */
alloc_failed:
{
GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
- return GST_FLOW_ERROR;
+ return ret;
}
not_ok:
{
GST_DEBUG_OBJECT (src, "fill returned %d (%s)", ret,
gst_flow_get_name (ret));
- gst_buffer_unref (buf);
+ gst_buffer_unref (*buffer);
return ret;
}
}
g_atomic_int_set (&src->priv->pending_eos, TRUE);
GST_DEBUG_OBJECT (src, "EOS marked, calling unlock");
+
/* unlock the _create function so that we can check the pending_eos flag
* and we can do EOS. This will eventually release the LIVE_LOCK again so
* that we can grab it and stop the unlock again. We don't take the stream
* lock so that this operation is guaranteed to never block. */
+ gst_base_src_activate_pool (src, FALSE);
if (bclass->unlock)
bclass->unlock (src);
* lock is enough because that protects the create function. */
if (bclass->unlock_stop)
bclass->unlock_stop (src);
+ gst_base_src_activate_pool (src, TRUE);
GST_LIVE_UNLOCK (src);
result = TRUE;
static void
gst_base_src_set_allocation (GstBaseSrc * basesrc, GstBufferPool * pool,
- const GstMemoryAllocator * allocator)
+ const GstMemoryAllocator * allocator, guint prefix, guint alignment)
{
- if (basesrc->priv->pool)
- gst_object_unref (basesrc->priv->pool);
- basesrc->priv->pool = pool;
+ GstBufferPool *oldpool;
+ GstBaseSrcPrivate *priv = basesrc->priv;
+
+ GST_OBJECT_LOCK (basesrc);
+ if ((oldpool = priv->pool)) {
+ gst_object_unref (oldpool);
+ }
+ priv->pool = pool;
+
+ priv->allocator = allocator;
+
+ priv->prefix = prefix;
+ priv->alignment = alignment;
+ GST_OBJECT_UNLOCK (basesrc);
- basesrc->priv->allocator = allocator;
+ if (oldpool) {
+ gst_buffer_pool_set_active (oldpool, FALSE);
+ gst_object_unref (oldpool);
+ }
+}
+
+static gboolean
+gst_base_src_activate_pool (GstBaseSrc * basesrc, gboolean active)
+{
+ GstBaseSrcPrivate *priv = basesrc->priv;
+ GstBufferPool *pool;
+ gboolean res = TRUE;
+
+ GST_OBJECT_LOCK (basesrc);
+ if ((pool = priv->pool))
+ pool = gst_object_ref (pool);
+ GST_OBJECT_UNLOCK (basesrc);
+
+ if (pool) {
+ res = gst_buffer_pool_set_active (pool, active);
+ gst_object_unref (pool);
+ }
+ return res;
}
static gboolean
gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
alignment);
gst_buffer_pool_set_config (pool, config);
+
+ gst_buffer_pool_set_active (pool, TRUE);
}
- gst_base_src_set_allocation (basesrc, pool, allocator);
+ gst_base_src_set_allocation (basesrc, pool, allocator, prefix, alignment);
return result;
}
if (bclass->stop)
result = bclass->stop (basesrc);
+ gst_base_src_set_allocation (basesrc, NULL, NULL, 0, 0);
+
if (result)
GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
bclass = GST_BASE_SRC_GET_CLASS (basesrc);
if (flushing && unlock) {
+ gst_base_src_activate_pool (basesrc, FALSE);
/* unlock any subclasses, we need to do this before grabbing the
* LIVE_LOCK since we hold this lock before going into ::create. We pass an
* unlock to the params because of backwards compat (see seek handler)*/
/* signal the live source that it can start playing */
basesrc->live_running = live_play;
+ gst_base_src_activate_pool (basesrc, TRUE);
+
/* When unlocking drop all delayed events */
if (unlock) {
GST_OBJECT_LOCK (basesrc);
/* unlock subclasses locked in ::create, we only do this when we stop playing. */
if (!live_play) {
GST_DEBUG_OBJECT (basesrc, "unlock");
+ gst_base_src_activate_pool (basesrc, FALSE);
if (bclass->unlock)
bclass->unlock (basesrc);
}
/* clear our unlock request when going to PLAYING */
GST_DEBUG_OBJECT (basesrc, "unlock stop");
+ gst_base_src_activate_pool (basesrc, TRUE);
if (bclass->unlock_stop)
bclass->unlock_stop (basesrc);
static gboolean gst_push_src_query (GstBaseSrc * src, GstQuery * query);
static GstFlowReturn gst_push_src_create (GstBaseSrc * bsrc, guint64 offset,
guint length, GstBuffer ** ret);
+static GstFlowReturn gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset,
+ guint length, GstBuffer * ret);
static void
gst_push_src_class_init (GstPushSrcClass * klass)
GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_push_src_create);
+ gstbasesrc_class->fill = GST_DEBUG_FUNCPTR (gst_push_src_fill);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_push_src_query);
}
if (pclass->create)
fret = pclass->create (src, ret);
else
- fret = GST_FLOW_ERROR;
+ fret =
+ GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, ret);
+
+ return fret;
+}
+
+static GstFlowReturn
+gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset, guint length,
+ GstBuffer * ret)
+{
+ GstFlowReturn fret;
+ GstPushSrc *src;
+ GstPushSrcClass *pclass;
+
+ src = GST_PUSH_SRC (bsrc);
+ pclass = GST_PUSH_SRC_GET_CLASS (src);
+ if (pclass->fill)
+ fret = pclass->fill (src, ret);
+ else
+ fret = GST_BASE_SRC_CLASS (parent_class)->fill (bsrc, offset, length, ret);
return fret;
}