Re: VIDIOC_DQBUF in v4l2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Here is a somewhat detailed explanation of how xcaptest works.
You are correct, he has a global set of XImages, declared 
like thus...
XImage *capt_ximg[STREAMBUFS];
He also has a struct that has everything he wants to know about the capture 
buffers and the capture device itself, declared like thus
typedef struct
{
  int fd_video;
  int width;
  int height;
  int depth;
  int pixelformat;
  VIMAGE vimage[STREAMBUFS];
  struct v4l2_format fmt;
  struct v4l2_requestbuffers req;
}capture_device;

Pay attention to how he initializes the vimage member of that struct, it ends 
up containing pointers to the mmap'ed memory used for streaming capture.

         pcapt_d->vimage[i].data = mmap (0, vidbuf->length, 
	           PROT_READ|PROT_WRITE, MAP_PRIVATE/*MAP_SHARED*/,
	           pcapt_d->fd_video, vidbuf->offset);
         if ((int) pcapt_d->vimage[i].data == -1)
	   {
	     perror ("mmap() in capture_start");
	     return 0;
   	   }
         pcapt_d->vimage[i].length = vidbuf->length;

Later on, he passes in the memory FROM THE VIMAGE MEMBER to the call to 
XCreateImage, at the same time setting the data member of each member of his 
global set of XImages to the memory fmmap'ed rom the capture card.

capt_ximg[i] = display_alloc (pcapt_w, pcapt_d->vimage[i].data, 
                                    pcapt_d->width, pcapt_d->height);

That is why you seem to see the capture device capture directly to his ximage 
array.

Here are several a bugfixes of the xcapture program (I don't know who to 
submit them too).  It still does not work, but at least it gets a lot further 
than failing at the mmap section

First off, open a video capture device you want to use for streaming like 
thus, else the mmap later fails:
open (my_device, O_RDWR);
NOT 
open (my_device, O_RDONLY);

Second off, when you mmap, do it like this
mmap (0, vidbuf->length, 
PROT_READ|PROT_WRITE, MAP_SHARED,
pcapt_d->fd_video, vidbuf->offset);

NOT like this:
mmap (0, vidbuf->length, 
PROT_READ|PROT_WRITE, MAP_PRIVATE,
pcapt_d->fd_video, vidbuf->offset);

else you get an EACCES error.



Check out what happens when he wants to exit, specifically to his set of 
XImages:
void
display_free (XImage *XImgTmp)
{
  if (XImgTmp)
// memory leak, but XDestroyImage always segfaults...
//          XDestroyImage(XImgTmp);
   
  return;
}

What is happening here is that XDestroyImage is attempting to free the data 
member of the XImage struct, but that member is set to the memory from the 
capture card, thus the free causes a segfault.  A non-leaking (in this case), 
 non-segfaulting version would look like thus:
void
display_free (XImage *XImgTmp)
{
  if (XImgTmp) {
    XImgTmp->data = NULL;
    XDestroyImage(XImgTmp);
  }
   
  return;
}

Hope this helps, Chris





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux