camserv - A streaming camera server.
Copyright (C) 1999-2002 Jon Travis

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


-------------------------------------------------------------

Now that all that stuff is out of the way.  Welcome to one of my baby
projects -- a streaming webcam server.  The idea behind this project is to
allow as many people as possible (with all kinds of different cameras and
platforms) to be able to stream their webcam pictures on the web.  


==============
What you need:
==============

1)  If you want to run the camera server program:
	You must either be running on a Linux system with a supported
	Video4Linux device (and have the correct kernel setup)
	See: 	http://roadrunner.swansea.linux.org.uk/v4l.shtml

	Or you must be running on FreeBSD with a bttv card installed.  
	(NetBSD, and BSDi 4.0 have also been reported to work well)

	You can also use the video_basic module for pretty much any UNIX,
	however this module is mostly for demonstration of how to port
	video drivers.

	In addition you will need a rather recent version of the libjpeg 
	library.
	
	Most Redhat distributions should be fine.

2)  If you only want to function as a relay:
	This should be able to compile on most unices, with solely this
	package.

==============
Setup:
==============

1)  To use the camserv software:

 o   Configure and build the system.  You should be able to type
     ./configure in the toplevel camserv directory, and have it build
     just fine.  

 o   Next type `make install`.  If you did not use any flags to the configure
     program, it should default to installing everything in /usr/local/bin,
     /usr/local/lib, and /usr/local/share.  If not, it will install where
     you told it to.

     -- Important notes:
	Installed in /usr/local/lib are the filters and the video server 
	libraries that the camserv uses.

	Installed in /usr/local/bin is the camera server binary

	Installed in /usr/local/share is the default camserv.cfg configuration
	file.


 o   Setup a web page to reference the camera.  Any web page should work fine.
     You will need to add an image reference of the form:

		<IMG SRC=http://machinename.com:9192>
 
     or alternatively

		<IMG SRC=http://machinename.com:9192/singleframe>
	        (to only give out 1 frame, and then disconnect the client)

     where machinename.com is the address of the machine running the
     camserv software.  If you change the port number in the camserv config
     file, you must also change this HTML tag.

 o   Alternatively you may use the included 'javascript.txt' file which gives
     a simple example of how to use JavaScript to make pseudo-streaming
     JPG stream for IE users.  Netscape users will be able to handle the real,
     non-javascript streamer however (and should use this).

 o   Edit the camera configuration file.  By default this is installed in
     /usr/local/share/camserv.cfg.  You can either edit this file, or copy
     it to a location you prefer.  There are reasonable defaults there,
     but if you changed the default installation directories in the configure
     script, you will need to modify paths.  

 o   run camserv.  I do NOT suggest you run this as root!  Instead, chown
     the /dev/video0 device, or whichever device you plan on using, to your
     user name.  Without any arguments, camserv will use the camserv.cfg
     that was installed in /usr/local/share.  If you use an argument it
     will use that one instead.

 o   Load the web page with the <IMG> tag that you created earlier into your
     web browser.  You should see the image as seen by your camera.


2)  To use the relay software:

  o  Locate the port number of the remote camera server or other relay which
     you wish to connect to.  (Also the IP)

  o  Setup a web page similar to the camserv with an HTML tag such as:
	
	<IMG SRC=http://machinename.com:9192>

     where machinename.com is the machine runing the relay and 9192 is the
     localport you wish to use on the relay.

  o  run `relay localport REMOTEIP REMOTEPORT`.  

  o  Load the web page with the <IMG> tag you created, to test it out.  The
     remote camserv program must be running for all of this to work -- if it
     does, you will see the image as seen by camserv.


============
Important information about relays
============

The relay program is a little utility to offload your camera server!  This
can be handy if:

	-  You want to service a LOT of people
	-  You have a wimpy connection to the internet
	-  You camera server is being masqueraded by another machine.


The traditional webcams on the internet have the following configuration:

Client0 ---------
                 \
Client1 ----------+---- (your poor 28.8 link) [Your webserver ]
                 /
Client2 ---------



With the relay, you can offload your poor link to some other machine with
a fast connection.  Such as the following:

Client0 ---
           \
Client1 ----+--- (beasty fat pipe ) [University] ---- (28.8) -> [ Your home ]
           /
Client2 ---


This will allow you to service all of the clients that you want by really
only sending out 1 clients worth of packets!

NOTE:  Relays can also be attached to other relays.  Note that the latency
       between the snapped picture and the time it arrives on the remote
       machine will grow a lot with each relay you add.  You can add as 
       many relays as you want onto any camserv.


WARNING:  If the camserv is set to braodcast at maximum frames per second,
	  this will probably saturate small connections.  It would be a wise
	  thing to TWEAK the max frames per second that you send to your
	  relays.  This will not flood your connection and the relays so
	  badly, and will give you a much smoother, consistent picture.

============
Modification
============

Examine the camserv.cfg configuration file to make any changes you feel 
like.  It should be fairly explanitory.

===================================
MAIN PROGRAM INFORMATION && OPTIONS
===================================

The camserv.cfg file is used to configure the way camserv behaves.  If 
certain options are not specified, then camserv will warn you before using its
default values.  Here are the currently supported camserv fixed sections
and options.  Note:  These sections must be in camserv.cfg for it to function
properly.


------------------------------
socket:  The socket section is for providing information about how connection
	 making && managing should be done.  

Variables     listen_port  = The socket # that the camserv program listens on.
	      max_frames   = Max frames to send to a client before 
	                     disconnecting them.  0 disables this functionality
	      max_bytes    = Max # of bytes to send to a client before
	                     disconnecting them.  0 disables this functionality
	      max_seconds  = Max # of seconds to allow a client connection
	                     before disconnecting them.  0 disables this 
	                     functionality.

------------------------------
filters:  Probably one of the more interesting && useful sections of the 
          camserv configuration.  The filters section allows you to setup how
          the image should be processed before it is sent to the remote
          client.  The filters each get their chance to manipulate the image
          before sending it on to the next filter, so the order definitely
          matters.

Variables     num_filters  = The number of filters that are in the filters
                             section.  There should always be at least 1 filter
	                     (namely the jpg_filter), for changing the image
	                     from the internal RGB representation to the
                             jpg stream.
              filter#_section = Where # is anywhere from 0-> num_filters-1,
                                this designates which filter is to be applied
                                at which stage.  For instance:
		                  filter0_section     time_stamp
				Will look at the [time_stamp] section of the
                                configuration file for processing the image.
-------------------------------
main:    Provides information about how the main program should be run.  This
         affects the program as a whole

Variables      output_snapfile = A filename to output the image to.  If this
                                 option is specified, a picture will be taken,
                                 placed in this file, and then camserv will
                                 exit.
	       output_presnaps = A number of pictures to take before finally
                                 taking the 'snapfile' snapshot.  This only
                                 has any meaning when output_snapfile is
                                 given.
	       shm_alloc       = Amount of memory to allocate for shared 
                                 memory.  This defaults to the largest 
                                 potential memory that a picture may need when
                                 being processed, but if you feel that you
                                 can safely limit this, it is up to you.  
                         	 ** WARNING ** -- this is dangerous to change! 
------------------------------

==============================
MODULE INFORMATION && OPTIONS
==============================

The following are flags for the different modules and filters
that are distributed with the camserv package:


----------------
video_basic:  This module is mostly intended to give people who want to port
	      video modules for a given interface.  It currently just cycles
	      through some colours.

Variables     width   =  Width the video device should assume.
	      height  =  Height the video device should assume.


----------------
video_v4l:    This module is intended for use on Linux systems with the 
	      Video4Linux kernel options compiled in (and obviously some
	      imput device).  This module supports both color and B&W devices.

Variables:    device_path = Path to the device file to use for the camera.
	      width   =  Requested width from the video device (can change)
	      height  =  Requested height from the video device (can change)
              brightness, hue, color, contrast, whiteness: Params from 0->60000
	      port    =  Input port to take data from.  Often cards such as
	                 the bttv cards have multiple inputs such as RCA, etc.
	      frequency =  On cards with a tuner, this option will set the
	                   frequency that it is tuned to.
	      brightmean = When using autobright, this is the mean value of
			   a pixel that the camera attempts to attain.
	      brightx1,y1,x2,y2 = Coordinates of the region to gauge the
		                  brightness measurements.
	      autobright = Autobrightness adjustment variable.  A value of 0
			   disables the feature, else the value represents the
		           number of frames to wait in-between checking the
		           picture for brightness balance.  When the picture is
			   checked it will be brightneed or darkened depending
		           on the pixel values & the brightmean.
	      mode = Mode for the camera to use.  0 == PAL, 1 == NTSC, 
	             2 == SECAM, 3 == AUTO.
-----------------
video_fbsd_bttv:  This module is for people with cameras attached to BTTV
		  devices under FreeBSD.  	      

Variables:    device_path = Device path of the actual brooktree device.  
		            Defaults to /dev/bktr0.
	      tuner_path  = Path to the tuner device.  
			    Defaults to /dev/tuner0
	      width,height = Requested width & height of the camera pictures.
	      port        = Port number of the card input (0-4)
	      brightness  = Initial brightness of the camera.
	      chroma      = Initial chroma saturation axxion 
	      contrast    = Initial contrast of the device.
	      autobright  = If 0, this functionality will be disabled.  Else
		            it represents the number of frames until the 
		            brightness and the contrast will be auto-adjusted.
              channelset  = Channelset to use (nabscst=1, cableirc=2, 
	                    cablehrc=3, weurope=4, jpnbcst=5, jpncable=6,
	                    xussr=7, australia=8)
	      channel     = Channel # to view

-----------------
rand_filter:  A filter which should provide a basic example of how to do
	      filter programming.  This one will throw random dots all over
	      the picture.

Variables:    num_perline = Random modifier for how many pixels to put on each
	                    scanline
	      coloredpix  = 1 if colored pixels are to be used, else 0.

------------------
text_filter:  This filter will display text at arbitrary locations on the
	      picture.  

Variables:    bg = Backgound color for the text.  If B&W camera, then the 
	           value is #cc, with a hex value representing the 'blackness'
		   of the background.  If instead of #CC it is the string
	           transparent, the background will be transparent.
	      fg = Same as BG except for the foreground.
	      x,y= Pixel Coordinates to place the text bo.
	      mangle = 1 if the system should 'mangle' the text, else 0.
	      text = Text to display on the screen.  If mangle == 1, then the
		     text has special metacharacters "$X", etc which are 
		     replaced each time the filter is run.  Currently only a
	             few metachars are supported -- (from the date command)
		     (additionally $v == the current version of camserv)
	      fontname = Font to put the text in (either 6x11 or 8x8)

--------------------
jpg_filter:   Probably the most important filter, this one takes input of
	      either RGB or B&W values, and outputs a jpeg.  This is generally
	      the last filter in the chain.

Variable:     quality = A value from 0->100 representing the quality of the
	                jpeg

--------------------
imlib2_filter:  A preliminary test of this filter.  This filter will take an
	        image, import it and plaster it onto the output -- It will
	        respect the alpha values, so semi-transparency can be 
	        achieved.  Available by CVS from enlightenment.org.

Variables:	file = File of the image to import
	        x    = X location to place the image
		y    = Y location to place the image.

---------------------


======================
Getting Camserv
======================
Camserv is currently available from:
	http://cserv.sourceforge.net
			    

=======================
Bug reports & Additions
=======================

This is a work in progress!  If you have decided to make any new filters,
video input libraries, or modifications, please send patches to me for
inclusion into the program.  If you have any bugs, please also feel free to
send me an email.  jtravis@cse.unl.edu
     


=======================
Mad Props:
=======================

Merc (merc1@home.com) - 
	For testing of the installation and the B&W quickcam
	code.

Kaz Kylheku (kaz@ashi.footprints.net) - 
	For not making me re-write hashing
	and linked list code for the 3 millionth time, and
	doing so in a free fashion.

Gary Lawrence Murphy  (garym@canada.com) - 
	For providing lots of ideas for the overall product,
	patches for brightness modifications, and testing.

Joerg Henne (jh@cogito.de) - 
	For patches for non-NTSC inputs as well as resource management
	routines & single snapshot routines.

Andreas Wrede (andreas@planix.com) -
	For testing && patches for NetBSD/i386 (patches for multiple processes
        accessing multiple cards)

Scott Presnell (srp@zgi.com) -
	Mods for {Free,Net}BSD video server code to support tuning and
	channel sets.

Torsten Mueller (archesoft@pc.mdlink.de) -
	Javascript examples for IE users.

Barak Pearlmutter (bap@cs.unm.edu) -
        Lots of code cleanups including YUV->RGB

Walter Haidinger (walter.haidinger@gmx.at) -
        YUV->RGB as well as other patches

