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; }
int DemuxOpen( vlc_object_t *obj ) { demux_t *demux = (demux_t *)obj; demux_sys_t *sys = malloc (sizeof (*sys)); if (unlikely(sys == NULL)) return VLC_ENOMEM; demux->p_sys = sys; ParseMRL( obj, demux->psz_location ); char *path = var_InheritString (obj, CFG_PREFIX"dev"); if (unlikely(path == NULL)) goto error; /* probably OOM */ msg_Dbg (obj, "opening device '%s'", path); int rawfd = vlc_open (path, O_RDWR); if (rawfd == -1) { msg_Err (obj, "cannot open device '%s': %m", path); free (path); goto error; } free (path); int fd = v4l2_fd_open (rawfd, 0); if (fd == -1) { msg_Warn (obj, "cannot initialize user-space library: %m"); /* fallback to direct kernel mode anyway */ fd = rawfd; } sys->fd = fd; if (InitVideo (demux, fd)) { v4l2_close (fd); goto error; } sys->controls = ControlsInit (VLC_OBJECT(demux), fd); demux->pf_demux = NULL; demux->pf_control = DemuxControl; demux->info.i_update = 0; demux->info.i_title = 0; demux->info.i_seekpoint = 0; return VLC_SUCCESS; error: free (sys); return VLC_EGENERIC; }
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; }
/****************************************************** * gst_v4l2_open(): * open the video device (v4l2object->videodev) * return value: TRUE on success, FALSE on error ******************************************************/ gboolean gst_v4l2_open (GstV4l2Object * v4l2object) { struct stat st; int libv4l2_fd; GstPollFD pollfd = GST_POLL_FD_INIT; GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s", v4l2object->videodev); GST_V4L2_CHECK_NOT_OPEN (v4l2object); GST_V4L2_CHECK_NOT_ACTIVE (v4l2object); /* be sure we have a device */ if (!v4l2object->videodev) v4l2object->videodev = g_strdup ("/dev/video"); /* check if it is a device */ if (stat (v4l2object->videodev, &st) == -1) goto stat_failed; if (!S_ISCHR (st.st_mode)) goto no_device; /* open the device */ v4l2object->video_fd = open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ ); if (!GST_V4L2_IS_OPEN (v4l2object)) goto not_open; libv4l2_fd = v4l2_fd_open (v4l2object->video_fd, V4L2_ENABLE_ENUM_FMT_EMULATION); /* Note the v4l2_xxx functions are designed so that if they get passed an unknown fd, the will behave exactly as their regular xxx counterparts, so if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom cam format to normal formats conversion). Chances are big we will still fail then though, as normally v4l2_fd_open only fails if the device is not a v4l2 device. */ if (libv4l2_fd != -1) v4l2object->video_fd = libv4l2_fd; v4l2object->can_poll_device = TRUE; /* get capabilities, error will be posted */ if (!gst_v4l2_get_capabilities (v4l2object)) goto error; /* do we need to be a capture device? */ if (GST_IS_V4L2SRC (v4l2object->element) && !(v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) goto not_capture; if (GST_IS_V4L2SINK (v4l2object->element) && !(v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) goto not_output; /* create enumerations, posts errors. */ if (!gst_v4l2_fill_lists (v4l2object)) goto error; GST_INFO_OBJECT (v4l2object->element, "Opened device '%s' (%s) successfully", v4l2object->vcap.card, v4l2object->videodev); pollfd.fd = v4l2object->video_fd; gst_poll_add_fd (v4l2object->poll, &pollfd); gst_poll_fd_ctl_read (v4l2object->poll, &pollfd, TRUE); return TRUE; /* ERRORS */ stat_failed: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Cannot identify device '%s'."), v4l2object->videodev), GST_ERROR_SYSTEM); goto error; } no_device: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("This isn't a device '%s'."), v4l2object->videodev), GST_ERROR_SYSTEM); goto error; } not_open: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, OPEN_READ_WRITE, (_("Could not open device '%s' for reading and writing."), v4l2object->videodev), GST_ERROR_SYSTEM); goto error; } not_capture: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Device '%s' is not a capture device."), v4l2object->videodev), ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); goto error; } not_output: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Device '%s' is not a output device."), v4l2object->videodev), ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); goto error; } error: { if (GST_V4L2_IS_OPEN (v4l2object)) { /* close device */ v4l2_close (v4l2object->video_fd); v4l2object->video_fd = -1; } /* empty lists */ gst_v4l2_empty_lists (v4l2object); return FALSE; } }
/****************************************************** * gst_v4l2_open(): * open the video device (v4l2object->videodev) * return value: TRUE on success, FALSE on error ******************************************************/ gboolean gst_v4l2_open (GstV4l2Object * v4l2object) { struct stat st; int libv4l2_fd; GST_DEBUG_OBJECT (v4l2object->element, "Trying to open device %s", v4l2object->videodev); GST_V4L2_CHECK_NOT_OPEN (v4l2object); GST_V4L2_CHECK_NOT_ACTIVE (v4l2object); /* be sure we have a device */ if (!v4l2object->videodev) v4l2object->videodev = g_strdup ("/dev/video"); /* check if it is a device */ if (stat (v4l2object->videodev, &st) == -1) goto stat_failed; if (!S_ISCHR (st.st_mode)) goto no_device; /* open the device */ v4l2object->video_fd = open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ ); if (!GST_V4L2_IS_OPEN (v4l2object)) goto not_open; libv4l2_fd = v4l2_fd_open (v4l2object->video_fd, V4L2_ENABLE_ENUM_FMT_EMULATION); /* Note the v4l2_xxx functions are designed so that if they get passed an unknown fd, the will behave exactly as their regular xxx counterparts, so if v4l2_fd_open fails, we continue as normal (missing the libv4l2 custom cam format to normal formats conversion). Chances are big we will still fail then though, as normally v4l2_fd_open only fails if the device is not a v4l2 device. */ if (libv4l2_fd != -1) v4l2object->video_fd = libv4l2_fd; /* get capabilities, error will be posted */ if (!gst_v4l2_get_capabilities (v4l2object)) goto error; /* do we need to be a capture device? */ if (GST_IS_V4L2SRC (v4l2object->element) && !(v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE))) goto not_capture; if (GST_IS_V4L2SINK (v4l2object->element) && !(v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) goto not_output; if (GST_IS_V4L2_VIDEO_DEC (v4l2object->element) && /* Today's M2M device only expose M2M */ !((v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE)) || /* But legacy driver may expose both CAPTURE and OUTPUT */ ((v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) && (v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))))) goto not_m2m; gst_v4l2_adjust_buf_type (v4l2object); /* create enumerations, posts errors. */ if (!gst_v4l2_fill_lists (v4l2object)) goto error; GST_INFO_OBJECT (v4l2object->element, "Opened device '%s' (%s) successfully", v4l2object->vcap.card, v4l2object->videodev); if (v4l2object->extra_controls) gst_v4l2_set_controls (v4l2object, v4l2object->extra_controls); /* UVC devices are never interlaced, and doing VIDIOC_TRY_FMT on them * causes expensive and slow USB IO, so don't probe them for interlaced */ if (!strcmp ((char *) v4l2object->vcap.driver, "uvcusb")) { v4l2object->never_interlaced = TRUE; } return TRUE; /* ERRORS */ stat_failed: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Cannot identify device '%s'."), v4l2object->videodev), GST_ERROR_SYSTEM); goto error; } no_device: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("This isn't a device '%s'."), v4l2object->videodev), GST_ERROR_SYSTEM); goto error; } not_open: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, OPEN_READ_WRITE, (_("Could not open device '%s' for reading and writing."), v4l2object->videodev), GST_ERROR_SYSTEM); goto error; } not_capture: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Device '%s' is not a capture device."), v4l2object->videodev), ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); goto error; } not_output: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Device '%s' is not a output device."), v4l2object->videodev), ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); goto error; } not_m2m: { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Device '%s' is not a M2M device."), v4l2object->videodev), ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); goto error; } error: { if (GST_V4L2_IS_OPEN (v4l2object)) { /* close device */ v4l2_close (v4l2object->video_fd); v4l2object->video_fd = -1; } /* empty lists */ gst_v4l2_empty_lists (v4l2object); return FALSE; } }
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; }