Commit 23867b25 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

V4L/DVB (9661): uvcvideo: Commit streaming parameters when enabling the video stream

Sonix-based cameras seem to require the host to commit video streaming
parameters before selecting the alternate endpoint. While most applications
issue a VIDIOC_S_FMT ioctl before starting streaming, this is not required
by the V4L2 specification.

The problem has been noticed on Ubuntu 8.10 with applications using libv4l.
The library blocks VIDIOC_S_FMT calls when the requested format is identical
to the currently selected format. As the driver commits video streaming
parameters when initialising the device, only the first run of a
libv4l-enabled application would succeed.

For the sake of completeness, experiment showed that the camera keeps sending
12 bytes isochronous packets (header only, no data) without toggling the FID
bit if video streaming parameters haven't been committed before selecting the
alternate endpoint.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 9bc6218d
...@@ -252,9 +252,6 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video, ...@@ -252,9 +252,6 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
if (ret < 0) if (ret < 0)
return ret; return ret;
if ((ret = uvc_commit_video(video, &probe)) < 0)
return ret;
memcpy(&video->streaming->ctrl, &probe, sizeof probe); memcpy(&video->streaming->ctrl, &probe, sizeof probe);
video->streaming->cur_format = format; video->streaming->cur_format = format;
video->streaming->cur_frame = frame; video->streaming->cur_frame = frame;
...@@ -315,10 +312,6 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, ...@@ -315,10 +312,6 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
if ((ret = uvc_probe_video(video, &probe)) < 0) if ((ret = uvc_probe_video(video, &probe)) < 0)
return ret; return ret;
/* Commit the new settings. */
if ((ret = uvc_commit_video(video, &probe)) < 0)
return ret;
memcpy(&video->streaming->ctrl, &probe, sizeof probe); memcpy(&video->streaming->ctrl, &probe, sizeof probe);
/* Return the actual frame period. */ /* Return the actual frame period. */
......
...@@ -889,7 +889,7 @@ int uvc_video_resume(struct uvc_video_device *video) ...@@ -889,7 +889,7 @@ int uvc_video_resume(struct uvc_video_device *video)
video->frozen = 0; video->frozen = 0;
if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) { if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) {
uvc_queue_enable(&video->queue, 0); uvc_queue_enable(&video->queue, 0);
return ret; return ret;
} }
...@@ -970,11 +970,8 @@ int uvc_video_init(struct uvc_video_device *video) ...@@ -970,11 +970,8 @@ int uvc_video_init(struct uvc_video_device *video)
break; break;
} }
/* Commit the default settings. */
probe->bFormatIndex = format->index; probe->bFormatIndex = format->index;
probe->bFrameIndex = frame->bFrameIndex; probe->bFrameIndex = frame->bFrameIndex;
if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0)
return ret;
video->streaming->cur_format = format; video->streaming->cur_format = format;
video->streaming->cur_frame = frame; video->streaming->cur_frame = frame;
...@@ -1014,6 +1011,10 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) ...@@ -1014,6 +1011,10 @@ int uvc_video_enable(struct uvc_video_device *video, int enable)
if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
return ret; return ret;
/* Commit the streaming parameters. */
if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0)
return ret;
return uvc_init_video(video, GFP_KERNEL); return uvc_init_video(video, GFP_KERNEL);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment