Sysread of /dev/video with threads

Can someone explain why the following code does not work?
Ruby version: ruby 1.6.7 (2002-03-19) [i386-linux]
on Debian

Version A:

···

file = File.new "/dev/video0"
foo = Thread.new {
file.sysread(3 * 512 * 242) # 512x242 pixel image, 3 bytes per pixel
print “done\n”
}

foo.join

Version B:

Thread.new {
while true
sleep 1
end
}

file = File.new "/dev/video0"
file.sysread(3 * 512 * 242) # 512x242 pixel image, 3 bytes per pixel
print “done\n”

I’m trying to read data from the video device from a thread. The code
works when written without threads. However, neither version A nor B
works as written above. Both hang in the .sysread.

/dev/video0 is a video4linux device (webcam), but the particular driver
(3comhc, http://homeconnectusb.sf.net) does not require any ioctl setup;
a simple “cat /dev/video0 > foo.raw” produces an image. Replacing
"/dev/video0" with “/dev/zero” causes both scripts to work. And using
"read" instead of “sysread” still fails.

Thanks.


Pat Mahoney pat@tinyleaf.org

Hi,

···

In message “sysread of /dev/video with threads” on 03/01/02, Pat Mahoney pat@tinyleaf.org writes:

Can someone explain why the following code does not work?

Hmm, probably select(2) does not show “ready” for /dev/video0 for your
system. Could you try

ruby -e ‘p IO.select([File.open(“/dev/video0”)])’

and send us result?

						matz.

Indeed, the command never completes. The case is the same for my 2
different webcams.

For what it’s worth, webcam software gqcam grabs an image from the
camera the same way I do (via IO#sysread or read(2) ) while running
gtk_main() in a seperate thread. Unlike my script, it uses video4linux
ioctl’s before reading from the device (which is necessary for most
video4linux drivers; the driver for one of my webcams is an exception).

Is it possible that issuing some video4linux ioctl would fix this? I
appreciate your reply and apoligize for my lack of knowledge… what
should I be reading to better understand this?

On a slightly different note, are there any ruby libraries that
implement ioctl API’s that I could use as examples if I write something
for video4linux?

Thanks

···

On Thu, Jan 02, 2003 at 12:13:03PM +0900, Yukihiro Matsumoto wrote:

Hi,

In message “sysread of /dev/video with threads” > on 03/01/02, Pat Mahoney pat@tinyleaf.org writes:

Can someone explain why the following code does not work?

Hmm, probably select(2) does not show “ready” for /dev/video0 for your
system. Could you try

ruby -e ‘p IO.select([File.open(“/dev/video0”)])’

and send us result?


Pat Mahoney pat@tinyleaf.org

I fiddled around with the gqcam source code, and added a select(2) call
just before the read(2) call which reads a frame of video. Here too,
select(2) never reports “ready” yet read(2) works fine, so I assume it
is the correct behavior. According to the manpage, select(2) does not
return when one can read from the file descriptor, but when one can read
from the file without blocking… (I must admit, this means little to
me)

I assume it is the ruby threads which introduce a select call?

Well, thanks for all the help. It seems I need to learn a bit more
before I can think about solving the problem.

···

On Thu, Jan 02, 2003 at 12:13:03PM +0900, Yukihiro Matsumoto wrote:

Hmm, probably select(2) does not show “ready” for /dev/video0 for your
system. Could you try

ruby -e ‘p IO.select([File.open(“/dev/video0”)])’


Pat Mahoney pat@tinyleaf.org

Hi,

Is it possible that issuing some video4linux ioctl would fix this? I
appreciate your reply and apoligize for my lack of knowledge… what
should I be reading to better understand this?

I’m sorry, I have no idea.

On a slightly different note, are there any ruby libraries that
implement ioctl API’s that I could use as examples if I write something
for video4linux?

f = open(“/dev/video0”)
f.ioctl(req, arg)

may help.

						matz.
···

In message “Re: sysread of /dev/video with threads” on 03/01/03, Pat Mahoney pat@tinyleaf.org writes: