Index: libs/libmythtv/videoout_ivtv.h
===================================================================
--- libs/libmythtv/videoout_ivtv.h	(revision 1)
+++ libs/libmythtv/videoout_ivtv.h	(working copy)
@@ -1,11 +1,14 @@
 #ifndef VIDEOOUT_IVTV_H_
 #define VIDEOOUT_IVTV_H_
 
+#include <linux/fb.h>
+
 #include <qstring.h>
 #include <qmutex.h>
 #include <cassert>
 
 #include "videooutbase.h"
+#include "ivtv_myth.h"
 
 class NuppelVideoPlayer;
 
@@ -79,6 +82,7 @@
 
     void ShowPip(VideoFrame *frame, NuppelVideoPlayer *pipplayer);
     void SetAlpha(eAlphaState newAlpha);
+    void SetColorKey(int state, int color);
     long long GetFirmwareFramesPlayed(void);
 
     int videofd;
@@ -113,6 +117,14 @@
     bool last_normal;
     int last_mask;
     eAlphaState alphaState;
+
+    bool old_fb_ioctl;
+    bool v4l2_api;
+    int  fb_dma_ioctl;
+    bool color_key;
+    bool decoder_flush;
+    struct fb_var_screeninfo ivtvfb_var;
+    struct fb_var_screeninfo ivtvfb_var_old;
 };
 
 #endif
Index: libs/libmythtv/videodev2_myth.h
===================================================================
--- libs/libmythtv/videodev2_myth.h	(revision 1)
+++ libs/libmythtv/videodev2_myth.h	(working copy)
@@ -1,30 +1,67 @@
-#ifndef __LINUX_VIDEODEV2_H
-#define __LINUX_VIDEODEV2_H
 /*
- *	Video for Linux Two
+ *  Video for Linux Two header file
  *
- *	Header file for v4l or V4L2 drivers and applications, for
- *	Linux kernels 2.2.x or 2.4.x.
+ *  Copyright (C) 1999-2007 the contributors
  *
+ *  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.
+ *
+ *  Alternatively you can redistribute this file under the terms of the
+ *  BSD license as stated below:
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *  3. The names of its contributors may not be used to endorse or promote
+ *     products derived from this software without specific prior written
+ *     permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *	Header file for v4l or V4L2 drivers and applications
+ * with public API.
+ * All kernel-specific stuff were moved to media/v4l2-dev.h, so
+ * no #if __KERNEL tests are allowed here
+ *
  *	See http://linuxtv.org for more info
  *
- *	Author: Bill Dirks <bdirks@pacbell.net>
+ *	Author: Bill Dirks <bill@thedirks.org>
  *		Justin Schoeman
+ *              Hans Verkuil <hverkuil@xs4all.nl>
  *		et al.
  */
-
+#ifndef __LINUX_VIDEODEV2_H
+#define __LINUX_VIDEODEV2_H
+#include <sys/time.h>
 #include <sys/types.h>
 
-#define __user 
-
-#define OBSOLETE_OWNER 1 /* It will be removed for 2.6.15 */
-#define HAVE_V4L2 1
-
 /*
  * Common stuff for both V4L1 and V4L2
  * Moved from videodev.h
  */
-
 #define VIDEO_MAX_FRAME               32
 
 #define VID_TYPE_CAPTURE	1	/* Can capture */
@@ -54,47 +91,60 @@
  *	E N U M S
  */
 enum v4l2_field {
-	V4L2_FIELD_ANY        = 0, /* driver can choose from none,
-				      top, bottom, interlaced
-				      depending on whatever it thinks
-				      is approximate ... */
-	V4L2_FIELD_NONE       = 1, /* this device has no fields ... */
-	V4L2_FIELD_TOP        = 2, /* top field only */
-	V4L2_FIELD_BOTTOM     = 3, /* bottom field only */
-	V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
-	V4L2_FIELD_SEQ_TB     = 5, /* both fields sequential into one
-				      buffer, top-bottom order */
-	V4L2_FIELD_SEQ_BT     = 6, /* same as above + bottom-top order */
-	V4L2_FIELD_ALTERNATE  = 7, /* both fields alternating into
-				      separate buffers */
+	V4L2_FIELD_ANY           = 0, /* driver can choose from none,
+					 top, bottom, interlaced
+					 depending on whatever it thinks
+					 is approximate ... */
+	V4L2_FIELD_NONE          = 1, /* this device has no fields ... */
+	V4L2_FIELD_TOP           = 2, /* top field only */
+	V4L2_FIELD_BOTTOM        = 3, /* bottom field only */
+	V4L2_FIELD_INTERLACED    = 4, /* both fields interlaced */
+	V4L2_FIELD_SEQ_TB        = 5, /* both fields sequential into one
+					 buffer, top-bottom order */
+	V4L2_FIELD_SEQ_BT        = 6, /* same as above + bottom-top order */
+	V4L2_FIELD_ALTERNATE     = 7, /* both fields alternating into
+					 separate buffers */
+	V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
+					 first and the top field is
+					 transmitted first */
+	V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
+					 first and the bottom field is
+					 transmitted first */
 };
 #define V4L2_FIELD_HAS_TOP(field)	\
 	((field) == V4L2_FIELD_TOP 	||\
 	 (field) == V4L2_FIELD_INTERLACED ||\
+	 (field) == V4L2_FIELD_INTERLACED_TB ||\
+	 (field) == V4L2_FIELD_INTERLACED_BT ||\
 	 (field) == V4L2_FIELD_SEQ_TB	||\
 	 (field) == V4L2_FIELD_SEQ_BT)
 #define V4L2_FIELD_HAS_BOTTOM(field)	\
 	((field) == V4L2_FIELD_BOTTOM 	||\
 	 (field) == V4L2_FIELD_INTERLACED ||\
+	 (field) == V4L2_FIELD_INTERLACED_TB ||\
+	 (field) == V4L2_FIELD_INTERLACED_BT ||\
 	 (field) == V4L2_FIELD_SEQ_TB	||\
 	 (field) == V4L2_FIELD_SEQ_BT)
 #define V4L2_FIELD_HAS_BOTH(field)	\
 	((field) == V4L2_FIELD_INTERLACED ||\
-	 (field) == V4L2_FIELD_SEQ_TB	||\
+	 (field) == V4L2_FIELD_INTERLACED_TB ||\
+	 (field) == V4L2_FIELD_INTERLACED_BT ||\
+	 (field) == V4L2_FIELD_SEQ_TB ||\
 	 (field) == V4L2_FIELD_SEQ_BT)
 
 enum v4l2_buf_type {
-	V4L2_BUF_TYPE_VIDEO_CAPTURE      = 1,
-	V4L2_BUF_TYPE_VIDEO_OUTPUT       = 2,
-	V4L2_BUF_TYPE_VIDEO_OVERLAY      = 3,
-	V4L2_BUF_TYPE_VBI_CAPTURE        = 4,
-	V4L2_BUF_TYPE_VBI_OUTPUT         = 5,
+	V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,
+	V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,
+	V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,
+	V4L2_BUF_TYPE_VBI_CAPTURE          = 4,
+	V4L2_BUF_TYPE_VBI_OUTPUT           = 5,
+	V4L2_BUF_TYPE_SLICED_VBI_CAPTURE   = 6,
+	V4L2_BUF_TYPE_SLICED_VBI_OUTPUT    = 7,
 #if 1
-	/* Experimental Sliced VBI */
-	V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
-	V4L2_BUF_TYPE_SLICED_VBI_OUTPUT  = 7,
+	/* Experimental */
+	V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
 #endif
-	V4L2_BUF_TYPE_PRIVATE            = 0x80,
+	V4L2_BUF_TYPE_PRIVATE              = 0x80,
 };
 
 enum v4l2_ctrl_type {
@@ -185,11 +235,10 @@
 #define V4L2_CAP_VIDEO_OVERLAY		0x00000004  /* Can do video overlay */
 #define V4L2_CAP_VBI_CAPTURE		0x00000010  /* Is a raw VBI capture device */
 #define V4L2_CAP_VBI_OUTPUT		0x00000020  /* Is a raw VBI output device */
-#if 1
 #define V4L2_CAP_SLICED_VBI_CAPTURE	0x00000040  /* Is a sliced VBI capture device */
 #define V4L2_CAP_SLICED_VBI_OUTPUT	0x00000080  /* Is a sliced VBI output device */
-#endif
 #define V4L2_CAP_RDS_CAPTURE		0x00000100  /* RDS data capture */
+#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY	0x00000200  /* Can do video output overlay */
 
 #define V4L2_CAP_TUNER			0x00010000  /* has a tuner */
 #define V4L2_CAP_AUDIO			0x00020000  /* has audio support */
@@ -202,7 +251,6 @@
 /*
  *	V I D E O   I M A G E   F O R M A T
  */
-
 struct v4l2_pix_format
 {
 	__u32         		width;
@@ -243,7 +291,8 @@
 #define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y','U','1','2') /* 12  YUV 4:2:0     */
 #define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y','Y','U','V') /* 16  YUV 4:2:2     */
 #define V4L2_PIX_FMT_HI240   v4l2_fourcc('H','I','2','4') /*  8  8-bit color   */
-#define V4L2_PIX_FMT_HM12    v4l2_fourcc('H','M','1','2') /*  8  YUV 4:1:1 16x16 macroblocks */
+#define V4L2_PIX_FMT_HM12    v4l2_fourcc('H','M','1','2') /*  8  YUV 4:2:0 16x16 macroblocks */
+#define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R','4','4','4') /* 16  xxxxrrrr ggggbbbb */
 
 /* see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B','A','8','1') /*  8  BGBG.. GRGR.. */
@@ -276,8 +325,83 @@
 
 #define V4L2_FMT_FLAG_COMPRESSED 0x0001
 
+#if 1
+	/* Experimental Frame Size and frame rate enumeration */
+/*
+ *	F R A M E   S I Z E   E N U M E R A T I O N
+ */
+enum v4l2_frmsizetypes
+{
+	V4L2_FRMSIZE_TYPE_DISCRETE	= 1,
+	V4L2_FRMSIZE_TYPE_CONTINUOUS	= 2,
+	V4L2_FRMSIZE_TYPE_STEPWISE	= 3,
+};
 
+struct v4l2_frmsize_discrete
+{
+	__u32			width;		/* Frame width [pixel] */
+	__u32			height;		/* Frame height [pixel] */
+};
+
+struct v4l2_frmsize_stepwise
+{
+	__u32			min_width;	/* Minimum frame width [pixel] */
+	__u32			max_width;	/* Maximum frame width [pixel] */
+	__u32			step_width;	/* Frame width step size [pixel] */
+	__u32			min_height;	/* Minimum frame height [pixel] */
+	__u32			max_height;	/* Maximum frame height [pixel] */
+	__u32			step_height;	/* Frame height step size [pixel] */
+};
+
+struct v4l2_frmsizeenum
+{
+	__u32			index;		/* Frame size number */
+	__u32			pixel_format;	/* Pixel format */
+	__u32			type;		/* Frame size type the device supports. */
+
+	union {					/* Frame size */
+		struct v4l2_frmsize_discrete	discrete;
+		struct v4l2_frmsize_stepwise	stepwise;
+	};
+
+	__u32   reserved[2];			/* Reserved space for future use */
+};
+
 /*
+ *	F R A M E   R A T E   E N U M E R A T I O N
+ */
+enum v4l2_frmivaltypes
+{
+	V4L2_FRMIVAL_TYPE_DISCRETE	= 1,
+	V4L2_FRMIVAL_TYPE_CONTINUOUS	= 2,
+	V4L2_FRMIVAL_TYPE_STEPWISE	= 3,
+};
+
+struct v4l2_frmival_stepwise
+{
+	struct v4l2_fract	min;		/* Minimum frame interval [s] */
+	struct v4l2_fract	max;		/* Maximum frame interval [s] */
+	struct v4l2_fract	step;		/* Frame interval step size [s] */
+};
+
+struct v4l2_frmivalenum
+{
+	__u32			index;		/* Frame format index */
+	__u32			pixel_format;	/* Pixel format */
+	__u32			width;		/* Frame width */
+	__u32			height;		/* Frame height */
+	__u32			type;		/* Frame interval type the device supports. */
+
+	union {					/* Frame interval */
+		struct v4l2_fract		discrete;
+		struct v4l2_frmival_stepwise	stepwise;
+	};
+
+	__u32	reserved[2];			/* Reserved space for future use */
+};
+#endif
+
+/*
  *	T I M E C O D E
  */
 struct v4l2_timecode
@@ -307,97 +431,6 @@
 /* The above is based on SMPTE timecodes */
 
 
-/*
- *	M P E G   C O M P R E S S I O N   P A R A M E T E R S
- *
- *  ### WARNING: This experimental MPEG compression API is obsolete.
- *  ###          It is replaced by the MPEG controls API.
- *  ###          This old API will disappear in the near future!
- *
- */
-
-
-enum v4l2_bitrate_mode {
-	V4L2_BITRATE_NONE = 0,	/* not specified */
-	V4L2_BITRATE_CBR,	/* constant bitrate */
-	V4L2_BITRATE_VBR,	/* variable bitrate */
-};
-struct v4l2_bitrate {
-	/* rates are specified in kbit/sec */
-	enum v4l2_bitrate_mode	mode;
-	__u32			min;
-	__u32			target;  /* use this one for CBR */
-	__u32			max;
-};
-
-enum v4l2_mpeg_streamtype {
-	V4L2_MPEG_SS_1,		/* MPEG-1 system stream */
-	V4L2_MPEG_PS_2,		/* MPEG-2 program stream */
-	V4L2_MPEG_TS_2,		/* MPEG-2 transport stream */
-	V4L2_MPEG_PS_DVD,      	/* MPEG-2 program stream with DVD header fixups */
-};
-enum v4l2_mpeg_audiotype {
-	V4L2_MPEG_AU_2_I,	/* MPEG-2 layer 1 */
-	V4L2_MPEG_AU_2_II,	/* MPEG-2 layer 2 */
-	V4L2_MPEG_AU_2_III,	/* MPEG-2 layer 3 */
-	V4L2_MPEG_AC3,		/* AC3 */
-	V4L2_MPEG_LPCM,		/* LPCM */
-	V4L2_MPEG_AUDIO_UNKNOWN = 0xff,
-};
-enum v4l2_mpeg_videotype {
-	V4L2_MPEG_VI_1,		/* MPEG-1 */
-	V4L2_MPEG_VI_2,		/* MPEG-2 */
-	V4L2_MPEG_VIDEO_UNKNOWN = 0xff,
-};
-enum v4l2_mpeg_aspectratio {
-	V4L2_MPEG_ASPECT_SQUARE = 1,   /* square pixel */
-	V4L2_MPEG_ASPECT_4_3    = 2,   /*  4 : 3       */
-	V4L2_MPEG_ASPECT_16_9   = 3,   /* 16 : 9       */
-	V4L2_MPEG_ASPECT_1_221  = 4,   /*  1 : 2,21    */
-	V4L2_MPEG_ASPECT_UNKNOWN = 0xff,
-};
-
-struct v4l2_mpeg_compression {
-	/* general */
-	enum v4l2_mpeg_streamtype	st_type;
-	struct v4l2_bitrate		st_bitrate;
-
-	/* transport streams */
-	__u16				ts_pid_pmt;
-	__u16				ts_pid_audio;
-	__u16				ts_pid_video;
-	__u16				ts_pid_pcr;
-
-	/* program stream */
-	__u16				ps_size;
-	__u16				reserved_1;    /* align */
-
-	/* audio */
-	enum v4l2_mpeg_audiotype	au_type;
-	struct v4l2_bitrate		au_bitrate;
-	__u32				au_sample_rate;
-	__u8                            au_pesid;
-	__u8                            reserved_2[3]; /* align */
-
-	/* video */
-	enum v4l2_mpeg_videotype	vi_type;
-	enum v4l2_mpeg_aspectratio	vi_aspect_ratio;
-	struct v4l2_bitrate		vi_bitrate;
-	__u32				vi_frame_rate;
-	__u16				vi_frames_per_gop;
-	__u16				vi_bframes_count;
-	__u8                            vi_pesid;
-	__u8                            reserved_3[3]; /* align */
-
-	/* misc flags */
-	__u32                           closed_gops:1;
-	__u32                           pulldown:1;
-	__u32                           reserved_4:30; /* align */
-
-	/* I don't expect the above being perfect yet ;) */
-	__u32				reserved_5[8];
-};
-
 struct v4l2_jpegcompression
 {
 	int quality;
@@ -428,7 +461,6 @@
 					* allways use APP0 */
 };
 
-
 /*
  *	M E M O R Y - M A P P I N G   B U F F E R S
  */
@@ -489,15 +521,23 @@
 #define V4L2_FBUF_CAP_CHROMAKEY		0x0002
 #define V4L2_FBUF_CAP_LIST_CLIPPING     0x0004
 #define V4L2_FBUF_CAP_BITMAP_CLIPPING	0x0008
+#define V4L2_FBUF_CAP_LOCAL_ALPHA	0x0010
+#define V4L2_FBUF_CAP_GLOBAL_ALPHA	0x0020
+#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA	0x0040
+#define V4L2_FBUF_CAP_GLOBAL_INV_ALPHA	0x0080
 /*  Flags for the 'flags' field. */
 #define V4L2_FBUF_FLAG_PRIMARY		0x0001
 #define V4L2_FBUF_FLAG_OVERLAY		0x0002
 #define V4L2_FBUF_FLAG_CHROMAKEY	0x0004
+#define V4L2_FBUF_FLAG_LOCAL_ALPHA	0x0008
+#define V4L2_FBUF_FLAG_GLOBAL_ALPHA	0x0010
+#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA	0x0020
+#define V4L2_FBUF_FLAG_GLOBAL_INV_ALPHA	0x0040
 
 struct v4l2_clip
 {
 	struct v4l2_rect        c;
-	struct v4l2_clip	__user *next;
+	struct v4l2_clip	*next;
 };
 
 struct v4l2_window
@@ -505,12 +545,12 @@
 	struct v4l2_rect        w;
 	enum v4l2_field  	field;
 	__u32			chromakey;
-	struct v4l2_clip	__user *clips;
+	struct v4l2_clip	*clips;
 	__u32			clipcount;
-	void			__user *bitmap;
+	void			*bitmap;
+	__u8                    global_alpha;
 };
 
-
 /*
  *	C A P T U R E   P A R A M E T E R S
  */
@@ -523,6 +563,7 @@
 	__u32              readbuffers;   /*  # of buffers for read */
 	__u32		   reserved[4];
 };
+
 /*  Flags for 'capability' and 'capturemode' fields */
 #define V4L2_MODE_HIGHQUALITY	0x0001	/*  High quality imaging mode */
 #define V4L2_CAP_TIMEPERFRAME	0x1000	/*  timeperframe field is supported */
@@ -540,7 +581,6 @@
 /*
  *	I N P U T   I M A G E   C R O P P I N G
  */
-
 struct v4l2_cropcap {
 	enum v4l2_buf_type      type;
 	struct v4l2_rect        bounds;
@@ -592,6 +632,15 @@
 #define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
 #define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)
 
+/* FIXME:
+   Although std_id is 64 bits, there is an issue on PPC32 architecture that
+   makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding
+   this value to 32 bits.
+   As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide),
+   it should work fine. However, if needed to add more than two standards,
+   v4l2-common.c should be fixed.
+ */
+
 /* some merged standards */
 #define V4L2_STD_MN	(V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
 #define V4L2_STD_B	(V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
@@ -647,7 +696,6 @@
 	__u32		     reserved[4];
 };
 
-
 /*
  *	V I D E O   I N P U T S
  */
@@ -662,6 +710,7 @@
 	__u32	     status;
 	__u32	     reserved[4];
 };
+
 /*  Values for the 'type' field */
 #define V4L2_INPUT_TYPE_TUNER		1
 #define V4L2_INPUT_TYPE_CAMERA		2
@@ -721,7 +770,7 @@
 		__s64 value64;
 		void *reserved;
 	};
-}  __attribute__ ((packed));
+} __attribute__ ((packed));
 
 struct v4l2_ext_controls
 {
@@ -922,6 +971,7 @@
 	V4L2_MPEG_AUDIO_CRC_NONE  = 0,
 	V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
 };
+#define V4L2_CID_MPEG_AUDIO_MUTE 		(V4L2_CID_MPEG_BASE+109)
 
 /*  MPEG video */
 #define V4L2_CID_MPEG_VIDEO_ENCODING 		(V4L2_CID_MPEG_BASE+200)
@@ -948,6 +998,8 @@
 #define V4L2_CID_MPEG_VIDEO_BITRATE 		(V4L2_CID_MPEG_BASE+207)
 #define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK 	(V4L2_CID_MPEG_BASE+208)
 #define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
+#define V4L2_CID_MPEG_VIDEO_MUTE 		(V4L2_CID_MPEG_BASE+210)
+#define V4L2_CID_MPEG_VIDEO_MUTE_YUV 		(V4L2_CID_MPEG_BASE+211)
 
 /*  MPEG-class control IDs specific to the CX2584x driver as defined by V4L2 */
 #define V4L2_CID_MPEG_CX2341X_BASE 				(V4L2_CTRL_CLASS_MPEG | 0x1000)
@@ -988,6 +1040,7 @@
 #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP 	(V4L2_CID_MPEG_CX2341X_BASE+8)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM	(V4L2_CID_MPEG_CX2341X_BASE+9)
 #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP 	(V4L2_CID_MPEG_CX2341X_BASE+10)
+#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS 	(V4L2_CID_MPEG_CX2341X_BASE+11)
 
 /*
  *	T U N I N G
@@ -1060,13 +1113,13 @@
 	__u32	mode;
 	__u32	reserved[2];
 };
+
 /*  Flags for the 'capability' field */
 #define V4L2_AUDCAP_STEREO		0x00001
 #define V4L2_AUDCAP_AVL			0x00002
 
 /*  Flags for the 'mode' field */
 #define V4L2_AUDMODE_AVL		0x00001
-#define V4L2_AUDMODE_32BITS		0x00002
 
 struct v4l2_audioout
 {
@@ -1078,13 +1131,61 @@
 };
 
 /*
+ *	M P E G   S E R V I C E S
+ *
+ *	NOTE: EXPERIMENTAL API
+ */
+#if 1
+#define V4L2_ENC_IDX_FRAME_I    (0)
+#define V4L2_ENC_IDX_FRAME_P    (1)
+#define V4L2_ENC_IDX_FRAME_B    (2)
+#define V4L2_ENC_IDX_FRAME_MASK (0xf)
+
+struct v4l2_enc_idx_entry {
+	__u64 offset;
+	__u64 pts;
+	__u32 length;
+	__u32 flags;
+	__u32 reserved[2];
+};
+
+#define V4L2_ENC_IDX_ENTRIES (64)
+struct v4l2_enc_idx {
+	__u32 entries;
+	__u32 entries_cap;
+	__u32 reserved[4];
+	struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES];
+};
+
+
+#define V4L2_ENC_CMD_START      (0)
+#define V4L2_ENC_CMD_STOP       (1)
+#define V4L2_ENC_CMD_PAUSE      (2)
+#define V4L2_ENC_CMD_RESUME     (3)
+
+/* Flags for V4L2_ENC_CMD_STOP */
+#define V4L2_ENC_CMD_STOP_AT_GOP_END    (1 << 0)
+
+struct v4l2_encoder_cmd {
+	__u32 cmd;
+	__u32 flags;
+	union {
+		struct {
+			__u32 data[8];
+		} raw;
+	};
+};
+
+#endif
+
+
+/*
  *	D A T A   S E R V I C E S   ( V B I )
  *
  *	Data services API by Michael Schimek
  */
 
 /* Raw VBI */
-
 struct v4l2_vbi_format
 {
 	__u32	sampling_rate;		/* in 1 Hz */
@@ -1101,7 +1202,6 @@
 #define V4L2_VBI_UNSYNC		(1<< 0)
 #define V4L2_VBI_INTERLACED	(1<< 1)
 
-#if 1
 /* Sliced VBI
  *
  *    This implements is a proposal V4L2 API to allow SLICED VBI
@@ -1142,7 +1242,8 @@
 				 (equals frame lines 313-336 for 625 line video
 				  standards, 263-286 for 525 line standards) */
 	__u16   service_lines[2][24];
-	__u32   reserved[4];    /* must be 0 */
+	enum v4l2_buf_type type;
+	__u32   reserved[3];    /* must be 0 */
 };
 
 struct v4l2_sliced_vbi_data
@@ -1153,7 +1254,6 @@
 	__u32   reserved;       /* must be 0 */
 	__u8    data[48];
 };
-#endif
 
 /*
  *	A G G R E G A T E   S T R U C T U R E S
@@ -1169,9 +1269,7 @@
 		struct v4l2_pix_format		pix;     // V4L2_BUF_TYPE_VIDEO_CAPTURE
 		struct v4l2_window		win;     // V4L2_BUF_TYPE_VIDEO_OVERLAY
 		struct v4l2_vbi_format		vbi;     // V4L2_BUF_TYPE_VBI_CAPTURE
-#if 1
 		struct v4l2_sliced_vbi_format	sliced;  // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
-#endif
 		__u8	raw_data[200];                   // user-defined
 	} fmt;
 };
@@ -1190,8 +1288,33 @@
 	} parm;
 };
 
+/*
+ *	A D V A N C E D   D E B U G G I N G
+ *
+ *	NOTE: EXPERIMENTAL API
+ */
 
+/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
 
+#define V4L2_CHIP_MATCH_HOST       0  /* Match against chip ID on host (0 for the host) */
+#define V4L2_CHIP_MATCH_I2C_DRIVER 1  /* Match against I2C driver ID */
+#define V4L2_CHIP_MATCH_I2C_ADDR   2  /* Match against I2C 7-bit address */
+
+struct v4l2_register {
+	__u32 match_type; /* Match type */
+	__u32 match_chip; /* Match this chip, meaning determined by match_type */
+	__u64 reg;
+	__u64 val;
+};
+
+/* VIDIOC_G_CHIP_IDENT */
+struct v4l2_chip_ident {
+	__u32 match_type;  /* Match type */
+	__u32 match_chip;  /* Match this chip, meaning determined by match_type */
+	__u32 ident;       /* chip identifier as specified in <media/v4l2-chip-ident.h> */
+	__u32 revision;    /* chip revision, chip specific */
+};
+
 /*
  *	I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
  *
@@ -1201,8 +1324,6 @@
 #define VIDIOC_ENUM_FMT         _IOWR ('V',  2, struct v4l2_fmtdesc)
 #define VIDIOC_G_FMT		_IOWR ('V',  4, struct v4l2_format)
 #define VIDIOC_S_FMT		_IOWR ('V',  5, struct v4l2_format)
-#define VIDIOC_G_MPEGCOMP       _IOR  ('V',  6, struct v4l2_mpeg_compression)
-#define VIDIOC_S_MPEGCOMP     	_IOW  ('V',  7, struct v4l2_mpeg_compression)
 #define VIDIOC_REQBUFS		_IOWR ('V',  8, struct v4l2_requestbuffers)
 #define VIDIOC_QUERYBUF		_IOWR ('V',  9, struct v4l2_buffer)
 #define VIDIOC_G_FBUF		_IOR  ('V', 10, struct v4l2_framebuffer)
@@ -1248,14 +1369,26 @@
 #define VIDIOC_ENUMAUDOUT	_IOWR ('V', 66, struct v4l2_audioout)
 #define VIDIOC_G_PRIORITY       _IOR  ('V', 67, enum v4l2_priority)
 #define VIDIOC_S_PRIORITY       _IOW  ('V', 68, enum v4l2_priority)
-#if 1
-#define VIDIOC_G_SLICED_VBI_CAP _IOR  ('V', 69, struct v4l2_sliced_vbi_cap)
-#endif
+#define VIDIOC_G_SLICED_VBI_CAP _IOWR ('V', 69, struct v4l2_sliced_vbi_cap)
 #define VIDIOC_LOG_STATUS       _IO   ('V', 70)
 #define VIDIOC_G_EXT_CTRLS	_IOWR ('V', 71, struct v4l2_ext_controls)
 #define VIDIOC_S_EXT_CTRLS	_IOWR ('V', 72, struct v4l2_ext_controls)
 #define VIDIOC_TRY_EXT_CTRLS	_IOWR ('V', 73, struct v4l2_ext_controls)
+#if 1
+#define VIDIOC_ENUM_FRAMESIZES	_IOWR ('V', 74, struct v4l2_frmsizeenum)
+#define VIDIOC_ENUM_FRAMEINTERVALS	_IOWR ('V', 75, struct v4l2_frmivalenum)
+#define VIDIOC_G_ENC_INDEX      _IOR  ('V', 76, struct v4l2_enc_idx)
+#define VIDIOC_ENCODER_CMD      _IOWR ('V', 77, struct v4l2_encoder_cmd)
+#define VIDIOC_TRY_ENCODER_CMD  _IOWR ('V', 78, struct v4l2_encoder_cmd)
 
+/* Experimental, only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
+#define	VIDIOC_DBG_S_REGISTER 	_IOW  ('V', 79, struct v4l2_register)
+#define	VIDIOC_DBG_G_REGISTER 	_IOWR ('V', 80, struct v4l2_register)
+
+#define VIDIOC_G_CHIP_IDENT     _IOWR ('V', 81, struct v4l2_chip_ident)
+#endif
+
+#ifdef __OLD_VIDIOC_
 /* for compatibility, will go away some day */
 #define VIDIOC_OVERLAY_OLD     	_IOWR ('V', 14, int)
 #define VIDIOC_S_PARM_OLD      	_IOW  ('V', 22, struct v4l2_streamparm)
@@ -1263,6 +1396,7 @@
 #define VIDIOC_G_AUDIO_OLD     	_IOWR ('V', 33, struct v4l2_audio)
 #define VIDIOC_G_AUDOUT_OLD    	_IOWR ('V', 49, struct v4l2_audioout)
 #define VIDIOC_CROPCAP_OLD     	_IOR  ('V', 58, struct v4l2_cropcap)
+#endif
 
 #define BASE_VIDIOC_PRIVATE	192		/* 192-255 are private */
 
Index: libs/libmythtv/videoout_ivtv.cpp
===================================================================
--- libs/libmythtv/videoout_ivtv.cpp	(revision 1)
+++ libs/libmythtv/videoout_ivtv.cpp	(working copy)
@@ -23,17 +23,15 @@
 #include <iostream>
 using namespace std;
 
+#include <linux/fb.h>
+
 #include "videodev_myth.h"
 #include "videodev2_myth.h"
 
 #include "videoout_ivtv.h"
 extern "C" {
 #include <inttypes.h>
-#ifdef USING_IVTV_HEADER
-#include <linux/ivtv.h>
-#else
 #include "ivtv_myth.h"
-#endif
 }
 
 #include "libmyth/mythcontext.h"
@@ -50,6 +48,54 @@
 #define LOC QString("IVD: ")
 #define LOC_ERR QString("IVD Error: ")
 
+/***************************************************************/
+/* An extract from linux/video.h which is now required for the */
+/* decoder. Included here since we need an up to date version. */
+
+/* Decoder commands */
+#define VIDEO_CMD_PLAY        (0)
+#define VIDEO_CMD_STOP        (1)
+#define VIDEO_CMD_FREEZE      (2)
+#define VIDEO_CMD_CONTINUE    (3)
+
+/* Flags for VIDEO_CMD_FREEZE */
+#define VIDEO_CMD_FREEZE_TO_BLACK     	(1 << 0)
+
+/* Flags for VIDEO_CMD_STOP */
+#define VIDEO_CMD_STOP_TO_BLACK      	(1 << 0)
+#define VIDEO_CMD_STOP_IMMEDIATELY     	(1 << 1)
+
+/* The structure must be zeroed before use by the application
+   This ensures it can be extended safely in the future. */
+struct video_command {
+    __u32 cmd;
+    __u32 flags;
+    union {
+        struct {
+            __u64 pts;
+        } stop;
+
+        struct {
+            __u32 speed;
+            __u32 format;
+        } play;
+
+        struct {
+            __u32 data[16];
+        } raw;
+    };
+};
+
+#define VIDEO_GET_FRAME_COUNT _IOR('o', 58, __u64)
+#define VIDEO_COMMAND _IOWR('o', 59, struct video_command)
+
+/* End of extract from linux/video.h                           */
+/***************************************************************/
+
+/* Used by recent ivtv-fb. Replaces the older IVTVFB_IOCTL_PREP_FRAME */
+/* Argument list is identical */
+#define IVTVFB_IOC_DMA_FRAME  _IOW ('V', BASE_VIDIOC_PRIVATE+0, struct ivtvfb_ioctl_dma_host_to_ivtv_args)
+
 /** \class  VideoOutputIvtv
  *  \brief  Implementation of video output for the Hauppage PVR 350 cards.
  */
@@ -74,7 +120,9 @@
 
     last_normal(true),        last_mask(0x2),
 
-    alphaState(kAlpha_Solid)
+    alphaState(kAlpha_Solid), old_fb_ioctl(true),
+    v4l2_api(false),          fb_dma_ioctl(IVTVFB_IOCTL_PREP_FRAME),
+    color_key(false),         decoder_flush(true)
 {
 }
 
@@ -82,20 +130,14 @@
 {
     Close();
 
-    if (fbfd >= 0)
-    {
-        ClearOSD();
-        SetAlpha(kAlpha_Solid);
-
-        close(fbfd);
-    }
-
     if (osdbuffer)
         delete [] osdbuffer;
 }
 
 void VideoOutputIvtv::ClearOSD(void) 
 {
+    int ret;
+
     if (fbfd < 0)
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR + "ClearOSD() -- no framebuffer!");
@@ -104,27 +146,81 @@
 
     VERBOSE(VB_PLAYBACK, LOC + "ClearOSD");
 
-    struct ivtv_osd_coords osdcoords;
-    bzero(&osdcoords, sizeof(osdcoords));
+    bzero(osdbuf_aligned, osdbufsize);
 
-    if (ioctl(fbfd, IVTVFB_IOCTL_GET_ACTIVE_BUFFER, &osdcoords) < 0)
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Failed to get active buffer for ClearOSD()" + ENO);
-    }
     struct ivtvfb_ioctl_dma_host_to_ivtv_args prep;
     bzero(&prep, sizeof(prep));
 
     prep.source = osdbuf_aligned;
     prep.dest_offset = 0;
-    prep.count = osdcoords.max_offset;
 
-    bzero(osdbuf_aligned, osdbufsize);
+    if (old_fb_ioctl == true)
+    {
+        struct ivtv_osd_coords osdcoords;
+        bzero(&osdcoords, sizeof(osdcoords));
 
-    if (ioctl(fbfd, IVTVFB_IOCTL_PREP_FRAME, &prep) < 0)
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to prepare frame" + ENO);
+        if (ioctl(fbfd, IVTVFB_IOCTL_GET_ACTIVE_BUFFER, &osdcoords) < 0)
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR +
+                    "Failed to get active buffer for ClearOSD()" + ENO);
+            return;
+        }
+        prep.count = osdcoords.max_offset;
+    }
+    else
+    {
+        prep.count = ivtvfb_var.xres_virtual * ivtvfb_var.yres * (ivtvfb_var.bits_per_pixel / 8); 
+    }
+
+    if (old_fb_ioctl == false)
+        ioctl(fbfd, FBIOPAN_DISPLAY, &ivtvfb_var);
+
+    if ((ret = ioctl(fbfd, fb_dma_ioctl, &prep)) < 0)
+    {
+        if (errno == EINVAL && fb_dma_ioctl != IVTVFB_IOC_DMA_FRAME)
+        {
+            fb_dma_ioctl = IVTVFB_IOC_DMA_FRAME;
+            ret = ioctl(fbfd, fb_dma_ioctl, &prep);
+        }
+        if (ret < 0)
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to prepare frame" + ENO);
+    }
 }
 
+void VideoOutputIvtv::SetColorKey(int state, int color)
+{
+    if (v4l2_api)
+    {
+        struct v4l2_format alpha_state;
+        struct v4l2_framebuffer framebuffer_state;
+
+        ioctl(videofd, VIDIOC_G_FBUF, &framebuffer_state);
+        alpha_state.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY;
+        ioctl(videofd, VIDIOC_G_FMT, &alpha_state);
+
+        if (state)
+        {
+            framebuffer_state.flags |= V4L2_FBUF_FLAG_CHROMAKEY;
+            alpha_state.fmt.win.chromakey = color;
+        }
+        else
+        {
+            framebuffer_state.flags &= ~V4L2_FBUF_FLAG_CHROMAKEY;
+        }
+
+        ioctl(videofd, VIDIOC_S_FBUF, &framebuffer_state);
+        ioctl(videofd, VIDIOC_S_FMT, &alpha_state);
+    }
+    else if (color_key)
+    {
+        struct ivtvfb_ioctl_colorkey ivtvfb_colorkey;
+        // Setup color-key. This helps when X isn't running on the PVR350
+        ivtvfb_colorkey.state = state;
+        ivtvfb_colorkey.colorKey = color;
+        ioctl(fbfd,IVTVFB_IOCTL_SET_COLORKEY, &ivtvfb_colorkey);
+    }
+}
+
 void VideoOutputIvtv::SetAlpha(eAlphaState newAlphaState)
 {
     if (alphaState == newAlphaState)
@@ -141,34 +237,106 @@
         VERBOSE(VB_PLAYBACK, LOC + "SetAlpha(Embedded)");
 #endif
 
-    alphaState = newAlphaState;
-
     struct ivtvfb_ioctl_state_info fbstate;
     bzero(&fbstate, sizeof(fbstate));
-    if (ioctl(fbfd, IVTVFB_IOCTL_GET_STATE, &fbstate) < 0)
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to query alpha state" + ENO);
 
-    if (alphaState == kAlpha_Local)
+    if (v4l2_api)
     {
-        fbstate.status &= ~IVTVFB_STATUS_GLOBAL_ALPHA;
-        fbstate.status |= IVTVFB_STATUS_LOCAL_ALPHA;
+        struct v4l2_format alpha_state;
+        struct v4l2_framebuffer framebuffer_state;
+
+        ioctl(videofd, VIDIOC_G_FBUF, &framebuffer_state);
+        alpha_state.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY;
+        ioctl(videofd, VIDIOC_G_FMT, &alpha_state);
+
+        if (newAlphaState == kAlpha_Local)
+        {
+            framebuffer_state.flags &= ~V4L2_FBUF_FLAG_GLOBAL_ALPHA;
+            framebuffer_state.flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
+        }
+        else
+        {
+            framebuffer_state.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
+            framebuffer_state.flags &= ~V4L2_FBUF_FLAG_LOCAL_ALPHA;
+        }
+
+        if (newAlphaState == kAlpha_Solid)
+            alpha_state.fmt.win.global_alpha = 255;
+        else if (newAlphaState == kAlpha_Clear)
+            alpha_state.fmt.win.global_alpha = 0;
+        else if (newAlphaState == kAlpha_Embedded)
+            alpha_state.fmt.win.global_alpha = gContext->GetNumSetting("PVR350EPGAlphaValue", 164);
+
+        if (ioctl(videofd, VIDIOC_S_FBUF, &framebuffer_state) < 0)
+            VERBOSE(VB_IMPORTANT, LOC_ERR +
+                    "Failed to set ivtv alpha mode" + ENO);
+        if (ioctl(videofd, VIDIOC_S_FMT, &alpha_state) < 0)
+            VERBOSE(VB_IMPORTANT, LOC_ERR +
+                    "Failed to set ivtv alpha values." + ENO);
     }
     else
     {
-        fbstate.status |= IVTVFB_STATUS_GLOBAL_ALPHA;
-        fbstate.status &= ~IVTVFB_STATUS_LOCAL_ALPHA;
+        if (ioctl(fbfd, IVTVFB_IOCTL_GET_STATE, &fbstate) < 0)
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to query alpha state" + ENO);
+
+        if (newAlphaState == kAlpha_Local)
+        {
+            fbstate.status &= ~IVTVFB_STATUS_GLOBAL_ALPHA;
+            fbstate.status |= IVTVFB_STATUS_LOCAL_ALPHA;
+        }
+        else
+        {
+            fbstate.status |= IVTVFB_STATUS_GLOBAL_ALPHA;
+            fbstate.status &= ~IVTVFB_STATUS_LOCAL_ALPHA;
+        }
+
+        if (newAlphaState == kAlpha_Solid)
+            fbstate.alpha = 255;
+        else if (newAlphaState == kAlpha_Clear)
+            fbstate.alpha = 0;
+        else if (newAlphaState == kAlpha_Embedded)
+            fbstate.alpha = gContext->GetNumSetting("PVR350EPGAlphaValue", 164);
+
+        if (ioctl(fbfd, IVTVFB_IOCTL_SET_STATE, &fbstate) < 0)
+            VERBOSE(VB_IMPORTANT, LOC_ERR +
+                    "Failed to set ivtv alpha state." + ENO);
     }
 
-    if (alphaState == kAlpha_Solid)
-        fbstate.alpha = 255;
-    else if (alphaState == kAlpha_Clear)
-        fbstate.alpha = 0;
-    else if (alphaState == kAlpha_Embedded)
-        fbstate.alpha = gContext->GetNumSetting("PVR350EPGAlphaValue", 164);
+    // If using the new ioctl we need to check the fb mode
+    if (old_fb_ioctl == false)
+    {
+        struct fb_var_screeninfo *tmpfb_var = NULL;
 
-    if (ioctl(fbfd, IVTVFB_IOCTL_SET_STATE, &fbstate) < 0)
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Failed to set ivtv alpha values." + ENO);
+        // If EPG switched on, select old fb mode
+        if (newAlphaState == kAlpha_Embedded)
+            tmpfb_var = &ivtvfb_var_old;
+        // If EPG switched off, select new fb mode
+        else if (newAlphaState != kAlpha_Embedded && alphaState == kAlpha_Embedded)
+            tmpfb_var = &ivtvfb_var;
+
+        // Change fb mode if required
+        if (tmpfb_var)
+        {
+            if ((ivtvfb_var_old.bits_per_pixel != 32) &&
+                 (ivtvfb_var_old.bits_per_pixel != 8))
+            {
+                // Hide osd during mode change
+                ioctl(fbfd, FBIOBLANK, VESA_VSYNC_SUSPEND);
+                tmpfb_var->activate = FB_ACTIVATE_NOW;
+                if (ioctl(fbfd, FBIOPUT_VSCREENINFO, tmpfb_var) < 0)
+                    VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to switch framebuffer settings for EPG" + ENO);
+
+                // Restore osd
+                ioctl(fbfd, FBIOBLANK, VESA_NO_BLANKING);
+            }
+            // Reset display pan
+            ivtvfb_var.xoffset = 0;
+            ivtvfb_var.yoffset = 0;
+            ioctl(fbfd, FBIOPAN_DISPLAY, &ivtvfb_var);
+        }
+    }
+
+    alphaState = newAlphaState;
 }
 
 bool VideoOutputIvtv::InputChanged(const QSize &input_size,
@@ -221,40 +389,87 @@
     {
         int fbno = 0;
 
-        if (ioctl(videofd, IVTV_IOC_GET_FB, &fbno) < 0)
+        if (v4l2_api)
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "Framebuffer number query failed." + ENO +
-                    "\n\t\t\tDid you load the ivtv-fb Linux kernel module?");
-            return false;
+            struct v4l2_framebuffer fbuf;
+
+            ioctl(videofd, VIDIOC_G_FBUF, &fbuf);
+            for (fbno = 0; fbno < 10; fbno++)
+            {
+                struct fb_fix_screeninfo si;
+                char buf[10];
+
+                sprintf(buf, "/dev/fb%d", fbno);
+                fbfd = open(buf, O_RDWR);
+                if (fbfd < 0) 
+                    continue;
+                ioctl(fbfd, FBIOGET_FSCREENINFO, &si);
+                if (si.smem_start == (unsigned long)fbuf.base)
+                    break;
+                close(fbfd);
+                fbfd = -1;
+            }
+            if (fbfd < 0)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to locate framebuffer" +
+                        "\n\t\t\tDid you load the ivtv-fb Linux kernel module?");
+                return false;
+            }
         }
-
-        if (fbno < 0)
+        else
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "Failed to determine framebuffer number." +
-                    "\n\t\t\tDid you load the ivtv-fb Linux kernel module?");
-            return false;
-        }
+            if (ioctl(videofd, IVTV_IOC_GET_FB, &fbno) < 0)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR +
+                        "Framebuffer number query failed." + ENO +
+                        "\n\t\t\tDid you load the ivtv-fb Linux kernel module?");
+                return false;
+            }
 
-        QString fbdev = QString("/dev/fb%1").arg(fbno);
-        fbfd = open(fbdev.ascii(), O_RDWR);
-        if (fbfd < 0)
-        {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to open framebuffer " +
+            if (fbno < 0)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR +
+                        "Failed to determine framebuffer number." +
+                        "\n\t\t\tDid you load the ivtv-fb Linux kernel module?");
+                return false;
+            }
+
+            QString fbdev = QString("/dev/fb%1").arg(fbno);
+            fbfd = open(fbdev.ascii(), O_RDWR);
+
+            if (fbfd < 0)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to open framebuffer " +
                     QString("'%1'").arg(fbdev) + ENO +
                     "\n\t\t\tThis is needed for the OSD.");
-            return false;
+                return false;
+            }
         }
 
         struct ivtvfb_ioctl_get_frame_buffer igfb;
         bzero(&igfb, sizeof(igfb));
 
         if (ioctl(fbfd, IVTVFB_IOCTL_GET_FRAME_BUFFER, &igfb) < 0)
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Getting frame buffer" + ENO);
+        {
+            if (errno == EINVAL)
+            {
+                struct fb_fix_screeninfo ivtvfb_fix;
+                if (ioctl(fbfd, FBIOGET_FSCREENINFO, &ivtvfb_fix) < 0)
+                {
+                    VERBOSE(VB_IMPORTANT, LOC_ERR + "Getting frame buffer" + ENO);
+                }
+                else
+                {
+                    old_fb_ioctl = false;
+                    ioctl(fbfd, FBIOGET_VSCREENINFO, &ivtvfb_var_old);
+                }
+            }
+            else
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Getting frame buffer" + ENO);
+            }
+        }
 
-        stride = igfb.sizex * 4;
-
         long pagesize = sysconf(_SC_PAGE_SIZE);
         long pagemask = ~(pagesize-1);
         osdbuffer = new char[osdbufsize + pagesize];
@@ -263,17 +478,55 @@
 
         bzero(osdbuf_aligned, osdbufsize);
 
-        ClearOSD();
+        if (old_fb_ioctl == true)
+        {
+            struct ivtv_osd_coords osdcoords;
+            stride = igfb.sizex * 4;
+            bzero(&osdcoords, sizeof(osdcoords));
+            osdcoords.lines = video_dim.height();
+            osdcoords.offset = 0;
+            osdcoords.pixel_stride = video_dim.width() * 2;
+            if (ioctl(fbfd, IVTVFB_IOCTL_SET_ACTIVE_BUFFER, &osdcoords) < 0)
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting active buffer" + ENO);
+        }
+        else
+        {
+            bzero (&ivtvfb_var, sizeof(ivtvfb_var));
 
-        struct ivtv_osd_coords osdcoords;
-        bzero(&osdcoords, sizeof(osdcoords));
-        osdcoords.lines = video_dim.height();
-        osdcoords.offset = 0;
-        osdcoords.pixel_stride = video_dim.width() * 2;
+            // Switch dimensions to match the framebuffer
+            video_dim = QSize(ivtvfb_var_old.xres, ivtvfb_var_old.yres);
 
-        if (ioctl(fbfd, IVTVFB_IOCTL_SET_ACTIVE_BUFFER, &osdcoords) < 0)
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting active buffer" + ENO);
+            memcpy(&ivtvfb_var,&ivtvfb_var_old,sizeof ivtvfb_var);
 
+            // The OSD only supports 32bpp, so only change mode if needed
+            if (ivtvfb_var_old.bits_per_pixel != 32)
+            {
+                ivtvfb_var.xres_virtual = ivtvfb_var.xres;
+                ivtvfb_var.yres_virtual = ivtvfb_var.yres;
+                ivtvfb_var.xoffset = 0;
+                ivtvfb_var.yoffset = 0;
+                ivtvfb_var.bits_per_pixel = 32;
+                ivtvfb_var.nonstd = 0;
+                ivtvfb_var.activate = FB_ACTIVATE_NOW;
+
+                if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &ivtvfb_var) < 0)
+                    VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting frame buffer" + ENO);
+            }
+            else
+            {
+                ivtvfb_var.xoffset = 0;
+                ivtvfb_var.yoffset = 0;
+                ioctl(fbfd, FBIOPAN_DISPLAY, &ivtvfb_var);
+            }
+
+            stride = ivtvfb_var.xres_virtual * 4;
+        }
+
+        // Setup color-key. This helps when X isn't running on the PVR350
+        SetColorKey (1, 0x00010001);
+
+        ClearOSD();
+
         SetAlpha(kAlpha_Clear);
     }
 
@@ -289,6 +542,25 @@
 void VideoOutputIvtv::Close(void)
 {
     VERBOSE(VB_PLAYBACK, LOC + "Close() -- begin");
+
+    if (fbfd >= 0)
+    {
+        ClearOSD();
+        SetAlpha(kAlpha_Solid);
+        SetColorKey (0,0);
+
+        if (old_fb_ioctl == false)
+        {
+            ivtvfb_var_old.activate = FB_ACTIVATE_NOW;
+
+            if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &ivtvfb_var_old) < 0)
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to restore framebuffer settings" + ENO);
+        }
+
+        close (fbfd);
+        fbfd = -1;
+    }
+
     if (videofd >= 0)
     {
         Stop(true /* hide */);
@@ -323,9 +595,19 @@
     struct v4l2_capability vcap;
     bzero(&vcap, sizeof(vcap));
     if (ioctl(videofd, VIDIOC_QUERYCAP, &vcap) < 0)
+    {
         VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to query decoder" + ENO);
+    }
     else
+    {
         driver_version = vcap.version;
+        if (driver_version >= 0x000306)
+            color_key = true;
+        if (driver_version >= 0x000A00)
+            decoder_flush = false;
+        if (driver_version >= 0x010000)
+            v4l2_api = true;
+    }
     VERBOSE(VB_PLAYBACK, LOC + "Open() -- end");
 }
 
@@ -457,7 +739,7 @@
 
     VideoFrame tmpframe;
     init(&tmpframe, FMT_ARGB32, (unsigned char *)osdbuf_aligned,
-         stride, video_dim.height(), 32, 4 * stride * video_dim.height());
+         stride, video_dim.height(), 32, stride * video_dim.height());
 
     OSDSurface *surface = NULL;
     if (osd)
@@ -498,7 +780,6 @@
     {
         if (!clear || pipon)
         {
-            VERBOSE(VB_PLAYBACK, "clearing buffer");
             bzero(tmpframe.buf, video_dim.height() * stride);
             // redraw PiP...
             if (pipPlayer)
@@ -513,22 +794,28 @@
     pipon = (bool) pipPlayer;
 
     // If there is an OSD, make sure we draw OSD surface
-    lastcleared &= !osd;
+    lastcleared &= !osdon;
 
-#if 0
-// These optimizations have been disabled until someone with a real PVR-350
-// setup can test them Feb 7th, 2006 -- dtk
     // If nothing on OSD surface, just set the alpha to zero
-    if (lastcleared && drawanyway)
+    if (!osdon && !pipon)
     {
+        if (lastcleared == true)
+            return;
+
+        lastcleared = true;
         SetAlpha(kAlpha_Clear);
-        return;
+
+        if (color_key)
+#ifdef WORDS_BIGENDIAN
+            wmemset((wchar_t *)osdbuf_aligned, 0x01000100, osdbufsize/4);
+#else
+            wmemset((wchar_t *)osdbuf_aligned, 0x00010001, osdbufsize/4);
+#endif 
     }
 
     // If there has been no OSD change and no draw has been forced we're done
     if (ret <= 0 && !drawanyway)
         return;
-#endif
 
     // The OSD surface needs to be updated...
     struct ivtvfb_ioctl_dma_host_to_ivtv_args prep;
@@ -536,10 +823,34 @@
     prep.source = osdbuf_aligned;
     prep.count  = video_dim.height() * stride;
 
-    if (ioctl(fbfd, IVTVFB_IOCTL_PREP_FRAME, &prep) < 0)
+     // This shouldn't be here. OSD should be rendered correctly to start with
+#ifdef WORDS_BIGENDIAN
+    int b_index, i_index;
+    unsigned int *osd_int = (unsigned int *)osdbuf_aligned;
+    if (lastcleared != true)
+    {
+        for (b_index = 0, i_index = 0; b_index < prep.count; b_index += 4, i_index ++)
+        {
+            if (osd_int[i_index])
+            {
+                osd_int[i_index] =
+                    ((unsigned char)osdbuf_aligned[b_index+0]) |
+                    ((unsigned char)osdbuf_aligned[b_index+1] << 8) |
+                    ((unsigned char)osdbuf_aligned[b_index+2] << 16) |
+                    ((unsigned char)osdbuf_aligned[b_index+3] << 24);
+            }
+        }
+    }
+#endif
+
+    if (old_fb_ioctl == false)
+        ioctl(fbfd, FBIOPAN_DISPLAY, &ivtvfb_var);
+
+    if (ioctl(fbfd, fb_dma_ioctl, &prep) < 0)
         VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to process frame" + ENO);
 
-    SetAlpha(kAlpha_Local);
+    if (lastcleared != true)
+        SetAlpha(kAlpha_Local);
 }
 
 /** \fn VideoOutputIvtv::Start(int,int)
@@ -556,12 +867,23 @@
     start.gop_offset = skip;
     start.muted_audio_frames = mute;
 
-    while (ioctl(videofd, IVTV_IOC_START_DECODE, &start) < 0)
+    if (v4l2_api)
     {
-        if (errno != EBUSY)
+        struct video_command cmd;
+        memset(&cmd, 0, sizeof(cmd));
+        cmd.cmd = VIDEO_CMD_PLAY;
+        cmd.play.speed = 1000;
+        ioctl(videofd, VIDEO_COMMAND, &cmd);
+    }
+    else
+    {
+        while (ioctl(videofd, IVTV_IOC_START_DECODE, &start) < 0)
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to start decoder" + ENO);
-            break;
+            if (errno != EBUSY)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to start decoder" + ENO);
+                break;
+            }
         }
     }
     VERBOSE(VB_PLAYBACK, LOC + "Start("<<skip<<" skipped, "
@@ -579,12 +901,26 @@
     bzero(&stop, sizeof(stop));
     stop.hide_last = hide;
 
-    while (ioctl(videofd, IVTV_IOC_STOP_DECODE, &stop) < 0)
+    if (v4l2_api)
     {
-        if (errno != EBUSY)
+        struct video_command cmd;
+        memset(&cmd, 0, sizeof(cmd));
+        cmd.cmd = VIDEO_CMD_STOP;
+        cmd.flags = VIDEO_CMD_STOP_IMMEDIATELY;
+        if (hide)
+            cmd.flags |= VIDEO_CMD_STOP_TO_BLACK;
+        if (ioctl(videofd, VIDEO_COMMAND, &cmd) < 0)
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to stop decoder" + ENO);
+    }
+    else
+    {
+        while (ioctl(videofd, IVTV_IOC_STOP_DECODE, &stop) < 0)
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to stop decoder" + ENO);
-            break;
+            if (errno != EBUSY)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to stop decoder" + ENO);
+                break;
+            }
         }
     }
 
@@ -599,12 +935,22 @@
 void VideoOutputIvtv::Pause(void)
 {
     VERBOSE(VB_PLAYBACK, LOC + "Pause() -- begin");
-    while (ioctl(videofd, IVTV_IOC_PAUSE, 0) < 0)
+    if (v4l2_api)
     {
-        if (errno != EBUSY)
+        struct video_command cmd;
+        memset(&cmd, 0, sizeof(cmd));
+        cmd.cmd = VIDEO_CMD_FREEZE;
+        ioctl(videofd, VIDEO_COMMAND, &cmd);
+    }
+    else
+    {
+        while (ioctl(videofd, IVTV_IOC_PAUSE, 0) < 0)
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to pause decoder" + ENO);
-            break;
+            if (errno != EBUSY)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to pause decoder" + ENO);
+                break;
+            }
         }
     }
     VERBOSE(VB_PLAYBACK, LOC + "Pause() -- end");
@@ -660,16 +1006,27 @@
  */
 long long VideoOutputIvtv::GetFirmwareFramesPlayed(void)
 {
-    struct ivtv_ioctl_framesync frameinfo;
-    bzero(&frameinfo, sizeof(frameinfo));
-
-    if (ioctl(videofd, IVTV_IOC_GET_TIMING, &frameinfo) < 0)
+    if (v4l2_api)
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Fetching frames played from decoder" + ENO);
+        long long frame;
+        if (ioctl(videofd, VIDEO_GET_FRAME_COUNT, &frame) < 0)
+            VERBOSE(VB_IMPORTANT, LOC_ERR +
+                    "Fetching frames played from decoder" + ENO);
+        return frame;
     }
-    //cerr<<"<"<<frameinfo.frame<<">";
-    return frameinfo.frame;
+    else
+    {
+        struct ivtv_ioctl_framesync frameinfo;
+        bzero(&frameinfo, sizeof(frameinfo));
+
+        if (ioctl(videofd, IVTV_IOC_GET_TIMING, &frameinfo) < 0)
+        {
+            VERBOSE(VB_IMPORTANT, LOC_ERR +
+                    "Fetching frames played from decoder" + ENO);
+        }
+        //cerr<<"<"<<frameinfo.frame<<">";
+        return frameinfo.frame;
+    }
 }
 
 /** \fn VideoOutputIvtv::GetFramesPlayed(void)
@@ -692,29 +1049,43 @@
 bool VideoOutputIvtv::Play(float speed, bool normal, int mask)
 {
     VERBOSE(VB_PLAYBACK, LOC + "Play("<<speed<<", "<<normal<<", "<<mask<<")");
-    struct ivtv_speed play;
-    bzero(&play, sizeof(play));
-    play.scale = (speed >= 2.0f) ? (int)roundf(speed) : 1;
-    play.scale = (speed <= 0.5f) ? (int)roundf(1.0f / speed) : play.scale;
-    play.speed = (speed > 1.0f);
-    play.smooth = 0;
-    play.direction = 0;
-    play.fr_mask = mask;
-    play.b_per_gop = 0;
-    play.aud_mute = !normal;
-    play.fr_field = 0;
-    play.mute = 0;
-
     internal_offset = GetFramesPlayed();
     frame_at_speed_change = GetFirmwareFramesPlayed();
 
-    while (ioctl(videofd, IVTV_IOC_S_SPEED, &play) < 0)
+    if (speed >= 2.0f)
+        speed = 2.0f;
+
+    if (v4l2_api)
     {
-        if (errno != EBUSY)
+        struct video_command cmd;
+        memset(&cmd, 0, sizeof(cmd));
+        cmd.cmd = VIDEO_CMD_PLAY;
+        cmd.play.speed = (__u32)(1000.0f * speed);
+        ioctl(videofd, VIDEO_COMMAND, &cmd);
+    }
+    else
+    {
+        struct ivtv_speed play;
+        bzero(&play, sizeof(play));
+        play.scale = (speed >= 2.0f) ? (int)roundf(speed) : 1;
+        play.scale = (speed <= 0.5f) ? (int)roundf(1.0f / speed) : play.scale;
+        play.speed = (speed > 1.0f);
+        play.smooth = 0;
+        play.direction = 0;
+        play.fr_mask = mask;
+        play.b_per_gop = 0;
+        play.aud_mute = !normal;
+        play.fr_field = 0;
+        play.mute = 0;
+
+        while (ioctl(videofd, IVTV_IOC_S_SPEED, &play) < 0)
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "Setting decoder's playback speed" + ENO);
-            break;
+            if (errno != EBUSY)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR +
+                        "Setting decoder's playback speed" + ENO);
+                break;
+            }
         }
     }
 
@@ -731,10 +1102,12 @@
 void VideoOutputIvtv::Flush(void)
 {
     VERBOSE(VB_PLAYBACK, LOC + "Flush()");
-    int arg = 0;
-
-    if (ioctl(videofd, IVTV_IOC_DEC_FLUSH, &arg) < 0)
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Flushing decoder" + ENO);
+    if (decoder_flush)
+    {
+        int arg = 0;
+        if (ioctl(videofd, IVTV_IOC_DEC_FLUSH, &arg) < 0)
+            VERBOSE(VB_IMPORTANT, LOC_ERR + "Flushing decoder" + ENO);
+    }
 }
 
 /** \fn VideoOutputIvtv::Step(void)
@@ -743,20 +1116,26 @@
 void VideoOutputIvtv::Step(void)
 {
     VERBOSE(VB_PLAYBACK, LOC + "Step()");
-    enum {
-        STEP_FRAME     = 0,
-        STEP_TOP_FIELD = 1,
-        STEP_BOT_FIELD = 2,
-    };
 
-    int arg = STEP_FRAME;
+    if (v4l2_api)
+    {
+        struct video_command cmd;
+        memset(&cmd, 0, sizeof(cmd));
+        cmd.cmd = VIDEO_CMD_PLAY;
+        cmd.play.speed = 1;
+        ioctl(videofd, VIDEO_COMMAND, &cmd);
+    }
+    else
+    {
+        int arg = 0; // STEP_FRAME;
 
-    while (ioctl(videofd, IVTV_IOC_DEC_STEP, &arg) < 0)
-    {
-        if (errno != EBUSY)
+        while (ioctl(videofd, IVTV_IOC_DEC_STEP, &arg) < 0)
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting Step" + ENO);
-            break;
+            if (errno != EBUSY)
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting Step" + ENO);
+                break;
+            }
         }
     }
 }
@@ -768,7 +1147,7 @@
 
     if (((kCodec_MPEG1 == myth_codec_id) ||
          (kCodec_MPEG2 == myth_codec_id)) &&
-        (video_dim.width() <= 768) &&
+        (video_dim.width() <= 720) &&
         (video_dim.height() <= 576))
     {
         list += "ivtv";
