Ensure all access to v4l2object->pool imply taking a lock and a hard ref on the pool
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3481>
}
gboolean
-gst_v4l2_buffer_pool_orphan (GstBufferPool ** bpool)
+gst_v4l2_buffer_pool_orphan (GstV4l2Object * v4l2object)
{
- GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (*bpool);
+ GstBufferPool *bpool = gst_v4l2_object_get_buffer_pool (v4l2object);
+ GstV4l2BufferPool *pool;
gboolean ret;
- g_return_val_if_fail (pool->orphaned == FALSE, FALSE);
+ g_return_val_if_fail (bpool, FALSE);
- if (!GST_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS (pool->vallocator))
- return FALSE;
+ pool = GST_V4L2_BUFFER_POOL (bpool);
- if (g_getenv ("GST_V4L2_FORCE_DRAIN"))
+ if (pool->orphaned != FALSE
+ || !GST_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS (pool->vallocator)
+ || g_getenv ("GST_V4L2_FORCE_DRAIN")) {
+ gst_object_unref (bpool);
return FALSE;
+ }
GST_DEBUG_OBJECT (pool, "orphaning pool");
- gst_buffer_pool_set_active (*bpool, FALSE);
+ gst_buffer_pool_set_active (bpool, FALSE);
/* We lock to prevent racing with a return buffer in QBuf, and has a
* workaround of not being able to use the pool hidden activation lock. */
GST_OBJECT_UNLOCK (pool);
if (ret) {
- gst_object_unref (*bpool);
- *bpool = NULL;
+ GstBufferPool *old_pool;
+ GST_OBJECT_LOCK (v4l2object->element);
+ old_pool = v4l2object->pool;
+ v4l2object->pool = NULL;
+ GST_OBJECT_UNLOCK (v4l2object->element);
+ if (old_pool)
+ gst_object_unref (old_pool);
}
+ gst_object_unref (bpool);
+
return ret;
}
}
gboolean
-gst_v4l2_buffer_pool_flush (GstBufferPool * bpool)
+gst_v4l2_buffer_pool_flush (GstV4l2Object * v4l2object)
{
- GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
+ GstBufferPool *bpool = gst_v4l2_object_get_buffer_pool (v4l2object);
+ GstV4l2BufferPool *pool;
gboolean ret = TRUE;
+ if (!bpool)
+ return FALSE;
+
+ pool = GST_V4L2_BUFFER_POOL (bpool);
+
gst_v4l2_buffer_pool_streamoff (pool);
if (!V4L2_TYPE_IS_OUTPUT (pool->obj->type))
ret = gst_v4l2_buffer_pool_streamon (pool);
+ gst_object_unref (bpool);
return ret;
}
void gst_v4l2_buffer_pool_copy_at_threshold (GstV4l2BufferPool * pool,
gboolean copy);
-gboolean gst_v4l2_buffer_pool_flush (GstBufferPool *pool);
+gboolean gst_v4l2_buffer_pool_flush (GstV4l2Object * v4l2object);
-gboolean gst_v4l2_buffer_pool_orphan (GstBufferPool ** pool);
+gboolean gst_v4l2_buffer_pool_orphan (GstV4l2Object * v4l2object);
void gst_v4l2_buffer_pool_enable_resolution_change (GstV4l2BufferPool *self);
/* Map the buffers */
GST_LOG_OBJECT (v4l2object->dbg_obj, "initiating buffer pool");
- if (!(v4l2object->pool = gst_v4l2_buffer_pool_new (v4l2object, caps)))
- goto buffer_pool_new_failed;
+ {
+ GstBufferPool *pool = gst_v4l2_buffer_pool_new (v4l2object, caps);
+ GST_OBJECT_LOCK (v4l2object->element);
+ v4l2object->pool = pool;
+ GST_OBJECT_UNLOCK (v4l2object->element);
+ if (!pool)
+ goto buffer_pool_new_failed;
+ }
GST_V4L2_SET_ACTIVE (v4l2object);
GstStructure *config;
GstCaps *oldcaps;
gboolean ret;
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (v4l2object);
- if (!v4l2object->pool)
+ if (!pool)
return FALSE;
- config = gst_buffer_pool_get_config (v4l2object->pool);
+ config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);
ret = oldcaps && gst_caps_is_equal (caps, oldcaps);
gst_structure_free (config);
+ gst_object_unref (pool);
return ret;
}
GstStructure *config;
GstCaps *oldcaps;
gboolean ret;
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (v4l2object);
- if (!v4l2object->pool)
+ if (!pool)
return FALSE;
- config = gst_buffer_pool_get_config (v4l2object->pool);
+ config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);
ret = oldcaps && gst_caps_is_subset (oldcaps, caps);
gst_structure_free (config);
+ gst_object_unref (pool);
return ret;
}
{
GstStructure *config;
GstCaps *oldcaps;
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (v4l2object);
- if (!v4l2object->pool)
+ if (!pool)
return NULL;
- config = gst_buffer_pool_get_config (v4l2object->pool);
+ config = gst_buffer_pool_get_config (pool);
gst_buffer_pool_config_get_params (config, &oldcaps, NULL, NULL, NULL);
if (oldcaps)
gst_structure_free (config);
+ gst_object_unref (pool);
return oldcaps;
}
gst_v4l2_object_unlock (GstV4l2Object * v4l2object)
{
gboolean ret = TRUE;
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (v4l2object);
GST_LOG_OBJECT (v4l2object->dbg_obj, "start flushing");
- if (v4l2object->pool && gst_buffer_pool_is_active (v4l2object->pool))
- gst_buffer_pool_set_flushing (v4l2object->pool, TRUE);
+ if (!pool)
+ return ret;
+ if (gst_buffer_pool_is_active (pool))
+ gst_buffer_pool_set_flushing (pool, TRUE);
+
+ gst_object_unref (pool);
return ret;
}
gst_v4l2_object_unlock_stop (GstV4l2Object * v4l2object)
{
gboolean ret = TRUE;
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (v4l2object);
GST_LOG_OBJECT (v4l2object->dbg_obj, "stop flushing");
- if (v4l2object->pool && gst_buffer_pool_is_active (v4l2object->pool))
- gst_buffer_pool_set_flushing (v4l2object->pool, FALSE);
+ if (!pool)
+ return ret;
+
+ if (gst_buffer_pool_is_active (pool))
+ gst_buffer_pool_set_flushing (pool, FALSE);
+ gst_object_unref (pool);
return ret;
}
gboolean
gst_v4l2_object_stop (GstV4l2Object * v4l2object)
{
+ GstBufferPool *pool;
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "stopping");
if (!GST_V4L2_IS_OPEN (v4l2object))
if (!GST_V4L2_IS_ACTIVE (v4l2object))
goto done;
- if (v4l2object->pool) {
- if (!gst_v4l2_buffer_pool_orphan (&v4l2object->pool)) {
+ pool = gst_v4l2_object_get_buffer_pool (v4l2object);
+ if (pool) {
+ if (!gst_v4l2_buffer_pool_orphan (v4l2object)) {
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "deactivating pool");
- gst_buffer_pool_set_active (v4l2object->pool, FALSE);
- gst_object_unref (v4l2object->pool);
+ gst_buffer_pool_set_active (pool, FALSE);
+
+ {
+ GstBufferPool *old_pool;
+ GST_OBJECT_LOCK (v4l2object->element);
+ old_pool = v4l2object->pool;
+ v4l2object->pool = NULL;
+ GST_OBJECT_UNLOCK (v4l2object->element);
+ if (old_pool)
+ gst_object_unref (old_pool);
+ }
+ gst_object_unref (pool);
}
- v4l2object->pool = NULL;
}
GST_V4L2_SET_INACTIVE (v4l2object);
gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
{
GstCaps *caps;
- GstBufferPool *pool = NULL, *other_pool = NULL;
+ GstBufferPool *pool = NULL, *other_pool = NULL, *obj_pool = NULL;
GstStructure *config;
guint size, min, max, own_min = 0;
gboolean update;
gst_query_parse_allocation (query, &caps, NULL);
- if (obj->pool == NULL) {
+ obj_pool = gst_v4l2_object_get_buffer_pool (obj);
+ if (obj_pool == NULL) {
if (!gst_v4l2_object_setup_pool (obj, caps))
goto pool_failed;
+ obj_pool = gst_v4l2_object_get_buffer_pool (obj);
+ if (obj_pool == NULL)
+ goto pool_failed;
}
if (gst_query_get_n_allocation_params (query) > 0)
/* no downstream pool, use our own then */
GST_DEBUG_OBJECT (obj->dbg_obj,
"read/write mode: no downstream pool, using our own");
- pool = gst_object_ref (obj->pool);
+ pool = gst_object_ref (obj_pool);
size = obj->info.size;
pushing_from_our_pool = TRUE;
}
* our own, so it can serve itself */
if (pool == NULL)
goto no_downstream_pool;
- gst_v4l2_buffer_pool_set_other_pool (GST_V4L2_BUFFER_POOL (obj->pool),
+ gst_v4l2_buffer_pool_set_other_pool (GST_V4L2_BUFFER_POOL (obj_pool),
pool);
other_pool = pool;
gst_object_unref (pool);
- pool = gst_object_ref (obj->pool);
+ pool = gst_object_ref (obj_pool);
size = obj->info.size;
break;
if (can_share_own_pool) {
if (pool)
gst_object_unref (pool);
- pool = gst_object_ref (obj->pool);
+ pool = gst_object_ref (obj_pool);
size = obj->info.size;
GST_DEBUG_OBJECT (obj->dbg_obj,
"streaming mode: using our own pool %" GST_PTR_FORMAT, pool);
min = MAX (min, GST_V4L2_MIN_BUFFERS (obj));
/* To import we need the other pool to hold at least own_min */
- if (obj->pool == pool)
+ if (obj_pool == pool)
min += own_min;
}
max = MAX (min, max);
/* First step, configure our own pool */
- config = gst_buffer_pool_get_config (obj->pool);
+ config = gst_buffer_pool_get_config (obj_pool);
if (obj->need_video_meta || has_video_meta) {
GST_DEBUG_OBJECT (obj->dbg_obj, "activate Video Meta");
GST_PTR_FORMAT, config);
/* Our pool often need to adjust the value */
- if (!gst_buffer_pool_set_config (obj->pool, config)) {
- config = gst_buffer_pool_get_config (obj->pool);
+ if (!gst_buffer_pool_set_config (obj_pool, config)) {
+ config = gst_buffer_pool_get_config (obj_pool);
GST_DEBUG_OBJECT (obj->dbg_obj, "own pool config changed to %"
GST_PTR_FORMAT, config);
/* our pool will adjust the maximum buffer, which we are fine with */
- if (!gst_buffer_pool_set_config (obj->pool, config))
+ if (!gst_buffer_pool_set_config (obj_pool, config))
goto config_failed;
}
/* Now configure the other pool if different */
- if (obj->pool != pool)
+ if (obj_pool != pool)
other_pool = pool;
if (other_pool) {
if (pool)
gst_object_unref (pool);
+ if (obj_pool)
+ gst_object_unref (obj_pool);
+
return TRUE;
pool_failed:
(_("Video device did not suggest any buffer size.")), (NULL));
goto cleanup;
}
+no_downstream_pool:
+ {
+ GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS,
+ (_("No downstream pool to import from.")),
+ ("When importing DMABUF or USERPTR, we need a pool to import from"));
+ goto cleanup;
+ }
cleanup:
{
if (allocator)
if (pool)
gst_object_unref (pool);
- return FALSE;
- }
-no_downstream_pool:
- {
- GST_ELEMENT_ERROR (obj->element, RESOURCE, SETTINGS,
- (_("No downstream pool to import from.")),
- ("When importing DMABUF or USERPTR, we need a pool to import from"));
+
+ if (obj_pool)
+ gst_object_unref (obj_pool);
return FALSE;
}
}
switch (obj->mode) {
case GST_V4L2_IO_MMAP:
case GST_V4L2_IO_DMABUF:
- if (need_pool && obj->pool) {
- if (!gst_buffer_pool_is_active (obj->pool))
- pool = gst_object_ref (obj->pool);
+ if (need_pool) {
+ GstBufferPool *obj_pool = gst_v4l2_object_get_buffer_pool (obj);
+ if (obj_pool) {
+ if (!gst_buffer_pool_is_active (obj_pool))
+ pool = gst_object_ref (obj_pool);
+
+ gst_object_unref (obj_pool);
+ }
}
break;
default:
/* for the remaining, only the kernel driver can tell */
return TRUE;
}
+
+/**
+ * gst_v4l2_object_get_buffer_pool:
+ * @src: a #GstV4l2Object
+ *
+ * Returns: (nullable) (transfer full): the instance of the #GstBufferPool used
+ * by the v4l2object; unref it after usage.
+ */
+GstBufferPool *
+gst_v4l2_object_get_buffer_pool (GstV4l2Object * v4l2object)
+{
+ GstBufferPool *ret = NULL;
+
+ g_return_val_if_fail (v4l2object != NULL, NULL);
+
+ GST_OBJECT_LOCK (v4l2object->element);
+ if (v4l2object->pool)
+ ret = gst_object_ref (v4l2object->pool);
+ GST_OBJECT_UNLOCK (v4l2object->element);
+
+ return ret;
+}
gboolean gst_v4l2_object_propose_allocation (GstV4l2Object * obj, GstQuery * query);
+GstBufferPool * gst_v4l2_object_get_buffer_pool (GstV4l2Object * v4l2object);
+
GstStructure * gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc);
/* crop / compose */
GstFlowReturn ret;
GstV4l2Sink *v4l2sink = GST_V4L2SINK (vsink);
GstV4l2Object *obj = v4l2sink->v4l2object;
- GstBufferPool *bpool = GST_BUFFER_POOL (obj->pool);
+ GstBufferPool *bpool = gst_v4l2_object_get_buffer_pool (obj);
GST_DEBUG_OBJECT (v4l2sink, "render buffer: %p", buf);
- if (G_UNLIKELY (obj->pool == NULL))
+ if (G_UNLIKELY (bpool == NULL))
goto not_negotiated;
if (G_UNLIKELY (!gst_buffer_pool_is_active (bpool))) {
gst_buffer_ref (buf);
again:
- ret = gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL_CAST (obj->pool),
+ ret = gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL_CAST (bpool),
&buf, NULL);
if (ret == GST_FLOW_FLUSHING) {
ret = gst_base_sink_wait_preroll (GST_BASE_SINK (vsink));
goto again;
}
gst_buffer_unref (buf);
+ if (bpool)
+ gst_object_unref (bpool);
return ret;
GST_ELEMENT_ERROR (v4l2sink, RESOURCE, SETTINGS,
(_("Failed to allocated required memory.")),
("Buffer pool activation failed"));
+ if (bpool)
+ gst_object_unref (bpool);
return GST_FLOW_ERROR;
}
}
GstV4l2Object *obj = v4l2src->v4l2object;
struct v4l2_dv_timings dv_timings = { 0, };
const struct v4l2_bt_timings *bt = &dv_timings.bt;
+ gboolean not_streaming;
gint tot_width, tot_height;
gint gcd;
/* If are are not streaming (e.g. we received source-change event), lock the
* new timing immediatly so that TRY_FMT can properly work */
- if (!obj->pool || !GST_V4L2_BUFFER_POOL_IS_STREAMING (obj->pool)) {
+ {
+ GstBufferPool *obj_pool = gst_v4l2_object_get_buffer_pool (obj);
+ not_streaming = !obj_pool || !GST_V4L2_BUFFER_POOL_IS_STREAMING (obj_pool);
+ if (obj_pool)
+ gst_object_unref (obj_pool);
+ }
+
+ if (not_streaming) {
gst_v4l2_set_dv_timings (obj, &dv_timings);
/* Setting a new DV timings invalidates the probed caps. */
gst_caps_replace (&obj->probed_caps, NULL);
gst_v4l2src_decide_allocation (GstBaseSrc * bsrc, GstQuery * query)
{
GstV4l2Src *src = GST_V4L2SRC (bsrc);
+ GstBufferPool *bpool = gst_v4l2_object_get_buffer_pool (src->v4l2object);
gboolean ret = TRUE;
if (src->pending_set_fmt) {
ret = gst_v4l2src_set_format (src, caps, &error);
if (ret) {
- GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (src->v4l2object->pool);
+ GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
gst_v4l2_buffer_pool_enable_resolution_change (pool);
} else {
gst_v4l2_error (src, &error);
gst_caps_unref (caps);
src->pending_set_fmt = FALSE;
- } else if (gst_buffer_pool_is_active (src->v4l2object->pool)) {
+ } else if (gst_buffer_pool_is_active (bpool)) {
/* Trick basesrc into not deactivating the active pool. Renegotiating here
* would otherwise turn off and on the camera. */
GstAllocator *allocator;
gst_object_unref (pool);
if (allocator)
gst_object_unref (allocator);
+ if (bpool)
+ gst_object_unref (bpool);
return GST_BASE_SRC_CLASS (parent_class)->decide_allocation (bsrc, query);
}
}
if (ret) {
- if (!gst_buffer_pool_set_active (src->v4l2object->pool, TRUE))
+ if (!gst_buffer_pool_set_active (bpool, TRUE))
goto activate_failed;
}
+ if (bpool)
+ gst_object_unref (bpool);
return ret;
activate_failed:
GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS,
(_("Failed to allocate required memory.")),
("Buffer pool activation failed"));
+ if (bpool)
+ gst_object_unref (bpool);
return FALSE;
}
}
min_latency /= 2;
/* max latency is total duration of the frame buffer */
- if (obj->pool != NULL)
- num_buffers = GST_V4L2_BUFFER_POOL_CAST (obj->pool)->max_latency;
+ {
+ GstBufferPool *obj_pool = gst_v4l2_object_get_buffer_pool (obj);
+ if (obj_pool != NULL) {
+ num_buffers = GST_V4L2_BUFFER_POOL_CAST (obj_pool)->max_latency;
+ gst_object_unref (obj_pool);
+ }
+ }
if (num_buffers == 0)
max_latency = -1;
gboolean half_frame;
do {
- GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL_CAST (obj->pool);
-
ret = GST_BASE_SRC_CLASS (parent_class)->alloc (GST_BASE_SRC (src), 0,
obj->info.size, buf);
goto alloc_failed;
}
- ret = gst_v4l2_buffer_pool_process (pool, buf, NULL);
+ {
+ GstV4l2BufferPool *obj_pool =
+ GST_V4L2_BUFFER_POOL_CAST (gst_v4l2_object_get_buffer_pool (obj));
+ ret = gst_v4l2_buffer_pool_process (obj_pool, buf, NULL);
+ if (obj_pool)
+ gst_object_unref (obj_pool);
+ }
} while (ret == GST_V4L2_FLOW_CORRUPTED_BUFFER ||
ret == GST_V4L2_FLOW_RESOLUTION_CHANGE);
GST_DEBUG_OBJECT (self, "called");
if (gst_v4l2_object_decide_allocation (self->v4l2capture, query)) {
- GstBufferPool *pool = GST_BUFFER_POOL (self->v4l2capture->pool);
+ gboolean pool_active;
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (self->v4l2capture);
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans,
query);
- if (!gst_buffer_pool_set_active (pool, TRUE))
+ pool_active = gst_buffer_pool_set_active (pool, TRUE);
+ if (pool)
+ gst_object_unref (pool);
+ if (!pool_active)
goto activate_failed;
}
GstBuffer * inbuf, GstBuffer ** outbuf)
{
GstV4l2Transform *self = GST_V4L2_TRANSFORM (trans);
- GstBufferPool *pool = GST_BUFFER_POOL (self->v4l2output->pool);
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (self->v4l2output);
GstFlowReturn ret = GST_FLOW_OK;
GstBaseTransformClass *bclass = GST_BASE_TRANSFORM_CLASS (parent_class);
goto beach;
do {
+ if (pool)
+ g_object_unref (pool);
pool = gst_base_transform_get_buffer_pool (trans);
if (!gst_buffer_pool_set_active (pool, TRUE))
if (ret != GST_FLOW_OK)
goto alloc_failed;
- pool = self->v4l2capture->pool;
+ pool = gst_v4l2_object_get_buffer_pool (self->v4l2capture);
ret =
gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (pool), outbuf,
NULL);
}
beach:
+ if (pool)
+ g_object_unref (pool);
return ret;
activate_failed:
GST_DEBUG_OBJECT (self, "flush stop");
gst_v4l2_object_unlock_stop (self->v4l2capture);
gst_v4l2_object_unlock_stop (self->v4l2output);
- if (self->v4l2output->pool)
- gst_v4l2_buffer_pool_flush (self->v4l2output->pool);
- if (self->v4l2capture->pool)
- gst_v4l2_buffer_pool_flush (self->v4l2capture->pool);
+ gst_v4l2_buffer_pool_flush (self->v4l2output);
+ gst_v4l2_buffer_pool_flush (self->v4l2capture);
break;
default:
break;
* the complexity and should not have much impact in performance since the
* following allocation query will happen on a drained pipeline and won't
* block. */
- if (self->v4l2capture->pool &&
- !gst_v4l2_buffer_pool_orphan (&self->v4l2capture->pool)) {
+ if (!gst_v4l2_buffer_pool_orphan (self->v4l2capture)) {
GstCaps *caps = gst_pad_get_current_caps (decoder->srcpad);
if (caps) {
GstQuery *query = gst_query_new_allocation (caps, FALSE);
gst_v4l2_object_unlock_stop (self->v4l2output);
gst_v4l2_object_unlock_stop (self->v4l2capture);
- if (self->v4l2output->pool)
- gst_v4l2_buffer_pool_flush (self->v4l2output->pool);
+ gst_v4l2_buffer_pool_flush (self->v4l2output);
/* gst_v4l2_buffer_pool_flush() calls streamon the capture pool and must be
* called after gst_v4l2_object_unlock_stop() stopped flushing the buffer
* pool. */
- if (self->v4l2capture->pool)
- gst_v4l2_buffer_pool_flush (self->v4l2capture->pool);
+ gst_v4l2_buffer_pool_flush (self->v4l2capture);
return TRUE;
}
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
/* We don't allow renegotiation without careful disabling the pool */
- if (self->v4l2capture->pool &&
- gst_buffer_pool_is_active (GST_BUFFER_POOL (self->v4l2capture->pool)))
- return TRUE;
+ {
+ GstBufferPool *cpool = gst_v4l2_object_get_buffer_pool (self->v4l2capture);
+ if (cpool) {
+ gboolean is_active = gst_buffer_pool_is_active (cpool);
+ gst_object_unref (cpool);
+ if (is_active)
+ return TRUE;
+ }
+ }
return GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
}
gst_object_unref (task);
}
} else {
+ GstBufferPool *opool = gst_v4l2_object_get_buffer_pool (self->v4l2output);
/* otherwise keep queuing empty buffers until the processing thread has
* stopped, _pool_process() will return FLUSHING when that happened */
while (ret == GST_FLOW_OK) {
buffer = gst_buffer_new ();
ret =
- gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (self->
- v4l2output->pool), &buffer, NULL);
+ gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (opool), &buffer,
+ NULL);
gst_buffer_unref (buffer);
}
+ if (opool)
+ gst_object_unref (opool);
}
/* and ensure the processing thread has stopped in case another error
GstVideoCodecState *output_state;
GstCaps *acquired_caps, *available_caps, *caps, *filter;
GstStructure *st;
+ GstBufferPool *cpool;
+ gboolean active;
if (G_UNLIKELY (!GST_V4L2_IS_ACTIVE (self->v4l2capture))) {
/* init capture fps according to output */
output_state->info.interlace_mode = info.interlace_mode;
output_state->info.colorimetry = info.colorimetry;
gst_video_codec_state_unref (output_state);
+
+ cpool = gst_v4l2_object_get_buffer_pool (self->v4l2capture);
gst_v4l2_buffer_pool_enable_resolution_change (GST_V4L2_BUFFER_POOL
- (self->v4l2capture->pool));
+ (cpool));
if (!gst_video_decoder_negotiate (decoder)) {
+ if (cpool)
+ gst_object_unref (cpool);
if (GST_PAD_IS_FLUSHING (decoder->srcpad))
goto flushing;
else
}
/* Ensure our internal pool is activated */
- if (!gst_buffer_pool_set_active (GST_BUFFER_POOL (self->v4l2capture->pool),
- TRUE))
+ active = gst_buffer_pool_set_active (cpool, TRUE);
+ if (cpool)
+ gst_object_unref (cpool);
+ if (!active)
goto activate_failed;
}
gst_v4l2_video_dec_loop (GstVideoDecoder * decoder)
{
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
- GstV4l2BufferPool *v4l2_pool;
GstBufferPool *pool;
GstVideoCodecFrame *frame;
GstBuffer *buffer = NULL;
GST_LOG_OBJECT (decoder, "Allocate output buffer");
- v4l2_pool = GST_V4L2_BUFFER_POOL (self->v4l2capture->pool);
self->output_flow = GST_FLOW_OK;
do {
goto beach;
GST_LOG_OBJECT (decoder, "Process output buffer");
- ret = gst_v4l2_buffer_pool_process (v4l2_pool, &buffer, NULL);
+ {
+ GstV4l2BufferPool *cpool =
+ GST_V4L2_BUFFER_POOL (gst_v4l2_object_get_buffer_pool
+ (self->v4l2capture));
+ ret = gst_v4l2_buffer_pool_process (cpool, &buffer, NULL);
+ if (cpool)
+ gst_object_unref (cpool);
+ }
if (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE) {
GST_INFO_OBJECT (decoder, "Received resolution change");
{
GstV4l2Error error = GST_V4L2_ERROR_INIT;
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
- GstBufferPool *pool = GST_BUFFER_POOL (self->v4l2output->pool);
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (self->v4l2output);
GstFlowReturn ret = GST_FLOW_OK;
gboolean processed = FALSE;
GstBuffer *tmp;
GST_LOG_OBJECT (decoder, "Passing buffer with system frame number %u",
processed ? frame->system_frame_number : 0);
ret =
- gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (self->
- v4l2output->pool), &codec_data,
+ gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (pool), &codec_data,
processed ? &frame->system_frame_number : &dummy_frame_number);
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
GST_LOG_OBJECT (decoder, "Passing buffer with system frame number %u",
frame->system_frame_number);
ret =
- gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (self->v4l2output->
- pool), &frame->input_buffer, &frame->system_frame_number);
+ gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (pool),
+ &frame->input_buffer, &frame->system_frame_number);
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
if (ret == GST_FLOW_FLUSHING) {
gst_buffer_unref (tmp);
gst_video_codec_frame_unref (frame);
+ if (pool)
+ gst_object_unref (pool);
return ret;
/* ERRORS */
}
drop:
{
+ if (pool)
+ gst_object_unref (pool);
gst_video_decoder_drop_frame (decoder, frame);
return ret;
}
/* FIXME Check if buffer isn't the last one here */
GST_LOG_OBJECT (encoder, "Process output buffer");
- ret =
- gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL
- (self->v4l2capture->pool), &buffer, NULL);
-
+ {
+ GstV4l2BufferPool *cpool =
+ GST_V4L2_BUFFER_POOL (gst_v4l2_object_get_buffer_pool
+ (self->v4l2capture));
+ ret = gst_v4l2_buffer_pool_process (cpool, &buffer, NULL);
+ if (cpool)
+ gst_object_unref (cpool);
+ }
if (ret != GST_FLOW_OK)
goto beach;
GstV4l2VideoEnc *self = GST_V4L2_VIDEO_ENC (encoder);
GstFlowReturn ret = GST_FLOW_OK;
GstTaskState task_state;
+ gboolean active;
GST_DEBUG_OBJECT (self, "Handling frame %d", frame->system_frame_number);
task_state = gst_pad_get_task_state (GST_VIDEO_ENCODER_SRC_PAD (self));
if (task_state == GST_TASK_STOPPED || task_state == GST_TASK_PAUSED) {
- GstBufferPool *pool = GST_BUFFER_POOL (self->v4l2output->pool);
+ GstBufferPool *pool = gst_v4l2_object_get_buffer_pool (self->v4l2output);
/* It is possible that the processing thread stopped due to an error or
* when the last buffer has been met during the draining process. */
GST_DEBUG_OBJECT (self, "Processing loop stopped with error: %s, leaving",
gst_flow_get_name (self->output_flow));
ret = self->output_flow;
+ if (pool)
+ gst_object_unref (pool);
goto drop;
}
self->v4l2output->info.size, min, min);
/* There is no reason to refuse this config */
- if (!gst_buffer_pool_set_config (pool, config))
+ if (!gst_buffer_pool_set_config (pool, config)) {
+ if (pool)
+ gst_object_unref (pool);
goto activate_failed;
+ }
- if (!gst_buffer_pool_set_active (pool, TRUE))
+ if (!gst_buffer_pool_set_active (pool, TRUE)) {
+ if (pool)
+ gst_object_unref (pool);
goto activate_failed;
+ }
+ if (pool)
+ gst_object_unref (pool);
}
- if (!gst_buffer_pool_set_active
- (GST_BUFFER_POOL (self->v4l2capture->pool), TRUE)) {
+ {
+ GstBufferPool *cpool =
+ gst_v4l2_object_get_buffer_pool (self->v4l2capture);
+ active = gst_buffer_pool_set_active (cpool, TRUE);
+ if (cpool)
+ gst_object_unref (cpool);
+ }
+ if (!active) {
GST_WARNING_OBJECT (self, "Could not activate capture buffer pool.");
goto activate_failed;
}
GST_VIDEO_ENCODER_STREAM_UNLOCK (encoder);
GST_LOG_OBJECT (encoder, "Passing buffer with frame number %u",
frame->system_frame_number);
- ret =
- gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (self->
- v4l2output->pool), &frame->input_buffer,
- &frame->system_frame_number);
+
+ {
+ GstBufferPool *opool = gst_v4l2_object_get_buffer_pool (self->v4l2output);
+ ret = gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL (opool),
+ &frame->input_buffer, &frame->system_frame_number);
+ if (opool)
+ gst_object_unref (opool);
+ }
+
GST_VIDEO_ENCODER_STREAM_LOCK (encoder);
if (ret == GST_FLOW_FLUSHING) {