mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
v4l2: activate the pool in fallback
When nobody is using our pool, activate it ourselves. Avoid leaking the buffer array. Set default pool configuration with caps. Don't keep current_caps, core does that for us now.
This commit is contained in:
parent
edcaf20667
commit
add1cbdbd8
7 changed files with 59 additions and 39 deletions
|
@ -339,6 +339,9 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool)
|
|||
GST_DEBUG_OBJECT (pool, "starting, requesting %d MMAP buffers",
|
||||
max_buffers);
|
||||
|
||||
if (max_buffers == 0)
|
||||
max_buffers = 4;
|
||||
|
||||
memset (&breq, 0, sizeof (struct v4l2_requestbuffers));
|
||||
breq.type = obj->type;
|
||||
breq.count = max_buffers;
|
||||
|
@ -456,6 +459,9 @@ gst_v4l2_buffer_pool_stop (GstBufferPool * bpool)
|
|||
if (pool->buffers[n])
|
||||
gst_v4l2_buffer_pool_free_buffer (bpool, pool->buffers[n]);
|
||||
}
|
||||
g_free (pool->buffers);
|
||||
pool->buffers = NULL;
|
||||
|
||||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -813,10 +819,7 @@ gst_v4l2_buffer_pool_finalize (GObject * object)
|
|||
if (pool->video_fd >= 0)
|
||||
v4l2_close (pool->video_fd);
|
||||
|
||||
if (pool->buffers) {
|
||||
g_free (pool->buffers);
|
||||
pool->buffers = NULL;
|
||||
}
|
||||
g_free (pool->buffers);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
@ -851,8 +854,8 @@ gst_v4l2_buffer_pool_class_init (GstV4l2BufferPoolClass * klass)
|
|||
*
|
||||
* Returns: the new pool, use gst_object_unref() to free resources
|
||||
*/
|
||||
GstV4l2BufferPool *
|
||||
gst_v4l2_buffer_pool_new (GstV4l2Object * obj)
|
||||
GstBufferPool *
|
||||
gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
|
||||
{
|
||||
GstV4l2BufferPool *pool;
|
||||
gint fd;
|
||||
|
@ -865,7 +868,10 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj)
|
|||
pool->video_fd = fd;
|
||||
pool->obj = obj;
|
||||
|
||||
return pool;
|
||||
gst_buffer_pool_config_set (GST_BUFFER_POOL_CAST (pool)->config, caps,
|
||||
obj->sizeimage, 2, 0, 0, 0);
|
||||
|
||||
return GST_BUFFER_POOL (pool);
|
||||
|
||||
/* ERRORS */
|
||||
dup_failed:
|
||||
|
@ -1007,14 +1013,31 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer * buf)
|
|||
if (buf->pool == bpool) {
|
||||
/* nothing, we can queue directly */
|
||||
to_queue = buf;
|
||||
GST_LOG_OBJECT (pool, "processing buffer from our pool");
|
||||
} else {
|
||||
GST_LOG_OBJECT (pool, "alloc buffer from our pool");
|
||||
if (!gst_buffer_pool_is_active (bpool)) {
|
||||
GstStructure *config;
|
||||
|
||||
/* this pool was not activated, configure and activate */
|
||||
GST_DEBUG_OBJECT (pool, "activating pool");
|
||||
|
||||
config = gst_buffer_pool_get_config (bpool);
|
||||
gst_buffer_pool_config_add_option (config,
|
||||
GST_BUFFER_POOL_OPTION_META_VIDEO);
|
||||
gst_buffer_pool_set_config (bpool, config);
|
||||
|
||||
if (!gst_buffer_pool_set_active (bpool, TRUE))
|
||||
goto activate_failed;
|
||||
}
|
||||
|
||||
/* this can block if all buffers are outstanding which would be
|
||||
* strange because we would expect the upstream element to have
|
||||
* allocated them and returned to us.. */
|
||||
ret = GST_BUFFER_POOL_CLASS (parent_class)->acquire_buffer (bpool,
|
||||
&to_queue, NULL);
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto done;
|
||||
goto acquire_failed;
|
||||
|
||||
/* copy into it and queue */
|
||||
if (!gst_v4l2_object_copy (obj, to_queue, buf))
|
||||
|
@ -1058,6 +1081,17 @@ done:
|
|||
return ret;
|
||||
|
||||
/* ERRORS */
|
||||
activate_failed:
|
||||
{
|
||||
GST_ERROR_OBJECT (obj->element, "failed to activate pool");
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
acquire_failed:
|
||||
{
|
||||
GST_WARNING_OBJECT (obj->element, "failed to acquire a buffer: %s",
|
||||
gst_flow_get_name (ret));
|
||||
return ret;
|
||||
}
|
||||
copy_failed:
|
||||
{
|
||||
GST_ERROR_OBJECT (obj->element, "failed to copy data");
|
||||
|
|
|
@ -39,9 +39,10 @@ GST_DEBUG_CATEGORY_EXTERN (v4l2buffer_debug);
|
|||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GST_TYPE_V4L2_BUFFER_POOL (gst_v4l2_buffer_pool_get_type())
|
||||
#define GST_IS_V4L2_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_BUFFER_POOL))
|
||||
#define GST_V4L2_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_BUFFER_POOL, GstV4l2BufferPool))
|
||||
#define GST_TYPE_V4L2_BUFFER_POOL (gst_v4l2_buffer_pool_get_type())
|
||||
#define GST_IS_V4L2_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_BUFFER_POOL))
|
||||
#define GST_V4L2_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_BUFFER_POOL, GstV4l2BufferPool))
|
||||
#define GST_V4L2_BUFFER_POOL_CAST(obj) ((GstV4l2BufferPool*)(obj))
|
||||
|
||||
struct _GstV4l2BufferPool
|
||||
{
|
||||
|
@ -84,7 +85,7 @@ const GstMetaInfo * gst_meta_v4l2_get_info (void);
|
|||
|
||||
GType gst_v4l2_buffer_pool_get_type (void);
|
||||
|
||||
GstV4l2BufferPool * gst_v4l2_buffer_pool_new (GstV4l2Object *obj);
|
||||
GstBufferPool * gst_v4l2_buffer_pool_new (GstV4l2Object *obj, GstCaps *caps);
|
||||
|
||||
GstFlowReturn gst_v4l2_buffer_pool_process (GstV4l2BufferPool * bpool, GstBuffer * buf);
|
||||
|
||||
|
|
|
@ -2124,7 +2124,7 @@ gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps)
|
|||
/* Map the buffers */
|
||||
GST_LOG_OBJECT (v4l2object->element, "initiating buffer pool");
|
||||
|
||||
if (!(v4l2object->pool = gst_v4l2_buffer_pool_new (v4l2object)))
|
||||
if (!(v4l2object->pool = gst_v4l2_buffer_pool_new (v4l2object, caps)))
|
||||
goto buffer_pool_new_failed;
|
||||
|
||||
GST_V4L2_SET_ACTIVE (v4l2object);
|
||||
|
|
|
@ -126,7 +126,7 @@ struct _GstV4l2Object {
|
|||
|
||||
/* optional pool */
|
||||
gboolean always_copy;
|
||||
GstV4l2BufferPool *pool;
|
||||
GstBufferPool *pool;
|
||||
|
||||
/* the video device's capabilities */
|
||||
struct v4l2_capability vcap;
|
||||
|
|
|
@ -236,7 +236,6 @@ gst_v4l2sink_init (GstV4l2Sink * v4l2sink)
|
|||
g_object_set (v4l2sink, "device", "/dev/video1", NULL);
|
||||
|
||||
v4l2sink->probed_caps = NULL;
|
||||
v4l2sink->current_caps = NULL;
|
||||
|
||||
v4l2sink->overlay_fields_set = 0;
|
||||
v4l2sink->crop_fields_set = 0;
|
||||
|
@ -252,10 +251,6 @@ gst_v4l2sink_dispose (GObject * object)
|
|||
gst_caps_unref (v4l2sink->probed_caps);
|
||||
}
|
||||
|
||||
if (v4l2sink->current_caps) {
|
||||
gst_caps_unref (v4l2sink->current_caps);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
@ -584,16 +579,6 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (v4l2sink->current_caps) {
|
||||
GST_DEBUG_OBJECT (v4l2sink, "already have caps set.. are they equal?");
|
||||
LOG_CAPS (v4l2sink, v4l2sink->current_caps);
|
||||
if (gst_caps_is_equal (v4l2sink->current_caps, caps)) {
|
||||
GST_DEBUG_OBJECT (v4l2sink, "yes they are!");
|
||||
return TRUE;
|
||||
}
|
||||
GST_DEBUG_OBJECT (v4l2sink, "no they aren't!");
|
||||
}
|
||||
|
||||
if (!gst_v4l2_object_stop (obj))
|
||||
goto stop_failed;
|
||||
|
||||
|
@ -618,8 +603,6 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
GST_VIDEO_SINK_WIDTH (v4l2sink) = v4l2sink->video_width;
|
||||
GST_VIDEO_SINK_HEIGHT (v4l2sink) = v4l2sink->video_height;
|
||||
|
||||
v4l2sink->current_caps = gst_caps_ref (caps);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -642,9 +625,8 @@ gst_v4l2sink_setup_allocation (GstBaseSink * bsink, GstQuery * query)
|
|||
GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
|
||||
GstV4l2Object *obj = v4l2sink->v4l2object;
|
||||
GstBufferPool *pool;
|
||||
GstStructure *config;
|
||||
gsize size = 0;
|
||||
GstCaps *caps;
|
||||
guint size = 0;
|
||||
gboolean need_pool;
|
||||
|
||||
gst_query_parse_allocation (query, &caps, &need_pool);
|
||||
|
@ -652,11 +634,12 @@ gst_v4l2sink_setup_allocation (GstBaseSink * bsink, GstQuery * query)
|
|||
if (caps == NULL)
|
||||
goto no_caps;
|
||||
|
||||
if ((pool = GST_BUFFER_POOL_CAST (obj->pool)))
|
||||
if ((pool = obj->pool))
|
||||
gst_object_ref (pool);
|
||||
|
||||
if (pool != NULL) {
|
||||
const GstCaps *pcaps;
|
||||
GstStructure *config;
|
||||
|
||||
/* we had a pool, check caps */
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
|
@ -670,7 +653,7 @@ gst_v4l2sink_setup_allocation (GstBaseSink * bsink, GstQuery * query)
|
|||
}
|
||||
}
|
||||
/* we need at least 2 buffers to operate */
|
||||
gst_query_set_allocation_params (query, size, 2, 0, 0, 15, pool);
|
||||
gst_query_set_allocation_params (query, size, 2, 0, 0, 0, pool);
|
||||
|
||||
/* we also support various metadata */
|
||||
gst_query_add_allocation_meta (query, GST_META_API_VIDEO);
|
||||
|
@ -708,7 +691,8 @@ gst_v4l2sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
|
|||
if (G_UNLIKELY (obj->pool == NULL))
|
||||
goto not_negotiated;
|
||||
|
||||
ret = gst_v4l2_buffer_pool_process (obj->pool, buf);
|
||||
ret =
|
||||
gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL_CAST (obj->pool), buf);
|
||||
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ struct _GstV4l2Sink {
|
|||
/*< private >*/
|
||||
GstV4l2Object * v4l2object;
|
||||
GstCaps *probed_caps; /* all supported caps of underlying v4l2 device */
|
||||
GstCaps *current_caps; /* the current negotiated caps */
|
||||
|
||||
gint video_width, video_height; /* original (unscaled) video w/h */
|
||||
|
||||
|
|
|
@ -633,7 +633,8 @@ gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query)
|
|||
min_latency = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
|
||||
|
||||
/* max latency is total duration of the frame buffer */
|
||||
max_latency = obj->pool->max_buffers * min_latency;
|
||||
max_latency =
|
||||
GST_V4L2_BUFFER_POOL_CAST (obj->pool)->max_buffers * min_latency;
|
||||
|
||||
GST_DEBUG_OBJECT (bsrc,
|
||||
"report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT,
|
||||
|
@ -759,7 +760,8 @@ gst_v4l2src_fill (GstPushSrc * src, GstBuffer * buf)
|
|||
}
|
||||
#endif
|
||||
|
||||
ret = gst_v4l2_buffer_pool_process (obj->pool, buf);
|
||||
ret =
|
||||
gst_v4l2_buffer_pool_process (GST_V4L2_BUFFER_POOL_CAST (obj->pool), buf);
|
||||
|
||||
if (G_UNLIKELY (ret != GST_FLOW_OK))
|
||||
goto error;
|
||||
|
|
Loading…
Reference in a new issue