mmap()ing again ...
I've looked around in kernel and bttv2 code while looking for a nice
way to handle v4l2 mappings in bttv. Using page offsets as magic
cookie isn't a good idea. The VM will take the offset as real offset
and calculates a new value for it if a application does a partial
unmap(). Which in turn can lead to *ahem* intresting effects like
this one:
bttv0: Granting 4 buffers.
bttv0: vma_close called on buffer 1 (refcount -1)
IHMO there is no way around using the offset as normal offset:
Drivers should make sure that the mappings do not overlap, i.e.
buf[n].offset + buf[n].size <= buf[n+1].offset
There is also vma->vm_private_data which can be used by the drivers
to keep track of the mappings.
Gerd
--------- [ mmap.c ] -----------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>
#define BUFS 4
struct v4l2_format fmt = {
type: V4L2_BUF_TYPE_CAPTURE,
fmt: {
pix: {
width: 320,
height: 240,
depth: 32,
pixelformat: V4L2_PIX_FMT_BGR32
},
},
};
struct v4l2_requestbuffers req = {
count: BUFS,
type: V4L2_BUF_TYPE_CAPTURE,
};
struct v4l2_buffer bufs[BUFS];
int
main()
{
unsigned char *map;
int fd,i;
fd = open("/dev/video0",O_RDWR);
if (-1 == fd) {
perror("open /dev/video0");
exit(1);
}
if (-1 == ioctl(fd,VIDIOC_S_FMT,&fmt)) {
perror("ioctl VIDIOC_S_FMT");
exit(1);
}
if (-1 == ioctl(fd,VIDIOC_REQBUFS,&req)) {
perror("ioctl VIDIOC_REQBUFS");
exit(1);
}
for (i = 0; i < BUFS; i++) {
bufs[i].index = i;
bufs[i].type = V4L2_BUF_TYPE_CAPTURE;
if (-1 == ioctl(fd,VIDIOC_QUERYBUF,&bufs[i])) {
perror("ioctl VIDIOC_QUERYBUF");
exit(1);
}
fprintf(stderr,"%d: offset=0x%x length=%d\n",
i,bufs[i].offset,bufs[i].length);
}
fprintf(stderr,"mmap\n");
map = mmap(NULL, bufs[0].length, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, bufs[0].offset);
if (-1 == (int)map) {
perror("mmap");
exit(1);
}
fprintf(stderr,"munmap\n");
if (-1 == munmap(map, (bufs[1].offset - bufs[0].offset))) {
perror("munmap");
exit(1);
}
fprintf(stderr,"done\n");
exit(0);
}
_______________________________________________
Video4linux-list mailing list
[EMAIL PROTECTED]
https://listman.redhat.com/mailman/listinfo/video4linux-list