diff -Naur vdr-1.7.4/channels.c vdr-1.7.4-s2apiwrapper/channels.c
--- vdr-1.7.4/channels.c	2008-12-13 12:42:15.000000000 +0100
+++ vdr-1.7.4-s2apiwrapper/channels.c	2008-12-22 02:19:59.000000000 +0100
@@ -11,6 +11,7 @@
 #include <linux/dvb/frontend.h>
 #include <ctype.h>
 #include "device.h"
+#include "s2apiwrapper.h"
 #include "epg.h"
 #include "timers.h"
 
diff -Naur vdr-1.7.4/dvbdevice.c vdr-1.7.4-s2apiwrapper/dvbdevice.c
--- vdr-1.7.4/dvbdevice.c	2008-12-13 15:38:07.000000000 +0100
+++ vdr-1.7.4-s2apiwrapper/dvbdevice.c	2008-12-22 02:19:59.000000000 +0100
@@ -205,7 +205,7 @@
   memset(&CmdSeq, 0, sizeof(CmdSeq));
   CmdSeq.props = Frontend;
   SETCMD(DTV_CLEAR, 0);
-  if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
+  if (S2API_ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
      esyslog("ERROR: frontend %d: %m", cardIndex);
      return false;
      }
@@ -324,7 +324,7 @@
      return false;
      }
   SETCMD(DTV_TUNE, 0);
-  if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
+  if (S2API_ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
      esyslog("ERROR: frontend %d: %m", cardIndex);
      return false;
      }
@@ -1307,12 +1307,14 @@

 int cDvbDevice::PlayTsVideo(const uchar *Data, int Length)
 {
-  return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
+  //return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
+  return cDevice::PlayTsVideo(Data, Length);
 }

 int cDvbDevice::PlayTsAudio(const uchar *Data, int Length)
 {
-  return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10);
+  //return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10);
+  return cDevice::PlayTsAudio(Data, Length);
 }

 bool cDvbDevice::OpenDvr(void)
diff -Naur vdr-1.7.4/dvbdevice.h vdr-1.7.4-s2apiwrapper/dvbdevice.h
--- vdr-1.7.4/dvbdevice.h	2008-12-06 14:31:12.000000000 +0100
+++ vdr-1.7.4-s2apiwrapper/dvbdevice.h	2008-12-22 02:19:59.000000000 +0100
@@ -14,9 +14,10 @@
 #include <linux/dvb/version.h>
 #include "device.h"
 #include "dvbspu.h"
-
-#if DVB_API_VERSION != 5 || DVB_API_VERSION_MINOR != 0
-#error VDR requires Linux DVB driver API version 5.0!
+#include "s2apiwrapper.h"
+ 
+#if DVB_API_VERSION != 3
+#error VDR requires Linux DVB driver API version 3!
 #endif
 
 #define MAXDVBDEVICES  8
diff -Naur vdr-1.7.4/Makefile vdr-1.7.4-s2apiwrapper/Makefile
--- vdr-1.7.4/Makefile	2008-05-03 12:13:43.000000000 +0200
+++ vdr-1.7.4-s2apiwrapper/Makefile	2008-12-22 02:19:59.000000000 +0100
@@ -36,7 +36,7 @@
 
 SILIB    = $(LSIDIR)/libsi.a
 
-OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o dvbosd.o\
+OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o s2apiwrapper.o dvbdevice.o dvbci.o dvbosd.o\
        dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\
        lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\
        receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\
diff -Naur vdr-1.7.4/nit.c vdr-1.7.4-s2apiwrapper/nit.c
--- vdr-1.7.4/nit.c	2008-12-06 16:46:50.000000000 +0100
+++ vdr-1.7.4-s2apiwrapper/nit.c	2008-12-22 02:19:59.000000000 +0100
@@ -10,6 +10,7 @@
 #include "nit.h"
 #include <linux/dvb/frontend.h>
 #include "channels.h"
+#include "s2apiwrapper.h"
 #include "eitscan.h"
 #include "libsi/section.h"
 #include "libsi/descriptor.h"
diff -Naur vdr-1.7.4/s2apiwrapper.c vdr-1.7.4-s2apiwrapper/s2apiwrapper.c
--- vdr-1.7.4/s2apiwrapper.c	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.7.4-s2apiwrapper/s2apiwrapper.c	2008-12-22 02:20:31.000000000 +0100
@@ -0,0 +1,165 @@
+/*
+ * s2apiwrapper.c:
+ * Wrapper to translate DVB S2API to DVB 3.0 API calls
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: $
+ */
+
+#include "s2apiwrapper.h"
+#include <string.h>
+#include <errno.h>
+
+#ifdef DVB_S2API_WRAPPER
+
+static int ioctl_FE_SET_PROPERTY(int d, dtv_properties *properties) {
+  int result = 0;
+  fe_delivery_system Delivery = SYS_UNDEFINED;
+  dvb_frontend_parameters Frontend;
+  memset(&Frontend, 0, sizeof(Frontend));
+  
+  for (__u32 i=0; i<properties->num; i++) {
+      __u32 cmd = properties->props[i].cmd;
+      __u32 data = properties->props[i].u.data;
+      
+      switch (cmd) {
+        case DTV_CLEAR: 
+             memset(&Frontend, 0, sizeof(Frontend));
+             continue;
+                     
+        case DTV_DELIVERY_SYSTEM:
+             Delivery = fe_delivery_system(data);
+             continue;
+             
+        case DTV_FREQUENCY:
+             Frontend.frequency = data;
+             continue;
+             
+        case DTV_INVERSION:
+             Frontend.inversion = fe_spectral_inversion(data);
+             continue;
+
+        case DTV_TUNE:
+             result = ioctl(d, FE_SET_FRONTEND, &Frontend);
+             if (result < 0)
+             	return result;
+             continue;
+        }
+
+      if (Delivery == SYS_DVBS) {
+         switch (cmd) {
+           case DTV_MODULATION:
+           	    if (data != FE_QPSK) {
+                	errno = EINVAL;
+                	return -1; 
+                	}
+                break;
+                
+           case DTV_SYMBOL_RATE:
+                Frontend.u.qpsk.symbol_rate = data;
+                break;
+                
+           case DTV_INNER_FEC:
+                Frontend.u.qpsk.fec_inner = fe_code_rate(data);
+                break;
+                
+           case DTV_ROLLOFF:
+                if (data != ROLLOFF_35) { 
+                	errno = EINVAL;
+                	return -1; 
+                	}
+                break;
+	       default:
+	         	errno = EINVAL;
+	            return -1; 
+           }
+         }
+      else if (Delivery == SYS_DVBC_ANNEX_AC && result >= 0) {
+         switch (cmd) {
+           case DTV_MODULATION:
+                Frontend.u.qam.modulation = fe_modulation(data);
+                break;
+                
+           case DTV_SYMBOL_RATE:
+                Frontend.u.qam.symbol_rate = data;
+                break;
+                
+           case DTV_INNER_FEC:
+                Frontend.u.qam.fec_inner = fe_code_rate(data);
+                break;
+	       default:
+	         	errno = EINVAL;
+	            return -1; 
+           }
+         }
+      else if (Delivery == SYS_DVBT && result >= 0) {
+         switch (cmd) {
+           case DTV_MODULATION:
+                Frontend.u.ofdm.constellation = fe_modulation(data);
+                break;
+                
+           case DTV_BANDWIDTH_HZ:
+                Frontend.u.ofdm.bandwidth = fe_bandwidth(data);
+                break;
+               
+           case DTV_CODE_RATE_HP:
+                Frontend.u.ofdm.code_rate_HP = fe_code_rate(data);
+                break;
+               
+           case DTV_CODE_RATE_LP:
+                Frontend.u.ofdm.code_rate_LP = fe_code_rate(data);
+                break;
+               
+           case DTV_TRANSMISSION_MODE:
+                Frontend.u.ofdm.transmission_mode = fe_transmit_mode(data);
+                break;
+               
+           case DTV_GUARD_INTERVAL:
+                Frontend.u.ofdm.guard_interval = fe_guard_interval(data);
+                break;
+                
+           case DTV_HIERARCHY:
+                Frontend.u.ofdm.hierarchy_information = fe_hierarchy(data);
+                break;
+
+	       default:
+	         	errno = EINVAL;
+	            return -1; 
+           }
+         }
+      } // for
+  return result;
+}
+
+static int ioctl_FE_GET_PROPERTY(int d, dtv_properties *properties) {
+  errno = EINVAL;
+  return -1;
+}
+
+#ifdef DVB_S2API_RUNTIME
+static bool S2APITested = false;
+static bool HasS2APIResult;
+
+static bool HasS2API(int d) {
+  if (!S2APITested) {
+     // TODO: Test for S2API availability
+     HasS2APIResult = false;
+     S2APITested = true;
+     }
+  return HasS2APIResult;
+}
+#else
+static bool HasS2API(int d) { return false; }
+#endif // ifdef DVB_S2API_RUNTIME
+
+int S2API_ioctl(int d, int request, void *data) {
+  if (request == (int)FE_SET_PROPERTY && !HasS2API(d))
+     return ioctl_FE_SET_PROPERTY(d, (dtv_properties*)data);
+  if (request == (int)FE_GET_PROPERTY && !HasS2API(d))
+     return ioctl_FE_GET_PROPERTY(d, (dtv_properties*)data);
+  return ioctl(d, request, data);
+}
+
+#endif // ifdef DVB_S2API_WRAPPER
diff -Naur vdr-1.7.4/s2apiwrapper.h vdr-1.7.4-s2apiwrapper/s2apiwrapper.h
--- vdr-1.7.4/s2apiwrapper.h	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.7.4-s2apiwrapper/s2apiwrapper.h	2008-12-22 02:20:32.000000000 +0100
@@ -0,0 +1,213 @@
+/*
+ * s2apiwrapper.h:
+ * Wrapper to translate DVB S2API to DVB 3.0 API calls
+ *
+ * See the main source file 'vdr.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: $
+ */
+
+#ifndef __S2API_WRAPPER_H
+#define __S2API_WRAPPER_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/dvb/version.h>
+#include <sys/ioctl.h>
+
+#if DVB_API_VERSION != 3
+#error VDR requires Linux DVB driver API version 3!
+#endif
+
+#if !defined(DVB_S2API_RUNTIME) 
+#define DVB_S2API_RUNTIME 1
+#endif
+
+#if DVB_S2API_RUNTIME == 0
+#undef DVB_S2API_RUNTIME
+#endif
+
+#if !defined(DVB_S2API_WRAPPER) \
+    && (DVB_API_VERSION_MINOR < 3 || defined(DVB_S2API_RUNTIME))
+#define DVB_S2API_WRAPPER 1
+#endif
+
+#if defined(DVB_S2API_WRAPPER) && DVB_S2API_WRAPPER == 0
+#undef DVB_S2API_WRAPPER
+#endif
+
+#if DVB_API_VERSION_MINOR < 3
+
+// DVB API is missing S2API structs, so we declare them.
+// The following is based on frontend.h from s2api DVB driver
+
+
+enum fe_s2caps {
+	FE_HAS_EXTENDED_CAPS		= 0x800000,   // We need more bitspace for newer APIs, indicate this.
+   FE_CAN_2G_MODULATION        = 0x10000000, // frontend supports "2nd generation modulation" (DVB-S2)
+};
+
+enum fe_s2code_rate {
+	FEC_3_5 = FEC_AUTO + 1,
+	FEC_9_10,
+};
+
+enum fe_s2modulation {
+	PSK_8 = VSB_16 + 1,
+	APSK_16,
+	APSK_32,
+	DQPSK,
+};
+
+
+/* S2API Commands */
+#define DTV_UNDEFINED		0
+#define DTV_TUNE		1
+#define DTV_CLEAR		2
+#define DTV_FREQUENCY		3
+#define DTV_MODULATION		4
+#define DTV_BANDWIDTH_HZ	5
+#define DTV_INVERSION		6
+#define DTV_DISEQC_MASTER	7
+#define DTV_SYMBOL_RATE		8
+#define DTV_INNER_FEC		9
+#define DTV_VOLTAGE		10
+#define DTV_TONE		11
+#define DTV_PILOT		12
+#define DTV_ROLLOFF		13
+#define DTV_DISEQC_SLAVE_REPLY	14
+
+/* Basic enumeration set for querying unlimited capabilities */
+#define DTV_FE_CAPABILITY_COUNT	15
+#define DTV_FE_CAPABILITY	16
+#define DTV_DELIVERY_SYSTEM	17
+
+#if 0
+/* ISDB */
+/* maybe a dup of DTV_ISDB_SOUND_BROADCASTING_SUBCHANNEL_ID ??? */
+#define DTV_ISDB_SEGMENT_IDX	18
+/* 1, 3 or 13 ??? */
+#define DTV_ISDB_SEGMENT_WIDTH	19
+
+/* the central segment can be received independently or 1/3 seg in SB-mode */
+#define DTV_ISDB_PARTIAL_RECEPTION	20
+/* sound broadcasting is used 0 = 13segment, 1 = 1 or 3 see DTV_ISDB_PARTIAL_RECEPTION */
+#define DTV_ISDB_SOUND_BROADCASTING	21
+
+/* only used in SB */
+/* determines the initial PRBS of the segment (to match with 13seg channel) */
+#define DTV_ISDB_SOUND_BROADCASTING_SUBCHANNEL_ID	22
+
+#define DTV_ISDB_LAYERA_FEC			23
+#define DTV_ISDB_LAYERA_MODULATION		24
+#define DTV_ISDB_LAYERA_SEGMENT_WIDTH		25
+#define DTV_ISDB_LAYERA_TIME_INTERLEAVER	26
+
+#define DTV_ISDB_LAYERB_FEC			27
+#define DTV_ISDB_LAYERB_MODULATION		28
+#define DTV_ISDB_LAYERB_SEGMENT_WIDTH		29
+#define DTV_ISDB_LAYERB_TIME_INTERLEAVING	30
+
+#define DTV_ISDB_LAYERC_FEC			31
+#define DTV_ISDB_LAYERC_MODULATION		32
+#define DTV_ISDB_LAYERC_SEGMENT_WIDTH		33
+#define DTV_ISDB_LAYERC_TIME_INTERLEAVING	34
+#endif
+#define DTV_API_VERSION				35
+#define DTV_API_VERSION				35
+#define DTV_CODE_RATE_HP			36
+#define DTV_CODE_RATE_LP			37
+#define DTV_GUARD_INTERVAL			38
+#define DTV_TRANSMISSION_MODE			39
+#define DTV_HIERARCHY				40
+
+#define DTV_MAX_COMMAND				DTV_HIERARCHY
+
+typedef enum fe_pilot {
+	PILOT_ON,
+	PILOT_OFF,
+	PILOT_AUTO,
+} fe_pilot_t;
+
+typedef enum fe_rolloff {
+	ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */
+	ROLLOFF_20,
+	ROLLOFF_25,
+	ROLLOFF_AUTO,
+} fe_rolloff_t;
+
+typedef enum fe_delivery_system {
+	SYS_UNDEFINED,
+	SYS_DVBC_ANNEX_AC,
+	SYS_DVBC_ANNEX_B,
+	SYS_DVBT,
+	SYS_DSS,
+	SYS_DVBS,
+	SYS_DVBS2,
+	SYS_DVBH,
+	SYS_ISDBT,
+	SYS_ISDBS,
+	SYS_ISDBC,
+	SYS_ATSC,
+	SYS_ATSCMH,
+	SYS_DMBTH,
+	SYS_CMMB,
+	SYS_DAB,
+} fe_delivery_system_t;
+
+struct dtv_cmds_h {
+	char	*name;		/* A display name for debugging purposes */
+
+	__u32	cmd;		/* A unique ID */
+
+	/* Flags */
+	__u32	set:1;		/* Either a set or get property */
+	__u32	buffer:1;	/* Does this property use the buffer? */
+	__u32	reserved:30;	/* Align */
+};
+
+struct dtv_property {
+	__u32 cmd;
+	__u32 reserved[3];
+	union {
+		__u32 data;
+		struct {
+			__u8 data[32];
+			__u32 len;
+			__u32 reserved1[3];
+			void *reserved2;
+		} buffer;
+	} u;
+	int result;
+} __attribute__ ((packed));
+
+/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */
+#define DTV_IOCTL_MAX_MSGS 64
+
+struct dtv_properties {
+	__u32 num;
+	struct dtv_property *props;
+};
+
+#define FE_SET_PROPERTY		   _IOW('o', 82, struct dtv_properties)
+#define FE_GET_PROPERTY		   _IOR('o', 83, struct dtv_properties)
+
+// End of copied section of frontend.h
+
+#endif // DVB_API_VERSION_MINOR < 3
+
+
+
+#ifdef DVB_S2API_WRAPPER
+
+// Wrapper for S2API ioctl calls:
+int S2API_ioctl(int d, int request, void *data);
+
+#else // ifdef DVB_S2API_WRAPPER
+
+// Null wrapper for s2api ioctl calls:
+inline int S2API_ioctl(int d, int request, void *data) { return ioctl(d, request, data); }
+
+#endif // ifdef DVB_S2API_WRAPPER
+
+#endif // ifndef __S2API_WRAPPER_H
