v4l2: Fix v4l2src on OpenSolaris

The v4l2 driver for USB webcams on OpenSolaris does not support select()
calls. Detect when select() fails, and skip polling the device afterward,
which restores the pre 0.10.14 behaviour on OpenSolaris.

Signed-off-by: Jan Schmidt <thaytan@noraisin.net>
This commit is contained in:
Elaine Xiong 2009-07-17 13:22:57 +01:00 committed by Jan Schmidt
parent 988123b186
commit 085f87d85f
4 changed files with 25 additions and 8 deletions

View file

@ -72,6 +72,7 @@ struct _GstV4l2Object {
/* the video-device's file descriptor */
gint video_fd;
GstPoll * poll;
gboolean can_poll_device;
/* the video buffer (mmap()'ed) */
guint8 **buffer;

View file

@ -1248,8 +1248,14 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
if (G_UNLIKELY (ret < 0)) {
if (errno == EBUSY)
goto stopped;
if (errno != EAGAIN && errno != EINTR)
goto select_error;
if (errno == ENXIO) {
GST_DEBUG_OBJECT (v4l2src,
"v4l2 device doesn't support polling. Disabling");
v4l2src->v4l2object->can_poll_device = FALSE;
} else {
if (errno != EAGAIN && errno != EINTR)
goto select_error;
}
}
amount =
v4l2_read (v4l2src->v4l2object->video_fd, GST_BUFFER_DATA (*buf),

View file

@ -442,6 +442,8 @@ gst_v4l2_open (GstV4l2Object * v4l2object)
if (libv4l2_fd != -1)
v4l2object->video_fd = libv4l2_fd;
v4l2object->can_poll_device = TRUE;
/* get capabilities, error will be posted */
if (!gst_v4l2_get_capabilities (v4l2object))
goto error;

View file

@ -999,12 +999,20 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
buffer.memory = V4L2_MEMORY_MMAP;
for (;;) {
ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE);
if (G_UNLIKELY (ret < 0)) {
if (errno == EBUSY)
goto stopped;
if (errno != EAGAIN && errno != EINTR)
goto select_error;
if (v4l2src->v4l2object->can_poll_device) {
ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE);
if (G_UNLIKELY (ret < 0)) {
if (errno == EBUSY)
goto stopped;
if (errno == ENXIO) {
GST_DEBUG_OBJECT (v4l2src,
"v4l2 device doesn't support polling. Disabling");
v4l2src->v4l2object->can_poll_device = FALSE;
} else {
if (errno != EAGAIN && errno != EINTR)
goto select_error;
}
}
}
if (v4l2_ioctl (v4l2src->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) >= 0)