mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Enhanced the SDT filter to handle multi part sections
This commit is contained in:
parent
3f5c7e67ea
commit
2bf718b62f
1
HISTORY
1
HISTORY
@ -2554,3 +2554,4 @@ Video Disk Recorder Revision History
|
|||||||
Volkenandt for reporting this one).
|
Volkenandt for reporting this one).
|
||||||
- Changed calculation of channel ids to make it work for tv stations that use
|
- 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).
|
the undefined NID value 0 (thanks to Teemu Rantanen for reporting this one).
|
||||||
|
- Enhanced the SDT filter to handle multi part sections.
|
||||||
|
29
filter.c
29
filter.c
@ -4,12 +4,39 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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 "filter.h"
|
||||||
#include "sections.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::cFilterData(void)
|
cFilterData::cFilterData(void)
|
||||||
|
12
filter.h
12
filter.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __FILTER_H
|
||||||
@ -13,6 +13,16 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "tools.h"
|
#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 {
|
class cFilterData : public cListObject {
|
||||||
public:
|
public:
|
||||||
u_short pid;
|
u_short pid;
|
||||||
|
72
sdt.c
72
sdt.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "sdt.h"
|
||||||
@ -13,34 +13,38 @@
|
|||||||
#include "libsi/section.h"
|
#include "libsi/section.h"
|
||||||
#include "libsi/descriptor.h"
|
#include "libsi/descriptor.h"
|
||||||
|
|
||||||
// --- cSDT ------------------------------------------------------------------
|
// --- cSdtFilter ------------------------------------------------------------
|
||||||
|
|
||||||
class cSDT : public SI::SDT {
|
cSdtFilter::cSdtFilter(cPatFilter *PatFilter)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (!CheckCRCAndParse())
|
patFilter = PatFilter;
|
||||||
return;
|
Set(0x11, 0x42); // SDT
|
||||||
|
}
|
||||||
|
|
||||||
if (getVersionNumber() == lastSdtVersion)
|
void cSdtFilter::SetStatus(bool On)
|
||||||
return;
|
{
|
||||||
|
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))
|
if (!Channels.Lock(true, 10))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lastSdtVersion = getVersionNumber();
|
|
||||||
|
|
||||||
SI::SDT::Service SiSdtService;
|
SI::SDT::Service SiSdtService;
|
||||||
for (SI::Loop::Iterator it; serviceLoop.hasNext(it); ) {
|
for (SI::Loop::Iterator it; sdt.serviceLoop.hasNext(it); ) {
|
||||||
SiSdtService = serviceLoop.getNext(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)
|
if (!Channel)
|
||||||
Channel = Channels.GetByChannelID(tChannelID(Source, 0, Transponder, SiSdtService.getServiceId()));
|
Channel = Channels.GetByChannelID(tChannelID(Source(), 0, Transponder(), SiSdtService.getServiceId()));
|
||||||
|
|
||||||
SI::Descriptor *d;
|
SI::Descriptor *d;
|
||||||
for (SI::Loop::Iterator it2; (d = SiSdtService.serviceDescriptors.getNext(it2)); ) {
|
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;
|
pn = ShortNameBuf;
|
||||||
}
|
}
|
||||||
if (Channel) {
|
if (Channel) {
|
||||||
Channel->SetId(getOriginalNetworkId(), getTransportStreamId(), SiSdtService.getServiceId());
|
Channel->SetId(sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
|
||||||
if (Setup.UpdateChannels >= 1)
|
if (Setup.UpdateChannels >= 1)
|
||||||
Channel->SetName(pn);
|
Channel->SetName(pn);
|
||||||
// Using SiSdtService.getFreeCaMode() is no good, because some
|
// 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);
|
// Channel->SetCa(SiSdtService.getFreeCaMode() ? 0xFFFF : 0);
|
||||||
}
|
}
|
||||||
else if (*pn && Setup.UpdateChannels >= 3) {
|
else if (*pn && Setup.UpdateChannels >= 3) {
|
||||||
Channel = Channels.NewChannel(Source, Transponder, pn, getOriginalNetworkId(), getTransportStreamId(), SiSdtService.getServiceId());
|
Channel = Channels.NewChannel(Source(), Transponder(), pn, sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
|
||||||
PatFilter->Trigger();
|
patFilter->Trigger();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,25 +128,3 @@ cSDT::cSDT(int Source, int Transponder, uchar &lastSdtVersion, cPatFilter *PatFi
|
|||||||
}
|
}
|
||||||
Channels.Unlock();
|
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);
|
|
||||||
}
|
|
||||||
|
4
sdt.h
4
sdt.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __SDT_H
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
class cSdtFilter : public cFilter {
|
class cSdtFilter : public cFilter {
|
||||||
private:
|
private:
|
||||||
uchar lastSdtVersion;
|
cSectionSyncer sectionSyncer;
|
||||||
cPatFilter *patFilter;
|
cPatFilter *patFilter;
|
||||||
protected:
|
protected:
|
||||||
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
|
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
|
||||||
|
Loading…
Reference in New Issue
Block a user