Webcam drivers - Mini Howto Part 2 - Linux uvc cameras

From Gumstix User Wiki
Revision as of 14:11, 30 March 2012 by Danny Chan (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

this is my second How-to on webcams, this time covering uvc webcams. You may need to do some of the steps under the first Howto which deals with cameras using the pwc driver, so it's worth having that to hand also.

As with the first How-to, this is not guaranteed to work on your system but I hope there is enough info here for you to figure out the problem if it doesn't.


Why use a Linux uvc webcam?

Apart from the obvious reason that this is the kind of webcam you already have, one other reason, so I’m told, is the camera does all the file compression, so really big compressed images (up to 960x720) can be streamed without a big CPU load. I think 640x480 may be the limit though over the gumstix's USB 1.1 connection - but it’s still quite good. I haven’t tested the fps throughput yet but it should be respectable.

Another reason is that Logitech make a "driveable" motorised pan / tilt camera, the Orbit / Sphere, which uses this driver. I though the idea of controlling a remote (possibly solar powered) camera over a (wireless) IP connection was quite cool……


Building the Linux uvc driver

If you have previously installed the pwc camera (or another camera which uses the Video4Linux drivers) you will already have these installed, so there is no need to mess around with the kernel. Otherwise (I think) you will have to rebuild the kernel as previously described, and install the various modules or at least the V4l drivers.

The Linux uvc driver is only one module but you will have to build it. There is no bitbake recipe. I thought of trying to write one but building kernel modules is clearly a bit more complex so I ground to a halt on this.

I realised though that Open Embedded and bitbake use the exact same compiling tools - gcc, make, etc - as you would use if compiling "by hand". Therefore it is possible to quite easily tweak simple make files to build for the gumstix environment, as you have all the tools set up and working already. You need to make a few changes to the Makefile though – mostly just to tell the make system where to look for the tools.

The idea then is to download the source code for the driver, edit the Makefile and build the driver for the arm architecture on the gumstix using the cross compile tools you already have installed.

First, set up a new directory to receive the source code - download this using subversion:

svn checkout svn://svn.berlios.de/linux-uvc/linux-uvc/trunk 

Have a look at the Makefile that comes with the download. I found this a bit tricky to understand. There is a good explanation here of how this works: http://lwn.net/Kernel/LDD3/ - chapter 2 page 24.

Because it's a module, the build process also uses the kernel build processes and Makefile. Therefore in addition to telling the build system which set of compiler tools to use, you also have to specify the location of the kernel build directory, as the make process moves into the kernel build directory for part of the build.

You are going to substitute the locations of your kernel build directory and your cross compiler copy of gcc plus the other build tools by editing the Makefile - so you need to know where these are:

The kernel build directory should be here:

~/gumstix/gumstix-oe/tmp/work/gumstix-custom-verdex-angstrom-linux-gnueabi/gumstix-kernel-2.6.21-r1/linux-2.6.21 


Your cross compiling copy of gcc etc should be in:

~/ gumstix/gumstix-oe/tmp/cross/bin/  

The file name will have the prefix arm-angstrom-linux-gnueabi- so gcc will be gumstix/gumstix-oe/tmp/cross/bin/arm-angstrom-linux-gnueabi-gcc and so on.

I made three changes:

1. I specified the kernel build directory using the absolute path. Comment out the KERNEL_VERSION variable as you don’t need it.

2. I set the CROSS_COMPILE variable so make can find the various tools needed. CROSS_COMPILE is the path/ filename to the tool up to and including the last “dash” – for example ~/gumstix/gumstix-oe/tmp/cross/bin/arm-angstrom-linux-gnueabi-. If the compiler needs to use additional tools to gcc it finds them by adding the name of the tool to CROSS_COMPILE. Define it by adding this line near the top of the file:

CROSS_COMPILE := /your home directory/gumstix/gumstix-oe/tmp/cross/bin/arm-angstrom-linux-gnueabi-

3. finally I specified "ARCH=arm" for good measure in the “make” line for uvc video:

@(make -C $(KERNEL_DIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules)

Some of this may be overkill but it works! There is no doubt a more elegant bitbake way of doing this (for example, by using variables as path names).

CD into the directory where your edited Makefile is located, run “make” and you should get the uvcvideo.ko module built.

I didn’t bother trying to modify the Makefile so “make install” would work as it’s just one file. Install it in /lib/modules/2.6.21/kernel/drivers/media/video, do depmod -a and your camera should be recognised when you plug it in.


Seeing the picture

Why not use motion again?

It didn’t work for me with the uvcvideo driver. I think there may be a problem with motion working with the v4l2 drivers that uvcvideo uses. So if you want to use motion and it’s facilities, one way to do it is to get a stream produced which motion can then use – in the same way as if it would get a feed from an IP camera.

This is what mjpg-streamer does, and it also has the ability to drive the pan / tilt mechanism.

Again, the build uses a Makefile, and the same approach works.

Download from here:

svn co https://mjpg-streamer.svn.sourceforge.net/svnroot/mjpg-streamer mjpg-streamer 

Again you edit the Makefile. The structure of the program is a binary and six plugin shared libraries. A number of the libraries also have Makefiles themselves so remember you have to edit each one to avoid the libraries building using the i386 architecture on your build machine. This caused me some headscratching as the libraries built okay but then were unrecogniseable when installed. To build for the gumstix all I did was change the head of the file by making CC = (absolute path to your cross compile gcc), defining the CROSS_COMPILE variable as before, and defining ARCH = arm. I suspect the latter two changes aren’t needed but it did no harm to have them in. No changes are needed to the body of the Makefile.

CD into the main directory and enter "make".

If you have edited the Makefiles correctly, the binary and the six plugins will all be built.

To be honest, these are really simple Makefiles so it should be easy to write a bitbake recipe along the lines of the “hello world” tutorial. However the above approach took me very little time and was effective.

The source download also includes material for a sample webpage which the built in webserver can use. Included is a control page which allows you to drive a pan / tilt camera also.

You can install the libraries in the usual expected places or keep all the files in one directory and run it from there. There is a short script which allows this by exporting the current directory as the library path.

That’s it!

Briany 06:38, 15 July 2008 (CDT)

libwebcam

Logitech has created a library for accessing webcams called libwebcam. Of particular interest to me is the tool uvcdynctrl, which can control all aspects of the camera including the pan and tilt.

Compilation works with two caveats. For cmake, you'll need a toolchain file in order to cross compile for the gumstix. Mine looks like this:

SET(CMAKE_SYSTEM_NAME Linux)
#this one not so much
SET(CMAKE_SYSTEM_VERSION 1)
# specify the cross compiler
SET(CMAKE_C_COMPILER  /home/randall/gumstix/gumstix-oe/tmp/cross/bin/arm-angstrom-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER /home/randall/gumstix/gumstix-oe/tmp/cross/bin/arm-angstrom-linux-gnueabi-g++)
# where is the target environment 
SET(CMAKE_FIND_ROOT_PATH  /home/randall/gumstix/gumstix-oe/tmp/cross/arm-angstrom-linux-gnueabi)
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)


Make sure you've got cmake 2.6 or later. This won't work with earlier versions. I used libwebcam-0.1.1, but I think this works with the current trunk. Create links to uvcvideo.h and uvc_compat.h as instructed in the README. Then:

1. Create a file with text above and call it toolchain.cmake or whatever you like.

2. cd libwebcam-0.1.1

3. in Libs/libwebcam/libwebcam.c, change NAME_MAX to 255 This is a workaround because it seems to pick up limits.h in CMAKE_FIND_ROOT_PATH/include intead of CMAKE_FIND_ROOT_PATH/include/linux/

4. mkdir build && cd build

5. cmake -DCMAKE_TOOLCHAIN_FILE=../../toolchain.cmake ..

6. make


This builds build/Libs/libwebcam.so.0.1.1 (and hyperlink) and build/Apps/uvcdynctrl/uvcdynctrl (and hyperlink). Copy them over to your gumstix in /usr/local/lib and /usr/local/bin respectively and run ldconfig to pick up the library. To get access to all the camera controls, you'll need to copy Apps/uvcdynctrl/data/046d/logitech.xml also and load it with uvcdynctrl -i logitech.xml. There's a way to set this up to happen automagically with udev, but I don't know how yet.

If you've got a pan/tilt camera, run /usr/local/bin/uvcdynctrl -s "Pan (relative)" 1280 and smile! Steps are 1/64 degree (at least on the orbit) and the motor's smallest step is 1 degree. Note that negatives are done like "Pan (relative)" -- -1280

I used the stable version of libwebcam 0.1.1 and the recommended revision 178 of the Linux uvc driver. --Randall 23:57, 21 September 2008 (CDT)