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