summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2008-07-07 21:28:58 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-07-07 21:28:58 +0000
commit23078b431b8326da30fcb60101fd26618951587b (patch)
tree30bc0a2322f309e6c1bb04fff088aad74536ee46 /sys
parent0db3e69da91738f8ae84923ab3d78deb25bc2ca4 (diff)
sys/v4l2/v4l2src_calls.c: Try progressive video if interlaced fails. Fixes bug #541956 and the usage of v4l2src on OLPC.
Original commit message from CVS: Patch by: Daniel Drake <dsd at gentoo dot org> * sys/v4l2/v4l2src_calls.c: (gst_v4l2src_set_capture), (gst_v4l2src_get_nearest_size): Try progressive video if interlaced fails. Fixes bug #541956 and the usage of v4l2src on OLPC.
Diffstat (limited to 'sys')
-rw-r--r--sys/v4l2/v4l2src_calls.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c
index ad102f56..9ab0989d 100644
--- a/sys/v4l2/v4l2src_calls.c
+++ b/sys/v4l2/v4l2src_calls.c
@@ -107,8 +107,8 @@ gst_v4l2_buffer_finalize (GstV4l2Buffer * buffer)
gst_mini_object_unref (GST_MINI_OBJECT (pool));
munmap ((void *) GST_BUFFER_DATA (buffer), buffer->vbuffer.length);
- GST_MINI_OBJECT_CLASS (v4l2buffer_parent_class)->
- finalize (GST_MINI_OBJECT (buffer));
+ GST_MINI_OBJECT_CLASS (v4l2buffer_parent_class)->finalize (GST_MINI_OBJECT
+ (buffer));
}
}
@@ -240,8 +240,8 @@ gst_v4l2_buffer_pool_finalize (GstV4l2BufferPool * pool)
if (pool->buffers)
g_free (pool->buffers);
pool->buffers = NULL;
- GST_MINI_OBJECT_CLASS (buffer_pool_parent_class)->
- finalize (GST_MINI_OBJECT (pool));
+ GST_MINI_OBJECT_CLASS (buffer_pool_parent_class)->finalize (GST_MINI_OBJECT
+ (pool));
}
static void
@@ -1176,11 +1176,23 @@ gst_v4l2src_set_capture (GstV4l2Src * v4l2src, guint32 pixelformat,
format.fmt.pix.width = width;
format.fmt.pix.height = height;
format.fmt.pix.pixelformat = pixelformat;
- /* request whole frames; change when gstreamer supports interlaced video */
+ /* request whole frames; change when gstreamer supports interlaced video
+ * (INTERLACED mode returns frames where the fields have already been
+ * combined, there are other modes for requesting fields individually) */
format.fmt.pix.field = V4L2_FIELD_INTERLACED;
- if (ioctl (fd, VIDIOC_S_FMT, &format) < 0)
- goto set_fmt_failed;
+ if (ioctl (fd, VIDIOC_S_FMT, &format) < 0) {
+ if (errno != EINVAL)
+ goto set_fmt_failed;
+
+ /* try again with progressive video */
+ format.fmt.pix.width = width;
+ format.fmt.pix.height = height;
+ format.fmt.pix.pixelformat = pixelformat;
+ format.fmt.pix.field = V4L2_FIELD_NONE;
+ if (ioctl (fd, VIDIOC_S_FMT, &format) < 0)
+ goto set_fmt_failed;
+ }
if (format.fmt.pix.width != width || format.fmt.pix.height != height)
goto invalid_dimensions;
@@ -1500,6 +1512,7 @@ gst_v4l2src_get_nearest_size (GstV4l2Src * v4l2src, guint32 pixelformat,
{
struct v4l2_format fmt;
int fd;
+ int r;
g_return_val_if_fail (width != NULL, FALSE);
g_return_val_if_fail (height != NULL, FALSE);
@@ -1518,7 +1531,17 @@ gst_v4l2src_get_nearest_size (GstV4l2Src * v4l2src, guint32 pixelformat,
fmt.fmt.pix.pixelformat = pixelformat;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
- if (ioctl (fd, VIDIOC_TRY_FMT, &fmt) < 0) {
+ r = ioctl (fd, VIDIOC_TRY_FMT, &fmt);
+ if (r < 0 && errno == EINVAL) {
+ /* try again with progressive video */
+ fmt.fmt.pix.width = *width;
+ fmt.fmt.pix.height = *height;
+ fmt.fmt.pix.pixelformat = pixelformat;
+ fmt.fmt.pix.field = V4L2_FIELD_NONE;
+ r = ioctl (fd, VIDIOC_TRY_FMT, &fmt);
+ }
+
+ if (r < 0) {
/* The driver might not implement TRY_FMT, in which case we will try
S_FMT to probe */
if (errno != ENOTTY)
@@ -1535,7 +1558,17 @@ gst_v4l2src_get_nearest_size (GstV4l2Src * v4l2src, guint32 pixelformat,
fmt.fmt.pix.width = *width;
fmt.fmt.pix.height = *height;
- if (ioctl (fd, VIDIOC_S_FMT, &fmt) < 0)
+ r = ioctl (fd, VIDIOC_S_FMT, &fmt);
+ if (r < 0 && errno == EINVAL) {
+ /* try again with progressive video */
+ fmt.fmt.pix.width = *width;
+ fmt.fmt.pix.height = *height;
+ fmt.fmt.pix.pixelformat = pixelformat;
+ fmt.fmt.pix.field = V4L2_FIELD_NONE;
+ r = ioctl (fd, VIDIOC_S_FMT, &fmt);
+ }
+
+ if (r < 0)
return FALSE;
}