diff -Naupr motion-3.2.11.1/conf.c motion-3.2.11.1-pvr/conf.c
--- motion-3.2.11.1/conf.c	2008-09-22 01:20:58.000000000 +0200
+++ motion-3.2.11.1-pvr/conf.c	2009-09-14 14:31:57.000000000 +0200
@@ -62,6 +62,7 @@ struct config conf_template = {
     input:                      IN_DEFAULT,
     norm:                       0,
     frame_limit:                DEF_MAXFRAMERATE,
+    discard_frames:             0,
     quiet:                      1,
     ppm:                        0,
     noise:                      DEF_NOISELEVEL,
@@ -308,6 +309,16 @@ config_param config_params[] = {
     copy_int,
     print_int
     },
+    { 
+ 	"discard_frames",
+ 	"# This many frames are discarded for each frame that is read from the camera.\n"
+ 	"# This is for camera devices that get upset if you don't read all the frames\n"
+ 	"# they provide, but that provide too many frames.  Default 0 (use all frames).",
+    0,
+ 	CONF_OFFSET(discard_frames),
+ 	copy_int,
+ 	print_int
+ 	},
     {
     "minimum_frame_time",
     "# Minimum time in seconds between capturing picture frames from the camera.\n"
@@ -627,6 +638,19 @@ config_param config_params[] = {
     print_bool
     },
 #ifdef HAVE_FFMPEG
+  	{
+ 	"ffmpeg_device",
+ 	"\n############################################################\n"
+ 	"# Treat device as ffmpeg compliant video stream\n"
+ 	"############################################################\n\n"
+ 	"# Setting this flag treats the device specified previously\n"
+ 	"# as an ffmpeg compliant video stream. This could be a mpeg1,\n"
+ 	"# mpeg2, mpeg4, divx, xvid, or other compliant video stream.\n",
+    0,
+ 	CONF_OFFSET(ffmpeg_device),
+ 	copy_bool,
+ 	print_bool
+ 	},
     {
     "ffmpeg_cap_new",
     "\n############################################################\n"
diff -Naupr motion-3.2.11.1/conf.h motion-3.2.11.1-pvr/conf.h
--- motion-3.2.11.1/conf.h	2008-09-22 01:20:58.000000000 +0200
+++ motion-3.2.11.1-pvr/conf.h	2009-09-14 13:54:13.000000000 +0200
@@ -36,6 +36,7 @@ struct config {
     int input;
     int norm;
     int frame_limit;
+    int discard_frames;
     int quiet;
     int ppm;
     int noise;
@@ -52,6 +53,7 @@ struct config {
     int pre_capture;
     int post_capture;
     int switchfilter;
+    int ffmpeg_device;
     int ffmpeg_cap_new;
     int ffmpeg_cap_motion;
     int ffmpeg_bps;
diff -Naupr motion-3.2.11.1/motion.c motion-3.2.11.1-pvr/motion.c
--- motion-3.2.11.1/motion.c	2009-08-10 04:00:46.000000000 +0200
+++ motion-3.2.11.1-pvr/motion.c	2009-09-14 14:29:18.000000000 +0200
@@ -1109,11 +1109,16 @@ static void *motion_loop(void *arg)
              * <0 = fatal error - leave the thread by breaking out of the main loop
              * >0 = non fatal error - copy last image or show grey image with message
              */
-            if (cnt->video_dev >= 0)
+            if (cnt->video_dev >= 0) {
                 vid_return_code = vid_next(cnt, cnt->current_image->image);
-            else
+                /* Discard frames */
+                for (j = 0; j < cnt->conf.discard_frames; j++)
+                    vid_return_code = vid_next(cnt, cnt->current_image->image);
+            } else {
                 vid_return_code = 1; /* Non fatal error */
+            }    
 
+             
             // VALID PICTURE
             if (vid_return_code == 0) {
                 cnt->lost_connection = 0;
diff -Naupr motion-3.2.11.1/motion-dist.conf.in motion-3.2.11.1-pvr/motion-dist.conf.in
--- motion-3.2.11.1/motion-dist.conf.in	2008-09-22 01:20:58.000000000 +0200
+++ motion-3.2.11.1-pvr/motion-dist.conf.in	2009-09-14 13:51:03.000000000 +0200
@@ -76,6 +76,11 @@ height 240
 # Valid range: 2-100. Default: 100 (almost no limit).
 framerate 2
 
+# This many frames are discarded for each frame that is read from the camera.
+# This is for camera devices that get upset if you don't read all the frames
+# they provide, but that provide too many frames.  Default 0 (use all frames).
+discard_frames 0
+
 # Minimum time in seconds between capturing picture frames from the camera.
 # Default: 0 = disabled - the capture rate is given by the camera framerate.
 # This option is used when you want to capture images at a rate lower than 2 per second.
@@ -286,6 +291,11 @@ ffmpeg_video_codec mpeg4
 # (default: off)
 ffmpeg_deinterlace off
 
+# Use ffmpeg to decode the data from the camera.  Necessary if your
+# data source delivers data in a format that ffmpeg understands (eg
+# mpeg2 as delivered by ivtv cards).
+# (default: off)
+ffmpeg_device off
 
 ############################################################
 # Snapshots (Traditional Periodic Webcam File Output)
diff -Naupr motion-3.2.11.1/video_common.c motion-3.2.11.1-pvr/video_common.c
--- motion-3.2.11.1/video_common.c	2009-08-10 04:00:46.000000000 +0200
+++ motion-3.2.11.1-pvr/video_common.c	2009-09-14 21:28:52.000000000 +0200
@@ -563,7 +563,7 @@ void vid_close(struct context *cnt)
 
     /* Cleanup the netcam part */
     if (cnt->netcam) {
-        motion_log(LOG_DEBUG, 0, "vid_close: calling netcam_cleanup");
+        motion_log(LOG_DEBUG, 0, "%s: calling netcam_cleanup", __FUNCTION__);
         netcam_cleanup(cnt->netcam, 0);
         cnt->netcam = NULL;
         return;
@@ -585,12 +585,13 @@ void vid_close(struct context *cnt)
     cnt->video_dev = -1;
 
     if (dev == NULL) {
-        motion_log(LOG_ERR, 0, "vid_close: Unable to find video device");
+        motion_log(LOG_ERR, 0, "%s: Unable to find video device", __FUNCTION__);
         return;
     }
 
     if (--dev->usage_count == 0) {
-        motion_log(LOG_INFO, 0, "Closing video device %s", dev->video_device);
+        motion_log(LOG_INFO, 0, "%s: Closing video device %s", 
+                   __FUNCTION__, dev->video_device);
 #ifdef MOTION_V4L2
         if (dev->v4l2) {
             v4l2_close(dev);
@@ -617,8 +618,8 @@ void vid_close(struct context *cnt)
         pthread_mutex_destroy(&dev->mutex);
         free(dev);
     } else {
-        motion_log(LOG_INFO, 0, "Still %d users of video device %s, so we don't close it now", 
-                   dev->usage_count, dev->video_device);
+        motion_log(LOG_INFO, 0, "%s: Still %d users of video device %s, so we don't close it now", 
+                   __FUNCTION__, dev->usage_count, dev->video_device);
         /* There is still at least one thread using this device 
          * If we own it, release it
          */
@@ -631,8 +632,196 @@ void vid_close(struct context *cnt)
 #endif /* WITHOUT_V4L */
 }
 
-#ifndef WITHOUT_V4L
 
+#ifdef HAVE_FFMPEG
+static unsigned char *ffmpeg_start(struct video_dev *viddev, int input, int norm)
+{
+	int dev=viddev->fd;
+	int err=0;
+	unsigned int i=0, width=0, height=0;
+	viddev->fcx = NULL;
+	viddev->ccx = NULL;
+	viddev->codec = NULL;
+	viddev->ffmpeg_video_index = -1;
+	struct video_channel vid_chnl;
+
+	if (input != IN_DEFAULT) {
+		memset(&vid_chnl, 0, sizeof(struct video_channel));
+		vid_chnl.channel = input;
+		if (ioctl (dev, VIDIOCGCHAN, &vid_chnl) == -1) {
+			motion_log(LOG_ERR, 1, "%s: ioctl (VIDIOCGCHAN)", __FUNCTION__);
+		} else {
+			vid_chnl.channel = input;
+			vid_chnl.norm    = norm;
+			if (ioctl (dev, VIDIOCSCHAN, &vid_chnl) == -1) {
+				motion_log(LOG_ERR, 1, "%s: ioctl (VIDIOCSCHAN)", __FUNCTION__);
+				return (NULL);
+			}
+		}
+	}
+	// Open the input file.
+	motion_log(LOG_DEBUG, 0, "%s: Openning ffmpeg video stream device: %s", 
+               __FUNCTION__, viddev->video_device);
+	err = av_open_input_file(&viddev->fcx, viddev->video_device, NULL, 0, &viddev->params);
+	if (err < 0) {
+		motion_log(LOG_ERR, 1, "%s: Fatal: Can't open video device (%s) using ffmpeg", 
+                   __FUNCTION__, viddev->video_device);
+		motion_log(LOG_ERR, 1, "%s: Motion Exits", __FUNCTION__);
+		exit(-1);
+	}
+
+	// Find the stream info.
+	err = av_find_stream_info(viddev->fcx);
+	if (err < 0) {
+ 		motion_log(LOG_ERR, 0, "%s: Fatal: Could not locate ffmpeg stream info.", 
+                   __FUNCTION__);
+ 		motion_log(LOG_ERR, 1, "%s: Motion Exits", __FUNCTION__);
+ 		exit(-1);
+ 	}
+
+		// Find the first video stream.
+ 	motion_log(LOG_DEBUG, 0, "Found %d ffmpeg streams.", viddev->fcx->nb_streams);
+ 	for (i=0; i < viddev->fcx->nb_streams; i++) {
+		viddev->ccx=viddev->fcx->streams[i]->codec;
+		if( viddev->ccx->codec_type == CODEC_TYPE_VIDEO ) 
+			break;
+ 	}
+ 	viddev->ffmpeg_video_index = i;
+ 	motion_log(LOG_DEBUG, 0, "%s: Obtained ffmpeg video_index (%d).", 
+               __FUNCTION__, viddev->ffmpeg_video_index);
+    
+	// Open stream.
+ 	if (viddev->ffmpeg_video_index >= 0) {
+		viddev->codec = avcodec_find_decoder(viddev->ccx->codec_id);
+		if (viddev->codec)
+ 			err = avcodec_open(viddev->ccx, viddev->codec);
+		if (err < 0) {
+ 			motion_log(LOG_ERR, 1, "%s: Fatal: Can't open ffmpeg codec", __FUNCTION__);
+ 			motion_log(LOG_ERR, 1, "%s: Motion Exits", __FUNCTION__);
+     			av_close_input_file(viddev->fcx);
+ 			exit(-1); 
+ 		} else {
+ 			motion_log(LOG_DEBUG, 0, "%s: Found ffmpeg video stream codec: %s", 
+                       __FUNCTION__, viddev->codec->name);
+ 		}
+ 	} else {
+ 		motion_log(LOG_ERR, 1, "%s: Fatal: ffmpeg video stream not found", __FUNCTION__);
+ 		motion_log(LOG_ERR, 1, "%s: Motion Exits", __FUNCTION__);
+     		av_close_input_file(viddev->fcx);
+ 		exit(-1);
+ 	}
+ 	width = viddev->ccx->width;
+ 	height = viddev->ccx->height;
+ 	motion_log(LOG_DEBUG, 0, "%s: Size of image: %d x %d x 3/2 = %d.", __FUNCTION__,
+               width, height, (width * height * 3) / 2);
+ 	viddev->ffmpeg_fmt = VIDEO_PALETTE_YUV420P;
+	viddev->ffmpeg_bufsize = (width * height * 3) / 2;
+  	viddev->ffmpeg_maxbuffer = 1;
+  	viddev->ffmpeg_curbuffer = 0;
+  	viddev->ffmpeg_buffers[0] = mymalloc((width * height * 3) / 2);
+  	viddev->ffmpeg_buffers[1] = mymalloc((width * height * 3) / 2);
+
+	return viddev->ffmpeg_buffers[0];
+}
+
+static int ffmpeg_next(struct video_dev *viddev, unsigned char *map)
+{
+	int len1 = 0, got_picture = 0;
+	unsigned char *cap_map;
+	AVPicture av_pict;
+	AVPacket av_pkt;
+	AVFrame *av_frame = avcodec_alloc_frame();
+
+	int curbuf = 0, err = 0;
+	
+	viddev->ffmpeg_curbuffer++;
+	if (viddev->ffmpeg_curbuffer > viddev->ffmpeg_maxbuffer)
+		viddev->ffmpeg_curbuffer = 0;
+	curbuf = viddev->ffmpeg_curbuffer;
+	cap_map = viddev->ffmpeg_buffers[curbuf];
+	
+	while (!got_picture) {
+		if (!viddev->fcx) {
+			motion_log(LOG_ERR, 0, "%s: NULL pointer for AVFrameContext viddev->fcx.", 
+                       __FUNCTION__);
+			motion_log(LOG_ERR, 0, "%s: Motion Exits", __FUNCTION__);
+			exit(-1);
+		}
+		err = av_read_frame(viddev->fcx, &av_pkt);
+		switch(err) {
+		case AVERROR_UNKNOWN:
+			motion_log(LOG_ERR, 1, "%s: Unknown error or Invalid data reading AVFrame", 
+                       __FUNCTION__);
+			motion_log(LOG_ERR, 0, "%s: Motion Exits", __FUNCTION__);
+			exit(-1);
+			break;
+		case AVERROR_IO:
+			motion_log(LOG_ERR, 1, "IO error reading AVFrame");
+			motion_log(LOG_ERR, 0, "Motion Exits");
+			exit(-1);
+			break;
+		case AVERROR_NUMEXPECTED:
+			motion_log(LOG_ERR, 1, "Number syntax expected in file name while reading AVFrame");
+			motion_log(LOG_ERR, 0, "Motion Exits");
+			exit(-1);
+			break;
+		case AVERROR_NOMEM:
+			motion_log(LOG_ERR, 1, "Out of memory while reading AVFrame");
+			motion_log(LOG_ERR, 0, "Motion Exits");
+			exit(-1);
+			break;
+		case AVERROR_NOFMT:
+			motion_log(LOG_ERR, 1, "Unkown format while reading AVFrame");
+			motion_log(LOG_ERR, 0, "Motion Exits");
+			exit(-1);
+			break;
+		case AVERROR_NOTSUPP:
+			motion_log(LOG_ERR, 1, "Operation not supported while reading AVFrame");
+			motion_log(LOG_ERR, 0, "Motion Exits");
+			exit(-1);
+			break;
+		default:
+			break;
+		}
+
+		if (av_pkt.stream_index == viddev->ffmpeg_video_index) {
+			if (!viddev->ccx) {
+				motion_log(LOG_ERR, 0, "NULL pointer for AVCodecContext viddev->ccx.");
+				motion_log(LOG_ERR, 0, "Motion Exits");
+				exit(-1);
+			}
+			len1 = avcodec_decode_video(viddev->ccx, av_frame, &got_picture, av_pkt.data, av_pkt.size);
+		}
+	}
+
+	if (got_picture) {
+		avpicture_alloc(&av_pict, PIX_FMT_YUV420P, viddev->ccx->width, viddev->ccx->height);
+		img_convert(&av_pict, PIX_FMT_YUV420P, (AVPicture*) av_frame, viddev->ccx->pix_fmt, 
+                    viddev->ccx->width, viddev->ccx->height);
+		memset(map, 0, (viddev->ccx->width * viddev->ccx->height * 3) / 2);
+		memcpy(map, av_pict.data[0], (viddev->ccx->width * viddev->ccx->height * 3) / 2);
+	} else {
+		motion_log(LOG_WARNING, 0, "%s: Fatal: Unable to decode video packets into frame.", 
+                   __FUNCTION__);
+		exit(-1);
+	}
+
+    av_free_packet(&av_pkt);
+	
+    // Clean up
+    avpicture_free(&av_pict);
+    av_free(av_frame);
+	// FIXME: This should be closed before exiting motion
+    // av_close_input_file(av_fcx);
+
+	return 0;
+}
+#endif
+
+
+
+
+#ifndef WITHOUT_V4L
 /**
  * vid_v4lx_start
  *
@@ -706,6 +895,11 @@ static int vid_v4lx_start(struct context
     while (dev) {
         if (!strcmp(conf->video_device, dev->video_device)) {
             dev->usage_count++;
+#ifdef HAVE_FFMPEG
+            if (conf->ffmpeg_device) 
+                  cnt->imgs.type = dev->ffmpeg_fmt;
+            else    
+#endif
             cnt->imgs.type = dev->v4l_fmt;
 
             switch (cnt->imgs.type) {
@@ -763,44 +957,71 @@ static int vid_v4lx_start(struct context
     dev->owner = -1;
     dev->v4l_fmt = VIDEO_PALETTE_YUV420P;
     dev->fps = 0;
+
+#ifdef HAVE_FFMPEG
+    if (conf->ffmpeg_device) {
+
+        dev->ffmpeg_fmt = VIDEO_PALETTE_YUV420P;
+    
+	    if (!ffmpeg_start(dev, input, norm)) {
+	        motion_log(LOG_DEBUG, 0, "%s: Failed in ffmpeg_start.", __FUNCTION__);
+		    pthread_mutex_unlock(&vid_mutex);
+ 		    return -1;
+ 	    }
+
+	    cnt->imgs.type = dev->ffmpeg_fmt;
+	    width = dev->ccx->width;
+	    height = dev->ccx->height;
+	    cnt->imgs.width = width;
+	    cnt->imgs.height = height;
+    } 
+#endif /* HAVE_FFMPEG */
+
+    if (!conf->ffmpeg_device) {
+
 #ifdef MOTION_V4L2
-    /* First lets try V4L2 and if it's not supported V4L1 */
+        /* First lets try V4L2 and if it's not supported V4L1 */
 
-    dev->v4l2 = 1;
+        dev->v4l2 = 1;
 
-    if (!v4l2_start(cnt, dev, width, height, input, norm, frequency, tuner_number)) {
-        /* restore width & height before test with v4l
-         * because could be changed in v4l2_start ()
-         */
-        dev->width = width;
-        dev->height = height;
+        if (!v4l2_start(cnt, dev, width, height, input, norm, 
+                        frequency, tuner_number)) {
+            /* restore width & height before test with v4l
+             * because could be changed in v4l2_start ()
+             */
+            dev->width = width;
+            dev->height = height;
 #endif
 
-        if (!v4l_start(cnt, dev, width, height, input, norm, frequency, tuner_number)) {
-            close(dev->fd);
-            pthread_mutexattr_destroy(&dev->attr);
-            pthread_mutex_destroy(&dev->mutex);
-            free(dev);
+            if (!v4l_start(cnt, dev, width, height, input, norm, 
+                           frequency, tuner_number)) {
+                close(dev->fd);
+                pthread_mutexattr_destroy(&dev->attr);
+                pthread_mutex_destroy(&dev->mutex);
+                free(dev);
 
-            pthread_mutex_unlock(&vid_mutex);
-            return -1;
-        }
+                pthread_mutex_unlock(&vid_mutex);
+                return -1;
+            }
 #ifdef MOTION_V4L2
-        dev->v4l2 = 0;
-    }
+            dev->v4l2 = 0;
+        }
 #endif
-    if (dev->v4l2 == 0) {
-        motion_log(-1, 0, "Using V4L1");
-    } else {
-        motion_log(-1, 0, "Using V4L2");
-        /* Update width & height because could be changed in v4l2_start () */
-        width = dev->width;
-        height = dev->height;
-        cnt->imgs.width = width;
-        cnt->imgs.height = height;
-    }
+        if (dev->v4l2 == 0) {
+             motion_log(-1, 0, "Using V4L1");
+        } else {
+            motion_log(-1, 0, "Using V4L2");
+            /* Update width & height because could be changed in v4l2_start () */
+            width = dev->width;
+            height = dev->height;
+            cnt->imgs.width = width;
+            cnt->imgs.height = height;
+        }
+
+        cnt->imgs.type = dev->v4l_fmt;
+
+    } /* conf->ffmpeg_device */
 
-    cnt->imgs.type = dev->v4l_fmt;
 
     switch (cnt->imgs.type) {
     case VIDEO_PALETTE_GREY:
@@ -823,16 +1044,15 @@ static int vid_v4lx_start(struct context
 
     pthread_mutex_unlock(&vid_mutex);
 
-return fd;
+    return fd;
 }
 #endif                /*WITHOUT_V4L */
 
 
-
 /**
  * vid_start
  *
- * vid_start setup the capture device. This will be either a V4L device or a netcam.
+ * vid_start setup the capture device. This will be either a V4L device, a netcam or an mpeg stream.
  * The function does the following:
  * - If the camera is a netcam - netcam_start is called and function returns
  * - Width and height are checked for valid value (multiple of 16)
@@ -863,9 +1083,10 @@ int vid_start(struct context *cnt)
             cnt->netcam = NULL;
         }
     }
+
 #ifdef WITHOUT_V4L
     else    
-        motion_log(LOG_ERR, 0,"You must setup netcam_url");
+        motion_log(LOG_ERR, 0,"%s: You must setup netcam_url", __FUNCTION__);
 #else
     else
         dev = vid_v4lx_start(cnt);
@@ -905,6 +1126,7 @@ int vid_next(struct context *cnt, unsign
 
         return netcam_next(cnt, map);
     }
+
 #ifndef WITHOUT_V4L
     /* We start a new block so we can make declarations without breaking
      * gcc 2.95 or older
@@ -934,6 +1156,12 @@ int vid_next(struct context *cnt, unsign
             dev->owner = cnt->threadnr;
             dev->frames = conf->roundrobin_frames;
         }
+#ifdef HAVE_FFMPEG
+	    if(conf->ffmpeg_device) 
+            ret = ffmpeg_next(dev, map);
+#endif
+
+
 #ifdef MOTION_V4L2
         if (dev->v4l2) {
             v4l2_set_input(cnt, dev, map, width, height, conf);
@@ -958,6 +1186,6 @@ int vid_next(struct context *cnt, unsign
             rotate_map(cnt, map);
         
     }
-#endif                /*WITHOUT_V4L */
+#endif  /*WITHOUT_V4L */
     return ret;
 }
diff -Naupr motion-3.2.11.1/video.h motion-3.2.11.1-pvr/video.h
--- motion-3.2.11.1/video.h	2009-08-10 04:00:46.000000000 +0200
+++ motion-3.2.11.1-pvr/video.h	2009-09-14 14:00:04.000000000 +0200
@@ -15,6 +15,32 @@
 #include <linux/videodev.h>
 #include <sys/mman.h>
 #include "pwc-ioctl.h"
+
+#ifdef HAVE_FFMPEG
+#include <errno.h>
+
+#ifdef FFMPEG_NEW_INCLUDES
+#include <libavformat/avformat.h>
+#else
+#include <avformat.h>
+#endif
+
+#ifndef AVERROR /* 0.4.8 & 0.4.9-pre1 */
+
+#if EINVAL > 0
+#define AVERROR(e) (-(e)) 
+#define AVUNERROR(e) (-(e)) 
+#else
+/* Some platforms have E* and errno already negated. */
+#define AVERROR(e) (e)
+#define AVUNERROR(e) (e)
+#endif
+
+#endif /* AVERROR */
+
+#endif /* HAVE_FFMPEG */
+
+
 #endif
 
 /* video4linux stuff */
@@ -70,8 +96,22 @@ struct video_dev {
     int v4l_maxbuffer;
     int v4l_bufsize;
 #endif
+#ifdef HAVE_FFMPEG
+	AVFormatContext * fcx;
+	AVCodecContext * ccx;
+	AVCodec * codec;
+	AVFormatParameters params;
+	unsigned char *ffmpeg_buffers[2];
+	int ffmpeg_fmt;
+	int ffmpeg_video_index;
+	int ffmpeg_curbuffer;
+	int ffmpeg_maxbuffer;
+	int ffmpeg_bufsize;
+#endif
 };
 
+
+
 /* video functions, video_common.c */
 int vid_start(struct context *);
 int vid_next(struct context *, unsigned char *map);
