diff --git a/Makefile b/Makefile index cbe7ffc..75c7ffe 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile,v 1.11 2007/09/28 16:44:59 rahrenbe Exp $ +# $Id: Makefile,v 1.12 2007/09/28 23:23:12 rahrenbe Exp $ # Debugging on/off #IPTV_DEBUG = 1 @@ -58,7 +58,7 @@ endif ### The object files (add further files here): OBJS = $(PLUGIN).o config.o setup.o device.o streamer.o protocoludp.o \ - protocolhttp.o protocolfile.o sectionfilter.o + protocolhttp.o protocolfile.o sectionfilter.o sidfinder.o ### The main target: diff --git a/device.c b/device.c index 2a82ee1..60485bb 100644 --- a/device.c +++ b/device.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: device.c,v 1.43 2007/09/28 16:44:59 rahrenbe Exp $ + * $Id: device.c,v 1.44 2007/09/28 23:23:12 rahrenbe Exp $ */ #include "common.h" @@ -35,6 +35,10 @@ cIptvDevice::cIptvDevice(unsigned int Index) // Initialize filter pointers memset(&secfilters, '\0', sizeof(secfilters)); StartSectionHandler(); + // Sid filter must be created after the section handler + sidFinder = NULL; //new cSidFinder; + if (sidFinder) + AttachFilter(sidFinder); } cIptvDevice::~cIptvDevice() @@ -43,6 +47,11 @@ cIptvDevice::~cIptvDevice() delete pIptvStreamer; delete pUdpProtocol; delete tsBuffer; + // Detach and destroy sid filter + if (sidFinder) { + Detach(sidFinder); + delete sidFinder; + } // Destroy all filters for (int i = 0; i < eMaxSecFilterCount; ++i) DeleteFilter(i); @@ -143,6 +152,8 @@ bool cIptvDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) return false; } pIptvStreamer->Set(addr, port, protocol); + if (sidFinder) + sidFinder->SetChannel(Channel); return true; } @@ -217,6 +228,8 @@ bool cIptvDevice::OpenDvr(void) mutex.Unlock(); ResetBuffering(); pIptvStreamer->Open(); + if (sidFinder) + sidFinder->SetStatus(true); isOpenDvr = true; return true; } @@ -224,6 +237,9 @@ bool cIptvDevice::OpenDvr(void) void cIptvDevice::CloseDvr(void) { debug("cIptvDevice::CloseDvr(%d)\n", deviceIndex); + if (sidFinder) { + sidFinder->SetStatus(false); + } pIptvStreamer->Close(); isOpenDvr = false; } diff --git a/device.h b/device.h index 2e30e2a..90ede55 100644 --- a/device.h +++ b/device.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: device.h,v 1.20 2007/09/28 16:44:59 rahrenbe Exp $ + * $Id: device.h,v 1.21 2007/09/28 23:23:12 rahrenbe Exp $ */ #ifndef __IPTV_DEVICE_H @@ -15,6 +15,7 @@ #include "protocolfile.h" #include "streamer.h" #include "sectionfilter.h" +#include "sidfinder.h" class cIptvDevice : public cDevice { // static ones @@ -38,6 +39,7 @@ private: cIptvProtocolHttp *pHttpProtocol; cIptvProtocolFile *pFileProtocol; cIptvStreamer *pIptvStreamer; + cSidFinder *sidFinder; cMutex mutex; cIptvSectionFilter* secfilters[eMaxSecFilterCount]; diff --git a/sidfinder.c b/sidfinder.c new file mode 100644 index 0000000..0f22259 --- /dev/null +++ b/sidfinder.c @@ -0,0 +1,65 @@ +/* + * sidfilter.c: IPTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: sidfinder.c,v 1.1 2007/09/28 23:23:12 rahrenbe Exp $ + */ + +#include + +#include "common.h" +#include "sidfinder.h" + +cSidFinder::cSidFinder(void) +{ + debug("cSidFinder::cSidFinder()\n"); + channel = cChannel(); + Set(0x00, 0x00); // PAT +} + +void cSidFinder::SetStatus(bool On) +{ + debug("cSidFinder::SetStatus(): %d\n", On); + cFilter::SetStatus(On); +} + +void cSidFinder::SetChannel(const cChannel *Channel) +{ + if (Channel) { + debug("cSidFinder::SetChannel(): %s\n", Channel->PluginParam()); + channel = *Channel; + } + else { + debug("cSidFinder::SetChannel()\n"); + channel = cChannel(); + } +} + +void cSidFinder::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) +{ + debug("cSidFinder::Process()\n"); + if ((Pid == 0x00) && (Tid == 0x00) && (channel.GetChannelID() == Channel()->GetChannelID())) { + debug("cSidFinder::Process(): Pid=%d Tid=%02X\n", Pid, Tid); + 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()) { + if (assoc.getServiceId() != channel.Sid()) { + debug("cSidFinder::Process(): Sid=%d\n", assoc.getServiceId()); + if (!Channels.Lock(true, 10)) { + return; + } + channel.SetId(channel.Nid(), channel.Tid(), assoc.getServiceId(), channel.Rid()); + Channels.Unlock(); + } + SetChannel(NULL); + SetStatus(false); + return; + } + } + } +} + diff --git a/sidfinder.h b/sidfinder.h new file mode 100644 index 0000000..e983d04 --- /dev/null +++ b/sidfinder.h @@ -0,0 +1,28 @@ +/* + * sidfinder.h: IPTV plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: sidfinder.h,v 1.1 2007/09/28 23:23:12 rahrenbe Exp $ + */ + +#ifndef __SIDFINDER_H +#define __SIDFINDER_H + +#include +#include + +class cSidFinder : public cFilter { +private: + cChannel channel; + +protected: + virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length); + +public: + cSidFinder(void); + virtual void SetStatus(bool On); + void SetChannel(const cChannel *Channel); +}; + +#endif // __SIDFINDER_H