Raspberry Pi as Surveillance Cam

Install MJPG Streamer

Step 1 - Check if Raspberry Pi detects the webcam

Plug in your USB webcam. By listing al USB devices you can see if Raspbian sees your webcam.


Search for your USB webcam in the list of USB devices:

Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 005: ID 046d:0807 Logitech, Inc. Webcam B500

In my case the webcam is detected.

Step 2 - Install packages needed for MJPG Streamer

Make sure you are a root user if you want to install new packages. If you are not a root user, become a root user by entering the following command.

sudo su

These packages are necessary for MJPEG Streamer.

  • libjpeg8-dev are development files for the IJG JPEG library.
  • imagemagick for image manipulation programs.
  • libv4l-dev for the video4linux support libraries.
  • subversion for making a checkout of the mjpg-streamer-code

To install these packages run the following command.

apt-get install libjpeg8-dev imagemagick libv4l-dev subversion

Step 3 - Create symbolic link for videodev.h

MJPG Streamer expects videodev.h to exist, but it is replaced by a newer version videodev2.h. By creating a symbolic link the compiler uses the new file without a problem. By entering the following command a symbolic link is created.

ln -s /usr/include/linux/videodev2.h /usr/include/linux/videodev.h

Step 4 - Download and make MJPG Streamer.

You can download MJPG Streamer from the original sourceforge website, or the mirror from my own server by entering one of these commands.

svn checkout svn://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code

or download and unpack the tar file from this server.

wget http://www.steinvoorte.nl/mjpgstreamer/download/mjpg-streamer-code.tar
tar -xvf mjpg-streamer-code.tar

Enter the directory made by svn or unpacking the tar file.

cd mjpg-streamer-code/mjpg-streamer

Now we have to patch the checkout or download with a patch file. Because of the linux kernel update to 3.18 mjpg-streamer needs to be fixed. (I did an update of the pi and mjpg-streamer stopped working. koos wrote a patch to fix the problem here) Create the file input_uvc_patch and open the file in nano.

nano nano input_uvc_patch
Copy the following code and past this in nano by right click the mouse in putty.
--- plugins/input_uvc/input_uvc.c       (revision 174)
+++ plugins/input_uvc/input_uvc.c       (working copy)
@@ -405,9 +405,13 @@
         if(pcontext->videoIn->formatIn == V4L2_PIX_FMT_YUYV) {
             DBG("compressing frame from input: %d\n", (int)pcontext->id);
             pglobal->in[pcontext->id].size = compress_yuyv_to_jpeg(pcontext->videoIn, pglobal->in[pcontext->id].buf, pcontext->videoIn->framesizeIn, gquality);
+            /* copy this frame's timestamp to user space */
+            pglobal->in[pcontext->id].timestamp = pcontext->videoIn->buf.timestamp;
         } else {
             DBG("copying frame from input: %d\n", (int)pcontext->id);
-            pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->buf.bytesused);
+            pglobal->in[pcontext->id].size = memcpy_picture(pglobal->in[pcontext->id].buf, pcontext->videoIn->tmpbuffer, pcontext->videoIn->tmpbytesused);
+            /* copy this frame's timestamp to user space */
+            pglobal->in[pcontext->id].timestamp = pcontext->videoIn->tmptimestamp;
 #if 0
@@ -418,8 +422,6 @@
         prev_size = global->size;
-        /* copy this frame's timestamp to user space */
-        pglobal->in[pcontext->id].timestamp = pcontext->videoIn->buf.timestamp;
         /* signal fresh_frame */
Index: plugins/input_uvc/v4l2uvc.c
--- plugins/input_uvc/v4l2uvc.c (revision 174)
+++ plugins/input_uvc/v4l2uvc.c (working copy)
@@ -450,6 +450,8 @@
         memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused);
+        vd->tmpbytesused = vd->buf.bytesused;
+        vd->tmptimestamp = vd->buf.timestamp;
             fprintf(stderr, "bytes in used %d \n", vd->buf.bytesused);
Index: plugins/input_uvc/v4l2uvc.h
--- plugins/input_uvc/v4l2uvc.h (revision 174)
+++ plugins/input_uvc/v4l2uvc.h (working copy)
@@ -28,6 +28,7 @@
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -105,6 +106,8 @@
     int framecount;
     int recordstart;
     int recordtime;
+    uint32_t tmpbytesused;
+    struct timeval tmptimestamp;
 /* context of each camera thread */

Use Ctrl+O to save the file and press Enter to confirm.
Press Ctrl+X to exit nano.

Now the patch with the fix for the new kernel must be applied to the code. This is done with the following command.

 patch -p0 < input_uvc_patch

Build MJPG Streamer for your platform. mjpg_streamer is the program, input_uvc.so is a plug-in for mjpg_streamer to get images from the webcam and output_http.so is a plug-in for exporting the images to the http web server.

make mjpg_streamer input_uvc.so output_http.so

To give MJPG Streamer a more permanent home at a more global location, run the following commands.
Copy mjpg_streamer to the local binary directory.

cp mjpg_streamer /usr/local/bin

Copy the libraries to the local library directory.

cp output_http.so input_uvc.so /usr/local/lib/

Copy the www files to local www directory.

cp -R www /usr/local/www

Now we have to define the location of the plug-ins so MJPG Streamer will be able to find them.

nano ~/.bashrc

At de last line of the file add the following line.

export LD_LIBRARY_PATH=/usr/local/lib/

You will end up with a file like this.

# ~/.bashrc: executed by bash(1) for non-login shells.

# Note: PS1 and umask are already set in /etc/profile. You should not
# need this unless you want different defaults for root.
# PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ '
# umask 022

# You may uncomment the following lines if you want `ls' to be colorized:
# export LS_OPTIONS='--color=auto'
# eval "`dircolors`"
# alias ls='ls $LS_OPTIONS'
# alias ll='ls $LS_OPTIONS -l'
# alias l='ls $LS_OPTIONS -lA'
# Some more alias to avoid making mistakes:
# alias rm='rm -i'
# alias cp='cp -i'
# alias mv='mv -i'
export LD_LIBRARY_PATH=/usr/local/lib/

Use Ctrl+O to save the file and press Enter to confirm.
Press Ctrl+X to exit nano.

To make this change effective you can either log out and log in or run the following command to reload the file.

source ~/.bashrc

Step 5 - Start MJPG streamer for the first time

By running the following command you will start MJPG Streamer.

mjpg_streamer -i "/usr/local/lib/input_uvc.so -d /dev/video0 -r 640x480 -f 15" -o "/usr/local/lib/output_http.so -p 8080 -w /usr/local/www"

Open a browser and surf to http://IPaddressFromStep4InstallRaspbian:8080. In my case

Yeay MJPG Streamer is operational!!

You can stop MJPG-streamer by pressing Ctrl+C.
By pressing ↑-key you will get your command you ran last time. This will enable you to adapt settings for input_uvc.so and output_http.so.
Options for mjpg_streamer options -i and -o are mandatory:

-i | --input"<input-plugin.so> [parameters]"
-o | --output"<output-plugin.so> [parameters]"
[-h | --help ]display this help
[-v | --version ]display version information
[-b | --background]fork to the background, daemon mode

Options for input_uvc.so:

[-d | --device ]video device to open (your camera)
[-r | --resolution ]the resolution of the video device, can be one of the following strings: QSIF QCIF CGA QVGA CIF VGA SVGA XGA SXGA or a custom value like the following example: 640x480
[-f | --fps ]frames per second
[-y | --yuv ]enable YUYV format and disable MJPEG mode (this uses a lot of CPU power maybe to much for the Pi)
[-q | --quality ]JPEG compression quality in percent (activates YUYV format, disables MJPEG this also uses a lot of CPU power)
[-m | --minimum_size ]drop frames smaller then this limit, useful if the webcam produces small-sized garbage frames may happen under low light conditions
[-n | --no_dynctrl ]do not initialize dynctrls of Linux-UVC driver
[-l | --led ]switch the LED "on", "off", let it "blink" or leave it up to the driver using the value "auto" (It does not work for my Webcam)

Options for output_http.so:

[-w | --www ]folder that contains web pages in flat hierarchy (no subfolders)
[-p | --port ]TCP port for this HTTP server
[-c | --credentials ]ask for "username:password" on connect
[-n | --nocommands ]disable execution of commands

steinvoorte.nl © 2017