int v4l2_open(const char *file, int oflag, ...) { int fd; /* original open code */ if (oflag & O_CREAT) { va_list ap; mode_t mode; va_start(ap, oflag); mode = va_arg(ap, mode_t); fd = SYS_OPEN(file, oflag, mode); va_end(ap); } else { fd = SYS_OPEN(file, oflag, 0); } /* end of original open code */ if (fd == -1) return fd; if (v4l2_fd_open(fd, 0) == -1) { int saved_err = errno; SYS_CLOSE(fd); errno = saved_err; return -1; } return fd; }
LIBV4L_PUBLIC int open(const char *file, int oflag, ...) { int fd; struct v4l2_capability cap; int v4l_device = 0; /* check if we're opening a video4linux2 device */ if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) { /* Some apps open the device read only, but we need rw rights as the buffers *MUST* be mapped rw */ oflag = (oflag & ~O_ACCMODE) | O_RDWR; v4l_device = 1; } /* original open code */ if (oflag & O_CREAT) { va_list ap; mode_t mode; va_start(ap, oflag); mode = va_arg(ap, mode_t); fd = SYS_OPEN(file, oflag, mode); va_end(ap); } else { fd = SYS_OPEN(file, oflag, 0); } /* end of original open code */ if (fd == -1 || !v4l_device) return fd; /* check that this is an v4l2 device, libv4l2 only supports v4l2 devices */ if (SYS_IOCTL(fd, VIDIOC_QUERYCAP, &cap)) return fd; /* libv4l2 only adds functionality to capture capable devices */ if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) return fd; /* Try to Register with libv4l2 (in case of failure pass the fd to the application as is) */ v4l2_fd_open(fd, 0); return fd; }
LIBV4L_PUBLIC int open(const char *file, int oflag, ...) { int fd; int v4l_device = 0; /* check if we're opening a video4linux2 device */ if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) { /* Some apps open the device read-only, but we need rw rights as the buffers *MUST* be mapped rw */ oflag = (oflag & ~O_ACCMODE) | O_RDWR; v4l_device = 1; } /* original open code */ if (oflag & O_CREAT) { va_list ap; mode_t mode; va_start(ap, oflag); mode = va_arg(ap, PROMOTED_MODE_T); fd = SYS_OPEN(file, oflag, mode); va_end(ap); } else { fd = SYS_OPEN(file, oflag, 0); } /* end of original open code */ if (fd == -1 || !v4l_device) return fd; /* Try to Register with libv4l2 (in case of failure pass the fd to the application as is) */ v4l2_fd_open(fd, 0); return fd; }
int v4l1_open(const char *file, int oflag, ...) { int index, fd; char *lfname; struct v4l2_capability cap2; struct v4l2_format fmt2; struct v4l2_input input2; struct v4l2_standard standard2; int v4l_device = 0; /* check if we're opening a video4linux2 device */ if (!strncmp(file, "/dev/video", 10) || !strncmp(file, "/dev/v4l/", 9)) { /* Some apps open the device read only, but we need rw rights as the buffers *MUST* be mapped rw */ oflag = (oflag & ~O_ACCMODE) | O_RDWR; v4l_device = 1; } /* original open code */ if (oflag & O_CREAT) { va_list ap; mode_t mode; va_start(ap, oflag); mode = va_arg(ap, PROMOTED_MODE_T); fd = SYS_OPEN(file, oflag, mode); va_end(ap); } else { fd = SYS_OPEN(file, oflag, 0); } /* end of original open code */ if (fd == -1 || !v4l_device) return fd; /* check that this is an v4l2 device, no need to emulate v4l1 on a v4l1 device */ if (SYS_IOCTL(fd, VIDIOC_QUERYCAP, &cap2)) return fd; /* If no log file was set by the app, see if one was specified through the environment */ if (!v4l1_log_file) { lfname = getenv("LIBV4L1_LOG_FILENAME"); if (lfname) v4l1_log_file = fopen(lfname, "w"); } /* redirect libv4l2 log messages to our logfile if no libv4l2 logfile is specified */ if (!v4l2_log_file) v4l2_log_file = v4l1_log_file; /* Register with libv4l2, as we use that todo format conversion and read() emulation for us */ if (v4l2_fd_open(fd, 0) == -1) { int saved_err = errno; SYS_CLOSE(fd); errno = saved_err; return -1; } /* Get initial width, height and pixelformat */ fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (v4l2_ioctl(fd, VIDIOC_G_FMT, &fmt2)) { int saved_err = errno; SYS_CLOSE(fd); errno = saved_err; return -1; } /* So we have a device on which we can (and want to) emulate v4l1, register it in our devices array */ pthread_mutex_lock(&v4l1_open_mutex); for (index = 0; index < V4L1_MAX_DEVICES; index++) if (devices[index].fd == -1) { devices[index].fd = fd; break; } pthread_mutex_unlock(&v4l1_open_mutex); if (index == V4L1_MAX_DEVICES) { V4L1_LOG_ERR("attempting to open more then %d video devices\n", V4L1_MAX_DEVICES); v4l2_close(fd); errno = EBUSY; return -1; } if (index >= devices_used) devices_used = index + 1; devices[index].flags = 0; devices[index].open_count = 1; devices[index].v4l1_frame_buf_map_count = 0; devices[index].v4l1_frame_pointer = MAP_FAILED; devices[index].width = fmt2.fmt.pix.width; devices[index].height = fmt2.fmt.pix.height; devices[index].v4l2_pixfmt = fmt2.fmt.pix.pixelformat; devices[index].v4l1_pal = pixelformat_to_palette(fmt2.fmt.pix.pixelformat); devices[index].depth = ((fmt2.fmt.pix.bytesperline << 3) + (fmt2.fmt.pix.width - 1)) / fmt2.fmt.pix.width; v4l1_find_min_and_max_size(index, &fmt2); /* Check ENUM_INPUT and ENUM_STD support */ input2.index = 0; if (v4l2_ioctl(fd, VIDIOC_ENUMINPUT, &input2) == 0) devices[index].flags |= V4L1_SUPPORTS_ENUMINPUT; standard2.index = 0; if (v4l2_ioctl(fd, VIDIOC_ENUMSTD, &standard2) == 0) devices[index].flags |= V4L1_SUPPORTS_ENUMSTD; V4L1_LOG("open: %d\n", fd); return fd; }