Hi Ricardo and Dan,
could you please try the attached patch and see if it helps ?
Best regards,
Laurent Pinchart
Index: uvc_video.c
===================================================================
--- uvc_video.c (revision 209)
+++ uvc_video.c (working copy)
@@ -64,6 +64,31 @@
UVC_CTRL_CONTROL_TIMEOUT);
}
+static void uvc_fixup_buffer_size(struct uvc_video_device *video,
+ struct uvc_streaming_control *ctrl)
+{
+ struct uvc_format *format;
+ struct uvc_frame *frame;
+
+ if (ctrl->bFormatIndex <= 0 ||
+ ctrl->bFormatIndex > video->streaming->nformats)
+ return;
+
+ format = &video->streaming->format[ctrl->bFormatIndex - 1];
+
+ if (ctrl->bFrameIndex <= 0 ||
+ ctrl->bFrameIndex > format->nframes)
+ return;
+
+ frame = &format->frame[ctrl->bFrameIndex - 1];
+
+ if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
+ (ctrl->dwMaxVideoFrameSize == 0 &&
+ video->dev->uvc_version < 0x0110))
+ ctrl->dwMaxVideoFrameSize =
+ frame->dwMaxVideoFrameBufferSize;
+}
+
static int uvc_get_video_ctrl(struct uvc_video_device *video,
struct uvc_streaming_control *ctrl, int probe, __u8 query)
{
@@ -108,26 +133,11 @@
ctrl->bMaxVersion = 0;
}
- if (ctrl->dwMaxVideoFrameSize == 0 &&
- video->dev->uvc_version < 0x0110) {
- /* Some broken UVC 1.0 devices return a null
- * dwMaxVideoFrameSize. Try to get the value from the format
- * and frame descriptor.
- */
- const unsigned int fmt_index = ctrl->bFormatIndex;
- const unsigned int frm_index = ctrl->bFrameIndex;
- struct uvc_format *format = NULL;
- struct uvc_frame *frame = NULL;
+ /* Some broken devices return a null or wrong dwMaxVideoFrameSize.
+ * Try to get the value from the format and frame descriptor.
+ */
+ uvc_fixup_buffer_size(video, ctrl);
- if (fmt_index <= video->streaming->nformats && fmt_index != 0)
- format = &video->streaming->format[fmt_index - 1];
- if (format && frm_index <= format->nframes && frm_index != 0) {
- frame = &format->frame[frm_index - 1];
- ctrl->dwMaxVideoFrameSize =
- frame->dwMaxVideoFrameBufferSize;
- }
- }
-
return 0;
}
Index: uvc_driver.c
===================================================================
--- uvc_driver.c (revision 209)
+++ uvc_driver.c (working copy)
@@ -452,6 +452,18 @@
}
frame->dwFrameInterval = *intervals;
+ /* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
+ * completely. Observed behaviours range from setting the
+ * value to 1.1x the actual frame size of hardwiring the
+ * 16 low bits to 0. This results in a higher than necessary
+ * memory usage as well as a wrong image size information. For
+ * uncompressed formats this can be fixed by computing the
+ * value from the frame size.
+ */
+ if (!(format->flags & UVC_FMT_FLAG_COMPRESSED))
+ frame->dwMaxVideoFrameBufferSize = format->bpp
+ * frame->wWidth * frame->wHeight / 8;
+
/* Some bogus devices report dwMinFrameInterval equal to
* dwMaxFrameInterval and have dwFrameIntervalStep set to
* zero. Setting all null intervals to 1 fixes the problem and
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel