About gstmjpg
=============

Gstmjpg is a motion JPEG server for N8x0 internet tablets and it is based on the
GStreamer framework (it is not a Gstreamer plugin, though). Gstmjpg works
together with a web server like apache2 via CGI. It allows remotely to view
continuous motion JPEG stream or single snapshots, and allows multiple
simultaneous clients. It has also a simple motion detection algorithm - when
enabled the server stores mjpg stream into a file when motion is detected. The
stored stream can be later viewed via a simple web interface. Gstmjpg has also a
median filtering algorithm to reduce the noise from the camera module in order
to reduce false alarms in darker environment. The camera module is extremely
noisy and the filtering does not entirely eliminate the problem but makes it
more bearable.

The current web interface is very basic and simple, since the author does not
show any excellence in web or HTML programming. If someone has the time and
possibility to implement a nicer interface, all input is welcome.

NOTE: Currently gstmjpg has been only tested with the apache2 web server!
NOTE: Not all browsers support motion JPEG. At least Mozilla based ones should
      work out of the box, but MS IE needs some extension/plugin/whatever for
      live stream.

About the motion detection algorithm
====================================

The core motion detection algorithm is basically quite simple. The sum absolute
differences (SAD) <http://en.wikipedia.org/wiki/Sum_of_absolute_differences>
over pixels of two consecutive frames is calculated. This SAD value is then
compared to a threshold value to determine if there has been a change of greater
significance between the frames. However, before the SAD calculation takes place
certain things happen first. They are

1. The frame rate has been dropped to one frame per second (= motion detection
sampling interval is 1 second).

2. The frame dimensions have been halved compared to the original. This means
that the pixel count is 1/4 of the original.

3. Picture format is converted to YUV420 <http://en.wikipedia.org/wiki/Yuv>
format and only the luminance component (= black and white picture in practice)
is considered.

4. Luminance component is filtered using a median filter
<http://en.wikipedia.org/wiki/Median_filter> before it is fed to the actual core
detection algorithm. A nice constant time median filter implementation was found
here <http://nomis80.org/ctmf.html>.

Instructions
============

1. Install apache2 web server from https://garage.maemo.org/projects/apache/

2. Install gstmjpg package https://garage.maemo.org/projects/gstmjpg/

3. Visit the following address using your web browser (x.y.z replaced by
tablet's IP address of course):

http://x.y.z/webcam.html

(when accessing locally from the tablet where the server runs x.y.z is 127.0.0.1)
This should give you the main page that has links to different controls.

NOTE: If your tablet running gstmjpg + apache is located in a private network,
have a look at the section 'Dealing with NATs' later in this README.

4. If you want to start server without motion detection algorithm, access the
corresponding link in the main page.

5. If you want to start server with motion detection algorithm enabled, access
the corresponding link in the main page. In this case the stream is saved when
motion is detected by the server.

NOTE: You must first set a valid output file name in the .service -file using
the --out switch. The default location is /media/mmc2/gstmjpg.mjpg.

6. If you want to see a continuous and live motion JPEG stream, access the
corresponding the link in the main page.

7. If you want to see just a snapshot JPEG, access the corresponding the link in
the main page.

8. You can stop the server by accessing corresponding the link in the main page.

9. If you want play with image size, fps and JPEG quality settings etc, you
should edit the DBus service file

/usr/share/dbus-1/services/gstmjpg.service

where you can find the line like this:

Exec=/usr/bin/gstmjpg --size qvga --fps 8 --quality 85 --threshold 3.4
--port 8081 --radius 2 --out /media/mmc2/gstmjpg.mjpg

Different switches are

--[s]ize : sets the image size, values are: sqcif, qqvga, qcif, qvga, vga

--[f]ps : sets the frame rate, values are : 1 - 15

--[q]uality : sets the JPEG quality, values are: 0 - 100

--[t]hreshold : sets the motion detection SAD (sum of absolute differences)
    threshold

--[r]adius : sets the median filter kernel radius (2*r+1)

--[o]ut : sets output file name where the mjpg stream is stored when motion is
detected

--[p]ort : sets the port that that server listens to

NOTE: Increasing size and fps settings means of course an increase in needed CPU
cycles.

10. If you want to playback the mjpg saved stream (stored when motion detection
has been enabled and motion has been detected), you can use e.g. mplayer:

$ mplayer -fps <insert desired playback fps value here> <filename>

or you can access the corressponding link in the main page. The link target page
has an img tag, where the img source is a CGI script and location of the file is
given in the QUERY_STRING <http://en.wikipedia.org/wiki/Query_string>.  The CGI
script executes a separate binary program that feeds the file contents via
STDOUT to the web server.

Dealing with NATs
=================

When your tablet running gstmjpg + apache is located in a private network, e.g.
your home network, and you want to access it from outside, you might need to
setup port forwarding. This is because the IP address of your tablet is not
visible to public internet. You probably have some kind router and/or WLAN
access point that needs configuring in this case. This site seems to have router
specific instructions:

http://portforward.com/english/routers/port_forwarding/routerindex.htm

Anyway, the steps are roughly as follows:

1. Routers have usually a web configuration interface. It is usually accessible
with browser at http://192.168.1.1, http://192.168.255.1 or similar address.
Navigate to this page with your browser.

2. Login into your router and try to find the port forwarding setup page. The
keywords here are 'NAT' and 'port forwarding'.

3. Now you need to setup the actual port forwarding rule. Usually you need to
specify these things in the rule:

Name:         This can be anything you want, e.g. 'N810'
Port from/to: The default port that web servers listen to is 80, so set this to
              80.
Protocol:     This should be set to 'TCP' or 'both', but TCP should be enough.
IP address:   This should now be the numerical IP address that your tablet has
              in your private network, e.g. 192.168.1.2. You can determine your
              tablet's IP address via Settings -> Connection Manager and then
              from the Connection Manager menu: Internet connection -> IP
              address. It would be good if you could setup a static IP address
              for your tablet in your private network, so that you do not need
              to update the port forwarding rule each time the IP address
              changes.
 
4. Next save or apply the rule.

5. Next you need to find out the public IP address that your router is bound to.
You should be able to find it somewhere on your router's web configuration
pages. After this ANYONE who knows your router's public IP address and surfs to
http://router.public.ip.here/webcam.html is able to access your tablet, so...

6. ...next thing is probably to setup some kind of access control for apache in
order to prevent unauthorised people from accessing your tablet. Have a look at
here http://httpd.apache.org/docs/2.2/howto/auth.html and apache configuration
file at /etc/httpd/conf/httpd.conf.

About the various files included gstmjpg package
================================================

/usr/htdocs/webcam.html:
The main page that has links to other functions

/usr/share/dbus-1/services/gstmjpg.service:
DBus service file that contains the MJPG server launch command line for
/usr/bin/gstmjpg including the different options

/usr/htdocs/webcamproxy.html:
Enables continuous MJPG stream by calling /cgi-bin/mjprox, where source IP and
port is given in QUERY_STRING

/usr/htdocs/webcamgrab.html:
Enables single snaphots JPGs by calling /cgi-bin/mjgrab, where source IP and
port is given in QUERY_STRING

/usr/htdocs/mjpgplay.html:
Enables playback of a stored MJPG stream by calling /cgi-bin/mjpgplay.cgi, where
source file location is given in QUERY_STRING

/usr/cgi-bin/mjprox:
Native executable that connects to MJPG server given via cmd line and fetches &
writes a continuous stream of MJPG data to stdout

/usr/cgi-bin/mjgrab:
Native executable that connects to MJPG server given via cmd line and fetches &
writes a single JPEG picture data to stdout

/usr/cgi-bin/mjpg.cgi:
Shell script that starts or stops the MJPG server via DBus using dbus-send,
where action is given in QUERY_STRING

/usr/cgi-bin/mjpgplay.cgi:
Shell script that enables playback of a stored MJPG stream by calling the player
executable /usr/bin/mjpgplay, where file location is given in QUERY_STRING

/usr/bin/gstmjpg:
The actual MJPG server in native executable form that communicates with clients
using TCP sockets

/usr/bin/mjpgplay:
The MJPG file player in native executable form that gets the file as a command
line argument and writes data to stdout
