static int video_prepare_capture(struct device *dev, int nbufs, unsigned int offset, const char *filename) { unsigned int i; int ret; /* Allocate and map buffers. */ if ((ret = video_alloc_buffers(dev, nbufs, offset)) < 0) return ret; if (dev->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { ret = video_load_test_pattern(dev, filename); if (ret < 0) return ret; } /* Queue the buffers. */ for (i = 0; i < dev->nbufs; ++i) { ret = video_queue_buffer(dev, i); if (ret < 0) return ret; } return 0; }
int video_prepare_capture(struct device *dev, int nbufs, unsigned int offset, const char *filename, enum buffer_fill_mode fill) { unsigned int padding; unsigned int i; int ret; /* Allocate and map buffers. */ padding = (fill & BUFFER_FILL_PADDING) ? 4096 : 0; if ((ret = video_alloc_buffers(dev, nbufs, offset, padding)) < 0) return ret; if (dev->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { ret = video_load_test_pattern(dev, filename); if (ret < 0) return ret; } /* Queue the buffers. */ for (i = 0; i < dev->nbufs; ++i) { ret = video_queue_buffer(dev, i, fill); if (ret < 0) return ret; } return 0; }
static int uvc_drv_command(ErlDrvData handle, unsigned int command, char *buf, int len, char **rbuf, int rlen) { Uvc* d = (Uvc*) handle; switch(command) { case CMD_OPEN: { if(len != sizeof(Config)) { driver_failure_atom(d->port, "invalid_config"); return 0; } Config *cfg = (Config *)buf; char device_path[1024]; snprintf(device_path, sizeof(device_path), "/dev/video%d", cfg->device); d->fd = open(device_path, O_RDWR); if(d->fd == -1) { driver_failure_posix(d->port, errno); return 0; } struct v4l2_capability cap; memset(&cap, 0, sizeof cap); int ret; ret = ioctl(d->fd, VIDIOC_QUERYCAP, &cap); if (ret < 0) { driver_failure_posix(d->port, errno); return 0; } if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { driver_failure_atom(d->port, "not_a_capture_device"); return 0; } fprintf(stderr, "Setting size %dx%d\r\n", cfg->width, cfg->height); struct v4l2_format fmt; memset(&fmt, 0, sizeof fmt); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(cfg->width > 640 || cfg->height > 480) { d->pixelformat = V4L2_PIX_FMT_MJPEG; } else { d->pixelformat = V4L2_PIX_FMT_YUYV; } d->width = cfg->width; d->height = cfg->height; fmt.fmt.pix.width = cfg->width; fmt.fmt.pix.height = cfg->height; fmt.fmt.pix.pixelformat = d->pixelformat; fmt.fmt.pix.field = V4L2_FIELD_ANY; ret = ioctl(d->fd, VIDIOC_S_FMT, &fmt); if (ret < 0) { driver_failure_posix(d->port, errno); return 0; } fprintf(stderr, "Setting fps %d\r\n", cfg->fps); struct v4l2_streamparm parm; memset(&parm, 0, sizeof parm); parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(d->fd, VIDIOC_G_PARM, &parm); if (ret < 0) { driver_failure_posix(d->port, errno); return 0; } parm.parm.capture.timeperframe.numerator = 1; parm.parm.capture.timeperframe.denominator = cfg->fps; ret = ioctl(d->fd, VIDIOC_S_PARM, &parm); if (ret < 0) { driver_failure_posix(d->port, errno); return 0; } fprintf(stderr, "Setting quality 100\r\n"); struct v4l2_jpegcompression jpeg; memset(&jpeg, 0, sizeof jpeg); jpeg.quality = 90; ret = ioctl(d->fd, VIDIOC_S_JPEGCOMP, &jpeg); if (ret < 0) { // driver_failure_posix(d->port, errno); // return 0; fprintf(stderr, "Failed to set quality\r\n"); } if(video_alloc_buffers(d) < 0) { driver_failure_posix(d->port, errno); return 0; } int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret = ioctl(d->fd, VIDIOC_STREAMON, &type); if(ret < 0) { driver_failure_posix(d->port, errno); return 0; } fprintf(stderr, "Capture started\r\n"); driver_select(d->port, (ErlDrvEvent)d->fd, DO_READ, 1); memcpy(*rbuf, "ok", 2); return 2; } break; default: return 0; } return 0; }