Преглед изворни кода

linux-v4l2: Send STREAMON/STREAMOFF on vcam start/stop

This implements a suggestion made in
https://github.com/floe/backscrub/issues/133#issuecomment-1085598710 to
address what appears to be a problem in the v4l2loopback driver.
And better aligns OBS' usage to the v4l2 kernel interface.

fixes #4808
Co-authored-by: Norihiro Kamae <[email protected]>
Stefan Hoffmeister пре 3 година
родитељ
комит
5a68d4998b
1 измењених фајлова са 21 додато и 1 уклоњено
  1. 21 1
      plugins/linux-v4l2/v4l2-output.c

+ 21 - 1
plugins/linux-v4l2/v4l2-output.c

@@ -8,6 +8,8 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <dirent.h>
+#include <errno.h>
+#include <string.h>
 
 struct virtualcam_data {
 	obs_output_t *output;
@@ -161,6 +163,15 @@ static bool try_connect(void *data, const char *device)
 	vsi.height = height;
 	obs_output_set_video_conversion(vcam->output, &vsi);
 
+	memset(&parm, 0, sizeof(parm));
+	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+	if (ioctl(vcam->device, VIDIOC_STREAMON, &parm) < 0) {
+		blog(LOG_ERROR, "Failed to start streaming on '%s' (%s)",
+		     device, strerror(errno));
+		goto fail_close_device;
+	}
+
 	blog(LOG_INFO, "Virtual camera started");
 	obs_output_begin_data_capture(vcam->output, 0);
 
@@ -229,8 +240,17 @@ static void virtualcam_stop(void *data, uint64_t ts)
 {
 	struct virtualcam_data *vcam = (struct virtualcam_data *)data;
 	obs_output_end_data_capture(vcam->output);
-	close(vcam->device);
 
+	struct v4l2_streamparm parm = {0};
+	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+	if (ioctl(vcam->device, VIDIOC_STREAMOFF, &parm) < 0) {
+		blog(LOG_WARNING,
+		     "Failed to stop streaming on video device %d (%s)",
+		     vcam->device, strerror(errno));
+	}
+
+	close(vcam->device);
 	blog(LOG_INFO, "Virtual camera stopped");
 
 	UNUSED_PARAMETER(ts);