Projects
Multimedia
obs-studio
11906.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 11906.patch of Package obs-studio (Revision 121)
Currently displaying revision
121
,
Show latest
From 52d57cf70ca70f55378112f6eeb5708fb7680a6b Mon Sep 17 00:00:00 2001 From: stephematician <steph.fn.contact@proton.me> Date: Wed, 19 Mar 2025 13:59:21 +1100 Subject: [PATCH] linux-v4l2: Fix virtual camera start failure Add function that tries to reset v4l2loopback output for module versions from 0.12.5 to 0.12.7. If successful, then set flag that STREAMON and STREAMOFF are necessary each time the device is opened/closed. --- plugins/linux-v4l2/v4l2-output.c | 57 ++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/plugins/linux-v4l2/v4l2-output.c b/plugins/linux-v4l2/v4l2-output.c index 366fc474f69d4e..d5e4e0f6ad57fb 100644 --- a/plugins/linux-v4l2/v4l2-output.c +++ b/plugins/linux-v4l2/v4l2-output.c @@ -15,6 +15,7 @@ struct virtualcam_data { obs_output_t *output; int device; uint32_t frame_size; + bool use_caps_workaround; }; static const char *virtualcam_name(void *unused) @@ -110,11 +111,54 @@ static void *virtualcam_create(obs_data_t *settings, obs_output_t *output) return vcam; } +bool try_reset_output_caps(const char *device) +{ + struct v4l2_capability capability; + struct v4l2_format format; + int fd; + + blog(LOG_INFO, "Attempting to reset output capability of '%s'", device); + + fd = open(device, O_RDWR); + if (fd < 0) + return false; + + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + if (ioctl(fd, VIDIOC_G_FMT, &format) < 0) + goto reset_fail_close_fd; + + if (ioctl(fd, VIDIOC_S_FMT, &format) < 0) + goto reset_fail_close_fd; + + if (ioctl(fd, VIDIOC_STREAMON, &format.type) < 0) + goto reset_fail_close_fd; + + if (ioctl(fd, VIDIOC_STREAMOFF, &format.type) < 0) + goto reset_fail_close_fd; + + close(fd); + + fd = open(device, O_RDWR); + if (fd < 0) + return false; + + if (ioctl(fd, VIDIOC_QUERYCAP, &capability) < 0) + goto reset_fail_close_fd; + + close(fd); + return (capability.device_caps & V4L2_CAP_VIDEO_OUTPUT) != 0; + +reset_fail_close_fd: + close(fd); + return false; +} + static bool try_connect(void *data, const char *device) { + static bool use_caps_workaround = false; struct virtualcam_data *vcam = (struct virtualcam_data *)data; - struct v4l2_format format; struct v4l2_capability capability; + struct v4l2_format format; struct v4l2_streamparm parm; uint32_t width = obs_output_get_width(vcam->output); @@ -130,6 +174,13 @@ static bool try_connect(void *data, const char *device) if (ioctl(vcam->device, VIDIOC_QUERYCAP, &capability) < 0) goto fail_close_device; + if (!use_caps_workaround && !(capability.device_caps & V4L2_CAP_VIDEO_OUTPUT)) { + if (!try_reset_output_caps(device)) + goto fail_close_device; + use_caps_workaround = true; + } + vcam->use_caps_workaround = use_caps_workaround; + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (ioctl(vcam->device, VIDIOC_G_FMT, &format) < 0) @@ -165,7 +216,7 @@ static bool try_connect(void *data, const char *device) memset(&parm, 0, sizeof(parm)); parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - if (ioctl(vcam->device, VIDIOC_STREAMON, &parm) < 0) { + if (vcam->use_caps_workaround && ioctl(vcam->device, VIDIOC_STREAMON, &parm.type) < 0) { blog(LOG_ERROR, "Failed to start streaming on '%s' (%s)", device, strerror(errno)); goto fail_close_device; } @@ -241,7 +292,7 @@ static void virtualcam_stop(void *data, uint64_t ts) struct v4l2_streamparm parm = {0}; parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - if (ioctl(vcam->device, VIDIOC_STREAMOFF, &parm) < 0) { + if (vcam->use_caps_workaround && ioctl(vcam->device, VIDIOC_STREAMOFF, &parm) < 0) { blog(LOG_WARNING, "Failed to stop streaming on video device %d (%s)", vcam->device, strerror(errno)); }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.