static zbar_image_t *v4l1_dq (zbar_video_t *vdo) { video_iomode_t iomode = vdo->iomode; int fd = vdo->fd; zbar_image_t *img = video_dq_image(vdo); if(!img) return(NULL); if(iomode == VIDEO_MMAP) { int frame = img->srcidx; if(ioctl(fd, VIDIOCSYNC, &frame) < 0) return(NULL); } else if(v4l1_read(fd, (void*)img->data, img->datalen) != img->datalen) return(NULL); return(img); }
LIBV4L_PUBLIC ssize_t read(int fd, void *buffer, size_t n) { return v4l1_read(fd, buffer, n); }
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; }