@@ -220,20 +220,127 @@ static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev,
220
220
* Descriptors parsing
221
221
*/
222
222
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
+
223
331
static int uvc_parse_format (struct uvc_device * dev ,
224
332
struct uvc_streaming * streaming , struct uvc_format * format ,
225
333
struct uvc_frame * frames , u32 * * intervals , const unsigned char * buffer ,
226
334
int buflen )
227
335
{
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 ;
230
337
const struct uvc_format_desc * fmtdesc ;
231
338
struct uvc_frame * frame ;
232
339
const unsigned char * start = buffer ;
233
340
unsigned int width_multiplier = 1 ;
234
- unsigned int interval ;
235
341
unsigned int i , n ;
236
342
u8 ftype ;
343
+ int ret ;
237
344
238
345
format -> type = buffer [2 ];
239
346
format -> index = buffer [3 ];
@@ -371,111 +478,19 @@ static int uvc_parse_format(struct uvc_device *dev,
371
478
* Parse the frame descriptors. Only uncompressed, MJPEG and frame
372
479
* based formats have frame descriptors.
373
480
*/
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 ;
467
493
}
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 ];
479
494
}
480
495
481
496
if (buflen > 2 && buffer [1 ] == USB_DT_CS_INTERFACE &&
0 commit comments