Message ID | 20140202130430.GA15734@pengutronix.de (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Laurent Pinchart |
Headers |
Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from <linux-media-owner@vger.kernel.org>) id 1W9wjQ-0007UH-QX; Sun, 02 Feb 2014 14:05:04 +0100 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.72/mailfrontend-7) with esmtp id 1W9wjO-0006uC-1C; Sun, 02 Feb 2014 14:05:04 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751317AbaBBNEh (ORCPT <rfc822;mkrufky@linuxtv.org> + 1 other); Sun, 2 Feb 2014 08:04:37 -0500 Received: from metis.ext.pengutronix.de ([92.198.50.35]:53967 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751241AbaBBNEg (ORCPT <rfc822; linux-media@vger.kernel.org>); Sun, 2 Feb 2014 08:04:36 -0500 Received: from dude.hi.pengutronix.de ([2001:6f8:1178:2:21e:67ff:fe11:9c5c]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from <pza@pengutronix.de>) id 1W9wiv-0001Ti-Ea; Sun, 02 Feb 2014 14:04:33 +0100 Received: from pza by dude.hi.pengutronix.de with local (Exim 4.82) (envelope-from <pza@pengutronix.de>) id 1W9wis-0004Uh-Fq; Sun, 02 Feb 2014 14:04:30 +0100 Date: Sun, 2 Feb 2014 14:04:30 +0100 From: Philipp Zabel <pza@pengutronix.de> To: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Hans Verkuil <hverkuil@xs4all.nl>, Philipp Zabel <p.zabel@pengutronix.de>, linux-media@vger.kernel.org, Mauro Carvalho Chehab <m.chehab@samsung.com>, kernel@pengutronix.de Subject: Re: [PATCH] [media] uvcvideo: Enable VIDIOC_CREATE_BUFS Message-ID: <20140202130430.GA15734@pengutronix.de> References: <1391012032-19600-1-git-send-email-p.zabel@pengutronix.de> <1474634.xnVfC2yuQa@avalon> <52EB6214.9030806@xs4all.nl> <3803281.g9jSrV8SES@avalon> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <3803281.g9jSrV8SES@avalon> X-Sent-From: Pengutronix Hildesheim X-URL: http://www.pengutronix.de/ X-IRC: #ptxdist @freenode X-Accept-Language: de,en X-Accept-Content-Type: text/plain X-Uptime: 14:00:50 up 12 days, 1:29, 20 users, load average: 0,32, 0,35, 0,29 User-Agent: Mutt/1.5.21 (2010-09-15) X-SA-Exim-Connect-IP: 2001:6f8:1178:2:21e:67ff:fe11:9c5c X-SA-Exim-Mail-From: pza@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: <linux-media.vger.kernel.org> X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2014.2.2.125415 X-PMX-Spam: Gauge=IIIIIIIII, Probability=9%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, MSGID_ADDED_BY_MTA 0.05, BODYTEXTP_SIZE_3000_LESS 0, BODY_SIZE_2000_2999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __BOUNCE_CHALLENGE_SUBJ 0, __BOUNCE_NDR_SUBJ_EXEMPT 0, __CD 0, __CP_MEDIA_BODY 0, __CP_URI_IN_BODY 0, __CT 0, __CT_TEXT_PLAIN 0, __FORWARDED_MSG 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILING_LIST 0, __IN_REP_TO 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __MULTIPLE_RCPTS_CC_X2 0, __SANE_MSGID 0, __SUBJ_ALPHA_NEGATE 0, __TO_MALFORMED_2 0, __URI_NS , __USER_AGENT 0' |
Commit Message
Philipp Zabel
Feb. 2, 2014, 1:04 p.m. UTC
On Sun, Feb 02, 2014 at 11:21:13AM +0100, Laurent Pinchart wrote: > Hi Hans, > > On Friday 31 January 2014 09:43:00 Hans Verkuil wrote: > > I think you might want to add a check in uvc_queue_setup to verify the > > fmt that create_bufs passes. The spec says that: "Unsupported formats > > will result in an error". In this case I guess that the format basically > > should match the current selected format. > > > > I'm unhappy with the current implementations of create_bufs (see also this > > patch: > > http://www.mail-archive.com/linux-media@vger.kernel.org/msg70796.html). > > > > Nobody is actually checking the format today, which isn't good. > > > > The fact that the spec says that the fmt field isn't changed by the driver > > isn't helping as it invalidated my patch from above, although that can be > > fixed. > > > > I need to think about this some more, but for this particular case you can > > just do a memcmp of the v4l2_pix_format against the currently selected > > format and return an error if they differ. Unless you want to support > > different buffer sizes as well? > > Isn't the whole point of VIDIOC_CREATE_BUFS being able to create buffers of > different resolutions than the current active resolution ? For that to work the driver in question would need to keep track of per-buffer format and resolution, and not only of per-queue format and resolution. For now, would something like the following be enough? Unfortunately the uvc driver doesn't keep a v4l2_format around that we could just memcmp against: regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Comments
Hi Philipp, Laurent, On 02/02/2014 02:04 PM, Philipp Zabel wrote: > On Sun, Feb 02, 2014 at 11:21:13AM +0100, Laurent Pinchart wrote: >> Hi Hans, >> >> On Friday 31 January 2014 09:43:00 Hans Verkuil wrote: >>> I think you might want to add a check in uvc_queue_setup to verify the >>> fmt that create_bufs passes. The spec says that: "Unsupported formats >>> will result in an error". In this case I guess that the format basically >>> should match the current selected format. >>> >>> I'm unhappy with the current implementations of create_bufs (see also this >>> patch: >>> http://www.mail-archive.com/linux-media@vger.kernel.org/msg70796.html). >>> >>> Nobody is actually checking the format today, which isn't good. >>> >>> The fact that the spec says that the fmt field isn't changed by the driver >>> isn't helping as it invalidated my patch from above, although that can be >>> fixed. >>> >>> I need to think about this some more, but for this particular case you can >>> just do a memcmp of the v4l2_pix_format against the currently selected >>> format and return an error if they differ. Unless you want to support >>> different buffer sizes as well? >> >> Isn't the whole point of VIDIOC_CREATE_BUFS being able to create buffers of >> different resolutions than the current active resolution ? Or just additional buffers with the same resolution (or really, the same size). > For that to work the driver in question would need to keep track of per-buffer > format and resolution, and not only of per-queue format and resolution. > > For now, would something like the following be enough? Unfortunately the uvc > driver doesn't keep a v4l2_format around that we could just memcmp against: > > diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c > index fa58131..7fa469b 100644 > --- a/drivers/media/usb/uvc/uvc_v4l2.c > +++ b/drivers/media/usb/uvc/uvc_v4l2.c > @@ -1003,10 +1003,26 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) > case VIDIOC_CREATE_BUFS: > { > struct v4l2_create_buffers *cb = arg; > + struct v4l2_pix_format *pix; > + struct uvc_format *format; > + struct uvc_frame *frame; > > if (!uvc_has_privileges(handle)) > return -EBUSY; > > + format = stream->cur_format; > + frame = stream->cur_frame; > + pix = &cb->format.fmt.pix; > + > + if (pix->pixelformat != format->fcc || > + pix->width != frame->wWidth || > + pix->height != frame->wHeight || > + pix->field != V4L2_FIELD_NONE || > + pix->bytesperline != format->bpp * frame->wWidth / 8 || > + pix->sizeimage != stream->ctrl.dwMaxVideoFrameSize || > + pix->colorspace != format->colorspace) I would drop the field and colorspace checks (those do not really affect any size calculations), other than that it looks good. Regards, Hans > + return -EINVAL; > + > return uvc_create_buffers(&stream->queue, cb); > } > > > regards > Philipp > -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Hans, On Monday 03 February 2014 10:03:39 Hans Verkuil wrote: > On 02/02/2014 02:04 PM, Philipp Zabel wrote: > > On Sun, Feb 02, 2014 at 11:21:13AM +0100, Laurent Pinchart wrote: > >> On Friday 31 January 2014 09:43:00 Hans Verkuil wrote: > >>> I think you might want to add a check in uvc_queue_setup to verify the > >>> fmt that create_bufs passes. The spec says that: "Unsupported formats > >>> will result in an error". In this case I guess that the format basically > >>> should match the current selected format. > >>> > >>> I'm unhappy with the current implementations of create_bufs (see also > >>> this patch: > >>> http://www.mail-archive.com/linux-media@vger.kernel.org/msg70796.html). > >>> > >>> Nobody is actually checking the format today, which isn't good. > >>> > >>> The fact that the spec says that the fmt field isn't changed by the > >>> driver isn't helping as it invalidated my patch from above, although > >>> that can be fixed. > >>> > >>> I need to think about this some more, but for this particular case you > >>> can just do a memcmp of the v4l2_pix_format against the currently > >>> selected format and return an error if they differ. Unless you want to > >>> support different buffer sizes as well? > >> > >> Isn't the whole point of VIDIOC_CREATE_BUFS being able to create buffers > >> of different resolutions than the current active resolution ? > > Or just additional buffers with the same resolution (or really, the same > size). Sure, that as well, but one use is to allocate larger buffers, shouldn't that be allowed ? > > For that to work the driver in question would need to keep track of > > per-buffer format and resolution, and not only of per-queue format and > > resolution. > > > > For now, would something like the following be enough? Unfortunately the > > uvc driver doesn't keep a v4l2_format around that we could just memcmp > > against: > > > > diff --git a/drivers/media/usb/uvc/uvc_v4l2.c > > b/drivers/media/usb/uvc/uvc_v4l2.c index fa58131..7fa469b 100644 > > --- a/drivers/media/usb/uvc/uvc_v4l2.c > > +++ b/drivers/media/usb/uvc/uvc_v4l2.c > > @@ -1003,10 +1003,26 @@ static long uvc_v4l2_do_ioctl(struct file *file, > > unsigned int cmd, void *arg)> > > case VIDIOC_CREATE_BUFS: > > { > > > > struct v4l2_create_buffers *cb = arg; > > > > + struct v4l2_pix_format *pix; > > + struct uvc_format *format; > > + struct uvc_frame *frame; > > > > if (!uvc_has_privileges(handle)) > > > > return -EBUSY; > > > > + format = stream->cur_format; > > + frame = stream->cur_frame; > > + pix = &cb->format.fmt.pix; > > + > > + if (pix->pixelformat != format->fcc || > > + pix->width != frame->wWidth || > > + pix->height != frame->wHeight || > > + pix->field != V4L2_FIELD_NONE || > > + pix->bytesperline != format->bpp * frame->wWidth / 8 || > > + pix->sizeimage != stream->ctrl.dwMaxVideoFrameSize || > > + pix->colorspace != format->colorspace) > > I would drop the field and colorspace checks (those do not really affect > any size calculations), other than that it looks good. > > Regards, > > Hans > > > + return -EINVAL; > > + > > return uvc_create_buffers(&stream->queue, cb); > > > > }
Hi, On 02/03/2014 10:03 AM, Hans Verkuil wrote: > Hi Philipp, Laurent, > > On 02/02/2014 02:04 PM, Philipp Zabel wrote: >> On Sun, Feb 02, 2014 at 11:21:13AM +0100, Laurent Pinchart wrote: >>> Hi Hans, >>> >>> On Friday 31 January 2014 09:43:00 Hans Verkuil wrote: >>>> I think you might want to add a check in uvc_queue_setup to verify the >>>> fmt that create_bufs passes. The spec says that: "Unsupported formats >>>> will result in an error". In this case I guess that the format basically >>>> should match the current selected format. >>>> >>>> I'm unhappy with the current implementations of create_bufs (see also this >>>> patch: >>>> http://www.mail-archive.com/linux-media@vger.kernel.org/msg70796.html). >>>> >>>> Nobody is actually checking the format today, which isn't good. >>>> >>>> The fact that the spec says that the fmt field isn't changed by the driver >>>> isn't helping as it invalidated my patch from above, although that can be >>>> fixed. >>>> >>>> I need to think about this some more, but for this particular case you can >>>> just do a memcmp of the v4l2_pix_format against the currently selected >>>> format and return an error if they differ. Unless you want to support >>>> different buffer sizes as well? >>> >>> Isn't the whole point of VIDIOC_CREATE_BUFS being able to create buffers of >>> different resolutions than the current active resolution ? > > Or just additional buffers with the same resolution (or really, the same size). > >> For that to work the driver in question would need to keep track of per-buffer >> format and resolution, and not only of per-queue format and resolution. >> >> For now, would something like the following be enough? Unfortunately the uvc >> driver doesn't keep a v4l2_format around that we could just memcmp against: >> >> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c >> index fa58131..7fa469b 100644 >> --- a/drivers/media/usb/uvc/uvc_v4l2.c >> +++ b/drivers/media/usb/uvc/uvc_v4l2.c >> @@ -1003,10 +1003,26 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) >> case VIDIOC_CREATE_BUFS: >> { >> struct v4l2_create_buffers *cb = arg; >> + struct v4l2_pix_format *pix; >> + struct uvc_format *format; >> + struct uvc_frame *frame; >> >> if (!uvc_has_privileges(handle)) >> return -EBUSY; >> >> + format = stream->cur_format; >> + frame = stream->cur_frame; >> + pix =&cb->format.fmt.pix; >> + >> + if (pix->pixelformat != format->fcc || >> + pix->width != frame->wWidth || >> + pix->height != frame->wHeight || >> + pix->field != V4L2_FIELD_NONE || >> + pix->bytesperline != format->bpp * frame->wWidth / 8 || >> + pix->sizeimage != stream->ctrl.dwMaxVideoFrameSize || >> + pix->colorspace != format->colorspace) > > I would drop the field and colorspace checks (those do not really affect > any size calculations), other than that it looks good. That seems completely wrong to me, AFAICT the VIDIOC_CREATE_BUFS was designed so that the driver is supposed to allow any format which is supported by the hardware. What has currently selected format to do with the format passed to VIDIOC_CREATE_BUFS ? It should be allowed to create buffers of any size (implied by the passed v4l2_pix_format). It is supposed to be checked if a buffer meets constraints of current configuration of the hardware at QBUF, not at VIDIOC_CREATE_BUFS time. User space may well allocate buffers when one image format is set, keep them aside and then just before queueing them to the driver may set the format to a different one, so the hardware set up matches buffers allocated with VIDIOC_CREATE_BUFS. What's the point of having VIDIOC_CREATE_BUFS when you are doing checks like above ? Unless I'm missing something that is completely wrong. :) Adjusting cb->format.fmt.pix as in VIDIOC_TRY_FORMAT seems more appropriate thing to do. Thanks, Sylwester -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 02/05/2014 12:04 AM, Sylwester Nawrocki wrote: > Hi, > > On 02/03/2014 10:03 AM, Hans Verkuil wrote: >> Hi Philipp, Laurent, >> >> On 02/02/2014 02:04 PM, Philipp Zabel wrote: >>> On Sun, Feb 02, 2014 at 11:21:13AM +0100, Laurent Pinchart wrote: >>>> Hi Hans, >>>> >>>> On Friday 31 January 2014 09:43:00 Hans Verkuil wrote: >>>>> I think you might want to add a check in uvc_queue_setup to verify the >>>>> fmt that create_bufs passes. The spec says that: "Unsupported formats >>>>> will result in an error". In this case I guess that the format basically >>>>> should match the current selected format. >>>>> >>>>> I'm unhappy with the current implementations of create_bufs (see also this >>>>> patch: >>>>> http://www.mail-archive.com/linux-media@vger.kernel.org/msg70796.html). >>>>> >>>>> Nobody is actually checking the format today, which isn't good. >>>>> >>>>> The fact that the spec says that the fmt field isn't changed by the driver >>>>> isn't helping as it invalidated my patch from above, although that can be >>>>> fixed. >>>>> >>>>> I need to think about this some more, but for this particular case you can >>>>> just do a memcmp of the v4l2_pix_format against the currently selected >>>>> format and return an error if they differ. Unless you want to support >>>>> different buffer sizes as well? >>>> >>>> Isn't the whole point of VIDIOC_CREATE_BUFS being able to create buffers of >>>> different resolutions than the current active resolution ? >> >> Or just additional buffers with the same resolution (or really, the same size). >> >>> For that to work the driver in question would need to keep track of per-buffer >>> format and resolution, and not only of per-queue format and resolution. >>> >>> For now, would something like the following be enough? Unfortunately the uvc >>> driver doesn't keep a v4l2_format around that we could just memcmp against: >>> >>> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c >>> index fa58131..7fa469b 100644 >>> --- a/drivers/media/usb/uvc/uvc_v4l2.c >>> +++ b/drivers/media/usb/uvc/uvc_v4l2.c >>> @@ -1003,10 +1003,26 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) >>> case VIDIOC_CREATE_BUFS: >>> { >>> struct v4l2_create_buffers *cb = arg; >>> + struct v4l2_pix_format *pix; >>> + struct uvc_format *format; >>> + struct uvc_frame *frame; >>> >>> if (!uvc_has_privileges(handle)) >>> return -EBUSY; >>> >>> + format = stream->cur_format; >>> + frame = stream->cur_frame; >>> + pix =&cb->format.fmt.pix; >>> + >>> + if (pix->pixelformat != format->fcc || >>> + pix->width != frame->wWidth || >>> + pix->height != frame->wHeight || >>> + pix->field != V4L2_FIELD_NONE || >>> + pix->bytesperline != format->bpp * frame->wWidth / 8 || >>> + pix->sizeimage != stream->ctrl.dwMaxVideoFrameSize || >>> + pix->colorspace != format->colorspace) >> >> I would drop the field and colorspace checks (those do not really affect >> any size calculations), other than that it looks good. > > That seems completely wrong to me, AFAICT the VIDIOC_CREATE_BUFS was > designed > so that the driver is supposed to allow any format which is supported by the > hardware. > What has currently selected format to do with the format passed to > VIDIOC_CREATE_BUFS ? It should be allowed to create buffers of any size > (implied by the passed v4l2_pix_format). It is supposed to be checked if > a buffer meets constraints of current configuration of > the hardware at QBUF, not at VIDIOC_CREATE_BUFS time. User space may well > allocate buffers when one image format is set, keep them aside and then > just before queueing them to the driver may set the format to a different > one, so the hardware set up matches buffers allocated with > VIDIOC_CREATE_BUFS. > > What's the point of having VIDIOC_CREATE_BUFS when you are doing checks > like above ? Unless I'm missing something that is completely wrong. :) > Adjusting cb->format.fmt.pix as in VIDIOC_TRY_FORMAT seems more appropriate > thing to do. OK, I agree that the code above is wrong. So ignore that. What should CREATE_BUFS do when it is called? Should I go back to this patch: http://www.spinics.net/lists/linux-media/msg72171.html It will at least ensure that the fmt is consistent. It is however not quite according to the spec since invalid formats are generally 'reformatted' by TRY_FMT to something valid, and the spec says invalid formats should return an error. It is possible to do something more advanced here, though: you could make a copy of v4l2_format, call TRY_FMT on it, and check if there are any differences with what was passed in. If there are, return an error. It's a bit of work, but probably better to do it in the core rather than depend on drivers to do it (since they won't :-) ). If queue_setup can rely on fmt to be a valid format, then sizeimage can just be used as the buffer size. With regards to checking constraints on QBUF: I see a problem there. For a regular buffer it can be checked in buf_prepare, but what if a buffer is already prepared using VIDIOC_PREPARE_BUF, then the format is changed and you call VIDIOC_QBUF with that prepared buffer? Then there is no callback where you can check this since the buf_prepare call has already happened. Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 02/05/14 08:57, Hans Verkuil wrote: > On 02/05/2014 12:04 AM, Sylwester Nawrocki wrote: >> Hi, >> >> On 02/03/2014 10:03 AM, Hans Verkuil wrote: >>> Hi Philipp, Laurent, >>> >>> On 02/02/2014 02:04 PM, Philipp Zabel wrote: >>>> On Sun, Feb 02, 2014 at 11:21:13AM +0100, Laurent Pinchart wrote: >>>>> Hi Hans, >>>>> >>>>> On Friday 31 January 2014 09:43:00 Hans Verkuil wrote: >>>>>> I think you might want to add a check in uvc_queue_setup to verify the >>>>>> fmt that create_bufs passes. The spec says that: "Unsupported formats >>>>>> will result in an error". In this case I guess that the format basically >>>>>> should match the current selected format. >>>>>> >>>>>> I'm unhappy with the current implementations of create_bufs (see also this >>>>>> patch: >>>>>> http://www.mail-archive.com/linux-media@vger.kernel.org/msg70796.html). >>>>>> >>>>>> Nobody is actually checking the format today, which isn't good. >>>>>> >>>>>> The fact that the spec says that the fmt field isn't changed by the driver >>>>>> isn't helping as it invalidated my patch from above, although that can be >>>>>> fixed. >>>>>> >>>>>> I need to think about this some more, but for this particular case you can >>>>>> just do a memcmp of the v4l2_pix_format against the currently selected >>>>>> format and return an error if they differ. Unless you want to support >>>>>> different buffer sizes as well? >>>>> >>>>> Isn't the whole point of VIDIOC_CREATE_BUFS being able to create buffers of >>>>> different resolutions than the current active resolution ? >>> >>> Or just additional buffers with the same resolution (or really, the same size). >>> >>>> For that to work the driver in question would need to keep track of per-buffer >>>> format and resolution, and not only of per-queue format and resolution. >>>> >>>> For now, would something like the following be enough? Unfortunately the uvc >>>> driver doesn't keep a v4l2_format around that we could just memcmp against: >>>> >>>> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c >>>> index fa58131..7fa469b 100644 >>>> --- a/drivers/media/usb/uvc/uvc_v4l2.c >>>> +++ b/drivers/media/usb/uvc/uvc_v4l2.c >>>> @@ -1003,10 +1003,26 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) >>>> case VIDIOC_CREATE_BUFS: >>>> { >>>> struct v4l2_create_buffers *cb = arg; >>>> + struct v4l2_pix_format *pix; >>>> + struct uvc_format *format; >>>> + struct uvc_frame *frame; >>>> >>>> if (!uvc_has_privileges(handle)) >>>> return -EBUSY; >>>> >>>> + format = stream->cur_format; >>>> + frame = stream->cur_frame; >>>> + pix =&cb->format.fmt.pix; >>>> + >>>> + if (pix->pixelformat != format->fcc || >>>> + pix->width != frame->wWidth || >>>> + pix->height != frame->wHeight || >>>> + pix->field != V4L2_FIELD_NONE || >>>> + pix->bytesperline != format->bpp * frame->wWidth / 8 || >>>> + pix->sizeimage != stream->ctrl.dwMaxVideoFrameSize || >>>> + pix->colorspace != format->colorspace) >>> >>> I would drop the field and colorspace checks (those do not really affect >>> any size calculations), other than that it looks good. >> >> That seems completely wrong to me, AFAICT the VIDIOC_CREATE_BUFS was >> designed >> so that the driver is supposed to allow any format which is supported by the >> hardware. >> What has currently selected format to do with the format passed to >> VIDIOC_CREATE_BUFS ? It should be allowed to create buffers of any size >> (implied by the passed v4l2_pix_format). It is supposed to be checked if >> a buffer meets constraints of current configuration of >> the hardware at QBUF, not at VIDIOC_CREATE_BUFS time. User space may well >> allocate buffers when one image format is set, keep them aside and then >> just before queueing them to the driver may set the format to a different >> one, so the hardware set up matches buffers allocated with >> VIDIOC_CREATE_BUFS. >> >> What's the point of having VIDIOC_CREATE_BUFS when you are doing checks >> like above ? Unless I'm missing something that is completely wrong. :) >> Adjusting cb->format.fmt.pix as in VIDIOC_TRY_FORMAT seems more appropriate >> thing to do. > > OK, I agree that the code above is wrong. So ignore that. > > What should CREATE_BUFS do when it is called? > > Should I go back to this patch: http://www.spinics.net/lists/linux-media/msg72171.html > > It will at least ensure that the fmt is consistent. It is however not quite > according to the spec since invalid formats are generally 'reformatted' by > TRY_FMT to something valid, and the spec says invalid formats should return > an error. It is possible to do something more advanced here, though: you > could make a copy of v4l2_format, call TRY_FMT on it, and check if there > are any differences with what was passed in. If there are, return an > error. > > It's a bit of work, but probably better to do it in the core rather than > depend on drivers to do it (since they won't :-) ). > > If queue_setup can rely on fmt to be a valid format, then sizeimage can > just be used as the buffer size. > > With regards to checking constraints on QBUF: I see a problem there. For > a regular buffer it can be checked in buf_prepare, but what if a buffer > is already prepared using VIDIOC_PREPARE_BUF, then the format is changed > and you call VIDIOC_QBUF with that prepared buffer? Then there is no > callback where you can check this since the buf_prepare call has already > happened. A follow-up: are there any (Samsung?) drivers that use this? CREATE_BUFS and/or PREPARE_BUF? I'm adding streaming tests to v4l2-compliance and I also want to add tests for CREATE_BUFS there. Nasty things like zeroing the fmt and just set the pixelformat to something valid, or setting imagesize to half the current format size and then queuing it. I fear the worst :-) Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Hans, On Wednesday 05 February 2014 08:57:14 Hans Verkuil wrote: > On 02/05/2014 12:04 AM, Sylwester Nawrocki wrote: > > On 02/03/2014 10:03 AM, Hans Verkuil wrote: > >> On 02/02/2014 02:04 PM, Philipp Zabel wrote: > >>> On Sun, Feb 02, 2014 at 11:21:13AM +0100, Laurent Pinchart wrote: > >>>> On Friday 31 January 2014 09:43:00 Hans Verkuil wrote: > >>>>> I think you might want to add a check in uvc_queue_setup to verify the > >>>>> fmt that create_bufs passes. The spec says that: "Unsupported formats > >>>>> will result in an error". In this case I guess that the format > >>>>> basically should match the current selected format. > >>>>> > >>>>> I'm unhappy with the current implementations of create_bufs (see also > >>>>> this patch: > >>>>> http://www.mail-archive.com/linux-media@vger.kernel.org/msg70796.html) > >>>>> . > >>>>> > >>>>> Nobody is actually checking the format today, which isn't good. > >>>>> > >>>>> The fact that the spec says that the fmt field isn't changed by the > >>>>> driver isn't helping as it invalidated my patch from above, although > >>>>> that can be fixed. > >>>>> > >>>>> I need to think about this some more, but for this particular case you > >>>>> can just do a memcmp of the v4l2_pix_format against the currently > >>>>> selected format and return an error if they differ. Unless you want to > >>>>> support different buffer sizes as well? > >>>> > >>>> Isn't the whole point of VIDIOC_CREATE_BUFS being able to create > >>>> buffers of different resolutions than the current active resolution ? > >> > >> Or just additional buffers with the same resolution (or really, the same > >> size). > >> > >>> For that to work the driver in question would need to keep track of > >>> per-buffer format and resolution, and not only of per-queue format and > >>> resolution. > >>> > >>> For now, would something like the following be enough? Unfortunately the > >>> uvc driver doesn't keep a v4l2_format around that we could just memcmp > >>> against: > >>> > >>> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c > >>> b/drivers/media/usb/uvc/uvc_v4l2.c index fa58131..7fa469b 100644 > >>> --- a/drivers/media/usb/uvc/uvc_v4l2.c > >>> +++ b/drivers/media/usb/uvc/uvc_v4l2.c > >>> @@ -1003,10 +1003,26 @@ static long uvc_v4l2_do_ioctl(struct file *file, > >>> unsigned int cmd, void *arg)>>> > >>> case VIDIOC_CREATE_BUFS: > >>> { > >>> struct v4l2_create_buffers *cb = arg; > >>> + struct v4l2_pix_format *pix; > >>> + struct uvc_format *format; > >>> + struct uvc_frame *frame; > >>> > >>> if (!uvc_has_privileges(handle)) > >>> return -EBUSY; > >>> > >>> + format = stream->cur_format; > >>> + frame = stream->cur_frame; > >>> + pix =&cb->format.fmt.pix; > >>> + > >>> + if (pix->pixelformat != format->fcc || > >>> + pix->width != frame->wWidth || > >>> + pix->height != frame->wHeight || > >>> + pix->field != V4L2_FIELD_NONE || > >>> + pix->bytesperline != format->bpp * frame->wWidth / 8 || > >>> + pix->sizeimage != stream->ctrl.dwMaxVideoFrameSize || > >>> + pix->colorspace != format->colorspace) > >> > >> I would drop the field and colorspace checks (those do not really affect > >> any size calculations), other than that it looks good. > > > > That seems completely wrong to me, AFAICT the VIDIOC_CREATE_BUFS was > > designed so that the driver is supposed to allow any format which is > > supported by the hardware. What has currently selected format to do with > > the format passed to VIDIOC_CREATE_BUFS ? It should be allowed to create > > buffers of any size (implied by the passed v4l2_pix_format). It is > > supposed to be checked if a buffer meets constraints of current > > configuration of the hardware at QBUF, not at VIDIOC_CREATE_BUFS time. > > User space may well allocate buffers when one image format is set, keep > > them aside and then just before queueing them to the driver may set the > > format to a different one, so the hardware set up matches buffers > > allocated with VIDIOC_CREATE_BUFS. > > > > What's the point of having VIDIOC_CREATE_BUFS when you are doing checks > > like above ? Unless I'm missing something that is completely wrong. :) > > Adjusting cb->format.fmt.pix as in VIDIOC_TRY_FORMAT seems more > > appropriate thing to do. > > OK, I agree that the code above is wrong. So ignore that. > > What should CREATE_BUFS do when it is called? > > Should I go back to this patch: > http://www.spinics.net/lists/linux-media/msg72171.html > > It will at least ensure that the fmt is consistent. It is however not quite > according to the spec since invalid formats are generally 'reformatted' by > TRY_FMT to something valid, and the spec says invalid formats should return > an error. It is possible to do something more advanced here, though: you > could make a copy of v4l2_format, call TRY_FMT on it, and check if there > are any differences with what was passed in. If there are, return an > error. > > It's a bit of work, but probably better to do it in the core rather than > depend on drivers to do it (since they won't :-) ). > > If queue_setup can rely on fmt to be a valid format, then sizeimage can > just be used as the buffer size. It sounds good in the general case, but I wonder whether we wouldn't have cases where TRY_FMT can mangle the format in a way that depends on controls for instance. In that case applications wouldn't be able to create buffers for a format that will be valid later but isn't now. I suppose this is really a more generic problem of formats and controls interactions, which are ill-defined at the moment. > With regards to checking constraints on QBUF: I see a problem there. For > a regular buffer it can be checked in buf_prepare, but what if a buffer > is already prepared using VIDIOC_PREPARE_BUF, then the format is changed > and you call VIDIOC_QBUF with that prepared buffer? Then there is no > callback where you can check this since the buf_prepare call has already > happened. Maybe we shouldn't allow format changes when buffers have been prepared ? We might then need a way to unprepare a buffer... That sounds a bit hackish though. Another solution would be to unprepare all buffers when the format is changed, but that sounds even worse. Maybe we should document the queue operations interactions with format setup and start from there.
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index fa58131..7fa469b 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -1003,10 +1003,26 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_CREATE_BUFS: { struct v4l2_create_buffers *cb = arg; + struct v4l2_pix_format *pix; + struct uvc_format *format; + struct uvc_frame *frame; if (!uvc_has_privileges(handle)) return -EBUSY; + format = stream->cur_format; + frame = stream->cur_frame; + pix = &cb->format.fmt.pix; + + if (pix->pixelformat != format->fcc || + pix->width != frame->wWidth || + pix->height != frame->wHeight || + pix->field != V4L2_FIELD_NONE || + pix->bytesperline != format->bpp * frame->wWidth / 8 || + pix->sizeimage != stream->ctrl.dwMaxVideoFrameSize || + pix->colorspace != format->colorspace) + return -EINVAL; + return uvc_create_buffers(&stream->queue, cb); }