Commit 66ca1b22 authored by Edgard Gusmão Lima's avatar Edgard Gusmão Lima
Browse files

Always copy buffers by default (handle safer with bugged drivers) and added a...

Always copy buffers by default (handle safer with bugged drivers) and added a property to make it possible to use mma...

Original commit message from CVS:
Always copy buffers by default (handle safer with bugged drivers) and added a property to make it possible to use mmap effectively (no copy if possible) when application wants to. Fixes: #480557.
parent 62d8456e
2007-11-15 Edgard Lima <edgard.lima@indt.org.br>
* sys/v4l2/gstv4l2src.c: (gst_v4l2src_class_init),
(gst_v4l2src_init), (gst_v4l2src_set_property),
(gst_v4l2src_get_property):
* sys/v4l2/gstv4l2src.h:
* sys/v4l2/v4l2src_calls.c: (gst_v4l2src_grab_frame):
Always copy buffers by default (handle safer with bugged drivers)
and added a property to make it possible to use mmap effectively (no
copy if possible) when application wants to. Fixes: #480557.
2007-11-14 Tim-Philipp Müller <tim at centricular dot net>
 
* gst/id3demux/id3tags.c:
......
......@@ -68,11 +68,14 @@ GST_ELEMENT_DETAILS ("Video (video4linux2/raw) Source",
GST_DEBUG_CATEGORY (v4l2src_debug);
#define GST_CAT_DEFAULT v4l2src_debug
#define DEFAULT_PROP_ALWAYS_COPY TRUE
enum
{
PROP_0,
V4L2_STD_OBJECT_PROPS,
PROP_QUEUE_SIZE
PROP_QUEUE_SIZE,
PROP_ALWAYS_COPY
};
static const guint32 gst_v4l2_formats[] = {
......@@ -289,6 +292,10 @@ gst_v4l2src_class_init (GstV4l2SrcClass * klass)
"Number of buffers to be enqueud in the driver",
GST_V4L2_MIN_BUFFERS, GST_V4L2_MAX_BUFFERS, GST_V4L2_MIN_BUFFERS,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_ALWAYS_COPY,
g_param_spec_boolean ("always-copy", "Always Copy",
"If the buffer will or not be used directly from mmap",
DEFAULT_PROP_ALWAYS_COPY, G_PARAM_READWRITE));
basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_get_caps);
basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_set_caps);
......@@ -310,6 +317,8 @@ gst_v4l2src_init (GstV4l2Src * v4l2src, GstV4l2SrcClass * klass)
/* number of buffers requested */
v4l2src->num_buffers = GST_V4L2_MIN_BUFFERS;
v4l2src->always_copy = DEFAULT_PROP_ALWAYS_COPY;
v4l2src->formats = NULL;
v4l2src->is_capturing = FALSE;
......@@ -356,6 +365,9 @@ gst_v4l2src_set_property (GObject * object,
case PROP_QUEUE_SIZE:
v4l2src->num_buffers = g_value_get_uint (value);
break;
case PROP_ALWAYS_COPY:
v4l2src->always_copy = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -376,6 +388,9 @@ gst_v4l2src_get_property (GObject * object,
case PROP_QUEUE_SIZE:
g_value_set_uint (value, v4l2src->num_buffers);
break;
case PROP_ALWAYS_COPY:
g_value_set_boolean (value, v4l2src->always_copy);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......
......@@ -101,6 +101,9 @@ struct _GstV4l2Src
gboolean use_mmap;
guint32 frame_byte_size;
/* if the buffer will be or not used from directly mmap */
gboolean always_copy;
/* True if we want to stop */
gboolean quit;
gboolean is_capturing;
......
......@@ -954,26 +954,16 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
}
}
do {
g_mutex_lock (v4l2src->pool->lock);
g_mutex_lock (v4l2src->pool->lock);
index = buffer.index;
index = buffer.index;
/* get our GstBuffer with that index from the pool, if the buffer was
* outstanding we have a serious problem. */
pool_buffer = GST_BUFFER (v4l2src->pool->buffers[index]);
if (pool_buffer == NULL) {
g_mutex_unlock (v4l2src->pool->lock);
g_usleep (20000); /* wait 20 miliseconds */
/* FIXME: we need a exit condition here */
} else {
break;
}
} while (TRUE);
/* get our GstBuffer with that index from the pool, if the buffer was
* outstanding we have a serious problem. */
pool_buffer = GST_BUFFER (v4l2src->pool->buffers[index]);
if (pool_buffer == NULL)
goto no_buffer;
GST_LOG_OBJECT (v4l2src, "grabbed buffer %p at index %d", pool_buffer, index);
......@@ -982,7 +972,8 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
v4l2src->pool->num_live_buffers++;
/* if we are handing out the last buffer in the pool, we need to make a
* copy and bring the buffer back in the pool. */
need_copy = v4l2src->pool->num_live_buffers == v4l2src->pool->buffer_count;
need_copy = v4l2src->always_copy
|| (v4l2src->pool->num_live_buffers == v4l2src->pool->buffer_count);
g_mutex_unlock (v4l2src->pool->lock);
......@@ -1020,6 +1011,7 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
if (G_UNLIKELY (need_copy)) {
*buf = gst_buffer_copy (pool_buffer);
GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY);
/* this will requeue */
gst_buffer_unref (pool_buffer);
} else {
......@@ -1059,7 +1051,7 @@ too_many_trials:
NUM_TRIALS, v4l2src->v4l2object->videodev, g_strerror (errno)));
return GST_FLOW_ERROR;
}
#if 0
no_buffer:
{
GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED,
(_("Failed trying to get video frames from device '%s'."),
......@@ -1068,7 +1060,6 @@ too_many_trials:
g_mutex_unlock (v4l2src->pool->lock);
return GST_FLOW_ERROR;
}
#endif
/*
qbuf_failed:
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment