From 2bf718b62f051c0f563fa8ad1d95351b68c5315b Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Mon, 5 Jan 2004 14:30:31 +0100 Subject: [PATCH] Enhanced the SDT filter to handle multi part sections --- HISTORY | 1 + filter.c | 29 ++++++++++++++++++++++- filter.h | 12 +++++++++- sdt.c | 72 +++++++++++++++++++++----------------------------------- sdt.h | 4 ++-- 5 files changed, 69 insertions(+), 49 deletions(-) diff --git a/HISTORY b/HISTORY index 3361dd2c..e2033377 100644 --- a/HISTORY +++ b/HISTORY @@ -2554,3 +2554,4 @@ Video Disk Recorder Revision History Volkenandt for reporting this one). - Changed calculation of channel ids to make it work for tv stations that use the undefined NID value 0 (thanks to Teemu Rantanen for reporting this one). +- Enhanced the SDT filter to handle multi part sections. diff --git a/filter.c b/filter.c index 668b7d3a..56054d36 100644 --- a/filter.c +++ b/filter.c @@ -4,12 +4,39 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: filter.c 1.1 2003/12/21 15:26:16 kls Exp $ + * $Id: filter.c 1.2 2004/01/05 14:30:00 kls Exp $ */ #include "filter.h" #include "sections.h" +// --- cSectionSyncer -------------------------------------------------------- + +cSectionSyncer::cSectionSyncer(void) +{ + Reset(); +} + +void cSectionSyncer::Reset(void) +{ + lastVersion = 0xFF; + synced = false; +} + +bool cSectionSyncer::Sync(uchar Version, int Number, int LastNumber) +{ + if (Version == lastVersion) + return false; + if (!synced) { + if (Number != 0) + return false; // sync on first section + synced = true; + } + if (Number == LastNumber) + lastVersion = Version; + return synced; +} + // --- cFilterData ----------------------------------------------------------- cFilterData::cFilterData(void) diff --git a/filter.h b/filter.h index 09703e02..1696e6e2 100644 --- a/filter.h +++ b/filter.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: filter.h 1.1 2003/12/22 11:41:40 kls Exp $ + * $Id: filter.h 1.2 2004/01/05 14:29:49 kls Exp $ */ #ifndef __FILTER_H @@ -13,6 +13,16 @@ #include #include "tools.h" +class cSectionSyncer { +private: + int lastVersion; + bool synced; +public: + cSectionSyncer(void); + void Reset(void); + bool Sync(uchar Version, int Number, int LastNumber); + }; + class cFilterData : public cListObject { public: u_short pid; diff --git a/sdt.c b/sdt.c index 9ede48dd..33e458a7 100644 --- a/sdt.c +++ b/sdt.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: sdt.c 1.2 2004/01/05 11:40:24 kls Exp $ + * $Id: sdt.c 1.3 2004/01/05 14:30:31 kls Exp $ */ #include "sdt.h" @@ -13,34 +13,38 @@ #include "libsi/section.h" #include "libsi/descriptor.h" -// --- cSDT ------------------------------------------------------------------ +// --- cSdtFilter ------------------------------------------------------------ -class cSDT : public SI::SDT { -public: - cSDT(int Source, int Transponder, uchar &lastSdtVersion, cPatFilter *PatFilter, const u_char *Data); - }; - -cSDT::cSDT(int Source, int Transponder, uchar &lastSdtVersion, cPatFilter *PatFilter, const u_char *Data) -:SI::SDT(Data, false) +cSdtFilter::cSdtFilter(cPatFilter *PatFilter) { - if (!CheckCRCAndParse()) - return; + patFilter = PatFilter; + Set(0x11, 0x42); // SDT +} - if (getVersionNumber() == lastSdtVersion) - return; +void cSdtFilter::SetStatus(bool On) +{ + cFilter::SetStatus(On); + sectionSyncer.Reset(); +} +void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) +{ + if (!(Source() && Transponder())) + return; + SI::SDT sdt(Data, false); + if (!sdt.CheckCRCAndParse()) + return; + if (!sectionSyncer.Sync(sdt.getVersionNumber(), sdt.getSectionNumber(), sdt.getLastSectionNumber())) + return; if (!Channels.Lock(true, 10)) return; - - lastSdtVersion = getVersionNumber(); - SI::SDT::Service SiSdtService; - for (SI::Loop::Iterator it; serviceLoop.hasNext(it); ) { - SiSdtService = serviceLoop.getNext(it); + for (SI::Loop::Iterator it; sdt.serviceLoop.hasNext(it); ) { + SiSdtService = sdt.serviceLoop.getNext(it); - cChannel *Channel = Channels.GetByChannelID(tChannelID(Source, getOriginalNetworkId(), getTransportStreamId(), SiSdtService.getServiceId())); + cChannel *Channel = Channels.GetByChannelID(tChannelID(Source(), sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId())); if (!Channel) - Channel = Channels.GetByChannelID(tChannelID(Source, 0, Transponder, SiSdtService.getServiceId())); + Channel = Channels.GetByChannelID(tChannelID(Source(), 0, Transponder(), SiSdtService.getServiceId())); SI::Descriptor *d; for (SI::Loop::Iterator it2; (d = SiSdtService.serviceDescriptors.getNext(it2)); ) { @@ -80,7 +84,7 @@ cSDT::cSDT(int Source, int Transponder, uchar &lastSdtVersion, cPatFilter *PatFi pn = ShortNameBuf; } if (Channel) { - Channel->SetId(getOriginalNetworkId(), getTransportStreamId(), SiSdtService.getServiceId()); + Channel->SetId(sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId()); if (Setup.UpdateChannels >= 1) Channel->SetName(pn); // Using SiSdtService.getFreeCaMode() is no good, because some @@ -90,8 +94,8 @@ cSDT::cSDT(int Source, int Transponder, uchar &lastSdtVersion, cPatFilter *PatFi // Channel->SetCa(SiSdtService.getFreeCaMode() ? 0xFFFF : 0); } else if (*pn && Setup.UpdateChannels >= 3) { - Channel = Channels.NewChannel(Source, Transponder, pn, getOriginalNetworkId(), getTransportStreamId(), SiSdtService.getServiceId()); - PatFilter->Trigger(); + Channel = Channels.NewChannel(Source(), Transponder(), pn, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId()); + patFilter->Trigger(); } } } @@ -124,25 +128,3 @@ cSDT::cSDT(int Source, int Transponder, uchar &lastSdtVersion, cPatFilter *PatFi } Channels.Unlock(); } - - -// --- cSdtFilter ------------------------------------------------------------ - -cSdtFilter::cSdtFilter(cPatFilter *PatFilter) -{ - lastSdtVersion = 0xFF; - patFilter = PatFilter; - Set(0x11, 0x42); // SDT -} - -void cSdtFilter::SetStatus(bool On) -{ - cFilter::SetStatus(On); - lastSdtVersion = 0xFF; -} - -void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) -{ - if (Source() && Transponder()) - cSDT SDT(Source(), Transponder(), lastSdtVersion, patFilter, Data); -} diff --git a/sdt.h b/sdt.h index 8d75f3c7..a427119c 100644 --- a/sdt.h +++ b/sdt.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: sdt.h 1.1 2004/01/03 13:49:55 kls Exp $ + * $Id: sdt.h 1.2 2004/01/05 14:30:14 kls Exp $ */ #ifndef __SDT_H @@ -15,7 +15,7 @@ class cSdtFilter : public cFilter { private: - uchar lastSdtVersion; + cSectionSyncer sectionSyncer; cPatFilter *patFilter; protected: virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);