mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 04:31:06 +00:00
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.
This commit is contained in:
parent
62d8456eb7
commit
66ca1b2280
4 changed files with 41 additions and 21 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
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>
|
2007-11-14 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* gst/id3demux/id3tags.c:
|
* gst/id3demux/id3tags.c:
|
||||||
|
|
|
@ -68,11 +68,14 @@ GST_ELEMENT_DETAILS ("Video (video4linux2/raw) Source",
|
||||||
GST_DEBUG_CATEGORY (v4l2src_debug);
|
GST_DEBUG_CATEGORY (v4l2src_debug);
|
||||||
#define GST_CAT_DEFAULT v4l2src_debug
|
#define GST_CAT_DEFAULT v4l2src_debug
|
||||||
|
|
||||||
|
#define DEFAULT_PROP_ALWAYS_COPY TRUE
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
V4L2_STD_OBJECT_PROPS,
|
V4L2_STD_OBJECT_PROPS,
|
||||||
PROP_QUEUE_SIZE
|
PROP_QUEUE_SIZE,
|
||||||
|
PROP_ALWAYS_COPY
|
||||||
};
|
};
|
||||||
|
|
||||||
static const guint32 gst_v4l2_formats[] = {
|
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",
|
"Number of buffers to be enqueud in the driver",
|
||||||
GST_V4L2_MIN_BUFFERS, GST_V4L2_MAX_BUFFERS, GST_V4L2_MIN_BUFFERS,
|
GST_V4L2_MIN_BUFFERS, GST_V4L2_MAX_BUFFERS, GST_V4L2_MIN_BUFFERS,
|
||||||
G_PARAM_READWRITE));
|
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->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_get_caps);
|
||||||
basesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2src_set_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 */
|
/* number of buffers requested */
|
||||||
v4l2src->num_buffers = GST_V4L2_MIN_BUFFERS;
|
v4l2src->num_buffers = GST_V4L2_MIN_BUFFERS;
|
||||||
|
|
||||||
|
v4l2src->always_copy = DEFAULT_PROP_ALWAYS_COPY;
|
||||||
|
|
||||||
v4l2src->formats = NULL;
|
v4l2src->formats = NULL;
|
||||||
|
|
||||||
v4l2src->is_capturing = FALSE;
|
v4l2src->is_capturing = FALSE;
|
||||||
|
@ -356,6 +365,9 @@ gst_v4l2src_set_property (GObject * object,
|
||||||
case PROP_QUEUE_SIZE:
|
case PROP_QUEUE_SIZE:
|
||||||
v4l2src->num_buffers = g_value_get_uint (value);
|
v4l2src->num_buffers = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ALWAYS_COPY:
|
||||||
|
v4l2src->always_copy = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -376,6 +388,9 @@ gst_v4l2src_get_property (GObject * object,
|
||||||
case PROP_QUEUE_SIZE:
|
case PROP_QUEUE_SIZE:
|
||||||
g_value_set_uint (value, v4l2src->num_buffers);
|
g_value_set_uint (value, v4l2src->num_buffers);
|
||||||
break;
|
break;
|
||||||
|
case PROP_ALWAYS_COPY:
|
||||||
|
g_value_set_boolean (value, v4l2src->always_copy);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -101,6 +101,9 @@ struct _GstV4l2Src
|
||||||
gboolean use_mmap;
|
gboolean use_mmap;
|
||||||
guint32 frame_byte_size;
|
guint32 frame_byte_size;
|
||||||
|
|
||||||
|
/* if the buffer will be or not used from directly mmap */
|
||||||
|
gboolean always_copy;
|
||||||
|
|
||||||
/* True if we want to stop */
|
/* True if we want to stop */
|
||||||
gboolean quit;
|
gboolean quit;
|
||||||
gboolean is_capturing;
|
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. */
|
||||||
/* get our GstBuffer with that index from the pool, if the buffer was
|
pool_buffer = GST_BUFFER (v4l2src->pool->buffers[index]);
|
||||||
* 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);
|
|
||||||
|
|
||||||
|
if (pool_buffer == NULL)
|
||||||
|
goto no_buffer;
|
||||||
|
|
||||||
GST_LOG_OBJECT (v4l2src, "grabbed buffer %p at index %d", pool_buffer, index);
|
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++;
|
v4l2src->pool->num_live_buffers++;
|
||||||
/* if we are handing out the last buffer in the pool, we need to make a
|
/* 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. */
|
* 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);
|
g_mutex_unlock (v4l2src->pool->lock);
|
||||||
|
|
||||||
|
@ -1020,6 +1011,7 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
|
||||||
|
|
||||||
if (G_UNLIKELY (need_copy)) {
|
if (G_UNLIKELY (need_copy)) {
|
||||||
*buf = gst_buffer_copy (pool_buffer);
|
*buf = gst_buffer_copy (pool_buffer);
|
||||||
|
GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY);
|
||||||
/* this will requeue */
|
/* this will requeue */
|
||||||
gst_buffer_unref (pool_buffer);
|
gst_buffer_unref (pool_buffer);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1059,7 +1051,7 @@ too_many_trials:
|
||||||
NUM_TRIALS, v4l2src->v4l2object->videodev, g_strerror (errno)));
|
NUM_TRIALS, v4l2src->v4l2object->videodev, g_strerror (errno)));
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
#if 0
|
no_buffer:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED,
|
GST_ELEMENT_ERROR (v4l2src, RESOURCE, FAILED,
|
||||||
(_("Failed trying to get video frames from device '%s'."),
|
(_("Failed trying to get video frames from device '%s'."),
|
||||||
|
@ -1068,7 +1060,6 @@ too_many_trials:
|
||||||
g_mutex_unlock (v4l2src->pool->lock);
|
g_mutex_unlock (v4l2src->pool->lock);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
qbuf_failed:
|
qbuf_failed:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue