summaryrefslogtreecommitdiff
path: root/sys/dev/video.c
diff options
context:
space:
mode:
authorJeremie Courreges-Anglas <jca@cvs.openbsd.org>2021-01-06 18:57:59 +0000
committerJeremie Courreges-Anglas <jca@cvs.openbsd.org>2021-01-06 18:57:59 +0000
commite7610731ce07a09ed70e5d9beacc579b38fb305e (patch)
treecb7912e07a04f9cd8ab1fd0080e2a5861abfce44 /sys/dev/video.c
parentef2f01dc2f898e6f6cd20a0cfa335247118be4ab (diff)
Let a process open a video(4) device multiple times
The previous behavior was conservative but a bit too restrictive. The V4L API lets several processes open a single video device, with exclusive access to certain methods when a process starts streaming. This is not trivial to implement. This small change fixes webcam usage with Firefox and BigBlueButton. Diff simplified + ok mglocker@, thanks!
Diffstat (limited to 'sys/dev/video.c')
-rw-r--r--sys/dev/video.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/sys/dev/video.c b/sys/dev/video.c
index 43e9e16386d..c8e9f2c0f54 100644
--- a/sys/dev/video.c
+++ b/sys/dev/video.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: video.c,v 1.46 2020/12/28 18:28:11 mglocker Exp $ */
+/* $OpenBSD: video.c,v 1.47 2021/01/06 18:57:58 jca Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -28,6 +28,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/conf.h>
+#include <sys/proc.h>
#include <sys/videoio.h>
#include <dev/video_if.h>
@@ -46,8 +47,7 @@ struct video_softc {
struct device *sc_dev; /* hardware device struct */
struct video_hw_if *hw_if; /* hardware interface */
char sc_dying; /* device detached */
-#define VIDEO_OPEN 0x01
- char sc_open;
+ struct process *sc_owner; /* owner process */
int sc_fsize;
uint8_t *sc_fbuffer;
@@ -101,6 +101,7 @@ videoattach(struct device *parent, struct device *self, void *aux)
sc->hw_hdl = sa->hdl;
sc->sc_dev = parent;
sc->sc_fbufferlen = 0;
+ sc->sc_owner = NULL;
if (sc->hw_if->get_bufsize)
sc->sc_fbufferlen = (sc->hw_if->get_bufsize)(sc->hw_hdl);
@@ -128,9 +129,13 @@ videoopen(dev_t dev, int flags, int fmt, struct proc *p)
sc->hw_if == NULL)
return (ENXIO);
- if (sc->sc_open & VIDEO_OPEN)
- return (EBUSY);
- sc->sc_open |= VIDEO_OPEN;
+ if (sc->sc_owner != NULL) {
+ if (sc->sc_owner == p->p_p)
+ return (0);
+ else
+ return (EBUSY);
+ } else
+ sc->sc_owner = p->p_p;
sc->sc_vidmode = VIDMODE_NONE;
sc->sc_frames_ready = 0;
@@ -153,7 +158,7 @@ videoclose(dev_t dev, int flags, int fmt, struct proc *p)
if (sc->hw_if->close != NULL)
r = sc->hw_if->close(sc->hw_hdl);
- sc->sc_open &= ~VIDEO_OPEN;
+ sc->sc_owner = NULL;
return (r);
}