From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Philipp Zabel <philipp.zabel@gmail.com>
Cc: linux-media@vger.kernel.org
Subject: Re: [PATCH] media: uvcvideo: support multiple frame descriptors with the same dimensions
Date: Fri, 05 Jan 2018 15:30:46 +0200 [thread overview]
Message-ID: <3663272.AjVBumhkVf@avalon> (raw)
In-Reply-To: <20180104225129.9488-1-philipp.zabel@gmail.com>
Hi Philipp,
Thank you for the patch.
On Friday, 5 January 2018 00:51:29 EET Philipp Zabel wrote:
> The Microsoft HoloLens Sensors device has two separate frame descriptors
> with the same dimensions, each with a single different frame interval:
>
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 1
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1280
> wHeight 481
> dwMinBitRate 147763200
> dwMaxBitRate 147763200
> dwMaxVideoFrameBufferSize 615680
> dwDefaultFrameInterval 333333
> bFrameIntervalType 1
> dwFrameInterval( 0) 333333
> VideoStreaming Interface Descriptor:
> bLength 30
> bDescriptorType 36
> bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
> bFrameIndex 2
> bmCapabilities 0x00
> Still image unsupported
> wWidth 1280
> wHeight 481
> dwMinBitRate 443289600
> dwMaxBitRate 443289600
> dwMaxVideoFrameBufferSize 615680
> dwDefaultFrameInterval 111111
> bFrameIntervalType 1
> dwFrameInterval( 0) 111111
>
> Skip duplicate dimensions in enum_framesizes, let enum_frameintervals list
> the intervals from both frame descriptors. Change set_streamparm to switch
> to the correct frame index when changing the interval. This enables 90 fps
> capture on a Lenovo Explorer Windows Mixed Reality headset.
>
> Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
> ---
> Changes since v1 [1]:
> - Break out of frame size loop if maxd == 0 in uvc_v4l2_set_streamparm.
> - Moved d and tmp variables in uvc_v4l2_set_streamparm into loop,
> renamed tmp variable to tmp_ival.
> - Changed i loop variables to unsigned int.
> - Changed index variables to unsigned int.
> - One line per variable declaration.
>
> [1] https://patchwork.linuxtv.org/patch/46109/
> ---
> drivers/media/usb/uvc/uvc_v4l2.c | 71
> +++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+),
> 16 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c
> b/drivers/media/usb/uvc/uvc_v4l2.c index f5ab8164bca5..d9ee400bf47c 100644
> --- a/drivers/media/usb/uvc/uvc_v4l2.c
> +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> @@ -373,7 +373,10 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming
> *stream, {
> struct uvc_streaming_control probe;
> struct v4l2_fract timeperframe;
> - uint32_t interval;
> + struct uvc_format *format;
> + struct uvc_frame *frame;
> + __u32 interval, maxd;
> + unsigned int i;
> int ret;
>
> if (parm->type != stream->type)
> @@ -396,9 +399,33 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming
> *stream, return -EBUSY;
> }
>
> + format = stream->cur_format;
> + frame = stream->cur_frame;
> probe = stream->ctrl;
> - probe.dwFrameInterval =
> - uvc_try_frame_interval(stream->cur_frame, interval);
> + probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
> + maxd = abs((__s32)probe.dwFrameInterval - interval);
> +
> + /* Try frames with matching size to find the best frame interval. */
> + for (i = 0; i < format->nframes && maxd != 0; i++) {
> + __u32 d, tmp_ival;
How about ival instead of tmp_ival ?
Apart from that,
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
If you're fine with the change there's no need to resubmit.
> +
> + if (&format->frame[i] == stream->cur_frame)
> + continue;
> +
> + if (format->frame[i].wWidth != stream->cur_frame->wWidth ||
> + format->frame[i].wHeight != stream->cur_frame->wHeight)
> + continue;
> +
> + tmp_ival = uvc_try_frame_interval(&format->frame[i], interval);
> + d = abs((__s32)tmp_ival - interval);
> + if (d >= maxd)
> + continue;
> +
> + frame = &format->frame[i];
> + probe.bFrameIndex = frame->bFrameIndex;
> + probe.dwFrameInterval = tmp_ival;
> + maxd = d;
> + }
>
> /* Probe the device with the new settings. */
> ret = uvc_probe_video(stream, &probe);
> @@ -408,6 +435,7 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming
> *stream, }
>
> stream->ctrl = probe;
> + stream->cur_frame = frame;
> mutex_unlock(&stream->mutex);
>
> /* Return the actual frame period. */
> @@ -1209,7 +1237,8 @@ static int uvc_ioctl_enum_framesizes(struct file
> *file, void *fh, struct uvc_streaming *stream = handle->stream;
> struct uvc_format *format = NULL;
> struct uvc_frame *frame;
> - int i;
> + unsigned int index;
> + unsigned int i;
>
> /* Look for the given pixel format */
> for (i = 0; i < stream->nformats; i++) {
> @@ -1221,10 +1250,20 @@ static int uvc_ioctl_enum_framesizes(struct file
> *file, void *fh, if (format == NULL)
> return -EINVAL;
>
> - if (fsize->index >= format->nframes)
> + /* Skip duplicate frame sizes */
> + for (i = 0, index = 0; i < format->nframes; i++) {
> + if (i && frame->wWidth == format->frame[i].wWidth &&
> + frame->wHeight == format->frame[i].wHeight)
> + continue;
> + frame = &format->frame[i];
> + if (index == fsize->index)
> + break;
> + index++;
> + }
> +
> + if (i == format->nframes)
> return -EINVAL;
>
> - frame = &format->frame[fsize->index];
> fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
> fsize->discrete.width = frame->wWidth;
> fsize->discrete.height = frame->wHeight;
> @@ -1238,7 +1277,9 @@ static int uvc_ioctl_enum_frameintervals(struct file
> *file, void *fh, struct uvc_streaming *stream = handle->stream;
> struct uvc_format *format = NULL;
> struct uvc_frame *frame = NULL;
> - int i;
> + unsigned int nintervals;
> + unsigned int index;
> + unsigned int i;
>
> /* Look for the given pixel format and frame size */
> for (i = 0; i < stream->nformats; i++) {
> @@ -1250,30 +1291,28 @@ static int uvc_ioctl_enum_frameintervals(struct file
> *file, void *fh, if (format == NULL)
> return -EINVAL;
>
> + index = fival->index;
> for (i = 0; i < format->nframes; i++) {
> if (format->frame[i].wWidth == fival->width &&
> format->frame[i].wHeight == fival->height) {
> frame = &format->frame[i];
> - break;
> + nintervals = frame->bFrameIntervalType ?: 1;
> + if (index < nintervals)
> + break;
> + index -= nintervals;
> }
> }
> - if (frame == NULL)
> + if (i == format->nframes)
> return -EINVAL;
>
> if (frame->bFrameIntervalType) {
> - if (fival->index >= frame->bFrameIntervalType)
> - return -EINVAL;
> -
> fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
> fival->discrete.numerator =
> - frame->dwFrameInterval[fival->index];
> + frame->dwFrameInterval[index];
> fival->discrete.denominator = 10000000;
> uvc_simplify_fraction(&fival->discrete.numerator,
> &fival->discrete.denominator, 8, 333);
> } else {
> - if (fival->index)
> - return -EINVAL;
> -
> fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
> fival->stepwise.min.numerator = frame->dwFrameInterval[0];
> fival->stepwise.min.denominator = 10000000;
--
Regards,
Laurent Pinchart
next prev parent reply other threads:[~2018-01-05 13:30 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-04 22:51 [PATCH] media: uvcvideo: support multiple frame descriptors with the same dimensions Philipp Zabel
2018-01-05 13:30 ` Laurent Pinchart [this message]
2018-01-05 16:35 ` Philipp Zabel
-- strict thread matches above, loose matches on Subject: below --
2017-12-19 8:17 Philipp Zabel
2018-01-04 21:42 ` Laurent Pinchart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3663272.AjVBumhkVf@avalon \
--to=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=philipp.zabel@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).