diff -urb streamdevcvs-section-filters-0.3/client/device.c streamdev/client/device.c
--- streamdevcvs-section-filters-0.3/client/device.c	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/client/device.c	2007-04-14 19:51:53.000000000 +0300
@@ -42,6 +42,9 @@
 #endif
 
 	m_Device = this;
+	m_Pids = 0;
+	m_DvrClosed = true;
+	m_TSFails = 0;
 
 	if (StreamdevClientSetup.SyncEPG)	
 		ClientSocket.SynchronizeEPG();
@@ -57,12 +60,12 @@
 #endif
 }
 
-bool cStreamdevDevice::ProvidesSource(int Source) const {
-	Dprintf("ProvidesSource, Source=%d\n", Source);
+bool cStreamdevDevice::ProvidesSource(int /*Source*/) const {
+	Dprintf("ProvidesSource\n");
 	return true;
 }
 
-bool cStreamdevDevice::ProvidesTransponder(const cChannel *Channel) const
+bool cStreamdevDevice::ProvidesTransponder(const cChannel */*Channel*/) const
 {
 	Dprintf("ProvidesTransponder\n");
 	return true;
@@ -129,35 +132,116 @@
 	return r;
 }
 
-bool cStreamdevDevice::SetPid(cPidHandle *Handle, int Type, bool On) {
+bool cStreamdevDevice::SetPid(cPidHandle *Handle, int /*Type*/, bool On) {
 	Dprintf("SetPid, Pid=%d, Type=%d, On=%d, used=%d\n", Handle->pid, Type, On,
 			Handle->used);
-	if (Handle->pid && (On || !Handle->used))
-		return ClientSocket.SetPid(Handle->pid, On);
-	return true;
+	LOCK_THREAD;
+
+	if (On && !m_TSBuffer) {
+		Dprintf("SetPid: no data connection -> OpenDvr()");
+		OpenDvrInt();
+	}
+
+        bool res = true; 
+	if (Handle->pid && (On || !Handle->used)) {
+		res = ClientSocket.SetPid(Handle->pid, On);
+
+		m_Pids += (!res) ? 0 : On ? 1 : -1;
+		if (m_Pids < 0) 
+			m_Pids = 0;
+
+		if(m_Pids < 1 && m_DvrClosed) { 
+			Dprintf("SetPid: 0 pids left -> CloseDvr()"); 
+			CloseDvrInt(); 
+		}
+	}
+
+	return res;
 }
 
-bool cStreamdevDevice::OpenDvr(void) {
-	Dprintf("OpenDvr\n");
-	CloseDvr();
+bool cStreamdevDevice::OpenDvrInt(void) {
+	Dprintf("OpenDvrInt\n");
+	LOCK_THREAD;
+
+	CloseDvrInt();
+	if (m_TSBuffer) {
+		Dprintf("cStreamdevDevice::OpenDvrInt(): DVR connection already open\n");
+		return true;
+	}
+
+	Dprintf("cStreamdevDevice::OpenDvrInt(): Connecting ...\n");
 	if (ClientSocket.CreateDataConnection(siLive)) {
 		m_TSBuffer = new cTSBuffer(*ClientSocket.DataSocket(siLive), MEGABYTE(2), CardIndex() + 1);
 		return true;
 	}
+	esyslog("cStreamdevDevice::OpenDvrInt(): DVR connection FAILED");
 	return false;
 }
 
-void cStreamdevDevice::CloseDvr(void) {
-	Dprintf("CloseDvr\n");
+bool cStreamdevDevice::OpenDvr(void) {
+	Dprintf("OpenDvr\n");
+	LOCK_THREAD;
+
+	m_DvrClosed = false;
+	return OpenDvrInt();
+}
 
-	//DELETENULL(m_Assembler);
+void cStreamdevDevice::CloseDvrInt(void) {
+	Dprintf("CloseDvrInt\n");
+	LOCK_THREAD;
+
+	if (ClientSocket.CheckConnection()) {
+		if (!m_DvrClosed) {
+			Dprintf("cStreamdevDevice::CloseDvrInt(): m_DvrClosed=false -> not closing yet\n");
+			return;
+		}
+		if (m_Pids > 0) {
+			Dprintf("cStreamdevDevice::CloseDvrInt(): %d active pids -> not closing yet\n", m_Pids);
+			return;
+		}
+	} else {
+		Dprintf("cStreamdevDevice::CloseDvrInt(): Control connection gone !\n");
+	}
+
+	Dprintf("cStreamdevDevice::CloseDvrInt(): Closing DVR connection\n");
 	DELETENULL(m_TSBuffer);
 	ClientSocket.CloseDvr();
 }
 
+void cStreamdevDevice::CloseDvr(void) {
+	Dprintf("CloseDvr\n");
+	LOCK_THREAD;
+
+	m_DvrClosed = true;
+	CloseDvrInt();
+}
+
 bool cStreamdevDevice::GetTSPacket(uchar *&Data) {
 	if (m_TSBuffer) {
 		Data = m_TSBuffer->Get();
+#if 1 // TODO: this should be fixed in vdr cTSBuffer
+		// simple disconnect detection
+		if (!Data) {
+			cPoller Poller(*ClientSocket.DataSocket(siLive));
+			errno = 0;
+			if (Poller.Poll() && !errno) {
+				char tmp[1];
+				if (recv(*ClientSocket.DataSocket(siLive), tmp, 1, MSG_PEEK) == 0 && !errno) {
+esyslog("cStreamDevice::GetTSPacket: GetChecked: NOTHING (%d)", m_TSFails);
+                                        m_TSFails++; 
+					if (m_TSFails > 10) {
+						isyslog("cStreamdevDevice::GetTSPacket(): disconnected");
+						m_Pids = 0;
+						CloseDvrInt();
+						m_TSFails = 0;
+						return false;
+					}
+					return true;
+				}
+			}
+			m_TSFails = 0;
+		}
+#endif
 		return true;
 	}
 	return false;
@@ -167,22 +251,22 @@
 int cStreamdevDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask) {
 	Dprintf("OpenFilter\n");
 
-# ifdef FILTERTEST
-	if(! ClientSocket.DataSocket(siLiveFilter)) {
+	if (!StreamdevClientSetup.StreamFilters)
+		return -1;
+
+
+	if (!ClientSocket.DataSocket(siLiveFilter)) {
 	        if (ClientSocket.CreateDataConnection(siLiveFilter)) {
-		        if(!m_Filters)
-			        m_Filters = new cStreamdevFilters;
 		        m_Filters->SetConnection(*ClientSocket.DataSocket(siLiveFilter));
 		} else {
-		        isyslog("OpenFilter: connect failed");
+			isyslog("cStreamdevDevice::OpenFilter: connect failed: %m");
 			return -1;
 		}
 	}
-# endif
-	if (StreamdevClientSetup.StreamFilters 
-			&& ClientSocket.SetFilter(Pid, Tid, Mask, true)) {
+
+	if (ClientSocket.SetFilter(Pid, Tid, Mask, true))
 		return m_Filters->OpenFilter(Pid, Tid, Mask);
-	} else
+
 		return -1;
 }
 #endif
diff -urb streamdevcvs-section-filters-0.3/client/device.h streamdev/client/device.h
--- streamdevcvs-section-filters-0.3/client/device.h	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/client/device.h	2007-04-14 04:31:59.000000000 +0300
@@ -25,12 +25,18 @@
 #if VDRVERSNUM >= 10307
 	cStreamdevFilters   *m_Filters;
 #endif
+	int                  m_Pids;
+	bool                 m_DvrClosed;
+	int                  m_TSFails;
 
 	static cStreamdevDevice *m_Device;
 
+	bool OpenDvrInt(void);
+	void CloseDvrInt(void);
+
 protected:
 	virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
-	virtual bool HasLock(int TimeoutMs) 
+	virtual bool HasLock(int /*TimeoutMs*/) 
 	{
 		//printf("HasLock is %d\n", (ClientSocket.DataSocket(siLive) != NULL));
 		//return ClientSocket.DataSocket(siLive) != NULL;
diff -urb streamdevcvs-section-filters-0.3/client/filter.c streamdev/client/filter.c
--- streamdevcvs-section-filters-0.3/client/filter.c	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/client/filter.c	2007-04-14 19:54:08.000000000 +0300
@@ -27,7 +27,7 @@
 	virtual ~cStreamdevFilter();
 
 	bool Matches(u_short Pid, u_char Tid);
-	bool PutSection(const uchar *Data, int Length);
+	bool PutSection(const uchar *Data, int Length, bool pusi);
 	int  ReadPipe(void) const { return m_Pipe[0]; }
 
 	bool IsClosed(void);
@@ -76,7 +76,13 @@
 		close(m_Pipe[1]);
 }
 
-bool cStreamdevFilter::PutSection(const uchar *Data, int Length) {
+bool cStreamdevFilter::PutSection(const uchar *Data, int Length, bool pusi) {
+
+	if (!m_Used && !pusi) /* wait for payload unit start indicator */
+		return true;
+	if (m_Used && pusi)   /* reset at payload unit start */
+		Reset();
+
 	if (m_Used + Length >= (int)sizeof(m_Buffer)) {
 		esyslog("ERROR: Streamdev: Section handler buffer overflow (%d bytes lost)",
 				Length);
@@ -122,7 +128,7 @@
 bool cStreamdevFilter::IsClosed(void) {
 	char m_Buffer[3] = {0,0,0}; /* tid 0, 0 bytes */
 
-	// Test if pipe/socket has been closed by writing empty section
+	// Test if pipe/socket has been closed (write empty section)
 	if (write(m_Pipe[1], m_Buffer, 3) < 0 &&
 	    errno != EAGAIN &&  
 	    errno != EWOULDBLOCK) {
@@ -142,7 +148,6 @@
 
 cStreamdevFilters::cStreamdevFilters(void):
 		cThread("streamdev-client: sections assembler") {
-	m_Active = false;
 	m_TSBuffer = NULL;
 }
 
@@ -163,22 +168,36 @@
 	return fh;
 }
 
+bool cStreamdevFilters::ReActivateFilters(void)
+{
+	LOCK_THREAD;
+
+	bool res = true;
+	CarbageCollect();
+	for (cStreamdevFilter *fi = First(); fi; fi = Next(fi)) {
+		res = ClientSocket.SetFilter(fi->Pid(), fi->Tid(), fi->Mask(), true) && res;
+		Dprintf("ReActivateFilters(%d, %d, %d) -> %s", fi->Pid(), fi->Tid(), fi->Mask(), res ? "Ok" :"FAIL");
+	}
+	return res;
+}
+
 void cStreamdevFilters::CarbageCollect(void) {
-	Lock();
+	LOCK_THREAD;
 	for (cStreamdevFilter *fi = First(); fi;) {
 	        if (fi->IsClosed()) {
 		        if (errno == ECONNREFUSED ||
 			    errno == ECONNRESET ||
 			    errno == EPIPE) {
 			        ClientSocket.SetFilter(fi->Pid(), fi->Tid(), fi->Mask(), false);
-				//dsyslog("   * CarbageCollector: filter closed: Pid %4d, Tid %3d, Mask %2x (%d filters left)", 
-				//	(int)fi->Pid(), (int)fi->Tid(), fi->Mask(), Count()-1);
+				Dprintf("   * CarbageCollector: filter closed: Pid %4d, Tid %3d, Mask %2x (%d filters left)", 
+					(int)fi->Pid(), (int)fi->Tid(), fi->Mask(), Count()-1);
 
 				cStreamdevFilter *next = Prev(fi);
 				Del(fi);
 				fi = next ? Next(next) : First();
 			} else {
-			        isyslog("   * CarbageCollector: error: Pid %4d, Tid %3d, Mask %2x (%d filters left)", 
+			        esyslog("cStreamdevFilters::CarbageCollector() error: "
+					"Pid %4d, Tid %3d, Mask %2x (%d filters left) failed",
 					(int)fi->Pid(), (int)fi->Tid(), fi->Mask(), Count()-1);
 				LOG_ERROR;
 				fi = Next(fi);
@@ -187,41 +206,44 @@
 		        fi = Next(fi);
 		}
 	}
-	Unlock();
 }
 
 void cStreamdevFilters::SetConnection(int Handle) {
 
-	if(m_Active) {
-		m_Active = false;
-		Cancel(1);
-	}
-	if(m_TSBuffer)
+	Cancel(2);
 	      DELETENULL(m_TSBuffer);
 
-	if(Handle >= 0) {
+	if (Handle >= 0) {
 	        m_TSBuffer = new cTSBuffer(Handle, MEGABYTE(1), 1);
-		m_Active = true;
+		ReActivateFilters();
 		Start();
 	}
 }
 
 void cStreamdevFilters::Action(void) {
-	while (m_Active) {
+	int fails = 0;
+
+	while (Running()) {
 		const uchar *block = m_TSBuffer->Get();
 		if (block) {
 			u_short pid = (((u_short)block[1] & PID_MASK_HI) << 8) | block[2];
 			u_char tid = block[3];
+			bool pusi = block[1] & 0x40;
 			int len = block[4];
-
+#if 0
+			if (block[1] == 0xff &&
+			    block[2] == 0xff &&
+			    block[3] == 0xff &&
+			    block[4] == 0x7f)
+				isyslog("*********** TRANSPONDER -> %s **********", block+5);
+#endif
 			LOCK_THREAD;
 			cStreamdevFilter *f = First();
-
-			while(f) {
+			while (f) {
 			        cStreamdevFilter *next = Next(f);
 				if (f->Matches(pid, tid)) {
 
-				        if (f->PutSection(block + 5, len))
+					if (f->PutSection(block + 5, len, pusi))
 					        break;
 
 					if (errno != ECONNREFUSED && 
@@ -238,10 +260,35 @@
 				f = next;
 			}
 		} else {
-			usleep(1);
+#if 1 // TODO: this should be fixed in vdr cTSBuffer
+			// Check disconnection
+			int fd = *ClientSocket.DataSocket(siLiveFilter);
+			if(fd < 0)
+				break;
+			cPoller Poller(fd);
+			if (Poller.Poll()) {
+				char tmp[1];
+				errno = 0;
+				Dprintf("cStreamdevFilters::Action(): checking connection");
+				if (recv(fd, tmp, 1, MSG_PEEK) == 0 && errno != EAGAIN) {
+					++fails;
+					if (fails >= 10) {
+						esyslog("cStreamdevFilters::Action(): stream disconnected ?");
+						ClientSocket.CloseDataConnection(siLiveFilter);
+						break;
+					}
+				} else {
+					fails = 0;
+				}
+			} else {
+				fails = 0;
+			}
+			cCondWait::SleepMs(10);
+#endif
 		}
 	}
 
+	DELETENULL(m_TSBuffer);
 	dsyslog("StreamdevFilters::Action() ended");
 }
 
diff -urb streamdevcvs-section-filters-0.3/client/filter.h streamdev/client/filter.h
--- streamdevcvs-section-filters-0.3/client/filter.h	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/client/filter.h	2007-04-14 05:30:30.000000000 +0300
@@ -17,20 +17,20 @@
 
 class cStreamdevFilters: public cList<cStreamdevFilter>, public cThread {
 private:
-	bool               m_Active;
 	cTSBuffer         *m_TSBuffer;
 	
 protected:
 	virtual void Action(void);
 
 	void CarbageCollect(void);
+	bool ReActivateFilters(void);
 
 public:
 	cStreamdevFilters(void);
 	virtual ~cStreamdevFilters();
 
-	int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
 	void SetConnection(int Handle);
+	int  OpenFilter(u_short Pid, u_char Tid, u_char Mask);
 };
 
 #	endif // VDRVERSNUM >= 10300
diff -urb streamdevcvs-section-filters-0.3/client/socket.c streamdev/client/socket.c
--- streamdevcvs-section-filters-0.3/client/socket.c	2007-04-14 00:51:43.000000000 +0300
+++ streamdev/client/socket.c	2007-04-12 17:16:58.000000000 +0300
@@ -215,6 +215,24 @@
 	return true;
 }
 
+bool cClientSocket::CloseDataConnection(eSocketId Id) {
+	//if (!CheckConnection()) return false;
+
+	CMD_LOCK;
+
+	if(Id == siLive || Id == siLiveFilter)
+		if (m_DataSockets[Id] != NULL) {
+			std::string command = (std::string)"ABRT " + (const char*)itoa(Id);
+			if (!Command(command, 220)) {
+				if (errno == 0)
+					esyslog("ERROR: Streamdev: Couldn't cleanly close data connection");
+				//return false;
+			}		
+			DELETENULL(m_DataSockets[Id]);
+		}
+	return true;
+}
+
 bool cClientSocket::SetChannelDevice(const cChannel *Channel) {
 	if (!CheckConnection()) return false;
 
Only in streamdev/client: socket.c.~1.7.~
diff -urb streamdevcvs-section-filters-0.3/client/socket.h streamdev/client/socket.h
--- streamdevcvs-section-filters-0.3/client/socket.h	2006-01-15 23:35:13.000000000 +0200
+++ streamdev/client/socket.h	2007-04-12 17:13:01.000000000 +0300
@@ -47,6 +47,7 @@
 	bool CheckConnection(void);
 	bool ProvidesChannel(const cChannel *Channel, int Priority);
 	bool CreateDataConnection(eSocketId Id);
+	bool CloseDataConnection(eSocketId Id);
 	bool SetChannelDevice(const cChannel *Channel);
 	bool SetPid(int Pid, bool On);
 #if VDRVERSNUM >= 10300
Only in streamdev/client: socket.h.~1.3.~
diff -urb streamdevcvs-section-filters-0.3/common.h streamdev/common.h
--- streamdevcvs-section-filters-0.3/common.h	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/common.h	2007-04-10 16:53:57.000000000 +0300
@@ -122,8 +122,4 @@
 	virtual eOSState ProcessKey(eKeys Key);
 };
 
-#if VDRVERSNUM >= 10300
-#       define FILTERTEST
-#endif
-
 #endif // VDR_STREAMDEV_COMMON_H
diff -urb streamdevcvs-section-filters-0.3/server/connectionVTP.c streamdev/server/connectionVTP.c
--- streamdevcvs-section-filters-0.3/server/connectionVTP.c	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/server/connectionVTP.c	2007-04-14 04:57:26.000000000 +0300
@@ -153,8 +153,6 @@
 
 bool cLSTEHandler::Next(bool &Last)
 {
-	char *buffer;
-
 	if (m_Error != NULL) {
 		Last = true;
 		cString str(m_Error, true);
@@ -491,6 +489,11 @@
 	delete m_LSTEHandler;
 }
 
+inline bool cConnectionVTP::Abort(void) const
+{
+	return m_LiveStreamer && m_LiveStreamer->Abort();
+}
+
 void cConnectionVTP::Welcome(void) 
 {
 	Respond(220, "Welcome to Video Disk Recorder (VTP)");
@@ -504,14 +507,14 @@
 
 void cConnectionVTP::Detach(void) 
 {
-	if (m_LiveStreamer != NULL) m_LiveStreamer->Detach();
-	if (m_FilterStreamer != NULL) m_FilterStreamer->Detach();
+	if (m_LiveStreamer) m_LiveStreamer->Detach();
+	if (m_FilterStreamer) m_FilterStreamer->Detach();
 }
 
 void cConnectionVTP::Attach(void) 
 {
-	if (m_LiveStreamer != NULL) m_LiveStreamer->Attach();
-	if (m_FilterStreamer != NULL) m_FilterStreamer->Attach();
+	if (m_LiveStreamer) m_LiveStreamer->Attach();
+	if (m_FilterStreamer) m_FilterStreamer->Attach();
 }
 
 bool cConnectionVTP::Command(char *Cmd) 
@@ -555,8 +558,8 @@
 	else if (strcasecmp(Cmd, "ADDF") == 0) return CmdADDF(param);
 	else if (strcasecmp(Cmd, "DELF") == 0) return CmdDELF(param);
 	else if (strcasecmp(Cmd, "ABRT") == 0) return CmdABRT(param);
-	else if (strcasecmp(Cmd, "QUIT") == 0) return CmdQUIT(param);
-	else if (strcasecmp(Cmd, "SUSP") == 0) return CmdSUSP(param);
+	else if (strcasecmp(Cmd, "QUIT") == 0) return CmdQUIT();
+	else if (strcasecmp(Cmd, "SUSP") == 0) return CmdSUSP();
 	// Commands adopted from SVDRP
 	//else if (strcasecmp(Cmd, "DELR") == 0) return CmdDELR(param);
 	else if (strcasecmp(Cmd, "MODT") == 0) return CmdMODT(param);
@@ -568,8 +571,6 @@
 
 bool cConnectionVTP::CmdCAPS(char *Opts) 
 {
-	char *buffer;
-
 	if (strcasecmp(Opts, "TS") == 0) {
 		m_NoTSPIDS = true;
 		return Respond(220, "Ignored, capability \"%s\" accepted for "
@@ -581,13 +582,12 @@
 		return Respond(220, "Capability \"%s\" accepted", Opts);
 	}
 
-#ifdef FILTERTEST
+#if VDRVERSNUM >= 10300
 	//
 	// Deliver section filters data in separate, channel-independent data stream
 	//
-	if (strcasecmp(Opts, "FILTERS") == 0) {
+	if (strcasecmp(Opts, "FILTERS") == 0)
 		return Respond(220, "Capability \"%s\" accepted", Opts);
-	}
 #endif
 
 	return Respond(561, "Capability \"%s\" not known", Opts);
@@ -623,11 +623,11 @@
 	if (ep == Opts || !isspace(*ep))
 		return Respond(500, "Use: PORT Id Destination");
 
-#ifdef FILTERTEST
+#if VDRVERSNUM >= 10300
 	if (id != siLive && id != siLiveFilter)
 		return Respond(501, "Wrong connection id %d", id);
 #else
-	if (id != 0)
+	if (id != siLive)
 		return Respond(501, "Wrong connection id %d", id);
 #endif
 	
@@ -656,9 +656,12 @@
 
 	isyslog("Streamdev: Setting data connection to %s:%d", dataip, dataport);
 
-#ifdef FILTERTEST
+#if VDRVERSNUM >= 10300
 	if (id == siLiveFilter) {
+		if(m_FilterStreamer)
+			m_FilterStreamer->Stop();
 		delete m_FilterSocket;
+
 		m_FilterSocket = new cTBSocket(SOCK_STREAM);
 		if (!m_FilterSocket->Connect(dataip, dataport)) {
 			esyslog("ERROR: Streamdev: Couldn't open data connection to %s:%d: %s",
@@ -666,6 +669,9 @@
 			DELETENULL(m_FilterSocket);
 			return Respond(551, "Couldn't open data connection");
 		}
+
+		if(!m_FilterStreamer)
+			m_FilterStreamer = new cStreamdevFilterStreamer;
 		m_FilterStreamer->Start(m_FilterSocket);
 		m_FilterStreamer->Activate(true);
 
@@ -673,6 +679,10 @@
 	}
 #endif
 
+	if(m_LiveSocket && m_LiveStreamer)
+		m_LiveStreamer->Stop();
+	delete m_LiveSocket;
+
 	m_LiveSocket = new cTBSocket(SOCK_STREAM);
 	if (!m_LiveSocket->Connect(dataip, dataport)) {
 		esyslog("ERROR: Streamdev: Couldn't open data connection to %s:%d: %s",
@@ -681,7 +691,7 @@
 		return Respond(551, "Couldn't open data connection");
 	}
 
-	if (id == siLive)
+	if(m_LiveStreamer)
 		m_LiveStreamer->Start(m_LiveSocket);
 
   return Respond(220, "Port command ok, data connection opened");
@@ -698,6 +708,11 @@
 	if ((dev = GetDevice(chan, 0)) == NULL)
 		return Respond(560, "Channel not available");
 
+#if VDRVERSNUM >= 10300
+	//if(m_FilterStreamer)
+	//	m_FilterStreamer->SetChannel(NULL);
+#endif
+
 	if (!dev->SwitchChannel(chan, false))
 		return Respond(560, "Channel not available");
 
@@ -705,12 +720,16 @@
 	m_LiveStreamer = new cStreamdevLiveStreamer(1);
 	m_LiveStreamer->SetChannel(chan, m_NoTSPIDS ? stTS : stTSPIDS);
 	m_LiveStreamer->SetDevice(dev);
+	if(m_LiveSocket)
+		m_LiveStreamer->Start(m_LiveSocket);
 	
-# ifdef FILTERTEST
+#if VDRVERSNUM >= 10300
 	if(!m_FilterStreamer)
 	        m_FilterStreamer = new cStreamdevFilterStreamer;
 	m_FilterStreamer->SetDevice(dev);
-# endif	
+	//m_FilterStreamer->SetChannel(chan);
+#endif
+
 	return Respond(220, "Channel tuned");
 }
 
@@ -748,13 +767,8 @@
 	int pid, tid, mask;
 	char *ep;
 
-# ifdef FILTERTEST
 	if (m_FilterStreamer == NULL)
 		return Respond(560, "Can't set filters without a filter stream");
-# else
-	if (m_LiveStreamer == NULL)
-		return Respond(560, "Can't set filters without a stream");
-# endif
 	
 	pid = strtol(Opts, &ep, 10);
 	if (ep == Opts || (*ep != ' '))
@@ -768,14 +782,9 @@
 	if (ep == Opts || (*ep != '\0' && *ep != ' '))
 		return Respond(500, "Use: ADDF Pid Tid Mask");
 
-# ifdef FILTERTEST
-	m_FilterStreamer->SetFilter(pid, tid, mask, true);
-	return Respond(220, "Filter %d transferring", pid);
-# else
-	return m_LiveStreamer->SetFilter(pid, tid, mask, true)
+	return m_FilterStreamer->SetFilter(pid, tid, mask, true)
 			? Respond(220, "Filter %d transferring", pid)
 			: Respond(560, "Filter %d not available", pid);
-# endif
 #else
 	return Respond(500, "ADDF known but unimplemented with VDR < 1.3.0");
 #endif
@@ -787,13 +796,8 @@
 	int pid, tid, mask;
 	char *ep;
 	
-# ifdef FILTERTEST
 	if (m_FilterStreamer == NULL)
 		return Respond(560, "Can't delete filters without a stream");
-# else
-	if (m_LiveStreamer == NULL)
-		return Respond(560, "Can't delete filters without a filter stream");
-# endif
 	
 	pid = strtol(Opts, &ep, 10);
 	if (ep == Opts || (*ep != ' '))
@@ -807,14 +811,8 @@
 	if (ep == Opts || (*ep != '\0' && *ep != ' '))
 		return Respond(500, "Use: DELF Pid Tid Mask");
 
-# ifdef FILTERTEST
 	m_FilterStreamer->SetFilter(pid, tid, mask, false);
 	return  Respond(220, "Filter %d stopped", pid);
-# else
-	return m_LiveStreamer->SetFilter(pid, tid, mask, false)
-			? Respond(220, "Filter %d stopped", pid)
-			: Respond(560, "Filter %d not transferring", pid);
-# endif
 #else
 	return Respond(500, "DELF known but unimplemented with VDR < 1.3.0");
 #endif
@@ -830,28 +828,32 @@
 		return Respond(500, "Use: ABRT Id");
 
 	switch (id) {
-	case siLive: DELETENULL(m_LiveStreamer); break;
-#ifdef FILTERTEST
+	case siLive: 
+		DELETENULL(m_LiveStreamer); 
+		DELETENULL(m_LiveSocket);
+		break;
+#if VDRVERSNUM >= 10300
 	case siLiveFilter:
-isyslog("cConnectionVTP::CmdABRT(siLiveFilter)");
 	        DELETENULL(m_FilterStreamer);
 		DELETENULL(m_FilterSocket);
-		return Respond(220, "Data connection closed");
 		break;
 #endif	 
+	default:
+		return Respond(501, "Wrong connection id %d", id);
+		break;
+
 	}
 
-	DELETENULL(m_LiveSocket);
 	return Respond(220, "Data connection closed");
 }
 
-bool cConnectionVTP::CmdQUIT(char *Opts) 
+bool cConnectionVTP::CmdQUIT(void) 
 {
 	DeferClose();
 	return Respond(221, "Video Disk Recorder closing connection");
 }
 
-bool cConnectionVTP::CmdSUSP(char *Opts) 
+bool cConnectionVTP::CmdSUSP(void) 
 {
 	if (StreamdevServerSetup.SuspendMode == smAlways || cSuspendCtl::IsActive())
 		return Respond(220, "Server is suspended");
diff -urb streamdevcvs-section-filters-0.3/server/connectionVTP.h streamdev/server/connectionVTP.h
--- streamdevcvs-section-filters-0.3/server/connectionVTP.h	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/server/connectionVTP.h	2007-04-14 04:36:26.000000000 +0300
@@ -2,7 +2,6 @@
 #define VDR_STREAMDEV_SERVERS_CONNECTIONVTP_H
 
 #include "server/connection.h"
-#include "server/livestreamer.h"
 
 class cTBSocket;
 class cStreamdevLiveStreamer;
@@ -57,8 +56,8 @@
 	bool CmdADDF(char *Opts);
 	bool CmdDELF(char *Opts);
 	bool CmdABRT(char *Opts);
-	bool CmdQUIT(char *Opts);
-	bool CmdSUSP(char *Opts);
+	bool CmdQUIT(void);
+	bool CmdSUSP(void);
 
 	// Thread-safe implementations of SVDRP commands
 	bool CmdLSTE(char *Opts);
@@ -77,9 +76,4 @@
 			__attribute__ ((format (printf, 3, 4)));
 };
 
-inline bool cConnectionVTP::Abort(void) const
-{
-	return m_LiveStreamer && m_LiveStreamer->Abort();
-}
-
 #endif // VDR_STREAMDEV_SERVERS_CONNECTIONVTP_H
diff -urb streamdevcvs-section-filters-0.3/server/livefilter.c streamdev/server/livefilter.c
--- streamdevcvs-section-filters-0.3/server/livefilter.c	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/server/livefilter.c	2007-04-14 02:48:30.000000000 +0300
@@ -28,7 +28,7 @@
 	while (length > 0) {
 		int chunk = min(length, TS_SIZE - 5);
 		buffer[0] = TS_SYNC_BYTE;
-		buffer[1] = (Pid >> 8) & 0xff;
+		buffer[1] = ((Pid >> 8) & 0x3f) | (pos==0 ? 0x40 : 0); /* bit 6: payload unit start indicator (PUSI) */
 		buffer[2] = Pid & 0xff;
 		buffer[3] = Tid;
 		buffer[4] = (uchar)chunk;
diff -urb streamdevcvs-section-filters-0.3/server/livefilter.h streamdev/server/livefilter.h
--- streamdevcvs-section-filters-0.3/server/livefilter.h	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/server/livefilter.h	2007-04-14 01:56:35.000000000 +0300
@@ -14,9 +14,6 @@
 class cStreamdevStreamer;
 
 class cStreamdevLiveFilter: public cFilter {
-	friend class cStreamdevLiveStreamer;
-	friend class cStreamdevFilterStreamer;
-
 private:
 	cStreamdevStreamer *m_Streamer;
 
@@ -25,6 +22,13 @@
 
 public:
 	cStreamdevLiveFilter(cStreamdevStreamer *Streamer);
+
+	void Set(u_short Pid, u_char Tid, u_char Mask) {
+		cFilter::Set(Pid, Tid, Mask);
+	}
+	void Del(u_short Pid, u_char Tid, u_char Mask) {
+		cFilter::Del(Pid, Tid, Mask);
+	}
 };
 
 #	endif // VDRVERSNUM >= 10300
diff -urb streamdevcvs-section-filters-0.3/server/livestreamer.c streamdev/server/livestreamer.c
--- streamdevcvs-section-filters-0.3/server/livestreamer.c	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/server/livestreamer.c	2007-04-14 04:52:24.000000000 +0300
@@ -76,6 +76,8 @@
 	cStreamdevLiveStreamer *m_Streamer;
 
 	virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
+
+	int GetPid(SI::PMT::Stream& stream);
 public:
 	cStreamdevPatFilter(cStreamdevLiveStreamer *Streamer, const cChannel *Channel);
 };
@@ -93,7 +95,7 @@
 }
 
 static const char * const psStreamTypes[] = {
-	"0", 
+	"UNKNOWN", 
 	"ISO/IEC 11172 Video", 
 	"ISO/IEC 13818-2 Video", 
 	"ISO/IEC 11172 Audio", 
@@ -116,61 +118,13 @@
 	"",
 };
 
-void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
+int cStreamdevPatFilter::GetPid(SI::PMT::Stream& stream)
 {
-	if (Pid == 0x00) {
-		if (Tid == 0x00 && !pmtPid) {
-			SI::PAT pat(Data, false);
-			if (!pat.CheckCRCAndParse())
-				return;
-			SI::PAT::Association assoc;
-			for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) {
-				if (!assoc.isNITPid()) {
-					const cChannel *Channel =  Channels.GetByServiceID(Source(), Transponder(), assoc.getServiceId());
-					if (Channel && (Channel == m_Channel)) {
-						if (0 != (pmtPid = assoc.getPid())) {
-							Dprintf("cStreamdevPatFilter: PMT pid for channel %s: %d", Channel->Name(), pmtPid);
-							pmtSid = assoc.getServiceId();
-							if (Length < TS_SIZE-5) {
-								// repack PAT to TS frame and send to client
-								uint8_t pat_ts[TS_SIZE] = {TS_SYNC_BYTE, 0x40 /* pusi=1 */, 0 /* pid=0 */, 0x10 /* adaption=1 */, 0 /* pointer */};
-								memcpy(pat_ts + 5, Data, Length);
-								m_Streamer->Put(pat_ts, TS_SIZE);
-							} else 
-								isyslog("cStreamdevPatFilter: PAT size %d too large to fit in one TS", Length);
-							m_Streamer->SetPid(pmtPid, true);
-							Add(pmtPid, 0x02);
-							pmtVersion = -1;
-							return;
-						}
-					}
-				}
-			}
-		}
-	} else if (Pid == pmtPid && Tid == SI::TableIdPMT && Source() && Transponder()) {
-		SI::PMT pmt(Data, false);
-		if (!pmt.CheckCRCAndParse())
-			return;
-		if (pmt.getServiceId() != pmtSid)
-			return; // skip broken PMT records
-		if (pmtVersion != -1) {
-			if (pmtVersion != pmt.getVersionNumber()) {
-				Dprintf("cStreamdevPatFilter: PMT version changed, detaching all pids");
-				m_Streamer->ClearPids();
-				Del(pmtPid, 0x02);
-				pmtPid = 0; // this triggers PAT scan
-			}
-			return;
-		}
-		pmtVersion = pmt.getVersionNumber();
-		SI::PMT::Stream stream;
-		int Ppid = pmt.getPCRPid();
-		if (Ppid && !m_Streamer->HasPid(Ppid)) {
-			Dprintf("cStreamdevPatFilter PMT scanner: adding PCR PID %d", Ppid);
-			m_Streamer->SetPid(Ppid, true);
-		}
-		for (SI::Loop::Iterator it; pmt.streamLoop.getNext(stream, it); ) {
-			if (stream.getPid() && !m_Streamer->HasPid(stream.getPid())) {
+	SI::Descriptor *d;
+
+	if (!stream.getPid()) 
+		return 0;
+
 				switch (stream.getStreamType()) {
 				case 0x01: // ISO/IEC 11172 Video
 				case 0x02: // ISO/IEC 13818-2 Video
@@ -191,28 +145,23 @@
 				case 0x1b: // ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264)
 					Dprintf("cStreamdevPatFilter PMT scanner adding PID %d (%s)",
 						stream.getPid(), psStreamTypes[stream.getStreamType()]);
-					m_Streamer->SetPid(stream.getPid(), true);
-					break;
+		return stream.getPid();
 				case 0x05: // ISO/IEC 13818-1 private sections
 				case 0x06: // ISO/IEC 13818-1 PES packets containing private data
-					SI::Descriptor *d;
 					for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
 						switch (d->getDescriptorTag()) {
 						case SI::AC3DescriptorTag:
 							Dprintf("cStreamdevPatFilter PMT scanner: adding PID %d (%s) %s", 
 								stream.getPid(), psStreamTypes[stream.getStreamType()], "AC3");
-							m_Streamer->SetPid(stream.getPid(), true);
-							break;
+				return stream.getPid();
 						case SI::TeletextDescriptorTag:
 							Dprintf("cStreamdevPatFilter PMT scanner: adding PID %d (%s) %s", 
 								stream.getPid(), psStreamTypes[stream.getStreamType()], "Teletext");
-							m_Streamer->SetPid(stream.getPid(), true);
-							break;
+				return stream.getPid();
 						case SI::SubtitlingDescriptorTag:
 							Dprintf("cStreamdevPatFilter PMT scanner: adding PID %d (%s) %s", 
 								stream.getPid(), psStreamTypes[stream.getStreamType()], "DVBSUB");
-							m_Streamer->SetPid(stream.getPid(), true);
-							break;
+				return stream.getPid();
 						default:
 							Dprintf("cStreamdevPatFilter PMT scanner: NOT adding PID %d (%s) %s", 
 								stream.getPid(), psStreamTypes[stream.getStreamType()], "UNKNOWN");
@@ -222,12 +171,112 @@
 					}
 					break;
 				default:
+		/* This following section handles all the cases where the audio track 
+		 * info is stored in PMT user info with stream id >= 0x80
+		 * we check the registration format identifier to see if it 
+		 * holds "AC-3"
+		 */
+		if (stream.getStreamType() >= 0x80) {
+			bool found = false;
+			for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
+				switch (d->getDescriptorTag()) {
+				case SI::RegistrationDescriptorTag:
+					/* unfortunately libsi does not implement RegistrationDescriptor */
+					if (d->getLength() >= 4) {
+						found = true;
+						SI::CharArray rawdata = d->getData();
+						if (/*rawdata[0] == 5 && rawdata[1] >= 4 && */
+						    rawdata[2] == 'A' && rawdata[3] == 'C' &&
+						    rawdata[4] == '-' && rawdata[5] == '3') {
+							isyslog("cStreamdevPatFilter PMT scanner:"
+								"Adding pid %d (type 0x%x) RegDesc len %d (%c%c%c%c)", 
+								stream.getPid(), stream.getStreamType(), 
+								d->getLength(), rawdata[2], rawdata[3], 
+								rawdata[4], rawdata[5]);
+							return stream.getPid();
+						}
+					}
+					break;
+				default: 
+					break;
+				}
+				delete d;
+			}
+			if(!found) {
+				isyslog("Adding pid %d (type 0x%x) RegDesc not found -> assume AC-3", 
+					stream.getPid(), stream.getStreamType());
+				return stream.getPid();
+			}
+		}
 					Dprintf("cStreamdevPatFilter PMT scanner: NOT adding PID %d (%s) %s",
-						stream.getPid(), psStreamTypes[stream.getStreamType()], "UNKNOWN");
+			stream.getPid(), psStreamTypes[stream.getStreamType()<0x1c?stream.getStreamType():0], "UNKNOWN");
 					break;
 				}
+	return 0;
+}
+
+void cStreamdevPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
+{
+	if (Pid == 0x00) {
+		if (Tid == 0x00 && !pmtPid) {
+			SI::PAT pat(Data, false);
+			if (!pat.CheckCRCAndParse())
+				return;
+			SI::PAT::Association assoc;
+			for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) {
+				if (!assoc.isNITPid()) {
+					const cChannel *Channel =  Channels.GetByServiceID(Source(), Transponder(), assoc.getServiceId());
+					if (Channel && (Channel == m_Channel)) {
+						if (0 != (pmtPid = assoc.getPid())) {
+							Dprintf("cStreamdevPatFilter: PMT pid for channel %s: %d", Channel->Name(), pmtPid);
+							pmtSid = assoc.getServiceId();
+							if (Length < TS_SIZE-5) {
+								// repack PAT to TS frame and send to client
+								uint8_t pat_ts[TS_SIZE] = {TS_SYNC_BYTE, 0x40 /* pusi=1 */, 0 /* pid=0 */, 0x10 /* adaption=1 */, 0 /* pointer */};
+								memcpy(pat_ts + 5, Data, Length);
+								m_Streamer->Put(pat_ts, TS_SIZE);
+							} else 
+								isyslog("cStreamdevPatFilter: PAT size %d too large to fit in one TS", Length);
+							m_Streamer->SetPids(pmtPid);
+							Add(pmtPid, 0x02);
+							pmtVersion = -1;
+							return;
+						}
+					}
+				}
 			}
 		}
+	} else if (Pid == pmtPid && Tid == SI::TableIdPMT && Source() && Transponder()) {
+		SI::PMT pmt(Data, false);
+		if (!pmt.CheckCRCAndParse())
+			return;
+		if (pmt.getServiceId() != pmtSid)
+			return; // skip broken PMT records
+		if (pmtVersion != -1) {
+			if (pmtVersion != pmt.getVersionNumber()) {
+				Dprintf("cStreamdevPatFilter: PMT version changed, detaching all pids");
+				Del(pmtPid, 0x02);
+				pmtPid = 0; // this triggers PAT scan
+			}
+			return;
+		}
+		pmtVersion = pmt.getVersionNumber();
+
+		SI::PMT::Stream stream;
+		int pids[MAXRECEIVEPIDS + 1], npids = 0;
+		pids[npids++] = pmtPid;
+#if 0
+		pids[npids++] = 0x10;  // pid 0x10, tid 0x40: NIT 
+		pids[npids++] = 0x11;  // pid 0x11, tid 0x42: SDT 
+		pids[npids++] = 0x12;  // pid 0x12, tid 0x4E...0x6F: EIT 
+		pids[npids++] = 0x14;  // pid 0x14, tid 0x70: TDT 
+#endif
+		for (SI::Loop::Iterator it; pmt.streamLoop.getNext(stream, it); )
+			if (0 != (pids[npids] = GetPid(stream)) && npids < MAXRECEIVEPIDS)
+				npids++;
+
+		pids[npids] = 0;
+		m_Streamer->SetPids(pmt.getPCRPid(), pids);
 	}
 }
 
@@ -273,12 +322,6 @@
 	return false;
 }
 
-void cStreamdevLiveStreamer::ClearPids(void)
-{
-	m_NumPids = 0;
-	// do not detach yet, instead wait for next PMT update
-}
-
 bool cStreamdevLiveStreamer::SetPid(int Pid, bool On) 
 {
 	int idx;
@@ -308,6 +351,44 @@
 		}
 	}
 
+	StartReceiver();
+	return true;
+}
+
+bool cStreamdevLiveStreamer::SetPids(int Pid, const int *Pids1, const int *Pids2, const int *Pids3)
+{
+	m_NumPids = 0;
+
+	if (Pid)
+		m_Pids[m_NumPids++] = Pid;
+
+	if (Pids1)
+		for ( ; *Pids1 && m_NumPids < MAXRECEIVEPIDS; Pids1++)
+			if (!HasPid(*Pids1))
+				m_Pids[m_NumPids++] = *Pids1;
+
+	if (Pids2)
+		for ( ; *Pids2 && m_NumPids < MAXRECEIVEPIDS; Pids2++)
+			if (!HasPid(*Pids2))
+				m_Pids[m_NumPids++] = *Pids2;
+
+	if (Pids3)
+		for ( ; *Pids3 && m_NumPids < MAXRECEIVEPIDS; Pids3++)
+			if (!HasPid(*Pids3))
+				m_Pids[m_NumPids++] = *Pids3;
+
+	if (m_NumPids >= MAXRECEIVEPIDS) {
+		esyslog("ERROR: Streamdev: No free slot to receive pid %d\n", Pid);
+		return false;
+	}
+
+	m_Pids[m_NumPids] = 0;
+	StartReceiver();
+	return true;
+}
+
+void cStreamdevLiveStreamer::StartReceiver(void)
+{
 	DELETENULL(m_Receiver);
 	if (m_NumPids > 0) {
 		Dprintf("Creating Receiver to respect changed pids\n");
@@ -321,15 +402,19 @@
 			Attach();
 		}
 	}
-	return true;
 }
 
 bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid) 
 {
 	Dprintf("Initializing Remuxer for full channel transfer\n");
-	printf("ca pid: %d\n", Channel->Ca());
+	//printf("ca pid: %d\n", Channel->Ca());
 	m_Channel = Channel;
 	m_StreamType = StreamType;
+
+	int apid[2] = { Apid, 0 };
+	const int *Apids = Apid ? apid : m_Channel->Apids();
+	const int *Dpids = Apid ? NULL : m_Channel->Dpids();
+
 	switch (m_StreamType) {
 	case stES: 
 		{
@@ -337,37 +422,24 @@
 			if (Apid != 0)
 				pid = Apid;
 			m_ESRemux = new cTS2ESRemux(pid);
-			return SetPid(pid, true);
+			return SetPids(pid);
 		}
 
 	case stPES: 
 		m_PESRemux = new cRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(), 
 								m_Channel->Spids(), false);
-		if (Apid != 0)
-			return SetPid(m_Channel->Vpid(),  true)
-			    && SetPid(Apid, true);
-		else
-			return SetPid(m_Channel->Vpid(),  true)
-			    && SetPid(m_Channel->Apid(0), true)
-			    && SetPid(m_Channel->Dpid(0), true);
+		return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
 
 	case stPS:  
 		m_PSRemux = new cTS2PSRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
 		                            m_Channel->Spids());
-		if (Apid != 0)
-			return SetPid(m_Channel->Vpid(),  true)
-			    && SetPid(Apid, true);
-		else
-			return SetPid(m_Channel->Vpid(),  true)
-			    && SetPid(m_Channel->Apid(0), true)
-			    && SetPid(m_Channel->Dpid(0), true);
+		return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
 
 	case stTS:
 		// This should never happen, but ...
 		if (m_PatFilter) {
 			Detach();
 			DELETENULL(m_PatFilter);
-			ClearPids();
 		}
 		// Set pids from PMT
 		m_PatFilter = new cStreamdevPatFilter(this, m_Channel);
@@ -376,13 +448,7 @@
 	case stExtern:
 		m_ExtRemux = new cExternRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),
 		                              m_Channel->Spids());
-		if (Apid != 0)
-			return SetPid(m_Channel->Vpid(),  true)
-			    && SetPid(Apid, true);
-		else
-			return SetPid(m_Channel->Vpid(),  true)
-			    && SetPid(m_Channel->Apid(0), true)
-			    && SetPid(m_Channel->Dpid(0), true);
+		return SetPids(m_Channel->Vpid(), Apids, Dpids, m_Channel->Spids());
 
 	case stTSPIDS:
 		Dprintf("pid streaming mode\n");
@@ -391,25 +457,6 @@
 	return false;
 }
 
-bool cStreamdevLiveStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On) 
-{
-#if 0
-	Dprintf("setting filter\n");
-	if (On) {
-		if (m_Filter == NULL) {
-			m_Filter = new cStreamdevLiveFilter(this);
-			Dprintf("attaching filter to device\n");
-			m_Device->AttachFilter(m_Filter);
-		}
-		m_Filter->Set(Pid, Tid, Mask);
-	} else if (m_Filter != NULL)
-		m_Filter->Del(Pid, Tid, Mask);
-	return true;
-#else
-	return false;
-#endif
-}
-
 int cStreamdevLiveStreamer::Put(const uchar *Data, int Count) 
 {
 	switch (m_StreamType) {
@@ -486,7 +533,7 @@
 	
 void cStreamdevLiveStreamer::Attach(void) 
 { 
-	Dprintf("RIGHT ATTACH\n");
+	Dprintf("cStreamdevLiveStreamer::Attach()\n");
 	if (m_Device) {
 		if (m_Receiver) {
 			m_Device->Detach(m_Receiver); 
@@ -501,7 +548,7 @@
 
 void cStreamdevLiveStreamer::Detach(void) 
 { 
-	Dprintf("RIGHT DETACH\n");
+	Dprintf("cStreamdevLiveStreamer::Detach()\n");
 	if (m_Device) {
 		if (m_Receiver)
 			m_Device->Detach(m_Receiver); 
@@ -529,11 +576,12 @@
 
 // --- cStreamdevFilterStreamer -------------------------------------------------
 
+#if VDRVERSNUM >= 10300
 cStreamdevFilterStreamer::cStreamdevFilterStreamer():
 		cStreamdevStreamer("streamdev-filterstreaming"),
 		m_Device(NULL),
-		m_Filter(NULL),
-		m_Channel(NULL)
+		m_Filter(NULL)/*,
+		m_Channel(NULL)*/
 {
 }
 
@@ -548,7 +596,7 @@
 
 void cStreamdevFilterStreamer::Attach(void) 
 { 
-	Dprintf("RIGHT ATTACH\n");
+	Dprintf("cStreamdevFilterStreamer::Attach()\n");
 	LOCK_THREAD;
 	if(m_Device && m_Filter)
 		m_Device->AttachFilter(m_Filter);
@@ -556,25 +604,41 @@
 
 void cStreamdevFilterStreamer::Detach(void) 
 { 
-	Dprintf("RIGHT DETACH\n");
+	Dprintf("cStreamdevFilterStreamer::Detach()\n");
 	LOCK_THREAD;
 	if(m_Device && m_Filter)
 		m_Device->Detach(m_Filter); 
 }
 
+#if 0
+void cStreamdevFilterStreamer::SetChannel(const cChannel *Channel)
+{
+	LOCK_THREAD;
+	Dprintf("cStreamdevFilterStreamer::SetChannel(%s : %s)", Channel?Channel->Name():"<null>",
+		Channel ? *Channel->GetChannelID().ToString() : "");
+	m_Channel = Channel;
+}
+#endif
+
 void cStreamdevFilterStreamer::SetDevice(cDevice *Device)
 {
+	Dprintf("cStreamdevFilterStreamer::SetDevice()\n");
 	LOCK_THREAD;
 	if(Device != m_Device) {
 		Detach();
 		m_Device = Device; 
+		//m_Channel = NULL;
 		Attach();
 	}
 }
 
-void cStreamdevFilterStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On) 
+bool cStreamdevFilterStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On) 
 {
-	Dprintf("setting filter\n");
+	Dprintf("cStreamdevFilterStreamer::SetFilter(%u,0x%x,0x%x,%s)\n", Pid, Tid, Mask, On?"On":"Off");
+
+	if(!m_Device)
+		return false;
+
 	if (On) {
 		if (m_Filter == NULL) {
 			m_Filter = new cStreamdevLiveFilter(this);
@@ -584,34 +648,41 @@
 		m_Filter->Set(Pid, Tid, Mask);
 	} else if (m_Filter != NULL) 
 		m_Filter->Del(Pid, Tid, Mask);
+
+	return true;
 }
 
+#if 0
 void cStreamdevFilterStreamer::ChannelSwitch(const cDevice *Device, int ChannelNumber) {
-
-	// TODO:
-	// Need to signal channel changes to streamdev-client 
-	// unless change request is from streamdev-client
-	// (section data will come from another transponder 
-	//  after transponder change)
-
 	LOCK_THREAD;
+	if(Device == m_Device) {
+		if(ChannelNumber > 0) {
+			cChannel *ch = Channels.GetByNumber(ChannelNumber);
+			if(ch != NULL) {
 	if(m_Filter != NULL &&
-	   Device == m_Device && 
-	   ChannelNumber > 0 &&
-	   m_Channel &&
-	   ! TRANSPONDER(Channels.GetByNumber(ChannelNumber), m_Channel)) {
+				   m_Channel != NULL &&
+				   (! TRANSPONDER(ch, m_Channel))) {
 
-isyslog("***** LiveFilterStreamer: transponder changed !");
+					isyslog("***** LiveFilterStreamer: transponder changed ! %s",
+						*ch->GetChannelID().ToString());
 
-		//SetDevice(NULL);
-		Detach();
+					uchar buffer[TS_SIZE] = {TS_SYNC_BYTE, 0xff, 0xff, 0xff, 0x7f, 0};
+					strcpy((char*)(buffer + 5), ch->GetChannelID().ToString());
+					int p = Put(buffer, TS_SIZE);
+					if (p != TS_SIZE)
+						ReportOverflow(TS_SIZE - p);
+				}
+				m_Channel = ch;
+			}
+		}
 	}
-	m_Channel = Channels.GetByNumber(ChannelNumber);
 }
+#endif
+
+#endif // if VDRVERSNUM >= 10300
 
 // Local Variables:
 // c-basic-offset: 8
-//
 // indent-tabs-mode: t
 // End:
 //
Only in streamdev/server: livestreamer.c.ph
diff -urb streamdevcvs-section-filters-0.3/server/livestreamer.h streamdev/server/livestreamer.h
--- streamdevcvs-section-filters-0.3/server/livestreamer.h	2007-04-14 00:56:33.000000000 +0300
+++ streamdev/server/livestreamer.h	2007-04-14 04:39:02.000000000 +0300
@@ -31,14 +31,17 @@
 	cTS2PSRemux            *m_PSRemux;
 	cExternRemux           *m_ExtRemux;
 
+	void StartReceiver(void);
+	bool HasPid(int Pid);
+
 public:
 	cStreamdevLiveStreamer(int Priority);
 	virtual ~cStreamdevLiveStreamer();
 
 	void SetDevice(cDevice *Device) { m_Device = Device; }
 	bool SetPid(int Pid, bool On);
+	bool SetPids(int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL);
 	bool SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid = 0);
-	bool SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On);
 	
 	virtual int Put(const uchar *Data, int Count);
 	virtual uchar *Get(int &Count);
@@ -47,39 +50,42 @@
 	virtual void Attach(void);
 	virtual void Detach(void);
 
-	bool HasPid(int Pid);
-	void ClearPids(void); 
-
 	// Statistical purposes:
 	virtual std::string Report(void);
 };
 
+
 // --- cStreamdevFilterStreamer -------------------------------------------------
 
-#include <vdr/status.h>
+#  if VDRVERSNUM >= 10300
+
+//#include <vdr/status.h>
 
 class cStreamdevLiveFilter;
 
-class cStreamdevFilterStreamer: public cStreamdevStreamer, public cStatus {
+class cStreamdevFilterStreamer: public cStreamdevStreamer /*, public cStatus*/ {
 private:
 	cDevice                *m_Device;
 	cStreamdevLiveFilter   *m_Filter;
-	const cChannel         *m_Channel;
+	//const cChannel         *m_Channel;
 
 public:
 	cStreamdevFilterStreamer();
 	virtual ~cStreamdevFilterStreamer();
 
 	void SetDevice(cDevice *Device);
-	void SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On);
+	//void SetChannel(const cChannel *Channel);
+	bool SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On);
 	
 	virtual void Attach(void);
 	virtual void Detach(void);
 
 	// cStatus message handlers
-	virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber);
+	//virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber);
 };
 
+#  endif // if VDRVERSNUM >= 10300
+
 #endif // VDR_STREAMDEV_LIVESTREAMER_H
 
 // Local Variables:
Only in streamdev/server: livestreamer.h.ph
Only in streamdev/server: vdr-streamdev-cvs-ts-streaming.patch
diff -urb streamdevcvs-section-filters-0.3/streamdev-server.c streamdev/streamdev-server.c
--- streamdevcvs-section-filters-0.3/streamdev-server.c	2007-04-14 00:51:43.000000000 +0300
+++ streamdev/streamdev-server.c	2007-04-14 04:38:00.000000000 +0300
@@ -63,7 +63,7 @@
 
 	if (!StreamdevHosts.Load(STREAMDEVHOSTSPATH, true, true)) {
 		esyslog("streamdev-server: error while loading %s", STREAMDEVHOSTSPATH);
-		fprintf(stderr, "streamdev-server: error while loading %s\n");
+		fprintf(stderr, "streamdev-server: error while loading %s\n", STREAMDEVHOSTSPATH);
 		if (access(STREAMDEVHOSTSPATH, F_OK) != 0) {
 			fprintf(stderr, "  Please install streamdevhosts.conf into the path "
 			                "printed above. Without it\n" 
diff -urb streamdevcvs-section-filters-0.3/tools/source.c streamdev/tools/source.c
--- streamdevcvs-section-filters-0.3/tools/source.c	2007-04-14 00:51:43.000000000 +0300
+++ streamdev/tools/source.c	2007-04-14 04:34:47.000000000 +0300
@@ -110,7 +110,7 @@
 
 ssize_t cTBSource::ReadUntil(void *Buffer, size_t Length, const char *Seq,
 		uint TimeoutMs) {
-	int seqlen, ms;
+	int ms;
 	size_t len;
 	cTBSelect sel;
 
Only in streamdev/tools: source.c.~1.5.~
diff -urb streamdevcvs-section-filters-0.3/tools/tools.c streamdev/tools/tools.c
--- streamdevcvs-section-filters-0.3/tools/tools.c	2006-01-15 23:35:13.000000000 +0200
+++ streamdev/tools/tools.c	2007-04-14 04:34:26.000000000 +0300
@@ -6,7 +6,7 @@
 #include <unistd.h>
 #include <stdarg.h>
 
-void *operator new(size_t nSize, void *p) throw () {
+void *operator new(size_t /*nSize*/, void *p) throw () {
 	return p;
 }
 
