Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > d1f51fd37b183762096b194d68fc5e84 > files > 7

gqcam-0.9-4mdk.ppc.rpm

This is just a brief rundown on how the various threads interact
via mutexes and semaphores.

There are three main threads,
gtk runs in its own thread
the display function runs its own thread
the grab function (gets the picture from the cam) runs its own thread

there are three semaphores
s_draw
s_grab1
s_grab2

and three mutexes
pref_mutex
freeze_mutex
iscam_mutex

There are two picture buffers, one (camera->pic) is the one that is displayed.
The other (camera->picbuff) is the one that is written to by the grab thread

the display function waits for the s_draw semaphore to be raised.
It then swaps the two buffers (pic/picbuff) and raises the s_grab1 sempahore
Then it displays the image using gtk
Then it goes back to the top, and waits for the s_draw sempahore to be raised
again.

The grab function waits on alot of stuff, but mainly it waits for the two
grab semaphores to be raised.  As we have seen, display() raises the s_grab1
semaphore whenever it wants a new image in camera->picbuff.  The s_grab2
sempahore is used if you are doing frames per second limiting.  if FPS is
locked at 10 fps, 10 times a second the s_grab2 semaphore will be raised.
So whenever display() wants another image AND we haven't gotten a new image
in the last 10th of a second, get an image.

This is complicated a bit because we don't want to get any new images when
the 'freeze' button is on, and we don't want to try to get images when we
don't have an open camera.  This is where two of our three mutexes come in.
open_camera and close_camera control the 'iscam_mutex'  When there is NOT
a camera, that mutex is locked.  The grab function wants to lock that mutex
before it grabs an image, so if close_camera locked the mutex, grab_image()
will sit and wait for open_camera() to release the iscam_mutex.
The freeze_mutex works similarly.  When you click the 'freeze' button,
it locks the freeze_mutex.  grab_image() will wait to get another image
until it can get the freeze_mutex.  When you click on the 'freeze' button
to turn it off, it releases the mutex and grab_image() will start running
again.

If you were wondering why freeze_mutex and iscam_mutex are in grab_image
instead of display, don't.  It doesn't really matter which they are in,
I just felt like putting them in grab_image().

The only mutex left is pref_mutex.  I don't know how neccessary this one
really is, but it makes me feel much safer knowing it is there.  This mutex
is used whenever you click a slider or push a radio button.  Only one thread
can access the preferences at a time, so they don't get in each other's way.
This might be overkill, but it makes me feel safer.  grab_image() checks
the camera->update_camera value, and if it is set, it does a set_camera
and clears the update_camera flag.

Thats the whole explanation, I hope it was more helpful than confusing.
The nice thing about this little setup is that the grab_image() thread starts
reading another picture AT THE SAME TIME that the display thread is writing
to the screen.  This allows me to get 30 fps on my CPiA camera that has
a theoretical limit of, well, 30.  With weaker threading, or just a single
process for grab/display I could only get a max of 28 fps.  Besides, this
is more fun.

enjoy,
john smallberries ( spred@geocities.com )