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; } |