static zbar_image_t *v4l2_dq (zbar_video_t *vdo) { zbar_image_t *img; int fd = vdo->fd; if(vdo->iomode != VIDEO_READWRITE) { video_iomode_t iomode = vdo->iomode; if(video_unlock(vdo)) return(NULL); struct v4l2_buffer vbuf; memset(&vbuf, 0, sizeof(vbuf)); vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(iomode == VIDEO_MMAP) vbuf.memory = V4L2_MEMORY_MMAP; else vbuf.memory = V4L2_MEMORY_USERPTR; if(ioctl(fd, VIDIOC_DQBUF, &vbuf) < 0) return(NULL); if(iomode == VIDEO_MMAP) { assert(vbuf.index >= 0); assert(vbuf.index < vdo->num_images); img = vdo->images[vbuf.index]; } else { /* reverse map pointer back to image (FIXME) */ assert(vbuf.m.userptr >= (unsigned long)vdo->buf); assert(vbuf.m.userptr < (unsigned long)(vdo->buf + vdo->buflen)); int i = (vbuf.m.userptr - (unsigned long)vdo->buf) / vdo->datalen; assert(i >= 0); assert(i < vdo->num_images); img = vdo->images[i]; assert(vbuf.m.userptr == (unsigned long)img->data); } } else { img = video_dq_image(vdo); if(!img) return(NULL); /* FIXME should read entire image */ unsigned long datalen = read(fd, (void*)img->data, img->datalen); if(datalen < 0) return(NULL); else if(datalen != img->datalen) zprintf(0, "WARNING: read() size mismatch: 0x%lx != 0x%lx\n", datalen, img->datalen); } return(img); }
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(read(fd, (void*)img->data, img->datalen) != img->datalen) return(NULL); return(img); }
static LRESULT CALLBACK vfw_stream_cb (HWND hwnd, VIDEOHDR *hdr) { if(!hwnd || !hdr) return(0); zbar_video_t *vdo = (void*)capGetUserData(hwnd); _zbar_mutex_lock(&vdo->qlock); zbar_image_t *img = vdo->state->image; if(!img) { _zbar_mutex_lock(&vdo->qlock); img = video_dq_image(vdo); } if(img) { img->data = hdr->lpData; img->datalen = hdr->dwBufferLength; vdo->state->image = img; SetEvent(vdo->state->captured); } _zbar_mutex_unlock(&vdo->qlock); return(1); }