summaryrefslogtreecommitdiffstats
path: root/sys/v4l2/v4l2src_calls.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2007-09-04 16:40:05 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-09-04 16:40:05 +0000
commitb4e5796a04dd2ba7c176024d9bf5d51dd3ee917b (patch)
treee20791a6c977b130eea4c38e516afccc4ece19ef /sys/v4l2/v4l2src_calls.c
parent5248639cc180189ff3cc7acde83f8b041c1b8f78 (diff)
sys/v4l2/gstv4l2src.c: Restructure the setcaps function so that we can also compute the expected GStreamer output siz...
Original commit message from CVS: * sys/v4l2/gstv4l2src.c: (gst_v4l2_get_caps_info), (gst_v4l2src_set_caps), (gst_v4l2src_get_mmap): Restructure the setcaps function so that we can also compute the expected GStreamer output size of the video frames. Set frame_byte_size correctly so that read-based devices have a chance of working correctly. When grabbing a frame, discard frames that are not of the expected size. Some cameras don't output the right framesize for the first buffer. Try only a couple of times to get a valid frame, else error out. * sys/v4l2/v4l2_calls.c: (gst_v4l2_get_capabilities), (gst_v4l2_fill_lists), (gst_v4l2_get_input): Add some more debug info when scanning the device. * sys/v4l2/v4l2src_calls.c: (gst_v4l2_buffer_new), (gst_v4l2_buffer_pool_new), (gst_v4l2_buffer_pool_activate), (gst_v4l2src_fill_format_list), (gst_v4l2src_grab_frame), (gst_v4l2src_set_capture), (gst_v4l2src_capture_init): Add some more debug info when dequeing a frame.
Diffstat (limited to 'sys/v4l2/v4l2src_calls.c')
-rw-r--r--sys/v4l2/v4l2src_calls.c70
1 files changed, 54 insertions, 16 deletions
diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c
index 0006f0e0..5483e6da 100644
--- a/sys/v4l2/v4l2src_calls.c
+++ b/sys/v4l2/v4l2src_calls.c
@@ -138,12 +138,16 @@ static GstV4l2Buffer *
gst_v4l2_buffer_new (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
{
GstV4l2Buffer *ret;
+ guint8 *data;
ret = (GstV4l2Buffer *) gst_mini_object_new (GST_TYPE_V4L2_BUFFER);
+ GST_LOG ("creating buffer %u, %p in pool %p", index, ret, pool);
+
ret->pool = pool;
gst_mini_object_ref (GST_MINI_OBJECT (pool));
memset (&ret->vbuffer, 0x00, sizeof (ret->vbuffer));
+
ret->vbuffer.index = index;
ret->vbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret->vbuffer.memory = V4L2_MEMORY_MMAP;
@@ -151,18 +155,34 @@ gst_v4l2_buffer_new (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
if (ioctl (pool->video_fd, VIDIOC_QUERYBUF, &ret->vbuffer) < 0)
goto querybuf_failed;
- GST_BUFFER_DATA (ret) = mmap (0, ret->vbuffer.length,
+ GST_LOG (" index: %u", ret->vbuffer.index);
+ GST_LOG (" type: %d", ret->vbuffer.type);
+ GST_LOG (" bytesused: %u", ret->vbuffer.bytesused);
+ GST_LOG (" flags: %08x", ret->vbuffer.flags);
+ GST_LOG (" field: %d", ret->vbuffer.field);
+ GST_LOG (" memory: %d", ret->vbuffer.memory);
+ if (ret->vbuffer.memory == V4L2_MEMORY_MMAP)
+ GST_LOG (" MMAP offset: %u", ret->vbuffer.m.offset);
+ GST_LOG (" length: %u", ret->vbuffer.length);
+ GST_LOG (" input: %u", ret->vbuffer.input);
+
+ data = mmap (0, ret->vbuffer.length,
PROT_READ | PROT_WRITE, MAP_SHARED, pool->video_fd,
ret->vbuffer.m.offset);
- if (GST_BUFFER_DATA (ret) == MAP_FAILED)
+ if (data == MAP_FAILED)
goto mmap_failed;
+ GST_BUFFER_DATA (ret) = data;
+ GST_BUFFER_SIZE (ret) = ret->vbuffer.length;
+
GST_BUFFER_FLAG_SET (ret, GST_BUFFER_FLAG_READONLY);
+
gst_buffer_set_caps (GST_BUFFER (ret), caps);
return ret;
+ /* ERRORS */
querybuf_failed:
{
gint errnosave = errno;
@@ -266,6 +286,7 @@ gst_v4l2_buffer_pool_new (GstV4l2Src * v4l2src, gint fd, gint num_buffers,
return pool;
+ /* ERRORS */
dup_failed:
{
gint errnosave = errno;
@@ -296,18 +317,22 @@ gst_v4l2_buffer_pool_activate (GstV4l2BufferPool * pool, GstV4l2Src * v4l2src)
g_mutex_lock (pool->lock);
for (n = 0; n < pool->buffer_count; n++) {
- struct v4l2_buffer *buf = &pool->buffers[n]->vbuffer;
+ struct v4l2_buffer *buf;
+
+ buf = &pool->buffers[n]->vbuffer;
+
+ GST_LOG ("enqueue pool buffer %d", n);
if (ioctl (pool->video_fd, VIDIOC_QBUF, buf) < 0)
goto queue_failed;
}
-
pool->running = TRUE;
g_mutex_unlock (pool->lock);
return TRUE;
+ /* ERRORS */
queue_failed:
{
GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
@@ -367,19 +392,27 @@ gst_v4l2src_fill_format_list (GstV4l2Src * v4l2src)
format->index = n;
format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
if (ioctl (v4l2src->v4l2object->video_fd, VIDIOC_ENUM_FMT, format) < 0) {
- if (errno == EINVAL) {
+ if (errno == EINVAL)
break; /* end of enumeration */
- } else
+ else
goto failed;
}
- GST_DEBUG_OBJECT (v4l2src, "got format %" GST_FOURCC_FORMAT,
+
+ GST_LOG_OBJECT (v4l2src, "index: %u", format->index);
+ GST_LOG_OBJECT (v4l2src, "type: %d", format->type);
+ GST_LOG_OBJECT (v4l2src, "flags: %08x", format->flags);
+ GST_LOG_OBJECT (v4l2src, "description: '%s'", format->description);
+ GST_LOG_OBJECT (v4l2src, "pixelformat: %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (format->pixelformat));
v4l2src->formats = g_slist_prepend (v4l2src->formats, format);
}
v4l2src->formats = g_slist_reverse (v4l2src->formats);
+
GST_DEBUG_OBJECT (v4l2src, "got %d format(s)", n);
+
return TRUE;
/* ERRORS */
@@ -803,8 +836,9 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
*buf = pool_buffer;
}
- GST_LOG_OBJECT (v4l2src, "grabbed frame %d (ix=%d), pool-ct=%d",
- buffer.sequence, buffer.index, v4l2src->pool->num_live_buffers);
+ GST_LOG_OBJECT (v4l2src, "grabbed frame %d (ix=%d), flags %08x, pool-ct=%d",
+ buffer.sequence, buffer.index, buffer.flags,
+ v4l2src->pool->num_live_buffers);
return GST_FLOW_OK;
@@ -910,11 +944,9 @@ gst_v4l2src_set_capture (GstV4l2Src * v4l2src, guint32 pixelformat,
if (stream.parm.capture.timeperframe.numerator != fps_d
|| stream.parm.capture.timeperframe.denominator != fps_n)
goto invalid_framerate;
-
}
}
-
return TRUE;
/* ERRORS */
@@ -986,24 +1018,30 @@ gst_v4l2src_capture_init (GstV4l2Src * v4l2src, GstCaps * caps)
GST_V4L2_CHECK_NOT_ACTIVE (v4l2src->v4l2object);
if (v4l2src->v4l2object->vcap.capabilities & V4L2_CAP_STREAMING) {
- breq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- breq.count = v4l2src->num_buffers;
+ GST_DEBUG_OBJECT (v4l2src, "STREAMING, requesting %d MMAP CAPTURE buffers",
+ v4l2src->num_buffers);
+
+ breq.count = v4l2src->num_buffers;
+ breq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
breq.memory = V4L2_MEMORY_MMAP;
+
if (ioctl (fd, VIDIOC_REQBUFS, &breq) < 0)
goto reqbufs_failed;
+ GST_LOG_OBJECT (v4l2src, " count: %u", breq.count);
+ GST_LOG_OBJECT (v4l2src, " type: %d", breq.type);
+ GST_LOG_OBJECT (v4l2src, " memory: %d", breq.memory);
+
if (breq.count < GST_V4L2_MIN_BUFFERS)
goto no_buffers;
if (v4l2src->num_buffers != breq.count) {
+ GST_WARNING_OBJECT (v4l2src, "using %u buffers instead", breq.count);
v4l2src->num_buffers = breq.count;
g_object_notify (G_OBJECT (v4l2src), "queue-size");
}
- GST_INFO_OBJECT (v4l2src, "Got %d buffers of size %d kB",
- breq.count, v4l2src->frame_byte_size / 1024);
-
/* Map the buffers */
GST_LOG_OBJECT (v4l2src, "initiating buffer pool");