mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Improved cSectionSyncer
This commit is contained in:
parent
ad35c9c2d3
commit
36a833053b
8
HISTORY
8
HISTORY
@ -9578,7 +9578,7 @@ Video Disk Recorder Revision History
|
|||||||
given (reported by Manuel Reimer).
|
given (reported by Manuel Reimer).
|
||||||
- Fixed handling $(PKG_CONFIG) in newplugin (thanks to Winfried Köhler).
|
- Fixed handling $(PKG_CONFIG) in newplugin (thanks to Winfried Köhler).
|
||||||
|
|
||||||
2021-01-19:
|
2021-03-16:
|
||||||
|
|
||||||
- Fixed strreplace() to handle NULL strings (reported by Jürgen Schneider).
|
- Fixed strreplace() to handle NULL strings (reported by Jürgen Schneider).
|
||||||
- Somewhere down the road the 'x' bit of Doxyfile.filter got lost, so the
|
- Somewhere down the road the 'x' bit of Doxyfile.filter got lost, so the
|
||||||
@ -9605,3 +9605,9 @@ Video Disk Recorder Revision History
|
|||||||
Jürgen Schneider).
|
Jürgen Schneider).
|
||||||
- Added some missing user command calls for copying, renaming and moving recordings
|
- Added some missing user command calls for copying, renaming and moving recordings
|
||||||
(thanks to Peter Bieringer).
|
(thanks to Peter Bieringer).
|
||||||
|
- Improved cSectionSyncer to make sure that no sections are missed, and to allow
|
||||||
|
handling partially used segments (as in the EIT) and processing sections in random
|
||||||
|
order. Segment syncing is now done with the two member functions Check() and
|
||||||
|
Processed(). The old functions Sync() and Repeat() are deprecated and may be
|
||||||
|
removed in a future version. See the comments in filter.h for a description on
|
||||||
|
how to use these new function.
|
||||||
|
43
eit.c
43
eit.c
@ -8,7 +8,7 @@
|
|||||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||||
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
|
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
|
||||||
*
|
*
|
||||||
* $Id: eit.c 4.11 2020/11/28 21:45:05 kls Exp $
|
* $Id: eit.c 5.1 2021/03/16 15:10:54 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
@ -22,6 +22,28 @@
|
|||||||
|
|
||||||
#define DBGEIT 0
|
#define DBGEIT 0
|
||||||
|
|
||||||
|
// --- cEitTables ------------------------------------------------------------
|
||||||
|
|
||||||
|
bool cEitTables::Check(uchar TableId, uchar Version, int SectionNumber)
|
||||||
|
{
|
||||||
|
int ti = Index(TableId);
|
||||||
|
return sectionSyncer[ti].Check(Version, SectionNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cEitTables::Processed(uchar TableId, uchar LastTableId, int SectionNumber, int LastSectionNumber, int SegmentLastSectionNumber)
|
||||||
|
{
|
||||||
|
int ti = Index(TableId);
|
||||||
|
int LastIndex = Index(LastTableId);
|
||||||
|
if (sectionSyncer[ti].Processed(SectionNumber, LastSectionNumber, SegmentLastSectionNumber)) {
|
||||||
|
for (int i = 0; i <= LastIndex; i++) {
|
||||||
|
if (!sectionSyncer[i].Complete())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true; // all tables have been processed
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cEIT ------------------------------------------------------------------
|
// --- cEIT ------------------------------------------------------------------
|
||||||
|
|
||||||
class cEIT : public SI::EIT {
|
class cEIT : public SI::EIT {
|
||||||
@ -34,13 +56,13 @@ cEIT::cEIT(cSectionSyncerHash &SectionSyncerHash, int Source, u_char Tid, const
|
|||||||
{
|
{
|
||||||
if (!CheckCRCAndParse())
|
if (!CheckCRCAndParse())
|
||||||
return;
|
return;
|
||||||
int HashId = Tid + (getServiceId() << 8);
|
int HashId = getServiceId();
|
||||||
cSectionSyncerEntry *SectionSyncerEntry = SectionSyncerHash.Get(HashId);
|
cEitTables *EitTables = SectionSyncerHash.Get(HashId);
|
||||||
if (!SectionSyncerEntry) {
|
if (!EitTables) {
|
||||||
SectionSyncerEntry = new cSectionSyncerEntry;
|
EitTables = new cEitTables;
|
||||||
SectionSyncerHash.Add(SectionSyncerEntry, HashId);
|
SectionSyncerHash.Add(EitTables, HashId);
|
||||||
}
|
}
|
||||||
bool Process = SectionSyncerEntry->Sync(getVersionNumber(), getSectionNumber(), getLastSectionNumber());
|
bool Process = EitTables->Check(Tid, getVersionNumber(), getSectionNumber());
|
||||||
if (Tid != 0x4E && !Process) // we need to set the 'seen' tag to watch the running status of the present/following event
|
if (Tid != 0x4E && !Process) // we need to set the 'seen' tag to watch the running status of the present/following event
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -50,10 +72,8 @@ cEIT::cEIT(cSectionSyncerHash &SectionSyncerHash, int Source, u_char Tid, const
|
|||||||
|
|
||||||
cStateKey ChannelsStateKey;
|
cStateKey ChannelsStateKey;
|
||||||
cChannels *Channels = cChannels::GetChannelsWrite(ChannelsStateKey, 10);
|
cChannels *Channels = cChannels::GetChannelsWrite(ChannelsStateKey, 10);
|
||||||
if (!Channels) {
|
if (!Channels)
|
||||||
SectionSyncerEntry->Repeat(); // let's not miss any section of the EIT
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
tChannelID channelID(Source, getOriginalNetworkId(), getTransportStreamId(), getServiceId());
|
tChannelID channelID(Source, getOriginalNetworkId(), getTransportStreamId(), getServiceId());
|
||||||
cChannel *Channel = Channels->GetByChannelID(channelID, true);
|
cChannel *Channel = Channels->GetByChannelID(channelID, true);
|
||||||
if (!Channel || EpgHandlers.IgnoreChannel(Channel)) {
|
if (!Channel || EpgHandlers.IgnoreChannel(Channel)) {
|
||||||
@ -64,7 +84,6 @@ cEIT::cEIT(cSectionSyncerHash &SectionSyncerHash, int Source, u_char Tid, const
|
|||||||
cStateKey SchedulesStateKey;
|
cStateKey SchedulesStateKey;
|
||||||
cSchedules *Schedules = cSchedules::GetSchedulesWrite(SchedulesStateKey, 10);
|
cSchedules *Schedules = cSchedules::GetSchedulesWrite(SchedulesStateKey, 10);
|
||||||
if (!Schedules) {
|
if (!Schedules) {
|
||||||
SectionSyncerEntry->Repeat(); // let's not miss any section of the EIT
|
|
||||||
ChannelsStateKey.Remove(false);
|
ChannelsStateKey.Remove(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -361,6 +380,8 @@ cEIT::cEIT(cSectionSyncerHash &SectionSyncerHash, int Source, u_char Tid, const
|
|||||||
EpgHandlers.DropOutdated(pSchedule, SegmentStart, SegmentEnd, Tid, getVersionNumber());
|
EpgHandlers.DropOutdated(pSchedule, SegmentStart, SegmentEnd, Tid, getVersionNumber());
|
||||||
pSchedule->SetModified();
|
pSchedule->SetModified();
|
||||||
}
|
}
|
||||||
|
if (Process)
|
||||||
|
EitTables->Processed(Tid, getLastTableId(), getSectionNumber(), getLastSectionNumber(), getSegmentLastSectionNumber());
|
||||||
SchedulesStateKey.Remove(Modified);
|
SchedulesStateKey.Remove(Modified);
|
||||||
ChannelsStateKey.Remove(ChannelsModified);
|
ChannelsStateKey.Remove(ChannelsModified);
|
||||||
EpgHandlers.EndSegmentTransfer(Modified);
|
EpgHandlers.EndSegmentTransfer(Modified);
|
||||||
|
23
eit.h
23
eit.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: eit.h 4.2 2017/05/08 21:10:29 kls Exp $
|
* $Id: eit.h 5.1 2021/03/16 15:10:54 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __EIT_H
|
#ifndef __EIT_H
|
||||||
@ -13,9 +13,26 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
class cSectionSyncerEntry : public cListObject, public cSectionSyncer {};
|
#define NUM_EIT_TABLES 17
|
||||||
|
|
||||||
class cSectionSyncerHash : public cHash<cSectionSyncerEntry> {
|
// Event information (or EPG) is broadcast in tables 0x4E and 0x4F for "present/following" events on
|
||||||
|
// "this transponder" (0x4E) and "other transponders" (0x4F), as well as 0x50-0x5F ("all events on this
|
||||||
|
// transponder) and 0x60-0x6F ("all events on other transponders). Since it's either "this" or "other",
|
||||||
|
// we only use one section syncer for 0x4E/0x4F and 16 syncers for either 0x5X or 0x6X.
|
||||||
|
|
||||||
|
class cEitTables : public cListObject {
|
||||||
|
private:
|
||||||
|
cSectionSyncerRandom sectionSyncer[NUM_EIT_TABLES]; // for tables 0x4E/0x4F and 0x50-0x5F/0x60-0x6F
|
||||||
|
bool complete;
|
||||||
|
int Index(uchar TableId) { return (TableId < 0x50) ? 0 : (TableId & 0x0F) + 1; }
|
||||||
|
public:
|
||||||
|
cEitTables(void) { complete = false; }
|
||||||
|
bool Check(uchar TableId, uchar Version, int SectionNumber);
|
||||||
|
bool Processed(uchar TableId, uchar LastTableId, int SectionNumber, int LastSectionNumber, int SegmentLastSectionNumber = -1);
|
||||||
|
bool Complete(void) { return complete; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSectionSyncerHash : public cHash<cEitTables> {
|
||||||
public:
|
public:
|
||||||
cSectionSyncerHash(void) : cHash(HASHSIZE, true) {};
|
cSectionSyncerHash(void) : cHash(HASHSIZE, true) {};
|
||||||
};
|
};
|
||||||
|
53
filter.c
53
filter.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: filter.c 4.3 2017/05/09 08:37:23 kls Exp $
|
* $Id: filter.c 5.1 2021/03/16 15:10:54 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
@ -12,8 +12,9 @@
|
|||||||
|
|
||||||
// --- cSectionSyncer --------------------------------------------------------
|
// --- cSectionSyncer --------------------------------------------------------
|
||||||
|
|
||||||
cSectionSyncer::cSectionSyncer(void)
|
cSectionSyncer::cSectionSyncer(bool Random)
|
||||||
{
|
{
|
||||||
|
random = Random;
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,9 +24,56 @@ void cSectionSyncer::Reset(void)
|
|||||||
currentSection = -1;
|
currentSection = -1;
|
||||||
synced = false;
|
synced = false;
|
||||||
complete = false;
|
complete = false;
|
||||||
|
segments = 0;
|
||||||
memset(sections, 0x00, sizeof(sections));
|
memset(sections, 0x00, sizeof(sections));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cSectionSyncer::Check(uchar Version, int SectionNumber)
|
||||||
|
{
|
||||||
|
if (Version != currentVersion) {
|
||||||
|
Reset();
|
||||||
|
currentVersion = Version;
|
||||||
|
}
|
||||||
|
if (complete)
|
||||||
|
return false;
|
||||||
|
if (!random) {
|
||||||
|
if (!synced) {
|
||||||
|
if (SectionNumber == 0) {
|
||||||
|
currentSection = 0;
|
||||||
|
synced = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (SectionNumber != currentSection)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !GetSectionFlag(SectionNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cSectionSyncer::Processed(int SectionNumber, int LastSectionNumber, int SegmentLastSectionNumber)
|
||||||
|
{
|
||||||
|
SetSectionFlag(SectionNumber, true); // the flag for this section
|
||||||
|
if (!random)
|
||||||
|
currentSection++; // expect the next section
|
||||||
|
int Index = SectionNumber / 8; // the segment (byte) in which this section lies
|
||||||
|
uchar b = 0xFF; // all sections in this segment
|
||||||
|
if (SegmentLastSectionNumber < 0 && Index == LastSectionNumber / 8)
|
||||||
|
SegmentLastSectionNumber = LastSectionNumber;
|
||||||
|
if (SegmentLastSectionNumber >= 0) {
|
||||||
|
b >>= 7 - (SegmentLastSectionNumber & 0x07); // limits them up to the last section in this segment
|
||||||
|
if (!random && SectionNumber == SegmentLastSectionNumber)
|
||||||
|
currentSection = (SectionNumber + 8) & ~0x07; // expect first section of next segment
|
||||||
|
}
|
||||||
|
if (sections[Index] == b) // all expected sections in this segment have been received
|
||||||
|
segments |= 1 << Index; // so we set the respective bit in the segments flags
|
||||||
|
uint32_t s = 0xFFFFFFFF; // all segments
|
||||||
|
s >>= 31 - (LastSectionNumber / 8); // limits them up to the last expected segment
|
||||||
|
complete = segments == s;
|
||||||
|
return complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEPRECATED_SECTIONSYNCER_SYNC_REPEAT
|
||||||
void cSectionSyncer::Repeat(void)
|
void cSectionSyncer::Repeat(void)
|
||||||
{
|
{
|
||||||
SetSectionFlag(currentSection, false);
|
SetSectionFlag(currentSection, false);
|
||||||
@ -52,6 +100,7 @@ bool cSectionSyncer::Sync(uchar Version, int Number, int LastNumber)
|
|||||||
complete = true;
|
complete = true;
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// --- cFilterData -----------------------------------------------------------
|
// --- cFilterData -----------------------------------------------------------
|
||||||
|
|
||||||
|
37
filter.h
37
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 4.3 2017/05/09 08:37:23 kls Exp $
|
* $Id: filter.h 5.1 2021/03/16 15:10:54 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __FILTER_H
|
#ifndef __FILTER_H
|
||||||
@ -13,21 +13,52 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
|
#define DEPRECATED_SECTIONSYNCER_SYNC_REPEAT 1
|
||||||
|
|
||||||
class cSectionSyncer {
|
class cSectionSyncer {
|
||||||
private:
|
private:
|
||||||
int currentVersion;
|
int currentVersion;
|
||||||
int currentSection;
|
int currentSection;
|
||||||
|
bool random;
|
||||||
bool synced;
|
bool synced;
|
||||||
bool complete;
|
bool complete;
|
||||||
|
uint32_t segments; // bit flags for the 32 segments
|
||||||
uchar sections[32]; // holds 32 * 8 = 256 bits, as flags for the sections
|
uchar sections[32]; // holds 32 * 8 = 256 bits, as flags for the sections
|
||||||
void SetSectionFlag(uchar Section, bool On) { if (On) sections[Section / 8] |= (1 << (Section % 8)); else sections[Section / 8] &= ~(1 << (Section % 8)); }
|
void SetSectionFlag(uchar Section, bool On) { if (On) sections[Section / 8] |= (1 << (Section % 8)); else sections[Section / 8] &= ~(1 << (Section % 8)); }
|
||||||
bool GetSectionFlag(uchar Section) { return sections[Section / 8] & (1 << (Section % 8)); }
|
bool GetSectionFlag(uchar Section) { return sections[Section / 8] & (1 << (Section % 8)); }
|
||||||
public:
|
public:
|
||||||
cSectionSyncer(void);
|
cSectionSyncer(bool Random = false);
|
||||||
|
///< Sets up a new section syncer.
|
||||||
|
///< Call Check() to see whether a given section needs processing. Once the section
|
||||||
|
///< has been processed, call Processed() to mark it as such. If, for any reason,
|
||||||
|
///< processing is not completed after calling Check(), nothing special needs to be
|
||||||
|
///< done. Just don't call Processed() and a later call to Check() with the same
|
||||||
|
///< SectionNumber will return true again.
|
||||||
|
///< If Random is true, sections can be processed in random order, not necessarily
|
||||||
|
///< starting with section 0.
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
void Repeat(void);
|
bool Check(uchar Version, int SectionNumber);
|
||||||
|
///< Returns true if Version is not the current version, or the given SectionNumber has not
|
||||||
|
///< been marked as processed, yet. Sections are handled in ascending order, starting at 0,
|
||||||
|
///< unless Random is true in the constructor call.
|
||||||
|
bool Processed(int SectionNumber, int LastSectionNumber, int SegmentLastSectionNumber = -1);
|
||||||
|
///< Marks the given SectionNumber as processed.
|
||||||
|
///< LastSectionNumber is used to determine whether all sections have been processed.
|
||||||
|
///< SegmentLastSectionNumber can be given to handle partially filled segments (like,
|
||||||
|
///< for instance in the EIT).
|
||||||
|
///< Returns true if all sections have been processed.
|
||||||
bool Complete(void) { return complete; }
|
bool Complete(void) { return complete; }
|
||||||
|
///< Returns true if all sections have been processed.
|
||||||
|
#if DEPRECATED_SECTIONSYNCER_SYNC_REPEAT
|
||||||
|
void Repeat(void);
|
||||||
bool Sync(uchar Version, int Number, int LastNumber);
|
bool Sync(uchar Version, int Number, int LastNumber);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class cSectionSyncerRandom : public cSectionSyncer {
|
||||||
|
///< Helper class for having an array of random section syncers.
|
||||||
|
public:
|
||||||
|
cSectionSyncerRandom(void): cSectionSyncer(true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class cFilterData : public cListObject {
|
class cFilterData : public cListObject {
|
||||||
|
10
nit.c
10
nit.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: nit.c 4.9 2019/05/31 13:25:00 kls Exp $
|
* $Id: nit.c 5.1 2021/03/16 15:10:54 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nit.h"
|
#include "nit.h"
|
||||||
@ -43,7 +43,7 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
|||||||
SI::NIT nit(Data, false);
|
SI::NIT nit(Data, false);
|
||||||
if (!nit.CheckCRCAndParse())
|
if (!nit.CheckCRCAndParse())
|
||||||
return;
|
return;
|
||||||
if (!sectionSyncer.Sync(nit.getVersionNumber(), nit.getSectionNumber(), nit.getLastSectionNumber()))
|
if (!sectionSyncer.Check(nit.getVersionNumber(), nit.getSectionNumber()))
|
||||||
return;
|
return;
|
||||||
if (DebugNit) {
|
if (DebugNit) {
|
||||||
char NetworkName[MAXNETWORKNAME] = "";
|
char NetworkName[MAXNETWORKNAME] = "";
|
||||||
@ -63,10 +63,8 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
|||||||
}
|
}
|
||||||
cStateKey StateKey;
|
cStateKey StateKey;
|
||||||
cChannels *Channels = cChannels::GetChannelsWrite(StateKey, 10);
|
cChannels *Channels = cChannels::GetChannelsWrite(StateKey, 10);
|
||||||
if (!Channels) {
|
if (!Channels)
|
||||||
sectionSyncer.Repeat(); // let's not miss any section of the NIT
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
bool ChannelsModified = false;
|
bool ChannelsModified = false;
|
||||||
SI::NIT::TransportStream ts;
|
SI::NIT::TransportStream ts;
|
||||||
for (SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it); ) {
|
for (SI::Loop::Iterator it; nit.transportStreamLoop.getNext(ts, it); ) {
|
||||||
@ -371,7 +369,7 @@ void cNitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nit.getSectionNumber() == nit.getLastSectionNumber()) {
|
if (sectionSyncer.Processed(nit.getSectionNumber(), nit.getLastSectionNumber())) {
|
||||||
dbgnit(" trigger sdtFilter for current tp %d\n", Transponder());
|
dbgnit(" trigger sdtFilter for current tp %d\n", Transponder());
|
||||||
sdtFilter->Trigger(Source());
|
sdtFilter->Trigger(Source());
|
||||||
}
|
}
|
||||||
|
6
pat.c
6
pat.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: pat.c 4.9 2020/12/18 14:51:57 kls Exp $
|
* $Id: pat.c 5.1 2021/03/16 15:10:54 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pat.h"
|
#include "pat.h"
|
||||||
@ -424,7 +424,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
|||||||
SI::PAT pat(Data, false);
|
SI::PAT pat(Data, false);
|
||||||
if (!pat.CheckCRCAndParse())
|
if (!pat.CheckCRCAndParse())
|
||||||
return;
|
return;
|
||||||
if (sectionSyncer.Sync(pat.getVersionNumber(), pat.getSectionNumber(), pat.getLastSectionNumber())) {
|
if (sectionSyncer.Check(pat.getVersionNumber(), pat.getSectionNumber())) {
|
||||||
DBGLOG("PAT %d %d -> %d %d/%d", Transponder(), patVersion, pat.getVersionNumber(), pat.getSectionNumber(), pat.getLastSectionNumber());
|
DBGLOG("PAT %d %d -> %d %d/%d", Transponder(), patVersion, pat.getVersionNumber(), pat.getSectionNumber(), pat.getLastSectionNumber());
|
||||||
if (pat.getVersionNumber() != patVersion) {
|
if (pat.getVersionNumber() != patVersion) {
|
||||||
if (pat.getLastSectionNumber() > 0)
|
if (pat.getLastSectionNumber() > 0)
|
||||||
@ -457,7 +457,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sectionSyncer.Complete()) { // all PAT sections done
|
if (sectionSyncer.Processed(pat.getSectionNumber(), pat.getLastSectionNumber())) { // all PAT sections done
|
||||||
if (pmtPidList.Count() != pmtSidList.Count())
|
if (pmtPidList.Count() != pmtSidList.Count())
|
||||||
DBGLOG(" PAT %d: shared PMT PIDs", Transponder());
|
DBGLOG(" PAT %d: shared PMT PIDs", Transponder());
|
||||||
if (pmtSidList.Count() && !activePmt)
|
if (pmtSidList.Count() && !activePmt)
|
||||||
|
10
sdt.c
10
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 4.8 2020/06/16 14:50:07 kls Exp $
|
* $Id: sdt.c 5.1 2021/03/16 15:10:54 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sdt.h"
|
#include "sdt.h"
|
||||||
@ -82,14 +82,12 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
|||||||
}
|
}
|
||||||
if (!(source && Transponder()))
|
if (!(source && Transponder()))
|
||||||
return;
|
return;
|
||||||
if (!sectionSyncer.Sync(sdt.getVersionNumber(), sdt.getSectionNumber(), sdt.getLastSectionNumber()))
|
if (!sectionSyncer.Check(sdt.getVersionNumber(), sdt.getSectionNumber()))
|
||||||
return;
|
return;
|
||||||
cStateKey StateKey;
|
cStateKey StateKey;
|
||||||
cChannels *Channels = cChannels::GetChannelsWrite(StateKey, 10);
|
cChannels *Channels = cChannels::GetChannelsWrite(StateKey, 10);
|
||||||
if (!Channels) {
|
if (!Channels)
|
||||||
sectionSyncer.Repeat(); // let's not miss any section of the SDT
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
dbgsdt("SDT: %2d %2d %2d %s %d\n", sdt.getVersionNumber(), sdt.getSectionNumber(), sdt.getLastSectionNumber(), *cSource::ToString(source), Transponder());
|
dbgsdt("SDT: %2d %2d %2d %s %d\n", sdt.getVersionNumber(), sdt.getSectionNumber(), sdt.getLastSectionNumber(), *cSource::ToString(source), Transponder());
|
||||||
bool ChannelsModified = false;
|
bool ChannelsModified = false;
|
||||||
SI::SDT::Service SiSdtService;
|
SI::SDT::Service SiSdtService;
|
||||||
@ -203,7 +201,7 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
|||||||
delete LinkChannels;
|
delete LinkChannels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sdt.getSectionNumber() == sdt.getLastSectionNumber()) {
|
if (sectionSyncer.Processed(sdt.getSectionNumber(), sdt.getLastSectionNumber())) {
|
||||||
if (Setup.UpdateChannels == 1 || Setup.UpdateChannels >= 3) {
|
if (Setup.UpdateChannels == 1 || Setup.UpdateChannels >= 3) {
|
||||||
ChannelsModified |= Channels->MarkObsoleteChannels(source, sdt.getOriginalNetworkId(), sdt.getTransportStreamId());
|
ChannelsModified |= Channels->MarkObsoleteChannels(source, sdt.getOriginalNetworkId(), sdt.getTransportStreamId());
|
||||||
if (source != Source())
|
if (source != Source())
|
||||||
|
Loading…
Reference in New Issue
Block a user