@@ -220,20 +220,127 @@ static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev,
220220 * Descriptors parsing
221221 */
222222
223+ static int uvc_parse_frame (struct uvc_device * dev ,
224+ struct uvc_streaming * streaming ,
225+ struct uvc_format * format , struct uvc_frame * frame ,
226+ u32 * * intervals , u8 ftype , int width_multiplier ,
227+ const unsigned char * buffer , int buflen )
228+ {
229+ struct usb_host_interface * alts = streaming -> intf -> cur_altsetting ;
230+ unsigned int maxIntervalIndex ;
231+ unsigned int interval ;
232+ unsigned int i , n ;
233+
234+ if (ftype != UVC_VS_FRAME_FRAME_BASED )
235+ n = buflen > 25 ? buffer [25 ] : 0 ;
236+ else
237+ n = buflen > 21 ? buffer [21 ] : 0 ;
238+
239+ n = n ? n : 3 ;
240+
241+ if (buflen < 26 + 4 * n ) {
242+ uvc_dbg (dev , DESCR ,
243+ "device %d videostreaming interface %d FRAME error\n" ,
244+ dev -> udev -> devnum , alts -> desc .bInterfaceNumber );
245+ return - EINVAL ;
246+ }
247+
248+ frame -> bFrameIndex = buffer [3 ];
249+ frame -> bmCapabilities = buffer [4 ];
250+ frame -> wWidth = get_unaligned_le16 (& buffer [5 ]) * width_multiplier ;
251+ frame -> wHeight = get_unaligned_le16 (& buffer [7 ]);
252+ frame -> dwMinBitRate = get_unaligned_le32 (& buffer [9 ]);
253+ frame -> dwMaxBitRate = get_unaligned_le32 (& buffer [13 ]);
254+ if (ftype != UVC_VS_FRAME_FRAME_BASED ) {
255+ frame -> dwMaxVideoFrameBufferSize =
256+ get_unaligned_le32 (& buffer [17 ]);
257+ frame -> dwDefaultFrameInterval =
258+ get_unaligned_le32 (& buffer [21 ]);
259+ frame -> bFrameIntervalType = buffer [25 ];
260+ } else {
261+ frame -> dwMaxVideoFrameBufferSize = 0 ;
262+ frame -> dwDefaultFrameInterval =
263+ get_unaligned_le32 (& buffer [17 ]);
264+ frame -> bFrameIntervalType = buffer [21 ];
265+ }
266+
267+ /*
268+ * Copy the frame intervals.
269+ *
270+ * Some bogus devices report dwMinFrameInterval equal to
271+ * dwMaxFrameInterval and have dwFrameIntervalStep set to zero. Setting
272+ * all null intervals to 1 fixes the problem and some other divisions
273+ * by zero that could happen.
274+ */
275+ frame -> dwFrameInterval = * intervals ;
276+
277+ for (i = 0 ; i < n ; ++ i ) {
278+ interval = get_unaligned_le32 (& buffer [26 + 4 * i ]);
279+ (* intervals )[i ] = interval ? interval : 1 ;
280+ }
281+
282+ /*
283+ * Apply more fixes, quirks and workarounds to handle incorrect or
284+ * broken descriptors.
285+ */
286+
287+ /*
288+ * Several UVC chipsets screw up dwMaxVideoFrameBufferSize completely.
289+ * Observed behaviours range from setting the value to 1.1x the actual
290+ * frame size to hardwiring the 16 low bits to 0. This results in a
291+ * higher than necessary memory usage as well as a wrong image size
292+ * information. For uncompressed formats this can be fixed by computing
293+ * the value from the frame size.
294+ */
295+ if (!(format -> flags & UVC_FMT_FLAG_COMPRESSED ))
296+ frame -> dwMaxVideoFrameBufferSize = format -> bpp * frame -> wWidth
297+ * frame -> wHeight / 8 ;
298+
299+ /*
300+ * Clamp the default frame interval to the boundaries. A zero
301+ * bFrameIntervalType value indicates a continuous frame interval
302+ * range, with dwFrameInterval[0] storing the minimum value and
303+ * dwFrameInterval[1] storing the maximum value.
304+ */
305+ maxIntervalIndex = frame -> bFrameIntervalType ? n - 1 : 1 ;
306+ frame -> dwDefaultFrameInterval =
307+ clamp (frame -> dwDefaultFrameInterval ,
308+ frame -> dwFrameInterval [0 ],
309+ frame -> dwFrameInterval [maxIntervalIndex ]);
310+
311+ /*
312+ * Some devices report frame intervals that are not functional. If the
313+ * corresponding quirk is set, restrict operation to the first interval
314+ * only.
315+ */
316+ if (dev -> quirks & UVC_QUIRK_RESTRICT_FRAME_RATE ) {
317+ frame -> bFrameIntervalType = 1 ;
318+ (* intervals )[0 ] = frame -> dwDefaultFrameInterval ;
319+ }
320+
321+ uvc_dbg (dev , DESCR , "- %ux%u (%u.%u fps)\n" ,
322+ frame -> wWidth , frame -> wHeight ,
323+ 10000000 / frame -> dwDefaultFrameInterval ,
324+ (100000000 / frame -> dwDefaultFrameInterval ) % 10 );
325+
326+ * intervals += n ;
327+
328+ return buffer [0 ];
329+ }
330+
223331static int uvc_parse_format (struct uvc_device * dev ,
224332 struct uvc_streaming * streaming , struct uvc_format * format ,
225333 struct uvc_frame * frames , u32 * * intervals , const unsigned char * buffer ,
226334 int buflen )
227335{
228- struct usb_interface * intf = streaming -> intf ;
229- struct usb_host_interface * alts = intf -> cur_altsetting ;
336+ struct usb_host_interface * alts = streaming -> intf -> cur_altsetting ;
230337 const struct uvc_format_desc * fmtdesc ;
231338 struct uvc_frame * frame ;
232339 const unsigned char * start = buffer ;
233340 unsigned int width_multiplier = 1 ;
234- unsigned int interval ;
235341 unsigned int i , n ;
236342 u8 ftype ;
343+ int ret ;
237344
238345 format -> type = buffer [2 ];
239346 format -> index = buffer [3 ];
@@ -371,111 +478,19 @@ static int uvc_parse_format(struct uvc_device *dev,
371478 * Parse the frame descriptors. Only uncompressed, MJPEG and frame
372479 * based formats have frame descriptors.
373480 */
374- while (ftype && buflen > 2 && buffer [1 ] == USB_DT_CS_INTERFACE &&
375- buffer [2 ] == ftype ) {
376- unsigned int maxIntervalIndex ;
377-
378- frame = & frames [format -> nframes ];
379- if (ftype != UVC_VS_FRAME_FRAME_BASED )
380- n = buflen > 25 ? buffer [25 ] : 0 ;
381- else
382- n = buflen > 21 ? buffer [21 ] : 0 ;
383-
384- n = n ? n : 3 ;
385-
386- if (buflen < 26 + 4 * n ) {
387- uvc_dbg (dev , DESCR ,
388- "device %d videostreaming interface %d FRAME error\n" ,
389- dev -> udev -> devnum ,
390- alts -> desc .bInterfaceNumber );
391- return - EINVAL ;
392- }
393-
394- frame -> bFrameIndex = buffer [3 ];
395- frame -> bmCapabilities = buffer [4 ];
396- frame -> wWidth = get_unaligned_le16 (& buffer [5 ])
397- * width_multiplier ;
398- frame -> wHeight = get_unaligned_le16 (& buffer [7 ]);
399- frame -> dwMinBitRate = get_unaligned_le32 (& buffer [9 ]);
400- frame -> dwMaxBitRate = get_unaligned_le32 (& buffer [13 ]);
401- if (ftype != UVC_VS_FRAME_FRAME_BASED ) {
402- frame -> dwMaxVideoFrameBufferSize =
403- get_unaligned_le32 (& buffer [17 ]);
404- frame -> dwDefaultFrameInterval =
405- get_unaligned_le32 (& buffer [21 ]);
406- frame -> bFrameIntervalType = buffer [25 ];
407- } else {
408- frame -> dwMaxVideoFrameBufferSize = 0 ;
409- frame -> dwDefaultFrameInterval =
410- get_unaligned_le32 (& buffer [17 ]);
411- frame -> bFrameIntervalType = buffer [21 ];
412- }
413-
414- /*
415- * Copy the frame intervals.
416- *
417- * Some bogus devices report dwMinFrameInterval equal to
418- * dwMaxFrameInterval and have dwFrameIntervalStep set to
419- * zero. Setting all null intervals to 1 fixes the problem and
420- * some other divisions by zero that could happen.
421- */
422- frame -> dwFrameInterval = * intervals ;
423-
424- for (i = 0 ; i < n ; ++ i ) {
425- interval = get_unaligned_le32 (& buffer [26 + 4 * i ]);
426- (* intervals )[i ] = interval ? interval : 1 ;
427- }
428-
429- /*
430- * Apply more fixes, quirks and workarounds to handle incorrect
431- * or broken descriptors.
432- */
433-
434- /*
435- * Several UVC chipsets screw up dwMaxVideoFrameBufferSize
436- * completely. Observed behaviours range from setting the
437- * value to 1.1x the actual frame size to hardwiring the
438- * 16 low bits to 0. This results in a higher than necessary
439- * memory usage as well as a wrong image size information. For
440- * uncompressed formats this can be fixed by computing the
441- * value from the frame size.
442- */
443- if (!(format -> flags & UVC_FMT_FLAG_COMPRESSED ))
444- frame -> dwMaxVideoFrameBufferSize = format -> bpp
445- * frame -> wWidth * frame -> wHeight / 8 ;
446-
447- /*
448- * Clamp the default frame interval to the boundaries. A zero
449- * bFrameIntervalType value indicates a continuous frame
450- * interval range, with dwFrameInterval[0] storing the minimum
451- * value and dwFrameInterval[1] storing the maximum value.
452- */
453- maxIntervalIndex = frame -> bFrameIntervalType ? n - 1 : 1 ;
454- frame -> dwDefaultFrameInterval =
455- clamp (frame -> dwDefaultFrameInterval ,
456- frame -> dwFrameInterval [0 ],
457- frame -> dwFrameInterval [maxIntervalIndex ]);
458-
459- /*
460- * Some devices report frame intervals that are not functional.
461- * If the corresponding quirk is set, restrict operation to the
462- * first interval only.
463- */
464- if (dev -> quirks & UVC_QUIRK_RESTRICT_FRAME_RATE ) {
465- frame -> bFrameIntervalType = 1 ;
466- (* intervals )[0 ] = frame -> dwDefaultFrameInterval ;
481+ if (ftype ) {
482+ while (buflen > 2 && buffer [1 ] == USB_DT_CS_INTERFACE &&
483+ buffer [2 ] == ftype ) {
484+ frame = & frames [format -> nframes ];
485+ ret = uvc_parse_frame (dev , streaming , format , frame ,
486+ intervals , ftype , width_multiplier ,
487+ buffer , buflen );
488+ if (ret < 0 )
489+ return ret ;
490+ format -> nframes ++ ;
491+ buflen -= ret ;
492+ buffer += ret ;
467493 }
468-
469- uvc_dbg (dev , DESCR , "- %ux%u (%u.%u fps)\n" ,
470- frame -> wWidth , frame -> wHeight ,
471- 10000000 / frame -> dwDefaultFrameInterval ,
472- (100000000 / frame -> dwDefaultFrameInterval ) % 10 );
473-
474- format -> nframes ++ ;
475- * intervals += n ;
476-
477- buflen -= buffer [0 ];
478- buffer += buffer [0 ];
479494 }
480495
481496 if (buflen > 2 && buffer [1 ] == USB_DT_CS_INTERFACE &&
0 commit comments