A lot has happened since I posted my ugly hacks required to take advantage of the H.264 compressor in the Logitech C920 webcam. Gstreamer 1.2 now includes a uvch264src that can be used to read H.264 encoded video stream from the camera eliminating the need for an external capture application.
uvch264src
I believe the origin of this source block goes back to a GSoC project executed during the same time we were messing around with the capture hack. The source block was called uvch264_src and it was originally written for Gstreamer 0.10, then ported and included in Gstreamer 1.0 and 1.2 as uvch264src.
The original solution with the capture application still works and can be used with gstreamer; however, there are several characteristics about the uvch264src that make it very interesting compared to the “capture” solution:
- Eliminates the piping and the need to configure the camera using v4l2-ctl.
- It outputs two streams: The primary H.264 encoded stream and a secondary “viewfinder” stream.
- It provides a means to configure the hardware compressor (bitrate, key-frame rate, etc.).
Depending on your linux installation, you may have to build gstreamer 1.2 from source, just as I had. I found it to be relatively easy to install in a private directory under my home, isolated from the rest of the system and not interfering with gstreamer 0.10 and 1.0 required by various desktop applications. I have put my notes in my wiki in case anyone is interested. The uvch264src is in the gst-plugins-bad package. This means it is not maintained or guaranteed to work; however, it is certainly worth a try if you have a C920 and you want to use it with gstreamer.
The secondary viewfinder source is an interesting concept. In addition to the primary H.264 stream, you get a secondary, low resolution stream in MJPG or YUV format. I’m not sure whether this is a feature of the camera, the driver, or the gstreamer source block, but I hope it will be useful for our Beaglebone cameras provided that the feature does not use too much CPU for converting between raw and jpg formats.
An example pipeline that displays both the high resolution H.264 stream and the viewfinder stream is shown below:
$ gst-launch-1.0 -v -e uvch264src device=/dev/video1 name=src auto-start=true
src.vfsrc ! queue ! video/x-raw,format=(string)YUY2,width=320,height=240,framerate=10/1 ! xvimagesink sync=false
src.vidsrc ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false
The primary H.264 stream is decoded using the avdec_h264 block, available through the gst-libav package, see my notes in the wiki. The viewfinder pad can be connected to a fakesink if not needed, but I don’t think it can be switched off. At least that’s the impression I get reading the original post in KaKaRoTo’s Blog.
You will probably be overwhelmed when you see the large number of options that can be configured for this source block:
$ gst-inspect-1.0 uvch264src
Many of these options can be used to adjust parameters in the H.264 compression. I find this quite amazing considering that the compression is done by a chip inside the camera. The following example increases the bitrate from the default 3 to 5 Mbps and reduces the key frame interval from the default 10 to 3 seconds:
$ gst-launch-1.0 -v -e uvch264src initial-bitrate=5000000 average-bitrate=5000000 iframe-period=3000
device=/dev/video1 name=src auto-start=true
src.vfsrc ! queue ! video/x-raw,format=(string)YUY2,width=320,height=240,framerate=10/1 ! xvimagesink sync=false
src.vidsrc ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 ! h264parse ! avdec_h264 ! xvimagesink sync=false
On the downside, there appears to be no parameters for setting the usual webcam parameters, such as contrast, brightness, focus, etc. So, to configure these we still need external tools such as v4l2.ctl, or the option mentioned in the next section.
v4l2src
It looks like we can also use the good old v4l2src to capture H.264 encoded streams from the Logitech C920:
$ gst-launch-1.0 -v -e v4l2src device=/dev/video1 ! queue ! video/x-h264,width=1280,height=720,framerate=30/1 !
h264parse ! avdec_h264 ! xvimagesink sync=false
This is probably due to evolution of both gstreamer and V4L2. This option looks simpler if you don’t need to alter the H.264 compression parameters and it gives us access to camera settings such as brightness and contrast. It also has the advantage of being in the good plugin package, which might be better maintained in the future.
This was a quick write-up of my notes taken during my initial experiments with the new uvch264src. Do let me know if I missed something or you know some cool tricks in this area.
Do you know of anything like this for Mac? The module avfvideosrc doesn’t seem to like it when I ask it to output h264