Em Quinta-feira 04 Junho 2009, às 07:41:03, Laurent Pinchart escreveu:
> Hi Herton,
> 
> On Wednesday 03 June 2009 23:02:33 Herton Ronaldo Krzesinski wrote:
> > Fix this by not failing entirely if we have found an invalid format, as
> > we can still have a valid format. The initial problem and solution
> > (patch) was debugged and done by Clevo (probably by Michael Wang),
> > which uses the affected webcam in one of their laptops. I'm forwarding
> > their fix plus additional code that I noticed to be needed for generic
> > cases that decrements properly streaming->nformats and checks later if
> > we really found at least one valid format, and if there were really no
> > valid formats we make sure then to return with error.
> 
> What about modifying uvc_parse_streaming() to stop parsing the interface
> descriptors when it encounters a non CS Interface descriptor instead ?
> Something like

Yep, it works for me too and it's better since then we don't allocate extra
memory that we don't use for streaming->format

But your solution stops to count formats at the first buffer[1] !=
CS_INTERFACE, is it possible that CS_INTERFACE and ! CS_INTERFACE are mixed?
(!= CS_INTERFACE not always the last one) In this case is better to continue,
like patch below:

diff -p -up linux/drivers/media/video/uvc/uvc_driver.c.orig 
linux/drivers/media/video/uvc/uvc_driver.c
--- linux/drivers/media/video/uvc/uvc_driver.c.orig     2009-06-03 
12:49:50.000000000 -0300
+++ linux/drivers/media/video/uvc/uvc_driver.c  2009-06-04 11:11:34.000000000 
-0300
@@ -645,42 +645,49 @@ static int uvc_parse_streaming(struct uv
 
        /* Count the format and frame descriptors. */
        while (_buflen > 2) {
-               switch (_buffer[2]) {
-               case VS_FORMAT_UNCOMPRESSED:
-               case VS_FORMAT_MJPEG:
-               case VS_FORMAT_FRAME_BASED:
-                       nformats++;
-                       break;
+               if (_buffer[1] == CS_INTERFACE) {
+                       switch (_buffer[2]) {
+                       case VS_FORMAT_UNCOMPRESSED:
+                       case VS_FORMAT_MJPEG:
+                       case VS_FORMAT_FRAME_BASED:
+                               nformats++;
+                               break;
 
-               case VS_FORMAT_DV:
-                       /* DV format has no frame descriptor. We will create a
-                        * dummy frame descriptor with a dummy frame interval.
-                        */
-                       nformats++;
-                       nframes++;
-                       nintervals++;
-                       break;
+                       case VS_FORMAT_DV:
+                               /* DV format has no frame descriptor. We will
+                                * create a dummy frame descriptor with a dummy
+                                * frame interval.
+                                */
+                               nformats++;
+                               nframes++;
+                               nintervals++;
+                               break;
 
-               case VS_FORMAT_MPEG2TS:
-               case VS_FORMAT_STREAM_BASED:
-                       uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
-                               "interface %d FORMAT %u is not supported.\n",
-                               dev->udev->devnum,
-                               alts->desc.bInterfaceNumber, _buffer[2]);
-                       break;
+                       case VS_FORMAT_MPEG2TS:
+                       case VS_FORMAT_STREAM_BASED:
+                               uvc_trace(UVC_TRACE_DESCR, "device %d "
+                                       "videostreaming interface %d FORMAT "
+                                       "%u is not supported.\n",
+                                       dev->udev->devnum,
+                                       alts->desc.bInterfaceNumber,
+                                       _buffer[2]);
+                               break;
 
-               case VS_FRAME_UNCOMPRESSED:
-               case VS_FRAME_MJPEG:
-                       nframes++;
-                       if (_buflen > 25)
-                               nintervals += _buffer[25] ? _buffer[25] : 3;
-                       break;
+                       case VS_FRAME_UNCOMPRESSED:
+                       case VS_FRAME_MJPEG:
+                               nframes++;
+                               if (_buflen > 25)
+                                       nintervals += _buffer[25] ?
+                                                     _buffer[25] : 3;
+                               break;
 
-               case VS_FRAME_FRAME_BASED:
-                       nframes++;
-                       if (_buflen > 21)
-                               nintervals += _buffer[21] ? _buffer[21] : 3;
-                       break;
+                       case VS_FRAME_FRAME_BASED:
+                               nframes++;
+                               if (_buflen > 21)
+                                       nintervals += _buffer[21] ?
+                                                     _buffer[21] : 3;
+                               break;
+                       }
                }
 
                _buflen -= _buffer[0];
@@ -710,26 +717,28 @@ static int uvc_parse_streaming(struct uv
 
        /* Parse the format descriptors. */
        while (buflen > 2) {
-               switch (buffer[2]) {
-               case VS_FORMAT_UNCOMPRESSED:
-               case VS_FORMAT_MJPEG:
-               case VS_FORMAT_DV:
-               case VS_FORMAT_FRAME_BASED:
-                       format->frame = frame;
-                       ret = uvc_parse_format(dev, streaming, format,
-                               &interval, buffer, buflen);
-                       if (ret < 0)
-                               goto error;
+               if (buffer[1] == CS_INTERFACE) {
+                       switch (buffer[2]) {
+                       case VS_FORMAT_UNCOMPRESSED:
+                       case VS_FORMAT_MJPEG:
+                       case VS_FORMAT_DV:
+                       case VS_FORMAT_FRAME_BASED:
+                               format->frame = frame;
+                               ret = uvc_parse_format(dev, streaming, format,
+                                       &interval, buffer, buflen);
+                               if (ret < 0)
+                                       goto error;
 
-                       frame += format->nframes;
-                       format++;
+                               frame += format->nframes;
+                               format++;
 
-                       buflen -= ret;
-                       buffer += ret;
-                       continue;
+                               buflen -= ret;
+                               buffer += ret;
+                               continue;
 
-               default:
-                       break;
+                       default:
+                               break;
+                       }
                }
 
                buflen -= buffer[0];


> 
> diff -r 66a270023c26 linux/drivers/media/video/uvc/uvc_driver.c
> --- a/linux/drivers/media/video/uvc/uvc_driver.c      Sun May 31 22:05:55 
> 2009 +0200
> +++ b/linux/drivers/media/video/uvc/uvc_driver.c      Thu Jun 04 12:40:09 
> 2009 +0200
> @@ -644,7 +644,7 @@
>       _buflen = buflen;
>  
>       /* Count the format and frame descriptors. */
> -     while (_buflen > 2) {
> +     while (_buflen > 2 && _buffer[1] == CS_INTERFACE) {
>               switch (_buffer[2]) {
>               case VS_FORMAT_UNCOMPRESSED:
>               case VS_FORMAT_MJPEG:
> @@ -709,7 +709,7 @@
>       streaming->nformats = nformats;
>  
>       /* Parse the format descriptors. */
> -     while (buflen > 2) {
> +     while (buflen > 2 && buffer[1] == CS_INTERFACE) {
>               switch (buffer[2]) {
>               case VS_FORMAT_UNCOMPRESSED:
>               case VS_FORMAT_MJPEG:
> 
> Best regards,
> 
> Laurent Pinchart
> 
> 

--
[]'s
Herton
_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to