Index: configure.in
===================================================================
--- configure.in	(revision 467)
+++ configure.in	(working copy)
@@ -767,7 +767,7 @@
 
 #Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS(stdio.h unistd.h stdint.h fcntl.h time.h signal.h sys/ioctl.h sys/mman.h linux/videodev.h linux/videodev2.h sys/param.h sys/types.h)
+AC_CHECK_HEADERS(stddef.h stdio.h unistd.h stdint.h fcntl.h time.h signal.h sys/ioctl.h sys/mman.h linux/videodev.h linux/videodev2.h sys/param.h sys/types.h)
 
 AC_CHECK_FUNCS(get_current_dir_name)
 
@@ -809,6 +809,37 @@
 fi
 
 
+# Check for libv4lconvert
+SUPPORTED_V4LCONVERT=false
+LIBV4L="no"
+AC_ARG_WITH(v4lconvert,
+    [  --with-v4lconvert       Enables v4lconvert support in motion.
+    ],
+    LIBV4L="$withval"
+    # if not given argument, assume standard
+)
+
+if test "${LIBV4L}" = "no"; then
+    AC_MSG_CHECKING(for v4lconvert support)
+    AC_MSG_RESULT(skipping)
+else
+    saved_CFLAGS=$CFLAGS
+    saved_LIBS=$LIBS
+
+    AC_CHECK_LIB([v4lconvert], [v4lconvert_create], 
+    [
+     TEMP_LIBS="$TEMP_LIBS -lv4lconvert"
+     SUPPORTED_V4LCONVERT="yes"
+     AC_DEFINE([HAVE_V4LCONVERT],1,[Define to 1 if you have V4LCONVERT support])
+    ], 
+    AC_MSG_ERROR([Could not find libv4lconvert library - please install the libv4lconvert library])
+    )
+
+
+    CFLAGS=$saved_CFLAGS
+    LIBS=$saved_LIBS
+fi
+
 # Check sizes of integer types
 AC_CHECK_SIZEOF(short)
 AC_CHECK_SIZEOF(int)
@@ -1146,20 +1177,20 @@
 fi
 
 if test "${PTHREAD_SUPPORT}" = "yes"; then
-	echo "pthread Support:     Yes"
+	echo "pthread support:     Yes"
 else
-	echo "pthread Support:     No"
+	echo "pthread support:     No"
 	echo "**********************************************"
         echo "** Fatal Error YOU MUST HAVE pthread Support *"
         echo "**********************************************" 
 fi
 
 if test "${JPEG_SUPPORT_MMX}" = "yes"; then
-	echo "jpeg-mmx Support:    Yes"
+	echo "jpeg-mmx support:    Yes"
 elif test "${JPEG_SUPPORT}" = "yes"; then
-	echo "jpeg Support:        Yes"
+	echo "jpeg support:        Yes"
 else
-	echo "jpeg Support:        No"
+	echo "jpeg support:        No"
 	echo "**********************************************"
         echo "** Fatal Error YOU MUST HAVE jpeg Support  ***"
         echo "**********************************************"
@@ -1186,34 +1217,40 @@
 	fi
 
 	if test x$SUPPORTED_V4L2 = xtrue; then
-		echo "V4L2 supported:      Yes"	
+		echo "V4L2 support:        Yes"	
 	else
-		echo "V4L2 supported:      No"
+		echo "V4L2 support:        No"
 	fi
 fi
 
+if test "${SUPPORTED_V4LCONVERT}" = "yes"; then
+    echo "v4lconvert support:  Yes"
+else
+    echo "v4lconvert support:  No"
+fi
+
 if test "${FFMPEG_OK}" = "found"; then
-	echo "FFmpeg Support:      Yes"
+	echo "FFmpeg support:      Yes"
 else
-	echo "FFmpeg Support:      No"
+	echo "FFmpeg support:      No"
 fi
 
 if test "${SQLITE3_SUPPORT}" = "yes"; then
-	echo "SQLite3 Support:     Yes"
+	echo "SQLite3 support:     Yes"
 else
-	echo "SQLite3 Support:     No"
+	echo "SQLite3 support:     No"
 fi
 
 if test "${MYSQL_SUPPORT}" = "yes"; then
-	echo "MYSQL Support:       Yes"
+	echo "MYSQL support:       Yes"
 else
-	echo "MYSQL Support:       No"
+	echo "MYSQL support:       No"
 fi
 
 if test "${PGSQL_SUPPORT}" = "yes"; then
-	echo "PostgreSQL Support:  Yes"
+	echo "PostgreSQL support:  Yes"
 else
-	echo "PostgreSQL Support:  No"
+	echo "PostgreSQL support:  No"
 fi
 echo 
 
Index: video.h
===================================================================
--- video.h	(revision 467)
+++ video.h	(working copy)
@@ -16,8 +16,13 @@
 #include <sys/mman.h>
 #include "vloopback_motion.h"
 #include "pwc-ioctl.h"
+
+#if defined(HAVE_V4LCONVERT)
+#include <libv4lconvert.h>
 #endif
 
+#endif
+
 /* video4linux stuff */
 #define NORM_DEFAULT    0
 #define NORM_PAL        0
@@ -97,6 +102,11 @@
 int vid_do_autobright(struct context *cnt, struct video_dev *viddev);
 int mjpegtoyuv420p(unsigned char *map, unsigned char *cap_map, int width, int height, unsigned int size);
 
+#if defined(HAVE_V4LCONVERT)
+struct v4lconvert_data * convert_v4l_start(int fd);
+int try_convert(int fd, struct v4lconvert_data * convert, unsigned int pixelformat, struct v4l2_format *dfmt, struct v4l2_format *sfmt);
+#endif
+
 #ifndef WITHOUT_V4L
 /* video functions, video.c */
 unsigned char *v4l_start(struct video_dev *viddev, int width, int height,
Index: config.h.in
===================================================================
--- config.h.in	(revision 467)
+++ config.h.in	(working copy)
@@ -30,6 +30,12 @@
 /* Define to 1 if you have SQLITE3 support */
 #undef HAVE_SQLITE3
 
+/* Define to 1 if you have V4LCONVERT support */
+#undef HAVE_V4LCONVERT
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
Index: video2.c
===================================================================
--- video2.c	(revision 467)
+++ video2.c	(working copy)
@@ -24,6 +24,7 @@
        V4L2_PIX_FMT_SPCA508,
        V4L2_PIX_FMT_UYVY,     (tested)
        V4L2_PIX_FMT_YUV422P,
+       V4L2_PIX_FMT_YVU420
        V4L2_PIX_FMT_YUV420,   (tested)
        V4L2_PIX_FMT_YUYV      (tested)
 
@@ -132,7 +133,6 @@
 #endif
 
 
-
 #define ZC301_V4L2_CID_DAC_MAGN       V4L2_CID_PRIVATE_BASE
 #define ZC301_V4L2_CID_GREEN_BALANCE  (V4L2_CID_PRIVATE_BASE+1)
 
@@ -171,6 +171,9 @@
     u32 ctrl_flags;
     struct v4l2_queryctrl *controls;
 
+#if defined(HAVE_V4LCONVERT)    
+    struct v4lconvert_data *v4l_conv;
+#endif
 } src_v4l2_t;
 
 static int xioctl(int fd, int request, void *arg) 
@@ -238,10 +241,6 @@
     struct v4l2_standard standard;
     v4l2_std_id std_id;
 
-    /*if (in == IN_DEFAULT)
-        in = IN_TV;
-    */
-
     /* Set the input. */
     memset(&input, 0, sizeof (input));
     if (in == IN_DEFAULT)
@@ -386,6 +385,11 @@
 
     motion_log(LOG_INFO, 0, "%s: Supported palettes:", __FUNCTION__);
 
+#if defined(HAVE_V4LCONVERT)
+    motion_log(LOG_INFO, 0, "%s: Init libv4lconvert", __FUNCTION__);
+    vid_source->v4l_conv = convert_v4l_start(vid_source->fd);
+#endif
+
     while (xioctl(vid_source->fd, VIDIOC_ENUM_FMT, &fmtd) != -1) {
 
         int i;
@@ -417,36 +421,65 @@
         fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     }
 
-    if (index_format >= 0) {
-        
+    if (index_format >= 0) {      
+
         u32 pixformat = supported_formats[index_format];
 
-        CLEAR(vid_source->dst_fmt);
         CLEAR(vid_source->src_fmt);
-        vid_source->dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-        vid_source->dst_fmt.fmt.pix.width = *width;
-        vid_source->dst_fmt.fmt.pix.height = *height;
-        vid_source->dst_fmt.fmt.pix.pixelformat = pixformat;
-        vid_source->dst_fmt.fmt.pix.field = V4L2_FIELD_ANY;
+        vid_source->src_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        vid_source->src_fmt.fmt.pix.width = *width;
+        vid_source->src_fmt.fmt.pix.height = *height;
+        vid_source->src_fmt.fmt.pix.pixelformat = pixformat;
+        vid_source->src_fmt.fmt.pix.field = V4L2_FIELD_ANY;
 
-        if (xioctl(vid_source->fd, VIDIOC_TRY_FMT, &vid_source->dst_fmt) != -1 && 
-            vid_source->dst_fmt.fmt.pix.pixelformat == pixformat) {
+#if defined(HAVE_V4LCONVERT)
+#warning "Using libv4convert for unsupported formats"
+        int ret = 0;
+        
+        CLEAR(vid_source->dst_fmt);
+        memcpy(&vid_source->dst_fmt, &vid_source->src_fmt, sizeof(vid_source->src_fmt));
+                
+        if (!try_convert(vid_source->fd, vid_source->v4l_conv, pixformat, &vid_source->src_fmt, &vid_source->dst_fmt)) {
+             motion_log(LOG_ERR, 0, "%s: try_convert error :-( ", __FUNCTION__);
+             vid_source->v4l_conv = NULL;    
+             ret = -1;
+        }        
+      
+        vid_source->dst_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;   
+        pixformat = vid_source->src_fmt.fmt.pix.pixelformat;
+        motion_log(LOG_INFO, 0, "%s: (src) Using palette %c%c%c%c (%dx%d) bytesperlines %d sizeimage "
+                   "%d colorspace %08x", __FUNCTION__, pixformat >> 0, pixformat >> 8, 
+                   pixformat >> 16, pixformat >> 24, *width, *height, vid_source->src_fmt.fmt.pix.bytesperline, 
+                   vid_source->src_fmt.fmt.pix.sizeimage, vid_source->src_fmt.fmt.pix.colorspace);
+
+#if 0         
+        pixformat = vid_source->dst_fmt.fmt.pix.pixelformat;
+        motion_log(LOG_INFO, 0, "%s: (dst) Using palette %c%c%c%c (%dx%d) bytesperlines %d sizeimage "
+                   "%d colorspace %08x", __FUNCTION__, pixformat >> 0, pixformat >> 8, 
+                   pixformat >> 16, pixformat >> 24, *width, *height, vid_source->dst_fmt.fmt.pix.bytesperline, 
+                   vid_source->dst_fmt.fmt.pix.sizeimage, vid_source->dst_fmt.fmt.pix.colorspace);
+#endif
+                             
+        return ret;
+#else        
+        if (xioctl(vid_source->fd, VIDIOC_TRY_FMT, &vid_source->src_fmt) != -1 && 
+            vid_source->src_fmt.fmt.pix.pixelformat == pixformat) {
             motion_log(LOG_INFO, 0, "%s: index_format %d Testing palette %c%c%c%c (%dx%d)", 
                        __FUNCTION__, index_format, pixformat >> 0, pixformat >> 8, 
                        pixformat >> 16, pixformat >> 24, *width, *height);
 
-            if (vid_source->dst_fmt.fmt.pix.width != (unsigned int) *width || 
-                vid_source->dst_fmt.fmt.pix.height != (unsigned int) *height) {
+            if (vid_source->src_fmt.fmt.pix.width != (unsigned int) *width || 
+                vid_source->src_fmt.fmt.pix.height != (unsigned int) *height) {
 
                 motion_log(LOG_INFO, 0, "%s: Adjusting resolution from %ix%i to %ix%i.", 
-                           __FUNCTION__, *width, *height, vid_source->dst_fmt.fmt.pix.width, 
-                           vid_source->dst_fmt.fmt.pix.height);
+                           __FUNCTION__, *width, *height, vid_source->src_fmt.fmt.pix.width, 
+                           vid_source->src_fmt.fmt.pix.height);
 
-                *width = vid_source->dst_fmt.fmt.pix.width;
-                *height = vid_source->dst_fmt.fmt.pix.height;
+                *width = vid_source->src_fmt.fmt.pix.width;
+                *height = vid_source->src_fmt.fmt.pix.height;
             }
 
-            if (xioctl(vid_source->fd, VIDIOC_S_FMT, &vid_source->dst_fmt) == -1) {
+            if (xioctl(vid_source->fd, VIDIOC_S_FMT, &vid_source->src_fmt) == -1) {
                 motion_log(LOG_ERR, 1, "%s: Error setting pixel format.\nVIDIOC_S_FMT: ",
                            __FUNCTION__);
                 return -1;
@@ -455,14 +488,13 @@
             motion_log(LOG_INFO, 0, "%s: Using palette %c%c%c%c (%dx%d) bytesperlines %d sizeimage "
                        "%d colorspace %08x", __FUNCTION__, pixformat >> 0, pixformat >> 8, pixformat >> 16, 
                        pixformat >> 24, *width, *height, vid_source->dst_fmt.fmt.pix.bytesperline, 
-                       vid_source->dst_fmt.fmt.pix.sizeimage, vid_source->dst_fmt.fmt.pix.colorspace);
+                       vid_source->src_fmt.fmt.pix.sizeimage, vid_source->src_fmt.fmt.pix.colorspace);
 
             return 0;
         }
-
+#endif
         motion_log(LOG_ERR, 1, "%s: VIDIOC_TRY_FMT failed for format %c%c%c%c ", __FUNCTION__,
                    pixformat >> 0, pixformat >> 8, pixformat >> 16, pixformat >> 24);
-
         return -1;
     }
 
@@ -730,7 +762,11 @@
     vid_source->fps = cnt->conf.frame_limit;
     vid_source->pframe = -1;
     struct config *conf = &cnt->conf;
+#if defined(HAVE_V4LCONVERT)    
+    vid_source->v4l_conv = NULL;
+#endif
 
+
     if (v4l2_get_capability(vid_source)) 
         goto err;
     
@@ -742,10 +778,10 @@
     
     if (v4l2_scan_controls(vid_source)) 
         goto err;
-
 #if 0
     v4l2_set_fps(vid_source);
 #endif
+    
     if (v4l2_set_mmap(vid_source)) 
         goto err;
     
@@ -765,8 +801,13 @@
     return (void *) 1;
 
 err:
-    if (vid_source) 
+    if (vid_source) {
+#if defined(HAVE_V4LCONVERT)    
+        if (vid_source->v4l_conv != NULL)
+            v4lconvert_destroy(vid_source->v4l_conv);
+#endif 
         free(vid_source);
+    }
 
     viddev->v4l2_private = NULL;
     viddev->v4l2 = 0;
@@ -800,15 +841,6 @@
         viddev->width = width;
         viddev->height = height;
 
-        /*
-        viddev->input = input;
-        viddev->norm = norm;
-        viddev->width = width;
-        viddev->height = height;
-        viddev->freq = freq;
-        viddev->tuner_number = tuner_number;
-        */
-
         /* Skip all frames captured before switchtime, capture 1 after switchtime */
         {
             src_v4l2_t *vid_source = (src_v4l2_t *) viddev->v4l2_private;
@@ -905,8 +937,8 @@
 
     {
         video_buff *the_buffer = &vid_source->buffers[vid_source->buf.index];
-        
-        switch (vid_source->dst_fmt.fmt.pix.pixelformat) {
+
+        switch (vid_source->src_fmt.fmt.pix.pixelformat) {
         case V4L2_PIX_FMT_RGB24:
             conv_rgb24toyuv420p(map, the_buffer->ptr, width, height);
             return 0;
@@ -921,10 +953,11 @@
             return 0;
 
         case V4L2_PIX_FMT_YUV420:
+        case V4L2_PIX_FMT_YVU420:
             memcpy(map, the_buffer->ptr, viddev->v4l_bufsize);
             return 0;
 
-        case V4L2_PIX_FMT_PJPG:            
+        //case V4L2_PIX_FMT_PJPG:            
         case V4L2_PIX_FMT_JPEG:            
         case V4L2_PIX_FMT_MJPEG:
             return mjpegtoyuv420p(map, the_buffer->ptr, width, height, 
@@ -944,6 +977,18 @@
             bayer2rgb24(cnt->imgs.common_buffer, map, width, height);
             conv_rgb24toyuv420p(map, cnt->imgs.common_buffer, width, height);
             return 0;
+
+        default:
+#if defined(HAVE_V4LCONVERT)
+            if (v4lconvert_convert(vid_source->v4l_conv, &vid_source->src_fmt, &vid_source->dst_fmt,
+                                   the_buffer->ptr, vid_source->buffers[vid_source->buf.index].content_length,
+                                   map, viddev->v4l_bufsize ) < 0 ) {
+                motion_log(LOG_ERR, 0, "%s: v4lconvert_convert failed", __FUNCTION__);
+                return 1;
+            }
+            return 0;
+#endif
+            motion_log(LOG_ERR, 0, "%s: Format is unknown or not supported by motion", __FUNCTION__);
         }
     }
 
@@ -980,6 +1025,11 @@
         vid_source->controls = NULL;
     }
 
+#if defined(HAVE_V4LCONVERT)    
+    if (vid_source->v4l_conv != NULL)
+        v4lconvert_destroy(vid_source->v4l_conv);
+#endif    
+
     free(vid_source);
     viddev->v4l2_private = NULL;
 }
Index: video_common.c
===================================================================
--- video_common.c	(revision 467)
+++ video_common.c	(working copy)
@@ -174,7 +174,52 @@
     return 0;
 }
 
+
+#if defined(HAVE_V4LCONVERT)
 /*
+ * convert_v4l_start 
+ *
+ * Return v4lconvert_data or NULL on failure.
+ */ 
+struct v4lconvert_data * convert_v4l_start(int fd)
+{
+    struct v4lconvert_data *convert;
+
+    convert = v4lconvert_create(fd);
+
+    if (!convert) {
+        motion_log(LOG_ERR, 0, "%s: v4lconvert_create failed", __FUNCTION__);
+        return NULL;
+    }
+
+    return convert;
+}
+
+int try_convert(int fd, struct v4lconvert_data *convert, unsigned int pixelformat, struct v4l2_format *sfmt, struct v4l2_format *dfmt)
+{
+
+    if ((v4lconvert_try_format(convert, dfmt, sfmt) == 0) && 
+        (sfmt->fmt.pix.pixelformat == pixelformat)) {
+        motion_log(LOG_INFO, 0, "%s: format supported", __FUNCTION__); 
+        return 1;
+    } else {
+        motion_log(LOG_ERR, 1, "%s: failed", __FUNCTION__);
+        v4lconvert_destroy(convert);
+        return 0;
+    }
+
+    if (ioctl(fd, VIDIOC_S_FMT, sfmt) < 0) {
+        motion_log(LOG_ERR, 1, "%s: VIDIOC_S_FMT", __FUNCTION__);
+        v4lconvert_destroy(convert);
+        return 0;
+    }
+        
+    return 1;    
+}
+#endif
+
+
+/*
  * BAYER2RGB24 ROUTINE TAKEN FROM:
  *
  * Sonix SN9C10x based webcam basic I/F routines
