diff -Naur vdr-1.7.23/channels.c vdr-1.7.23-s2apiwrapper/channels.c
--- vdr-1.7.23/channels.c	2011-08-26 14:44:21.000000000 +0200
+++ vdr-1.7.23-s2apiwrapper/channels.c	2012-01-15 20:09:12.000000000 +0100
@@ -10,6 +10,7 @@
 #include "channels.h"
 #include <ctype.h>
 #include "device.h"
+#include "s2apiwrapper.h"
 #include "epg.h"
 #include "libsi/si.h"
 #include "timers.h"
diff -Naur vdr-1.7.23/dvbdevice.c vdr-1.7.23-s2apiwrapper/dvbdevice.c
--- vdr-1.7.23/dvbdevice.c	2012-01-15 15:31:47.000000000 +0100
+++ vdr-1.7.23-s2apiwrapper/dvbdevice.c	2012-01-15 20:09:12.000000000 +0100
@@ -722,7 +722,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/%d: %m", adapter, frontend);
      return false;
      }
@@ -840,7 +840,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/%d: %m", adapter, frontend);
      return false;
      }
diff -Naur vdr-1.7.23/dvbdevice.h vdr-1.7.23-s2apiwrapper/dvbdevice.h
--- vdr-1.7.23/dvbdevice.h	2012-01-13 12:32:45.000000000 +0100
+++ vdr-1.7.23-s2apiwrapper/dvbdevice.h	2012-01-15 20:09:12.000000000 +0100
@@ -13,9 +13,10 @@
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/version.h>
 #include "device.h"
-
-#if DVB_API_VERSION < 5 || (DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR < 3)
-#error VDR requires Linux DVB driver API version 5.3 or higher!
+#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.23/Makefile vdr-1.7.23-s2apiwrapper/Makefile
--- vdr-1.7.23/Makefile	2012-01-14 14:09:10.000000000 +0100
+++ vdr-1.7.23-s2apiwrapper/Makefile	2012-01-15 20:09:12.000000000 +0100
@@ -40,7 +40,7 @@
 
 SILIB    = $(LSIDIR)/libsi.a
 
-OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o\
+OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o s2apiwrapper.o dvbdevice.o dvbci.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.23/nit.c vdr-1.7.23-s2apiwrapper/nit.c
--- vdr-1.7.23/nit.c	2012-01-12 09:43:52.000000000 +0100
+++ vdr-1.7.23-s2apiwrapper/nit.c	2012-01-15 20:09:12.000000000 +0100
@@ -11,6 +11,7 @@
 #include <linux/dvb/frontend.h>
 #include "channels.h"
 #include "dvbdevice.h"
+#include "s2apiwrapper.h"
 #include "eitscan.h"
 #include "libsi/section.h"
 #include "libsi/descriptor.h"
diff -Naur vdr-1.7.23/PLUGINS/src/dvbsddevice/dvbsddevice.c vdr-1.7.23-s2apiwrapper/PLUGINS/src/dvbsddevice/dvbsddevice.c
--- vdr-1.7.23/PLUGINS/src/dvbsddevice/dvbsddevice.c	2011-08-27 13:34:58.000000000 +0200
+++ vdr-1.7.23-s2apiwrapper/PLUGINS/src/dvbsddevice/dvbsddevice.c	2012-01-15 20:09:12.000000000 +0100
@@ -23,6 +23,8 @@
   virtual const char *Description(void) { return DESCRIPTION; }
   virtual const char *CommandLineHelp(void);
   virtual bool ProcessArgs(int argc, char *argv[]);
+  virtual cMenuSetupPage *SetupMenu(void);
+  virtual bool SetupParse(const char *Name, const char *Value);
   };
 
 cPluginDvbsddevice::cPluginDvbsddevice(void)
@@ -58,4 +60,39 @@
   return true;
 }
 
+class cMenuSetupDvbsddevice : public cMenuSetupPage {
+private:
+  int TSOutput;
+protected:
+  virtual void Store(void);
+public:
+  cMenuSetupDvbsddevice(void);
+  };
+
+cMenuSetupDvbsddevice::cMenuSetupDvbsddevice(void)
+{
+  TSOutput = cDvbSdFfDevice::TSOutput ? 1 : 0;
+  Add(new cMenuEditBoolItem( "Video stream output type:", &TSOutput, "PES", "TS"));
+}
+
+void cMenuSetupDvbsddevice::Store(void)
+{
+  SetupStore("SDFF_TSOutput", cDvbSdFfDevice::TSOutput = (TSOutput != 0));
+}
+
+cMenuSetupPage *cPluginDvbsddevice::SetupMenu()
+{
+  // Return a setup menu in case the plugin supports one.
+  return new cMenuSetupDvbsddevice();
+}
+
+bool cPluginDvbsddevice::SetupParse(const char *Name, const char *Value)
+{
+  // Parse your own setup parameters and store their values.
+  if      (!strcasecmp(Name, "SDFF_TSOutput"))         cDvbSdFfDevice::TSOutput = (atoi(Value) != 0);
+  else
+     return false;
+  return true;
+}
+
 VDRPLUGINCREATOR(cPluginDvbsddevice); // Don't touch this!
diff -Naur vdr-1.7.23/PLUGINS/src/dvbsddevice/dvbsdffdevice.c vdr-1.7.23-s2apiwrapper/PLUGINS/src/dvbsddevice/dvbsdffdevice.c
--- vdr-1.7.23/PLUGINS/src/dvbsddevice/dvbsdffdevice.c	2011-08-27 13:33:57.000000000 +0200
+++ vdr-1.7.23-s2apiwrapper/PLUGINS/src/dvbsddevice/dvbsdffdevice.c	2012-01-15 20:09:12.000000000 +0100
@@ -22,6 +22,7 @@
 // --- cDvbSdFfDevice --------------------------------------------------------
 
 int cDvbSdFfDevice::devVideoOffset = -1;
+bool cDvbSdFfDevice::TSOutput = true;
 
 cDvbSdFfDevice::cDvbSdFfDevice(int Adapter, int Frontend, bool OutputOnly)
 :cDvbDevice(Adapter, Frontend)
@@ -760,12 +761,18 @@
 
 int cDvbSdFfDevice::PlayTsVideo(const uchar *Data, int Length)
 {
-  return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
+  if (TSOutput)
+     return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
+  else
+     return cDevice::PlayTsVideo(Data, Length);
 }
 
 int cDvbSdFfDevice::PlayTsAudio(const uchar *Data, int Length)
 {
-  return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10);
+  if (TSOutput)
+     return WriteAllOrNothing(fd_audio, Data, Length, 1000, 10);
+  else
+     return cDevice::PlayTsAudio(Data, Length);
 }
 
 // --- cDvbSdFfDeviceProbe ---------------------------------------------------
diff -Naur vdr-1.7.23/PLUGINS/src/dvbsddevice/dvbsdffdevice.h vdr-1.7.23-s2apiwrapper/PLUGINS/src/dvbsddevice/dvbsdffdevice.h
--- vdr-1.7.23/PLUGINS/src/dvbsddevice/dvbsdffdevice.h	2011-08-27 13:32:42.000000000 +0200
+++ vdr-1.7.23-s2apiwrapper/PLUGINS/src/dvbsddevice/dvbsdffdevice.h	2012-01-15 20:09:12.000000000 +0100
@@ -26,6 +26,8 @@
   virtual bool HasDecoder(void) const;
   virtual bool AvoidRecording(void) const;
 
+  static bool TSOutput;
+
 // SPU facilities
 
 private:
diff -Naur vdr-1.7.23/s2apiwrapper.c vdr-1.7.23-s2apiwrapper/s2apiwrapper.c
--- vdr-1.7.23/s2apiwrapper.c	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.7.23-s2apiwrapper/s2apiwrapper.c	2012-01-15 20:09:12.000000000 +0100
@@ -0,0 +1,185 @@
+/*
+ * 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 "tools.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 int DvbApiVersion = 0;
+
+void S2API_SetDvbApiVersion(int ApiVersion) {
+   isyslog("Using DVB API v%d", ApiVersion);
+   DvbApiVersion = ApiVersion;
+   }
+#endif
+
+int S2API_ioctl(int d, int request, void *data) {
+  // Fast bypass for non-S2API call:
+  if (request != (int)FE_SET_PROPERTY && request != (int)FE_GET_PROPERTY)
+     return ioctl(d, request, data);
+
+#ifdef DVB_S2API_RUNTIME
+  // Fast bypass if we have S2API:
+  if (DvbApiVersion >= 5) // Do we have native S2API?
+     return ioctl(d, request, data);
+
+  if (!DvbApiVersion) {
+     // Try S2API native
+     int err = ioctl(d, request, data);
+     if (err != -1 || errno != EOPNOTSUPP) {
+        // ok or other error: we have S2API
+        isyslog("S2API support detected");
+        S2API_SetDvbApiVersion(5);
+        return err;
+        }
+     // error OPNOTSUPP: No S2API support.
+     isyslog("No S2API support detected");
+     S2API_SetDvbApiVersion(3);
+  }
+#endif // ifdef DVB_S2API_RUNTIME
+
+  if (request == (int)FE_SET_PROPERTY)
+     return ioctl_FE_SET_PROPERTY(d, (dtv_properties*)data);
+  if (request == (int)FE_GET_PROPERTY)
+     return ioctl_FE_GET_PROPERTY(d, (dtv_properties*)data);
+
+  // never get here
+  return ioctl(d, request, data);
+}
+
+#endif // ifdef DVB_S2API_WRAPPER
diff -Naur vdr-1.7.23/s2apiwrapper.h vdr-1.7.23-s2apiwrapper/s2apiwrapper.h
--- vdr-1.7.23/s2apiwrapper.h	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.7.23-s2apiwrapper/s2apiwrapper.h	2012-01-15 21:11:14.000000000 +0100
@@ -0,0 +1,268 @@
+/*
+ * 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 < 5 || 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 < 5
+
+// 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,
+};
+
+enum fe_s2transmit_mode {
+	TRANSMISSION_MODE_1K = TRANSMISSION_MODE_4K + 1,
+	TRANSMISSION_MODE_16K,
+	TRANSMISSION_MODE_32K,
+};
+
+enum fe_s2bandwidth {
+	BANDWIDTH_5_MHZ = BANDWIDTH_AUTO + 1,
+	BANDWIDTH_10_MHZ,
+	BANDWIDTH_1_712_MHZ,
+};
+
+
+enum fe_s2guard_interval {
+	GUARD_INTERVAL_1_128 = GUARD_INTERVAL_AUTO + 1,
+	GUARD_INTERVAL_19_128,
+	GUARD_INTERVAL_19_256,
+};
+
+
+/* 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
+
+/* ISDB-T and ISDB-Tsb */
+#define DTV_ISDBT_PARTIAL_RECEPTION	18
+#define DTV_ISDBT_SOUND_BROADCASTING	19
+
+#define DTV_ISDBT_SB_SUBCHANNEL_ID	20
+#define DTV_ISDBT_SB_SEGMENT_IDX	21
+#define DTV_ISDBT_SB_SEGMENT_COUNT	22
+
+#define DTV_ISDBT_LAYERA_FEC			23
+#define DTV_ISDBT_LAYERA_MODULATION		24
+#define DTV_ISDBT_LAYERA_SEGMENT_COUNT		25
+#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING	26
+
+#define DTV_ISDBT_LAYERB_FEC			27
+#define DTV_ISDBT_LAYERB_MODULATION		28
+#define DTV_ISDBT_LAYERB_SEGMENT_COUNT		29
+#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING	30
+
+#define DTV_ISDBT_LAYERC_FEC			31
+#define DTV_ISDBT_LAYERC_MODULATION		32
+#define DTV_ISDBT_LAYERC_SEGMENT_COUNT		33
+#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING	34
+
+#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_ISDBT_LAYER_ENABLED	41
+
+#define DTV_ISDBS_TS_ID		42
+
+#define DTV_DVBT2_PLP_ID	43
+
+#define DTV_MAX_COMMAND				DTV_DVBT2_PLP_ID
+
+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,
+	SYS_DVBT2,
+	SYS_TURBO,
+} 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
+
+#elif DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR < 3
+
+// Cherry-picking for 5.0 and 5.1
+
+enum fe_s2transmit_mode {
+	TRANSMISSION_MODE_1K = TRANSMISSION_MODE_4K + 1,
+	TRANSMISSION_MODE_16K,
+	TRANSMISSION_MODE_32K,
+};
+
+enum fe_s2bandwidth {
+	BANDWIDTH_5_MHZ = BANDWIDTH_AUTO + 1,
+	BANDWIDTH_10_MHZ,
+	BANDWIDTH_1_712_MHZ,
+};
+
+enum fe_s2guard_interval {
+	GUARD_INTERVAL_1_128 = GUARD_INTERVAL_AUTO + 1,
+	GUARD_INTERVAL_19_128,
+	GUARD_INTERVAL_19_256,
+};
+
+#define DTV_DVBT2_PLP_ID	43
+#undef DTV_MAX_COMMAND
+#define DTV_MAX_COMMAND				DTV_DVBT2_PLP_ID
+
+enum fe_delivery_system_5_3 {
+	SYS_DVBT2 = SYS_DAB,
+	SYS_TURBO,
+};
+
+#endif // DVB_API_VERSION < 5
+
+
+
+#ifdef DVB_S2API_WRAPPER
+
+// Wrapper for S2API ioctl calls:
+int S2API_ioctl(int d, int request, void *data);
+
+#ifdef DVB_S2API_RUNTIME
+void S2API_SetDvbApiVersion(int ApiVersion);
+#endif
+
+
+#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
diff -Naur vdr-1.7.23/vdr.c vdr-1.7.23-s2apiwrapper/vdr.c
--- vdr-1.7.23/vdr.c	2011-12-03 16:35:09.000000000 +0100
+++ vdr-1.7.23-s2apiwrapper/vdr.c	2012-01-15 20:09:12.000000000 +0100
@@ -55,6 +55,7 @@
 #include "plugin.h"
 #include "rcu.h"
 #include "recording.h"
+#include "s2apiwrapper.h"
 #include "shutdown.h"
 #include "skinclassic.h"
 #include "skinsttng.h"
@@ -221,6 +222,7 @@
       { "config",   required_argument, NULL, 'c' },
       { "daemon",   no_argument,       NULL, 'd' },
       { "device",   required_argument, NULL, 'D' },
+      { "dvbapi",   required_argument, NULL, 'd' | 0x100 },
       { "edit",     required_argument, NULL, 'e' | 0x100 },
       { "epgfile",  required_argument, NULL, 'E' },
       { "filesize", required_argument, NULL, 'f' | 0x100 },
@@ -268,6 +270,19 @@
                     fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg);
                     return 2;
                     break;
+          case 'd' | 0x100:
+                    if (isnumber(optarg)) {
+                       int n = atoi(optarg);
+                       if (n == 0 || n == 3 || n == 5) {
+#if defined(DVB_S2API_WRAPPER) && defined(DVB_S2API_RUNTIME)
+                          S2API_SetDvbApiVersion(n);
+#endif
+                          break;
+                          }
+                       }
+                    fprintf(stderr, "vdr: invalid DVB API version: %s\n", optarg);
+                    return 2;
+                    break;
           case 'e' | 0x100:
                     return CutRecording(optarg) ? 0 : 2;
           case 'E': EpgDataFileName = (*optarg != '-' ? optarg : NULL);
