void *my_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { switch (camDriver) { case DRIVER_V4L: printf("v4l driver is using..\n"); return mmap(addr,length,prot,flags,fd,offset); break; case DRIVER_V4L2: printf("v4l2 driver is using..\n"); return v4l1_mmap(addr,length,prot,flags,fd,offset); break; default: printf("Neither v4l nor v4l2 is using..\n"); return NULL; break; } return NULL; }
static int v4l1_mmap_buffers (zbar_video_t *vdo) { #ifdef HAVE_SYS_MMAN_H /* map camera image to memory */ struct video_mbuf vbuf; memset(&vbuf, 0, sizeof(vbuf)); if(ioctl(vdo->fd, VIDIOCGMBUF, &vbuf) < 0) return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__, "querying video frame buffers (VIDIOCGMBUF)")); assert(vbuf.frames && vbuf.size); zprintf(1, "mapping %d buffers size=0x%x\n", vbuf.frames, vbuf.size); vdo->buflen = vbuf.size; vdo->buf = v4l1_mmap(0, vbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, vdo->fd, 0); if(vdo->buf == MAP_FAILED) return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_SYSTEM, __func__, "mapping video frame buffers")); int i; for(i = 0; i < vbuf.frames; i++) { zbar_image_t *img = vdo->images[i]; zprintf(2, " [%02d] @%08x\n", img->srcidx, vbuf.offsets[i]); img->data = vdo->buf + vbuf.offsets[i]; img->datalen = vdo->datalen; int next_offset = ((i + 1 < vdo->num_images) ? vbuf.offsets[i + 1] : vbuf.size); if(next_offset < vbuf.offsets[i] + vdo->datalen) fprintf(stderr, "WARNING: insufficient v4l1 video buffer size:\n" "\tvbuf[%d]=%x vbuf[%d]=%x datalen=%lx\n" "\timage=%d x %d %.4s(%08x) palette=%d\n", i, vbuf.offsets[i], i + 1, next_offset, vdo->datalen, vdo->width, vdo->height, (char*)&vdo->format, vdo->format, vdo->palette); } return(0); #else return(err_capture(vdo, SEV_ERROR, ZBAR_ERR_UNSUPPORTED, __func__, "memory mapping not supported")); #endif }
SANE_Status sane_start (SANE_Handle handle) { int len, loop; V4L_Scanner *s; char data; DBG (2, "sane_start\n"); for (s = first_handle; s; s = s->next) { if (s == handle) break; } if (!s) { DBG (1, "sane_start: bad handle %p\n", handle); return SANE_STATUS_INVAL; /* oops, not a handle we know about */ } len = v4l1_ioctl (s->fd, VIDIOCGCAP, &s->capability); if (-1 == len) { DBG (1, "sane_start: can not get capabilities\n"); return SANE_STATUS_INVAL; } s->buffercount = 0; if (-1 == v4l1_ioctl (s->fd, VIDIOCGMBUF, &s->mbuf)) { s->is_mmap = SANE_FALSE; buffer = malloc (s->capability.maxwidth * s->capability.maxheight * s->pict.depth); if (0 == buffer) return SANE_STATUS_NO_MEM; DBG (3, "sane_start: V4L trying to read frame\n"); len = v4l1_read (s->fd, buffer, parms.bytes_per_line * parms.lines); DBG (3, "sane_start: %d bytes read\n", len); } else { s->is_mmap = SANE_TRUE; DBG (3, "sane_start: mmap frame, buffersize: %d bytes, buffers: %d, offset 0 %d\n", s->mbuf.size, s->mbuf.frames, s->mbuf.offsets[0]); buffer = v4l1_mmap (0, s->mbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, 0); if (buffer == (void *)-1) { DBG (1, "sane_start: mmap failed: %s\n", strerror (errno)); buffer = NULL; return SANE_STATUS_IO_ERROR; } DBG (3, "sane_start: mmapped frame, capture 1 pict into %p\n", buffer); s->mmap.frame = 0; s->mmap.width = s->window.width; /* s->mmap.width = parms.pixels_per_line; ??? huh? */ s->mmap.height = s->window.height; /* s->mmap.height = parms.lines; ??? huh? */ s->mmap.format = s->pict.palette; DBG (2, "sane_start: mmapped frame %d x %d with palette %d\n", s->mmap.width, s->mmap.height, s->mmap.format); /* We need to loop here to empty the read buffers, so we don't get a stale image */ for (loop = 0; loop <= s->mbuf.frames; loop++) { len = v4l1_ioctl (s->fd, VIDIOCMCAPTURE, &s->mmap); if (len == -1) { DBG (1, "sane_start: ioctl VIDIOCMCAPTURE failed: %s\n", strerror (errno)); return SANE_STATUS_INVAL; } DBG (3, "sane_start: waiting for frame %x, loop %d\n", s->mmap.frame, loop); len = v4l1_ioctl (s->fd, VIDIOCSYNC, &(s->mmap.frame)); if (-1 == len) { DBG (1, "sane_start: call to ioctl(%d, VIDIOCSYNC, ..) failed\n", s->fd); return SANE_STATUS_INVAL; } } DBG (3, "sane_start: frame %x done\n", s->mmap.frame); } /* v4l1 actually returns BGR when we ask for RGB, so convert it */ if (s->pict.palette == VIDEO_PALETTE_RGB24) { DBG (3, "sane_start: converting from BGR to RGB\n"); for (loop = 0; loop < (s->window.width * s->window.height * 3); loop += 3) { data = *(buffer + loop); *(buffer + loop) = *(buffer + loop + 2); *(buffer + loop + 2) = data; } } DBG (3, "sane_start: done\n"); return SANE_STATUS_GOOD; }
LIBV4L_PUBLIC void *mmap64(void *start, size_t length, int prot, int flags, int fd, __off64_t offset) { return v4l1_mmap(start, length, prot, flags, fd, offset); }
int main(int argc, char** argv) { if(argc == 2) { strcpy(my_video_dev, argv[1]); } else { strcpy(my_video_dev, "/dev/video0"); } //if (-1 == (fd = open(my_video_dev, O_RDWR))) { if (-1 == (fd = v4l1_open(my_video_dev, O_RDWR))) { printf("Error opening device: %s\n", my_video_dev); goto error; } printf("\n -----[ VIDIOCGCAP returns ]-----\n"); printf(" name: %s\n", capability.name); printf(" type: %i\n", capability.type); printf(" channels: %i\n", capability.channels); printf(" audios: %i\n", capability.audios); printf(" maxwidth: %i\n", capability.maxwidth); printf(" maxheight: %i\n", capability.maxheight); printf(" minwidth: %i\n", capability.minwidth); printf(" minheight: %i\n", capability.minheight); if (-1 == v4l1_ioctl(fd, VIDIOCGPICT,&picture)) { printf("Error: ioctl(fd,VIDIOCGCPICT,&picture)\n"); goto error; } printf("\n -----[ VIDIOCGPICT returns ]-----\n"); printf(" brightness: %i\n", picture.brightness); printf(" hue: %i\n", picture.hue); printf(" colour: %i\n", picture.colour); printf(" contrast: %i\n", picture.contrast); printf(" whiteness: %i\n", picture.whiteness); printf(" depth: %i\n", picture.depth); char static palet_tipi_str[64]; palette_name(palet_tipi_str, picture.palette); printf(" palette: %s\n\n", palet_tipi_str); vch.channel = 0; // vch.norm = VIDEO_MODE_PAL; if(-1 == v4l1_ioctl(fd, VIDIOCSCHAN,&vch)) { perror("Setting channel\n"); goto error; } fcntl(fd,F_SETFD,FD_CLOEXEC); if (-1 == v4l1_ioctl(fd, VIDIOCGMBUF,&gb_buffers)) { printf("Error: Error getting buffers\n"); goto error; } map = v4l1_mmap(0,gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (map == NULL) { printf("Error: Mmap returned NULL\n"); goto error; } // Set up out capture to use the correct resolution my_buf.width = mywidth; my_buf.height = myheight; my_buf.format = VIDEO_PALETTE_RGB24; // Set up out video output SDL_Init(SDL_INIT_VIDEO); screen = SDL_SetVideoMode(mywidth, myheight, 24, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } SDL_WM_SetCaption("Oy oy oy teve pirogrami", NULL); // Tell the capture card to fill frame 0 my_buf.frame = 0; if (-1 == v4l1_ioctl(fd, VIDIOCMCAPTURE, &my_buf)) { printf(" ilk my_buf.frame=0 da hata olustu\n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } // This is the infinate loop // We basically: // capture frame 1 // sync frame 0 // process frame 0 // capture frame 0 // sync frame 1 // process frame 1 // For more information, read the programming how-to that came with xawtv do { my_buf.frame = 1; if (-1 == v4l1_ioctl(fd, VIDIOCMCAPTURE, &my_buf)) { printf(" loop icinde frame=1 \n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } my_buf.frame = 0; if (-1 == v4l1_ioctl(fd, VIDIOCSYNC, &my_buf.frame)) { printf("Error on sync!\n"); goto error; } copytoscreen(map); my_buf.frame = 0; if (-1 == v4l1_ioctl(fd, VIDIOCMCAPTURE, &my_buf)) { printf(" loop icinde frame=0 \n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } my_buf.frame = 1; if (-1 == v4l1_ioctl(fd, VIDIOCSYNC, &my_buf.frame)) { printf("Error on sync!\n"); goto error; } copytoscreen(map + gb_buffers.offsets[1]); SDL_PollEvent(&event); } while (event.type != SDL_KEYDOWN); error: SDL_Quit(); return EXIT_SUCCESS; }