Share

SPCA50X USB Camera Linux Driver

Email Archive: spca50x-devs (read-only)

[Spca50x-devs] Adding gspca to the mainline kernel
From: Denver Gingerich <denver@os...> - 2007-06-04 02:28
I'd like to re-open the discussion into mainlining the gspca driver
because I feel there are some aspects of the discussion that haven't
been dealt with much. I've searched the list archives for past
discussions so hopefully there isn't too much repeat here (and if
there is, I'm intentionally quoting someone).

Based on my own experiences with the driver, including delving into
the code, here are the main reasons I see for mainlining the kernel
(in approximate order of importance):

1. Code accepted into the mainline kernel must meet certain quality
standards. Attempting to mainline the gspca driver would be met with
many suggestions for how to improve the code, allowing us to improve
the driver.

There are several issues pertaining to code quality that I have seen
in the gspca driver. The first is broken support for older hardware.
According to Michel, the gspca driver (spca50x at the time) used to
support composite video in on the CS430, but that functionality is
broken as I found out when I tried to use it with my CS430 webcam. If
the gspca driver had more stringent requirements on code submissions
as the Linux kernel does, these sorts of issues would be less likely
to occur.

The second is lack of support for multiple simultaneously-connected
webcams. From what I can tell, the gspca driver only recognizes one
gspca-compatible webcam even if more than one is connected to a given
computer. Usually mainlined drivers will be checked for these sorts
of robustness problems prior to inclusion.

The third is the abuse of header files to add webcam-specific code.
Header files should be used for function declarations, but NOT for
function implementations, especially when these implementations are
more than one line. The current .h files should be separated into .h
and .c files so the .c files can be compiled into their own object
files and then linked together to produce the gspca module.

Certainly all of the above code quality problems could be fixed
without mainlining the gspca driver. However, maintaining a high
level of code quality would best be done by adding the driver to the
mainline kernel because the kernel maintainers tend to demand
high-quality code.

I am not trying to say that the current code is horrible and
unmaintainable. I can see the reasons for not demanding the same
level of quality that the kernel people demand. Doing so makes
development move faster (people want their webcams working right
away), but it does lead to some crufty code that needs refactoring.


2. The gspca driver will benefit from kernel-wide fixes, such as
interface updates.

This is a common reason for mainlining any driver. An example of how
this would help the gspca driver is in the move from v4l to v4l2. The
onus for making the interface update would be shared between the gspca
maintainers and more general kernel maintainers; right now, the gspca
maintainers alone must make the interface update.


3. Distribution maintainers do not need to worry about including a
gspca package in their distribution.

Currently, in order to provide full webcam support for their users,
distribution maintainers need to maintain a gspca package to include
with their distribution. If the gspca driver were mainlined, this
would give distribution maintainers one less package to worry about
(since the gspca driver would effectively be included in their kernel
package), reducing their workload.


Of course there are also problems to overcome in order to mainline the
driver. I think some of these problems have been framed as barriers
that totally prevent the driver from being mainlined, but I don't
think that has to be the case. Here are some problems with mainlining
the kernel along with suggestions for overcoming them:

A. The development pace of the gspca driver is much faster than that
of the mainline kernel. Kernel submission procedures are too
restrictive and would prevent new webcams from being supported in a
timely fashion. [1] [2]

I don't think this is entirely true. Another webcam driver, the ov511
driver (http://ovcam.org/ov511/), has code in the kernel that is only
one minor release behind their most recent version, suggesting that
their changes are usually accepted in a timely manner by the kernel
people. I think we should at least consider doing things the way the
ov511 people do.

B. JPEG decoding is not allowed in the kernel and the gspca driver has
to include a JPEG decoder. [1] [3] [4]

This may be the case with the first version of v4l because some
webcams send JPEG data over USB and v4l requires data from the kernel
to be in uncompressed form. However, v4l2 allows drivers to pass JPEG
data directly to user space [5] [6] so this argument is no longer
valid. Most applications that use v4l have switched to v4l2 so it
would make sense for gspca to do the same (I understand this is
already in the works).

If we must continue to support v4l version 1, then we can use a method
like the ov511 people chose: mainline what you can and keep the
decompressor available out of the mainline for those who need it.


Here's what I suggest as a course of action:
1. Refactor the gspca driver so it works more like a Linux subsystem
(see drivers/leds in the Linux kernel
(http://lxr.linux.no/source/drivers/leds/) for a simple example of
such a subsystem)
- this would involve having each type of camera register itself with
the gspca core, which would provide some common functionality each
camera needs
- it would be good to see if over webcam projects, like ov511,
already have a subsystem setup which we could plug into or model our
new subsystem after
2. Fix up whatever other problems were not solved by the refactoring
(ie. add support for multiple simultaneously-connected web cams, make
everything work with v4l2)
3. Submit the code to the appropriate list (perhaps linux-usb-devel
would be the correct one, but I'm not entirely sure)


I am willing to help out with these efforts (as time permits), but I'd
need some support. If more people working on the gspca driver feel
that the driver should be mainlined, then I would be inclined to start
this process. But if few people are in support of the idea, it
doesn't make much sense to proceed.

If you strongly feel the gspca driver should not be mainlined, please
explain why. I think it's important that we get some good discussion
going on about this issue because it would mean an important change of
focus for the driver.

Denver



References:
1. Comments from Tomas Groth on mainlining the driver -

http://sourceforge.net/mailarchive/message.php?msg_id=20060720124839.64364.qmail%40web34707.mail.mud.yahoo.com
2. Comments from Michel Xhaard on freedom of current model -
http://mxhaard.free.fr/sview.html (see "Overview", paragraph 2)
3. Comments from Thomas Schorpp quoting Michel Xhaard as saying JPEG
decoder won't make it into kernel -
http://sourceforge.net/mailarchive/message.php?msg_name=450D3EC7.7090609%40gmx.de
4. First question in OV519 section suggests JPEG decoder in kernel is
impossible - http://ovcam.org/ov511/faq.html
5. v4l2 supports JPEG through the V4L2_PIX_FMT_JPEG option -
http://royale.zerezo.com/forum/viewtopic.php?p=418
6. Specification for v4l2 showing JPEG support -
http://v4l2spec.bytesex.org/spec-single/v4l2.html#STANDARD

 

Thread View

Thread Author Date
[Spca50x-devs] Adding gspca to the mainline kernel Denver Gingerich <denver@os...>
From: Serge A. Suchkov <Serge.S@to...> - 2007-06-04 06:40

Attachments: WebCam3c.png     
Hi Denver and all.
I shall afford some remarks on this theme

>1. Code accepted into the mainline kernel must meet certain quality
>standards.

What you mean when you say about "code quality standards" ?

> The second is lack of support for multiple simultaneously-connected
> webcams.  From what I can tell, the gspca driver only recognizes one
> gspca-compatible webcam even if more than one is connected to a given
> computer.  Usually mainlined drivers will be checked for these sorts
> of robustness problems prior to inclusion.

Denver, what you mean in this case ?
GSPCA work with multiple simultaneously-connected webcams pretty good.
Some problems can take place with USB bandwidth, but in this case GSPCA driver
has the certain advantages in comparison with other webcam drivers owing to an opportunity
dynamically allocated bandwidth for attached devices...see attached screenshot.
(it is my modular gspca branch but it has on 100% identically working code with original gspca)

>The third is the abuse of header files to add webcam-specific code.
>Header files should be used for function declarations, but NOT for
>function implementations, especially when these implementations are
>more than one line. The current .h files should be separated into .h
>and .c files so the .c files can be compiled into their own object
>files and then linked together to produce the gspca module.

It is not "code quality" problem. It is only "code style" issue.

>If we must continue to support v4l version 1, then we can use a method
>like the ov511 people chose: mainline what you can and keep the
>decompressor available out of the mainline for those who need it.

In my opinion the basic problems connected with low speed of transition from v4l1 to v4l2
just are connected by that decompressor now should is in userspace libraries, however it
creates the certain problems with backward compatibility.
In this case I consider your offer reasonable.

>If you strongly feel the gspca driver should not be mainlined, please
>explain why.

Denver, I believe that by the current moment nor gspca nor similar subsystems in the mainline kernel
have no harmonous, transparent general architecture or model of such architecture.
Entering gspca a code in a kernel in the present kind in my opinion prematurely.


--
Regards,
Serge A. Suchkov
--
Don't look back, the lemmings are gaining on you.

From: Michel Xhaard <mxhaard@ma...> - 2007-06-04 16:35
Le Lundi 4 Juin 2007 08:40, vous avez =C3=A9crit=C2=A0:
Hi Denver, Serge and all,
> Hi Denver and all.
> I shall afford some remarks on this theme
>
> >1. Code accepted into the mainline kernel must meet certain quality
> >standards.
>
> What you mean when you say about "code quality standards" ?
:)
>
> > The second is lack of support for multiple simultaneously-connected
> > webcams. =C2=A0From what I can tell, the gspca driver only recognizes o=
ne
> > gspca-compatible webcam even if more than one is connected to a given
> > computer. =C2=A0Usually mainlined drivers will be checked for these sor=
ts
> > of robustness problems prior to inclusion.
Ho Ho !!=20
>
> Denver, what you mean in this case ?
> GSPCA work with multiple simultaneously-connected webcams pretty good.
> Some problems can take place with USB bandwidth, but in this case GSPCA
> driver has the certain advantages in comparison with other webcam drivers
> owing to an opportunity dynamically allocated bandwidth for attached
> devices...see attached screenshot. (it is my modular gspca branch but it
> has on 100% identically working code with original gspca)
look here:
http://mxhaard.free.fr/spca50x/Doc/allinone/four_spca5xxwebcam.jpg

>
> >The third is the abuse of header files to add webcam-specific code.
> >Header files should be used for function declarations, but NOT for
> >function implementations, especially when these implementations are
> >more than one line. The current .h files should be separated into .h
> >and .c files so the .c files can be compiled into their own object
> >files and then linked together to produce the gspca module.
>
> It is not "code quality" problem. It is only "code style" issue.
Sorry man, i like *.inc file, maybe because i work a lot with assembler :)=
=20
>
> >If we must continue to support v4l version 1, then we can use a method
> >like the ov511 people chose: mainline what you can and keep the
> >decompressor available out of the mainline for those who need it.
Yes, i did not like this. My goal is to provided a working driver not to be=
=20
happy with a really good code, but no one can used ! As i say here, gspca i=
s=20
"users centric" NOT "kernel centric" .
http://www.theinquirer.net/default.aspx?article=3D39291
>
> In my opinion the basic problems connected with low speed of transition
> from v4l1 to v4l2 just are connected by that decompressor now should is in
> userspace libraries, however it creates the certain problems with backward
> compatibility.
The fourcc method in v4l2 should never works for the ton of proprietary=20
compressor, that is my opinion, after 5 years of people waiting this=20
wonderfull userspace video library, i am afraid, the concept is wrong !=20
> In this case I consider your offer reasonable.
>
> >If you strongly feel the gspca driver should not be mainlined, please
> >explain why.
I received a lot of mail about that:
What is wrong with GPL code outside the main line kernel ?
Is there only one way togo ? If so what "free" mean ?
>
> Denver, I believe that by the current moment nor gspca nor similar
> subsystems in the mainline kernel have no harmonous, transparent general
> architecture or model of such architecture. Entering gspca a code in a
> kernel in the present kind in my opinion prematurely.
Regards
=2D-=20
Michel Xhaard
http://mxhaard.free.fr

From: Denver Gingerich <denver@os...> - 2007-06-04 20:04
On 6/4/07, Michel Xhaard <mxhaard@ma...> wrote:
> > >1. Code accepted into the mainline kernel must meet certain quality
> > >standards.
> >
> > What you mean when you say about "code quality standards" ?
> :)

I'm talking mainly about two things: coding style and more general
overall code structure. The gspca driver has poor coding style in a
number of ways:
- too many indentations make the code unreadable (see spca5xx_setMode,
spca50x_move_data)
- code that indents too many times should be moved into a separate function
- inconsistent indentations (see spca5xx_set_light_freq, which uses
spaces instead of tabs, like the rest of the code uses)

The gspca driver has poor overall code style as well:
- the USB IDs and names of webcams should be associated with their
specific driver code, not contained in a huge list in gspca_core.c; it
makes it much easier to figure out which camera uses which driver when
the USB IDs and names are in the same file as the code that handles
them
- the header file abuse I mentioned earlier (see below)

> > Denver, what you mean in this case ?
> > GSPCA work with multiple simultaneously-connected webcams pretty good.
> > Some problems can take place with USB bandwidth, but in this case GSPCA
> > driver has the certain advantages in comparison with other webcam drivers
> > owing to an opportunity dynamically allocated bandwidth for attached
> > devices...see attached screenshot. (it is my modular gspca branch but it
> > has on 100% identically working code with original gspca)
> look here:
> http://mxhaard.free.fr/spca50x/Doc/allinone/four_spca5xxwebcam.jpg

My apologies. I should have looked into this a bit further. I had
tried to do this but it didn't work for me for some reason. I
incorrectly assumed it was the driver's fault, but clearly it is a
fault in the user.

> > >The third is the abuse of header files to add webcam-specific code.
> > >Header files should be used for function declarations, but NOT for
> > >function implementations, especially when these implementations are
> > >more than one line. The current .h files should be separated into .h
> > >and .c files so the .c files can be compiled into their own object
> > >files and then linked together to produce the gspca module.
> >
> > It is not "code quality" problem. It is only "code style" issue.
> Sorry man, i like *.inc file, maybe because i work a lot with assembler :)

I think if you asked around (especially among kernel developers), you
would find that this is frowned upon for many reasons. I recall a
post from Linus on the LKML about this. I'll find it and post back.

> > >If we must continue to support v4l version 1, then we can use a method
> > >like the ov511 people chose: mainline what you can and keep the
> > >decompressor available out of the mainline for those who need it.
> Yes, i did not like this. My goal is to provided a working driver not to be
> happy with a really good code, but no one can used ! As i say here, gspca is
> "users centric" NOT "kernel centric" .
> http://www.theinquirer.net/default.aspx?article=39291

Are you saying we need to continue to support v4l1? Why? From what I
recall, most applications have moved to v4l2 already.

> > In my opinion the basic problems connected with low speed of transition
> > from v4l1 to v4l2 just are connected by that decompressor now should is in
> > userspace libraries, however it creates the certain problems with backward
> > compatibility.
> The fourcc method in v4l2 should never works for the ton of proprietary
> compressor, that is my opinion, after 5 years of people waiting this
> wonderfull userspace video library, i am afraid, the concept is wrong !

I'm not sure precisely what you mean, but I think you're referring to
some of the webcam data formats that are not quite standard JPEG so
they need a bit of processing before being passed to userspace. What
do the Windows driver do about this? Certainly they don't decompress,
process, then recompress the JPEG before delivering it to the
application. I think we need some more investigation into this.

> > >If you strongly feel the gspca driver should not be mainlined, please
> > >explain why.
> I received a lot of mail about that:
> What is wrong with GPL code outside the main line kernel ?
> Is there only one way togo ? If so what "free" mean ?

I'm not saying that maintaining a driver outside of the mainline
kernel is wrong. But I think there the benefits of moving the gspca
driver into the mainline kernel outweigh the costs, which is why we
should strongly consider doing that.

> > Denver, I believe that by the current moment nor gspca nor similar
> > subsystems in the mainline kernel have no harmonous, transparent general
> > architecture or model of such architecture. Entering gspca a code in a
> > kernel in the present kind in my opinion prematurely.

If there is no current subsystem, then we should make one. It seems
logical to have a webcam subsystem that you could register with to
utilize standard webcam functions.

Denver

From: Denver Gingerich <denver@os...> - 2007-06-05 03:28
On 6/4/07, Denver Gingerich <denver@os...> wrote:
> > > >The third is the abuse of header files to add webcam-specific code.
> > > >Header files should be used for function declarations, but NOT for
> > > >function implementations, especially when these implementations are
> > > >more than one line. The current .h files should be separated into .h
> > > >and .c files so the .c files can be compiled into their own object
> > > >files and then linked together to produce the gspca module.
> > >
> > > It is not "code quality" problem. It is only "code style" issue.
> > Sorry man, i like *.inc file, maybe because i work a lot with assembler :)
>
> I think if you asked around (especially among kernel developers), you
> would find that this is frowned upon for many reasons. I recall a
> post from Linus on the LKML about this. I'll find it and post back.

The relevant posts from Linus that I was thinking of are the following:

from http://lkml.org/lkml/2007/2/28/180:
- in header files, we put "common definitions":
* #defines
* data structure declarations
* external function and data declarations
* inline functions ("nicer but otherwise equivalent to a #define")
- but we do *not* put
* actual real code
* actual real data
because those go into C files.

from http://lkml.org/lkml/2007/2/28/185:
If it has real code or data in it, it's a .c file, and you don't
#include it, you *compile* it and you *link* it.

Linus does go on to say that for every rule there are exceptions, but
he would rather not add new ugly stuff (suggesting that code added to
the kernel should follow the policy of no real code or data in header
files).

Denver

From: Serge A. Suchkov <Serge.S@to...> - 2007-06-05 03:54
В сообщении от 5 июня 2007 00:04 вы написали:
> On 6/4/07, Michel Xhaard <mxhaard@ma...> wrote:
> > > >1. Code accepted into the mainline kernel must meet certain quality
> > > >standards.
> > >
> > > What you mean when you say about "code quality standards" ?
> > :)
>
> I'm talking mainly about two things: coding style and more general
> overall code structure. The gspca driver has poor coding style in a
> number of ways:
> - too many indentations make the code unreadable (see spca5xx_setMode,
> spca50x_move_data)
> - code that indents too many times should be moved into a separate function
> - inconsistent indentations (see spca5xx_set_light_freq, which uses
> spaces instead of tabs, like the rest of the code uses)

I'm sorry ;) Just my IDE has such adjustments for my projects.
In my IDE this code style looks pretty good.
hint: Modern IDE allow to change indent style one command ;)

>
> The gspca driver has poor overall code style as well:
> - the USB IDs and names of webcams should be associated with their
> specific driver code, not contained in a huge list in gspca_core.c;

OK. See http://mgspca.e1.bmstu.ru
Especially mgspcav1-01.00.12-2 and mgspcav2-02.00.20-1

> it
> makes it much easier to figure out which camera uses which driver when
> the USB IDs and names are in the same file as the code that handles
> them
> - the header file abuse I mentioned earlier (see below)

But all it has no attitude to "quality of a code" it concerns to style of the coding introduced by numerous authors of various parts gspca more likely

>
> > > >If we must continue to support v4l version 1, then we can use a method
> > > >like the ov511 people chose: mainline what you can and keep the
> > > >decompressor available out of the mainline for those who need it.
> > Yes, i did not like this. My goal is to provided a working driver not to be
> > happy with a really good code, but no one can used ! As i say here, gspca is
> > "users centric" NOT "kernel centric" .
> > http://www.theinquirer.net/default.aspx?article=39291
>
> Are you saying we need to continue to support v4l1? Why? From what I
> recall, most applications have moved to v4l2 already.

"Most" ??? Name please even 5 applications. AFAIK more ore less well with current versions v4l2 drivers for webcams work only luvcview by Michel and ekiga.
In the others take place to be problems of this or that sort. The basic problem of compatibility with v4l1 consists in absence userspace libraries of proprietary
decoders and here the layer of compatibility with v4l1 which will not help even is available in v4l2
>
> > > In my opinion the basic problems connected with low speed of transition
> > > from v4l1 to v4l2 just are connected by that decompressor now should is in
> > > userspace libraries, however it creates the certain problems with backward
> > > compatibility.
> > The fourcc method in v4l2 should never works for the ton of proprietary
> > compressor, that is my opinion, after 5 years of people waiting this
> > wonderfull userspace video library, i am afraid, the concept is wrong !
+1
>
> If there is no current subsystem, then we should make one. It seems
> logical to have a webcam subsystem that you could register with to
> utilize standard webcam functions.

We work in this direction. Though speed of work probably not too impresses ;)
In GSPCA in my opinion many architectural problems which were to be solved
as much as possible effectively and elegantly and to be engaged cosmetic refactoring
not having solved these fundamental problems in my opinion waste of time and forces

>
> Denver
>

--
Regards,
Serge A. Suchkov
--
DeVries's Dilemma:
If you hit two keys on the typewriter, the one you don't want
hits the paper.

From: Denver Gingerich <denver@os...> - 2007-06-05 22:00
T24gNi80LzA3LCBTZXJnZSBBLiBTdWNoa292IDxTZXJnZS5BLlNAdG9jaGthLnJ1PiB3cm90ZToK
PiD3INPPz8Ldxc7JySDP1CA1IMnAztEgMjAwNyAwMDowNCDX2SDOwdDJ08HMyToKPiA+IE9uIDYv
NC8wNywgTWljaGVsIFhoYWFyZCA8bXhoYWFyZEBtYWdpYy5mcj4gd3JvdGU6Cj4gPiA+ID4gPjEu
IENvZGUgYWNjZXB0ZWQgaW50byB0aGUgbWFpbmxpbmUga2VybmVsIG11c3QgbWVldCBjZXJ0YWlu
IHF1YWxpdHkKPiA+ID4gPiA+c3RhbmRhcmRzLgo+ID4gPiA+Cj4gPiA+ID4gV2hhdCB5b3UgbWVh
biB3aGVuIHlvdSBzYXkgYWJvdXQgImNvZGUgcXVhbGl0eSBzdGFuZGFyZHMiID8KPiA+ID4gOikK
PiA+Cj4gPiBJJ20gdGFsa2luZyBtYWlubHkgYWJvdXQgdHdvIHRoaW5nczogY29kaW5nIHN0eWxl
IGFuZCBtb3JlIGdlbmVyYWwKPiA+IG92ZXJhbGwgY29kZSBzdHJ1Y3R1cmUuICBUaGUgZ3NwY2Eg
ZHJpdmVyIGhhcyBwb29yIGNvZGluZyBzdHlsZSBpbiBhCj4gPiBudW1iZXIgb2Ygd2F5czoKPiA+
IC0gdG9vIG1hbnkgaW5kZW50YXRpb25zIG1ha2UgdGhlIGNvZGUgdW5yZWFkYWJsZSAoc2VlIHNw
Y2E1eHhfc2V0TW9kZSwKPiA+IHNwY2E1MHhfbW92ZV9kYXRhKQo+ID4gIC0gY29kZSB0aGF0IGlu
ZGVudHMgdG9vIG1hbnkgdGltZXMgc2hvdWxkIGJlIG1vdmVkIGludG8gYSBzZXBhcmF0ZSBmdW5j
dGlvbgo+ID4gLSBpbmNvbnNpc3RlbnQgaW5kZW50YXRpb25zIChzZWUgc3BjYTV4eF9zZXRfbGln
aHRfZnJlcSwgd2hpY2ggdXNlcwo+ID4gc3BhY2VzIGluc3RlYWQgb2YgdGFicywgbGlrZSB0aGUg
cmVzdCBvZiB0aGUgY29kZSB1c2VzKQo+Cj4gSSdtIHNvcnJ5IDspIEp1c3QgbXkgSURFIGhhcyBz
dWNoIGFkanVzdG1lbnRzIGZvciBteSBwcm9qZWN0cy4KPiBJbiBteSBJREUgdGhpcyBjb2RlIHN0
eWxlIGxvb2tzIHByZXR0eSBnb29kLgo+IGhpbnQ6IE1vZGVybiBJREUgYWxsb3cgdG8gY2hhbmdl
IGluZGVudCBzdHlsZSBvbmUgY29tbWFuZCA7KQoKVHJ1ZSwgSSBjb3VsZCBjaGFuZ2UgbXkgdGFi
IHNldHRpbmdzIHNvIHRoYXQgdGFicyByZXByZXNlbnQgNCBzcGFjZXMKaW5zdGVhZCBvZiA4LiAg
QnV0IGhhdmluZyBwb29ybHktaW5kZW50ZWQgY29kZSAob3IgY29kZSB0aGF0IGlzCmluZGVudGVk
IHRvbyBtdWNoKSBnb2VzIGFnYWluc3QgdGhlIGtlcm5lbCBjb2RpbmcgZ3VpZGVsaW5lcwooRG9j
dW1lbnRhdGlvbi9Db2RpbmdTdHlsZSBpbiB0aGUga2VybmVsIHRyZWUsIGF2YWlsYWJsZSBhdApo
dHRwOi8vbHhyLmxpbnV4Lm5vL3NvdXJjZS9Eb2N1bWVudGF0aW9uL0NvZGluZ1N0eWxlKS4gIEkg
dGhpbmsgd2UKc2hvdWxkIHN0aWNrIHRvIHRoZXNlIHNpbmNlIGdzcGNhIGlzIGEga2VybmVsIGRy
aXZlciwgZXZlbiBpZiBpdCdzIG5vdAppbiB0aGUga2VybmVsIHRyZWUgKHlldCkuCgo+ID4gVGhl
IGdzcGNhIGRyaXZlciBoYXMgcG9vciBvdmVyYWxsIGNvZGUgc3R5bGUgYXMgd2VsbDoKPiA+IC0g
dGhlIFVTQiBJRHMgYW5kIG5hbWVzIG9mIHdlYmNhbXMgc2hvdWxkIGJlIGFzc29jaWF0ZWQgd2l0
aCB0aGVpcgo+ID4gc3BlY2lmaWMgZHJpdmVyIGNvZGUsIG5vdCBjb250YWluZWQgaW4gYSBodWdl
IGxpc3QgaW4gZ3NwY2FfY29yZS5jOwo+Cj4gT0suIFNlZSBodHRwOi8vbWdzcGNhLmUxLmJtc3R1
LnJ1Cj4gRXNwZWNpYWxseSAgbWdzcGNhdjEtMDEuMDAuMTItMiBhbmQgIG1nc3BjYXYyLTAyLjAw
LjIwLTEKClRoYXQncyBhbiBpbnRlcmVzdGluZyBwcm9qZWN0LiAgSSBoYXZlbid0IGxvb2tlZCBp
bnRvIGl0IGluIGRldGFpbCwKYnV0IGEgY3Vyc29yeSBnbGFuY2Ugc3VnZ2VzdHMgaXQgbWlnaHQg
YmUgYSBnb29kIGRpcmVjdGlvbiBmb3IgdGhlCm1haW4gZHJpdmVyIHRvIGdvIGluLiAgSXMgdGhl
cmUgYW55IHJlYXNvbiB3aHkgd2UncmUgc3RpY2tpbmcgd2l0aApnc3BjYSdzIGZhaXJseSB1bi1t
b2R1bGFyIGNvZGUgaW5zdGVhZCBvZiB1c2luZyBTZXJnZSdzIG1vcmUgbW9kdWxhcgpjb2RlPwoK
PiA+IGl0Cj4gPiBtYWtlcyBpdCBtdWNoIGVhc2llciB0byBmaWd1cmUgb3V0IHdoaWNoIGNhbWVy
YSB1c2VzIHdoaWNoIGRyaXZlciB3aGVuCj4gPiB0aGUgVVNCIElEcyBhbmQgbmFtZXMgYXJlIGlu
IHRoZSBzYW1lIGZpbGUgYXMgdGhlIGNvZGUgdGhhdCBoYW5kbGVzCj4gPiB0aGVtCj4gPiAtIHRo
ZSBoZWFkZXIgZmlsZSBhYnVzZSBJIG1lbnRpb25lZCBlYXJsaWVyIChzZWUgYmVsb3cpCj4KPiBC
dXQgYWxsIGl0IGhhcyBubyBhdHRpdHVkZSB0byAicXVhbGl0eSBvZiBhIGNvZGUiIGl0IGNvbmNl
cm5zIHRvIHN0eWxlIG9mIHRoZSBjb2RpbmcgaW50cm9kdWNlZCBieSBudW1lcm91cyBhdXRob3Jz
IG9mIHZhcmlvdXMgcGFydHMgZ3NwY2EgbW9yZSBsaWtlbHkKCkFyZSB5b3Ugc3VnZ2VzdGluZyB3
ZSBiZSBhY2NlcHRpbmcgb2YgbmV3IGF1dGhvcnMnIGRpZmZlcmVudCBjb2RpbmcKc3R5bGVzIGlu
IHRoZSBjb2RlIHRoZXkgc3VibWl0IHRvIHRoZSBnc3BjYSBwcm9qZWN0PyAgT3IgYXJlIHlvdQpz
YXlpbmcgdGhhdCBiZWNhdXNlIGF1dGhvcnMgd2l0aCBkaWZmZXJlbnQgY29kaW5nIHN0eWxlcyBo
YXZlIGFscmVhZHkKY29tbWl0dGVkIHRvIHRoZSBnc3BjYSBkcml2ZXIgYW5kIHNvIGl0J3MgYSBj
b21iaW5hdGlvbiBvZiBhIHZhcmlldHkKb2Ygc3R5bGVzIHRoYXQgd2Ugc2hvdWxkIGtlZXAgaXQg
dGhhdCB3YXk/CgpJbiBhbnkgY2FzZSwgSSB0aGluayBpdCdzIGEgZ29vZCBpZGVhIHRvIHNldHRs
ZSBvbiBvbmUgY29kaW5nIHN0eWxlCmFuZCBzdGljayB3aXRoIHRoYXQgZm9yIHRoZSBlbnRpcmUg
ZHJpdmVyLiAgU2luY2UgaXQncyBhIGtlcm5lbApkcml2ZXIsIEkgc3VnZ2VzdCB3ZSB1c2UgdGhl
IExpbnV4IGtlcm5lbCBjb2Rpbmcgc3R5bGUgZ3VpZGVsaW5lcywKd2hpY2ggSSBtZW50aW9uZWQg
YWJvdmUuCgo+ID4gPiA+ID5JZiB3ZSBtdXN0IGNvbnRpbnVlIHRvIHN1cHBvcnQgdjRsIHZlcnNp
b24gMSwgdGhlbiB3ZSBjYW4gdXNlIGEgbWV0aG9kCj4gPiA+ID4gPmxpa2UgdGhlIG92NTExIHBl
b3BsZSBjaG9zZTogbWFpbmxpbmUgd2hhdCB5b3UgY2FuIGFuZCBrZWVwIHRoZQo+ID4gPiA+ID5k
ZWNvbXByZXNzb3IgYXZhaWxhYmxlIG91dCBvZiB0aGUgbWFpbmxpbmUgZm9yIHRob3NlIHdobyBu
ZWVkIGl0Lgo+ID4gPiBZZXMsIGkgZGlkIG5vdCBsaWtlIHRoaXMuIE15IGdvYWwgaXMgdG8gcHJv
dmlkZWQgYSB3b3JraW5nIGRyaXZlciBub3QgdG8gYmUKPiA+ID4gaGFwcHkgd2l0aCBhIHJlYWxs
eSBnb29kIGNvZGUsIGJ1dCBubyBvbmUgY2FuIHVzZWQgISBBcyBpIHNheSBoZXJlLCBnc3BjYSBp
cwo+ID4gPiAidXNlcnMgY2VudHJpYyIgTk9UICJrZXJuZWwgY2VudHJpYyIgLgo+ID4gPiAgaHR0
cDovL3d3dy50aGVpbnF1aXJlci5uZXQvZGVmYXVsdC5hc3B4P2FydGljbGU9MzkyOTEKPiA+Cj4g
PiBBcmUgeW91IHNheWluZyB3ZSBuZWVkIHRvIGNvbnRpbnVlIHRvIHN1cHBvcnQgdjRsMT8gIFdo
eT8gIEZyb20gd2hhdCBJCj4gPiByZWNhbGwsIG1vc3QgYXBwbGljYXRpb25zIGhhdmUgbW92ZWQg
dG8gdjRsMiBhbHJlYWR5Lgo+Cj4gIk1vc3QiID8/PyBOYW1lIHBsZWFzZSBldmVuIDUgYXBwbGlj
YXRpb25zLiBBRkFJSyBtb3JlIG9yZSBsZXNzIHdlbGwgd2l0aCBjdXJyZW50IHZlcnNpb25zIHY0
bDIgZHJpdmVycyBmb3Igd2ViY2FtcyB3b3JrIG9ubHkgbHV2Y3ZpZXcgYnkgTWljaGVsIGFuZCBl
a2lnYS4KCk9mZiB0aGUgdG9wIG9mIG15IGhlYWQgSSBjYW4ndCBuYW1lIGFueS4gIEl0J3MgbW9y
ZSBhbiBpbXByZXNzaW9uIEkKd2FzIHVuZGVyIHRoYXQgc3VnZ2VzdGVkIGFwcGxpY2F0aW9ucyB3
ZXJlIG1vdmluZyBpbiB0aGUgdjRsMgpkaXJlY3Rpb24uCgo+IEluIHRoZSBvdGhlcnMgdGFrZSBw
bGFjZSB0byBiZSBwcm9ibGVtcyBvZiB0aGlzIG9yIHRoYXQgc29ydC4gVGhlIGJhc2ljIHByb2Js
ZW0gb2YgY29tcGF0aWJpbGl0eSB3aXRoIHY0bDEgY29uc2lzdHMgaW4gYWJzZW5jZSB1c2Vyc3Bh
Y2UgbGlicmFyaWVzIG9mIHByb3ByaWV0YXJ5Cj4gZGVjb2RlcnMgYW5kIGhlcmUgdGhlIGxheWVy
IG9mIGNvbXBhdGliaWxpdHkgd2l0aCB2NGwxIHdoaWNoIHdpbGwgbm90IGhlbHAgZXZlbiBpcyBh
dmFpbGFibGUgaW4gdjRsMgoKRm9yIHRoZSB3ZWJjYW1zIHRoYXQgcHJvdmlkZSBpbmZvcm1hdGlv
biBpbiBtb2RpZmllZCBKUEVHIGZvcm1hdCwKdGhlcmUgc2hvdWxkIGJlIHNvbWUgd2F5IHRvIHNl
dCB0aGUgY2FtZXJhIHNvIGl0IHNlbmRzIHB1cmUgSlBFRyBkYXRhLgogSWYgbm90LCB0aGVuIHRo
ZXJlIGlzIGxpa2VseSBhIHdheSB0byBkbyB0aGlzIHRoYXQgZG9lcyBub3QgcmVxdWlyZQpkZWNv
ZGluZyB0aGUgd2hvbGUgSlBFRyBzdHJlYW0gKEkgdGhpbmsgdGhpcyBpcyB3aGF0IHdlJ3JlIGN1
cnJlbnRseQpkb2luZyBmb3IgdGhlIFBBQzczMTEpIGJlY2F1c2UgSSBjYW4ndCBzZWUgYW55IGxv
Z2ljYWwgcmVhc29uIGZvciBhCndlYmNhbSB0byBzZW5kIGl0cyBkYXRhIGluIHN1Y2ggYSBmb3Jt
YXQgaWYgdGhhdCBjb3VsZG4ndCBiZSBkb25lLgoKRm9yIHRoZSB3ZWJjYW1zIHRoYXQgcGFzcyBp
bmZvcm1hdGlvbiBpbiBwdXJlIEpQRUcgZm9ybWF0LCBubwpwcm9wcmlldGFyeSBkZWNvZGVyIGlz
IHJlcXVpcmVkIHNvIHRoaXMgd291bGQgbm90IGJlIGEgcHJvYmxlbS4KCkFyZSB0aGVyZSBvdGhl
ciBmb3JtYXRzIHdlIGhhdmUgdG8gZGVhbCB3aXRoIHRoYXQgSSBoYXZlbid0IG1lbnRpb25lZD8K
Cj4gPiA+ID4gSW4gbXkgb3BpbmlvbiB0aGUgYmFzaWMgcHJvYmxlbXMgY29ubmVjdGVkIHdpdGgg
bG93IHNwZWVkIG9mIHRyYW5zaXRpb24KPiA+ID4gPiBmcm9tIHY0bDEgdG8gdjRsMiBqdXN0IGFy
ZSBjb25uZWN0ZWQgYnkgdGhhdCBkZWNvbXByZXNzb3Igbm93IHNob3VsZCBpcyBpbgo+ID4gPiA+
IHVzZXJzcGFjZSBsaWJyYXJpZXMsIGhvd2V2ZXIgaXQgY3JlYXRlcyB0aGUgY2VydGFpbiBwcm9i
bGVtcyB3aXRoIGJhY2t3YXJkCj4gPiA+ID4gY29tcGF0aWJpbGl0eS4KPiA+ID4gVGhlIGZvdXJj
YyBtZXRob2QgaW4gdjRsMiBzaG91bGQgbmV2ZXIgd29ya3MgZm9yIHRoZSB0b24gb2YgcHJvcHJp
ZXRhcnkKPiA+ID4gY29tcHJlc3NvciwgdGhhdCBpcyBteSBvcGluaW9uLCBhZnRlciA1IHllYXJz
IG9mIHBlb3BsZSB3YWl0aW5nIHRoaXMKPiA+ID4gd29uZGVyZnVsbCB1c2Vyc3BhY2UgdmlkZW8g
bGlicmFyeSwgaSBhbSBhZnJhaWQsIHRoZSBjb25jZXB0IGlzIHdyb25nICEKPiArMQo+ID4KPiA+
IElmIHRoZXJlIGlzIG5vIGN1cnJlbnQgc3Vic3lzdGVtLCB0aGVuIHdlIHNob3VsZCBtYWtlIG9u
ZS4gIEl0IHNlZW1zCj4gPiBsb2dpY2FsIHRvIGhhdmUgYSB3ZWJjYW0gc3Vic3lzdGVtIHRoYXQg
eW91IGNvdWxkIHJlZ2lzdGVyIHdpdGggdG8KPiA+IHV0aWxpemUgc3RhbmRhcmQgd2ViY2FtIGZ1
bmN0aW9ucy4KPgo+IFdlIHdvcmsgaW4gdGhpcyBkaXJlY3Rpb24uIFRob3VnaCBzcGVlZCBvZiB3
b3JrIHByb2JhYmx5IG5vdCB0b28gaW1wcmVzc2VzIDspCj4gSW4gR1NQQ0EgaW4gbXkgb3Bpbmlv
biBtYW55IGFyY2hpdGVjdHVyYWwgcHJvYmxlbXMgd2hpY2ggd2VyZSB0byBiZSBzb2x2ZWQKPiBh
cyBtdWNoIGFzIHBvc3NpYmxlIGVmZmVjdGl2ZWx5IGFuZCBlbGVnYW50bHkgYW5kIHRvIGJlIGVu
Z2FnZWQgY29zbWV0aWMgcmVmYWN0b3JpbmcKPiAgbm90IGhhdmluZyBzb2x2ZWQgdGhlc2UgZnVu
ZGFtZW50YWwgcHJvYmxlbXMgaW4gbXkgb3BpbmlvbiB3YXN0ZSBvZiB0aW1lIGFuZCBmb3JjZXMK
CkFyZSB5b3Ugc2F5aW5nIHdlIHNob3VsZCBvciBzaG91bGQgbm90IGJlIHJlZmFjdG9yaW5nIHRo
ZSBjb2RlPwpDZXJ0YWlubHkgSSBhZ3JlZSB0aGF0IHB1cmVseSBjb3NtZXRpYyBjb2RlIGNoYW5n
ZXMgd291bGQgYmUgb2YKcXVlc3Rpb25hYmxlIHVzZWZ1bG5lc3MuICBCdXQgd2hhdCBJJ20gc3Vn
Z2VzdGluZyBpcyByZWZhY3RvcmluZyBmb3IKdGhlIHB1cnBvc2Ugb2YgbWFraW5nIHRoZSBjb2Rl
IG1vcmUgbWFpbnRhaW5hYmxlLgoKRGVudmVyCg==