From: Daniel Drake <dsd@laptop.org>
http://bugzilla.gnome.org/show_bug.cgi?id=541956
Index: gst-plugins-good-0.10.8/sys/v4l2/v4l2src_calls.c
===================================================================
--- gst-plugins-good-0.10.8.orig/sys/v4l2/v4l2src_calls.c
+++ gst-plugins-good-0.10.8/sys/v4l2/v4l2src_calls.c
@@ -1149,11 +1149,23 @@ gst_v4l2src_set_capture (GstV4l2Src * v4
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;
@@ -1473,6 +1485,7 @@ gst_v4l2src_get_nearest_size (GstV4l2Src
{
struct v4l2_format fmt;
int fd;
+ int r;
g_return_val_if_fail (width != NULL, FALSE);
g_return_val_if_fail (height != NULL, FALSE);
@@ -1491,7 +1504,17 @@ gst_v4l2src_get_nearest_size (GstV4l2Src
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)
@@ -1508,7 +1531,17 @@ gst_v4l2src_get_nearest_size (GstV4l2Src
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;
}