summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorEdgard Lima <edgard.lima@indt.org.br>2007-11-15 12:22:10 +0000
committerEdgard Lima <edgard.lima@indt.org.br>2007-11-15 12:22:10 +0000
commit66ca1b2280a918d3bd7c7ce09ec22d485be34666 (patch)
treeae256a076c31d42542f63cd4656e1e137f77eadc /sys
parent62d8456eb715a3cb849ca0f14d2182fe5229ddf4 (diff)
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/v4l2/gstv4l2src.c17
-rw-r--r--sys/v4l2/gstv4l2src.h3
-rw-r--r--sys/v4l2/v4l2src_calls.c31
3 files changed, 30 insertions, 21 deletions
diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
index 9fce1846..e8fd9c2d 100644
--- a/sys/v4l2/gstv4l2src.c
+++ b/sys/v4l2/gstv4l2src.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;
diff --git a/sys/v4l2/gstv4l2src.h b/sys/v4l2/gstv4l2src.h
index f4677458..ae7aa74e 100644
--- a/sys/v4l2/gstv4l2src.h
+++ b/sys/v4l2/gstv4l2src.h
@@ -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;
diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c
index 0b03c999..e2a07ea9 100644
--- a/sys/v4l2/v4l2src_calls.c
+++ b/sys/v4l2/v4l2src_calls.c
@@ -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:
{