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.
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;
if (pool->buffers[n])
gst_v4l2_buffer_pool_free_buffer (bpool, pool->buffers[n]);
}
+ g_free (pool->buffers);
+ pool->buffers = NULL;
+
return ret;
/* ERRORS */
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);
}
*
* 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;
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:
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))
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");
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
{
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);
/* 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);
/* optional pool */
gboolean always_copy;
- GstV4l2BufferPool *pool;
+ GstBufferPool *pool;
/* the video device's capabilities */
struct v4l2_capability vcap;
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;
gst_caps_unref (v4l2sink->probed_caps);
}
- if (v4l2sink->current_caps) {
- gst_caps_unref (v4l2sink->current_caps);
- }
-
G_OBJECT_CLASS (parent_class)->dispose (object);
}
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;
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 */
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);
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);
}
}
/* 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);
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;
/*< 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 */
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,
}
#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;