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
_______________________________________________
Video4linux-list mailing list
[EMAIL PROTECTED]
https://listman.redhat.com/mailman/listinfo/video4linux-list