Hello,

Lauries video(1) email to misc@ encouraged me to take this information
and try to come up with a proposal to enhance the multimedia faq with
information about webcam usage.

It's the first time I'm working on a faq article and I don't know about
any style guides. I tried to align with the articles already written.
Please educate me about the parts I missed.

I'm not sure where people working on documentation collaborate. So
I'm trying my luck here on tech@.

My proposal is online and I'm also inlining it (not as patch for easier
consumption): https://codevoid.de/h/wip_webcamfaq13.html

I'm sure some parts need refinement / better wording.

The part I'm mostly unsure about is how to correctly give the user
permissions to the video devices. Most people probably do it the
way I described (doas chmod $USER in .xsession).

Once it's good enough to get committed, I'll create a proper patch.

Any thoughts on it?

Thanks in advance,
Stefan

----

<h2 id="webcams">Using a Webcam</h2>

<h3>Supported Hardware</h3>

<p>
Most webcams today work according to the USB Video Class
(UVC) specification, which is supported by the <a
href="https://man.openbsd.org/uvideo";>uvideo(4)</a> device driver and
attaches to the <a href="https://man.openbsd.org/video.4";>video(4)</a>
device. The manpage lists some supported devices, but there is a
good chance that other devices work as well. For example, webcams in
Lenovo Thinkpads laptops do usually work.

<p>
A supported webcam (or other video device) shows up in <code>dmesg</code>
like this:

<pre class="cmdbox">
uvideo0 at uhub0 port 8 configuration 1 interface 0 "Azurewave Integrated 
Camera" rev 2.01/69.05 addr 10
video0 at uvideo0
uvideo1 at uhub0 port 8 configuration 1 interface 2 "Azurewave Integrated 
Camera" rev 2.01/69.05 addr 10
video1 at uvideo1
</pre>

<p>
You see that an <code>uvideo</code> device was detected and has
been attached to <code>video0</code>. This device will be accessible
through <code>/dev/video0</code>.

<p>
Modern laptops sometimes attach a second video device, which is the
infrared camera for face recognition. The second camera does not produce
a usable video stream.

<p>
You can find the usable camera with the <a
href="https://man.openbsd.org/video";>video(1)</a> command:

<pre class="cmdbox">
$ <b>video -q -f /dev/video0</b>
video device /dev/video0:
  encodings: yuy2
  frame sizes (width x height, in pixels) and rates (in frames per second):
        320x180: 30
        320x240: 30
        352x288: 30
        424x240: 30
        640x360: 30
        640x480: 30
        848x480: 20
        960x540: 15
        1280x720: 10
  controls: brightness, contrast, saturation, hue, gamma, sharpness, 
white_balance_temperature

$ <b>video -q -f /dev/video1</b>
video: /dev/video1 has no usable YUV encodings
</pre>

<p>
The usable camera device shows supported resolutions and framerates.
Note that the framerates only apply to the uncompressed YUY2 stream. More
on that in <a href="#recvideo">Recording a webcam stream</a>.

<h3>Using a webcam as user</h3>

<p>
To use the webcam as regular user, you need to change the device
permissions. Only root is allowed to access video devices by default.

<p>
One way of allowing your user to access the video devices is to change
the permissions from <code>~/.xsession</code>. You can configure 
<a href="https://man.openbsd.org/doas";>doas(1)</a> to perform 
<a href="https://man.openbsd.org/chmod";>chmod(1)</a> as superuser
without asking for a password for your user.

<p>
Then add the following line to your <code>~/.xsession</code>:

<pre class="cmdbox">
doas chown $USER /dev/video0
</pre>

<p>
If you're not using <a
href="https://man.openbsd.org/xenodm";>xenodm(1)</a>
and you are starting your X session with 
<a href="https://man.openbsd.org/startx";>startx(1)</a>, you can 
accomplish the same with 
<a href="https://man.openbsd.org/fbtab";>fbtab(5)</a>.

<p>
Example entry in <code>/etc/fbtab</code>:

<pre class="cmdbox">
/dev/ttyC0     0600    /dev/video0
</pre>

<h3 id="recvideo">Recording a webcam stream</h3>
 
<p>
This section uses <code>ffplay</code> and <code>ffmpeg</code> from
graphics/ffmpeg. To find out what your camera is capable of, run the
following command:

<pre class="cmdbox">    
$ <b>ffplay -f v4l2 -list_formats all -i /dev/video0</b>
[...]
[video4linux2,v4l2 @ 0x921f8420800] Compressed:   mjpeg : MJPEG : 1280x720 
320x180 320x240 352x288 424x240 640x360 640x480 848x480 960x540
[video4linux2,v4l2 @ 0x921f8420800] Raw       : yuyv422 : YUYV : 640x480 
320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720
</pre>

<p>
At the end of the output, you'll find two lines similiar to the two
above.

<p>
The first line shows resolutions supported in the uncompressed YUYV
format. The frame rates in this format can be very low.

<p>
The second line shows the supported MJPEG compressed video resolutions,
which deliver much higher framerates (usually 30fps or 60fps).

<p>
Now try to play the webcam stream. Choose one of the MJPEG resolutions
and run:

<pre class="cmdbox">
$ <b>ffplay -f v4l2 -input_format mjpeg -video_size 1280x720 -i /dev/video0</b>
[...]
Input #0, video4linux2,v4l2, from '/dev/video0':B sq=    0B f=0/0
  Duration: N/A, start: 1599377893.546533, bitrate: N/A
    Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, 
bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
</pre>

The webcam stream should be displayed. Ffplay also shows the used
resolution and the framerate (fps) used. 

<p>
If this works, you can go ahead and record the video with ffmpeg:

<pre class="cmdbox">   
$ <b>ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x720 -i /dev/video0 
~/video.mkv</b>
</pre>

End the recording with "q". You have now recorded your stream to file
<code>~/video.mkv</code>.

<h3>Controlling webcam settings</h3>

<p>
Webcams usually have brightness, contrast and other controls. 
<a href="https://man.openbsd.org/video.1";>Video(1)</a>
allows you to alter these settings. 

<p>
First find out which supported controls your camera has:

<pre class="cmdbox">
$ <b>video -c</b>
brightness=128
contrast=32
saturation=64
hue=0
gamma=120
sharpness=3
white_balance_temperature=auto
</pre>

<p>
You can change for example the brightness setting to 200:

<pre class="cmdbox">
$ <b>video brightness=200</b>
brightness: 128 -> 200
</pre>

<p>
If you would like to reset all settings to their defaults, you can do so
with:

<pre class="cmdbox">
$ <b>video -d</b>
$ <b>video -c</b>
brightness=128
contrast=32
saturation=64
hue=0
gamma=120
sharpness=3
white_balance_temperature=auto
</pre>

<p>
Some settings, like the <code>white_balance_temperature</code> support
automatic adjustments. You can set them to a fixed value or set them to
"auto", which lets the camera decide and use whatever value it thinks is
best. 

<h3>Access webcam in chromium</h3>

<p>
Chromium has access to <code>/dev/video</code> by default. To
allow Chromium to access other video devices, you need to add
the device paths to <code>/etc/chromium/unveil.main</code> and
<code>/etc/chromium/unveil.utility_video</code>

<h3>Access webcam in firefox</h3>

<p>
Firefox has access to <code>/dev/video</code> and <code>/dev/video0</code>
by default. To allow Firefox to access other video devices, you need to
add the device paths to <code>/etc/firefox/unveil.main</code>.

Reply via email to