From patchwork Tue Nov 17 10:41:47 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antonio Ospite X-Patchwork-Id: 2073 Return-path: Envelope-to: mchehab@infradead.org Delivery-date: Tue, 17 Nov 2009 10:52:31 +0000 Received: from bombadil.infradead.org [18.85.46.34] by pedra.chehab.org with IMAP (fetchmail-6.3.6) for (single-drop); Tue, 17 Nov 2009 08:54:56 -0200 (BRST) Received: from vger.kernel.org ([209.132.176.167]) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1NALfj-0008Fa-Dl; Tue, 17 Nov 2009 10:52:31 +0000 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754660AbZKQKwN (ORCPT + 1 other); Tue, 17 Nov 2009 05:52:13 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754855AbZKQKwM (ORCPT ); Tue, 17 Nov 2009 05:52:12 -0500 Received: from smtp-out01.alice.it ([85.33.2.12]:4807 "EHLO smtp-out01.alice.it" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754836AbZKQKwH (ORCPT ); Tue, 17 Nov 2009 05:52:07 -0500 X-Greylist: delayed 611 seconds by postgrey-1.27 at vger.kernel.org; Tue, 17 Nov 2009 05:52:06 EST Received: from FBCMMO03.fbc.local ([192.168.68.197]) by smtp-out01.alice.it with Microsoft SMTPSVC(6.0.3790.3959); Tue, 17 Nov 2009 11:42:00 +0100 Received: from FBCMCL01B02.fbc.local ([192.168.69.83]) by FBCMMO03.fbc.local with Microsoft SMTPSVC(6.0.3790.3959); Tue, 17 Nov 2009 11:41:59 +0100 Received: from badebec ([79.2.139.137]) by FBCMCL01B02.fbc.local with Microsoft SMTPSVC(6.0.3790.3959); Tue, 17 Nov 2009 11:41:57 +0100 Date: Tue, 17 Nov 2009 11:41:47 +0100 From: Antonio Ospite To: linux-media@vger.kernel.org Cc: Jean-Francois Moine Subject: [RFC, PATCH] gspca: implement vidioc_enum_frameintervals Message-Id: <20091117114147.09889427.ospite@studenti.unina.it> X-Mailer: Sylpheed 2.7.1 (GTK+ 2.18.3; i686-pc-linux-gnu) X-Face: z*RaLf`X<@C75u6Ig9}{oW$H; 1_\2t5)({*|jhM/Vb; ]yA5\I~93>J<_`<4)A{':UrE Mime-Version: 1.0 X-OriginalArrivalTime: 17 Nov 2009 10:41:57.0523 (UTC) FILETIME=[9612D630:01CA6772] Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Hi, gspca does not implement vidioc_enum_frameintervals yet, so even if a camera can support multiple frame rates (or frame intervals) there is still no way to enumerate them from userspace. The following is just a quick and dirty implementation to show the problem and to have something to base the discussion on. In the patch there is also a working example of use with the ov534 subdriver. Someone with a better knowledge of gspca and v4l internals can suggest better solutions. The tests has been done using 'luvcview -L', the output before the patch: $ luvcview -d /dev/video1 -L luvcview 0.2.6 SDL information: Video driver: x11 A window manager is available Device information: Device path: /dev/video1 { pixelformat = 'YUYV', description = 'YUYV' } { discrete: width = 320, height = 240 } Time interval between frame: 1/40, 1/30, { discrete: width = 640, height = 480 } Time interval between frame: And the output after it: $ luvcview -d /dev/video1 -L luvcview 0.2.6 SDL information: Video driver: x11 A window manager is available Device information: Device path: /dev/video1 { pixelformat = 'YUYV', description = 'YUYV' } { discrete: width = 320, height = 240 } Time interval between frame: 1/125, 1/100, 1/75, 1/60, 1/50, 1/40, 1/30, { discrete: width = 640, height = 480 } Time interval between frame: 1/60, 1/50, 1/40, 1/30, 1/15, Thanks, Antonio diff -r 182b5f8fa160 linux/drivers/media/video/gspca/gspca.c --- a/linux/drivers/media/video/gspca/gspca.c Sun Nov 15 10:05:30 2009 +0100 +++ b/linux/drivers/media/video/gspca/gspca.c Tue Nov 17 11:39:21 2009 +0100 @@ -995,6 +995,37 @@ return -EINVAL; } +static int vidioc_enum_frameintervals(struct file *filp, void *priv, + struct v4l2_frmivalenum *fival) +{ + struct gspca_dev *gspca_dev = priv; + int mode = wxh_to_mode(gspca_dev, fival->width, fival->height); + int i; + __u32 index = 0; + + if (gspca_dev->cam.mode_framerates == NULL || + gspca_dev->cam.mode_framerates[mode].nrates == 0) + return -EINVAL; + + /* FIXME: Needed? */ + if (fival->pixel_format != + gspca_dev->cam.cam_mode[mode].pixelformat) + return -EINVAL; + + for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) { + if (fival->index == index) { + fival->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fival->discrete.numerator = 1; + fival->discrete.denominator = + gspca_dev->cam.mode_framerates[mode].rates[i]; + return 0; + } + index++; + } + + return -EINVAL; +} + static void gspca_release(struct video_device *vfd) { struct gspca_dev *gspca_dev = container_of(vfd, struct gspca_dev, vdev); @@ -1987,6 +2018,7 @@ .vidioc_g_parm = vidioc_g_parm, .vidioc_s_parm = vidioc_s_parm, .vidioc_enum_framesizes = vidioc_enum_framesizes, + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, diff -r 182b5f8fa160 linux/drivers/media/video/gspca/gspca.h --- a/linux/drivers/media/video/gspca/gspca.h Sun Nov 15 10:05:30 2009 +0100 +++ b/linux/drivers/media/video/gspca/gspca.h Tue Nov 17 11:39:21 2009 +0100 @@ -45,11 +45,17 @@ /* image transfers */ #define MAX_NURBS 4 /* max number of URBs */ +struct framerates { + int *rates; + int nrates; +}; + /* device information - set at probe time */ struct cam { int bulk_size; /* buffer size when image transfer by bulk */ const struct v4l2_pix_format *cam_mode; /* size nmodes */ char nmodes; + const struct framerates *mode_framerates; /* size nmode, like cam_mode */ __u8 bulk_nurbs; /* number of URBs in bulk mode * - cannot be > MAX_NURBS * - when 0 and bulk_size != 0 means diff -r 182b5f8fa160 linux/drivers/media/video/gspca/ov534.c --- a/linux/drivers/media/video/gspca/ov534.c Sun Nov 15 10:05:30 2009 +0100 +++ b/linux/drivers/media/video/gspca/ov534.c Tue Nov 17 11:39:21 2009 +0100 @@ -287,6 +287,20 @@ .priv = 0}, }; +static int qvga_rates[] = {125, 100, 75, 60, 50, 40, 30}; +static int vga_rates[] = {60, 50, 40, 30, 15}; + +static const struct framerates ov772x_framerates[] = { + { /* 320x240 */ + .rates = qvga_rates, + .nrates = ARRAY_SIZE(qvga_rates), + }, + { /* 640x480 */ + .rates = vga_rates, + .nrates = ARRAY_SIZE(vga_rates), + }, +}; + static const struct v4l2_pix_format ov965x_mode[] = { {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, @@ -1411,6 +1425,7 @@ if (sd->sensor == SENSOR_OV772X) { cam->cam_mode = ov772x_mode; cam->nmodes = ARRAY_SIZE(ov772x_mode); + cam->mode_framerates = ov772x_framerates; cam->bulk = 1; cam->bulk_size = 16384;