----- Original Message -----
Sent: Wednesday, December 18, 2002 10:34
AM
Subject: problems with cleaning up after
capturing...
Hello!
I'm currently working on an application(using
svgalib)that starts capturing(v4l and bttv of course) from a Haupauge
BT878 chip after a certain serial command...
This works fine...but only
once.
When i captured once and i try to open the device
again then i get the error message : "device or resource busy"!
Maybe this is because of my poor cleanup
routine.
I only close the filedescriptor after the capture
process.
(I also tried to end caturing by sending
VIDIOCCAPTURE via ioctl but this causes an error too... "Invalid
argument")
Can anyone solve this riddle?
Here is the source code that runs in a
thread...
void* OldInterpreter::VIDEOCAP(void
*arg)
{
clock_t cstart=0;
clock_t clast=0;
float fps=0;
int frame_count=0;
int
fd=-1;
struct params *threadparams=(struct params *)
arg;
struct video_channel
mychannel;
DisplayVideoData=1;
cout<<threadparams->vidwidth<<endl;
cout<<threadparams->vidheight<<endl;
cout<<threadparams->vidinputchannel<<endl;
if
(-1 == (fd = open(VideoDevice.c_str(), O_RDWR))) {
perror("An
error occured while opening the device:");
goto
err;
}
Trace("Video Device
opened...");
if (-1 == ioctl(fd,VIDIOCGCAP,&capability))
{
Trace("Error:
ioctl(fd,VIDIOCGCAP,&capability)\n");
goto
err;
}
cout<<"Channels:
"<<capability.channels<<endl;
if
(threadparams->vidinputchannel>0 &&
threadparams->vidinputchannel<capability.channels)
{
mychannel.channel=threadparams->vidinputchannel;
if (-1 == ioctl(fd,VIDIOCGCHAN,&mychannel))
{
Trace("Error:
ioctl(fd,VIDIOGCHAN,&mychannel)\n");
goto
err;
}
if
(-1 == ioctl(fd,VIDIOCSCHAN,&mychannel))
{
Trace("Error:
ioctl(fd,VIDIOCSCHAN,&mychannel)\n");
goto
err;
}
}
fcntl(fd,F_SETFD,FD_CLOEXEC);
if (-1 == ioctl(fd,VIDIOCGMBUF,&gb_buffers))
{
Trace("Error: Error getting buffers, I
think\n");
goto err;
}
memmap = (char
*)mmap(0,gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if (mmap == NULL) {
Trace("Error: Mmap
returned NULL\n");
goto err;
}
// Set up out
capture to use the correct resolution
my_buf.width =
threadparams->vidwidth;
my_buf.height =
threadparams->vidheight;
my_buf.format =
VIDEO_PALETTE_RGB565;
cout<<threadparams->vidwidth<<threadparams->vidheight<<endl;
// Tell the capture card to fill frame 0
my_buf.frame =
0;
if (-1 == ioctl(fd, VIDIOCMCAPTURE, &my_buf)) {
printf("Error: Grabber chip can't sync (no station tuned in?)");
perror(" ");
goto err;
}
do {
my_buf.frame = 1;
if
(-1 == ioctl(fd, VIDIOCMCAPTURE, &my_buf))
{
printf("Error: Grabber chip can't sync (no station
tuned in?)");
perror(" ");
goto
err;
}
my_buf.frame =
0;
if (-1 == ioctl(fd, VIDIOCSYNC, &my_buf.frame))
{
printf("Error on
sync!");
perror(" ");
goto
err;
}
my_buf.frame =
0;
if (-1 == ioctl(fd, VIDIOCMCAPTURE, &my_buf))
{
printf("Error: Grabber chip can't sync (no station
tuned in?)");
perror(" ");
goto
err;
}
my_buf.frame =
1;
if (-1 == ioctl(fd, VIDIOCSYNC, &my_buf.frame))
{
Trace("Error on sync!");
perror("
");
goto
err;
}
}
while (DisplayVideoData);
if
(threadparams)
delete(threadparams);
close(fd);
err:
if
(threadparams)
delete(threadparams);
close(fd);
return
NULL;
}