From 23867b2511140ae5693587d2b15badbcc632e3cc Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 12 Nov 2008 11:46:43 -0300 Subject: [PATCH] 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: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_v4l2.c | 7 ------- drivers/media/video/uvc/uvc_video.c | 9 +++++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 624bf74..01b48a8 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -252,9 +252,6 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video, if (ret < 0) return ret; - if ((ret = uvc_commit_video(video, &probe)) < 0) - return ret; - memcpy(&video->streaming->ctrl, &probe, sizeof probe); video->streaming->cur_format = format; video->streaming->cur_frame = frame; @@ -315,10 +312,6 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video, if ((ret = uvc_probe_video(video, &probe)) < 0) return ret; - /* Commit the new settings. */ - if ((ret = uvc_commit_video(video, &probe)) < 0) - return ret; - memcpy(&video->streaming->ctrl, &probe, sizeof probe); /* Return the actual frame period. */ diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index e07bee9..186ef9f 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -889,7 +889,7 @@ int uvc_video_resume(struct uvc_video_device *video) 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); return ret; } @@ -970,11 +970,8 @@ int uvc_video_init(struct uvc_video_device *video) break; } - /* Commit the default settings. */ probe->bFormatIndex = format->index; probe->bFrameIndex = frame->bFrameIndex; - if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0) - return ret; video->streaming->cur_format = format; video->streaming->cur_frame = frame; @@ -1014,6 +1011,10 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) 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); } -- 2.7.4