get_unaligned_le32(&buffer[17]);
frame->bFrameIntervalType = buffer[21];
}
+
+ /*
+ * Copy the frame intervals.
+ *
+ * Some bogus devices report dwMinFrameInterval equal to
+ * dwMaxFrameInterval and have dwFrameIntervalStep set to
+ * zero. Setting all null intervals to 1 fixes the problem and
+ * some other divisions by zero that could happen.
+ */
frame->dwFrameInterval = *intervals;
+ for (i = 0; i < n; ++i) {
+ interval = get_unaligned_le32(&buffer[26+4*i]);
+ *(*intervals)++ = interval ? interval : 1;
+ }
+
+ /*
+ * Apply more fixes, quirks and workarounds to handle incorrect
+ * or broken descriptors.
+ */
+
/*
* Several UVC chipsets screw up dwMaxVideoFrameBufferSize
* completely. Observed behaviours range from setting the
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
- * some other divisions by zero that could happen.
- */
- for (i = 0; i < n; ++i) {
- interval = get_unaligned_le32(&buffer[26+4*i]);
- *(*intervals)++ = interval ? interval : 1;
- }
-
- /*
- * Make sure that the default frame interval stays between
- * the boundaries.
- */
+ /* Clamp the default frame interval to the boundaries. */
n -= frame->bFrameIntervalType ? 1 : 2;
frame->dwDefaultFrameInterval =
clamp(frame->dwDefaultFrameInterval,
frame->dwFrameInterval[0],
frame->dwFrameInterval[n]);
+ /*
+ * Some devices report frame intervals that are not functional.
+ * If the corresponding quirk is set, restrict operation to the
+ * first interval only.
+ */
if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) {
frame->bFrameIntervalType = 1;
frame->dwFrameInterval[0] =