vdr  2.0.6
pat.c
Go to the documentation of this file.
1 /*
2  * pat.c: PAT section filter
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * $Id: pat.c 2.19.1.2 2014/02/19 09:31:29 kls Exp $
8  */
9 
10 #include "pat.h"
11 #include <malloc.h>
12 #include "channels.h"
13 #include "libsi/section.h"
14 #include "libsi/descriptor.h"
15 #include "vdrttxtsubshooks.h"
16 
17 #define PMT_SCAN_TIMEOUT 1000 // ms
18 
19 // --- cCaDescriptor ---------------------------------------------------------
20 
21 class cCaDescriptor : public cListObject {
22 private:
23  int caSystem;
24  int esPid;
25  int length;
27 public:
28  cCaDescriptor(int CaSystem, int CaPid, int EsPid, int Length, const uchar *Data);
29  virtual ~cCaDescriptor();
30  bool operator== (const cCaDescriptor &arg) const;
31  int CaSystem(void) { return caSystem; }
32  int EsPid(void) { return esPid; }
33  int Length(void) const { return length; }
34  const uchar *Data(void) const { return data; }
35  };
36 
37 cCaDescriptor::cCaDescriptor(int CaSystem, int CaPid, int EsPid, int Length, const uchar *Data)
38 {
40  esPid = EsPid;
41  length = Length + 6;
42  data = MALLOC(uchar, length);
44  data[1] = length - 2;
45  data[2] = (caSystem >> 8) & 0xFF;
46  data[3] = caSystem & 0xFF;
47  data[4] = ((CaPid >> 8) & 0x1F) | 0xE0;
48  data[5] = CaPid & 0xFF;
49  if (Length)
50  memcpy(&data[6], Data, Length);
51 }
52 
54 {
55  free(data);
56 }
57 
59 {
60  return esPid == arg.esPid && length == arg.length && memcmp(data, arg.data, length) == 0;
61 }
62 
63 // --- cCaDescriptors --------------------------------------------------------
64 
65 class cCaDescriptors : public cListObject {
66 private:
67  int source;
69  int serviceId;
70  int numCaIds;
71  int caIds[MAXCAIDS + 1];
73  void AddCaId(int CaId);
74 public:
75  cCaDescriptors(int Source, int Transponder, int ServiceId);
76  bool operator== (const cCaDescriptors &arg) const;
77  bool Is(int Source, int Transponder, int ServiceId);
78  bool Is(cCaDescriptors * CaDescriptors);
79  bool Empty(void) { return caDescriptors.Count() == 0; }
80  void AddCaDescriptor(SI::CaDescriptor *d, int EsPid);
81  int GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, int EsPid);
82  const int *CaIds(void) { return caIds; }
83  };
84 
85 cCaDescriptors::cCaDescriptors(int Source, int Transponder, int ServiceId)
86 {
87  source = Source;
88  transponder = Transponder;
89  serviceId = ServiceId;
90  numCaIds = 0;
91  caIds[0] = 0;
92 }
93 
95 {
97  cCaDescriptor *ca2 = arg.caDescriptors.First();
98  while (ca1 && ca2) {
99  if (!(*ca1 == *ca2))
100  return false;
101  ca1 = caDescriptors.Next(ca1);
102  ca2 = arg.caDescriptors.Next(ca2);
103  }
104  return !ca1 && !ca2;
105 }
106 
107 bool cCaDescriptors::Is(int Source, int Transponder, int ServiceId)
108 {
109  return source == Source && transponder == Transponder && serviceId == ServiceId;
110 }
111 
112 bool cCaDescriptors::Is(cCaDescriptors *CaDescriptors)
113 {
114  return Is(CaDescriptors->source, CaDescriptors->transponder, CaDescriptors->serviceId);
115 }
116 
118 {
119  if (numCaIds < MAXCAIDS) {
120  for (int i = 0; i < numCaIds; i++) {
121  if (caIds[i] == CaId)
122  return;
123  }
124  caIds[numCaIds++] = CaId;
125  caIds[numCaIds] = 0;
126  }
127 }
128 
130 {
131  cCaDescriptor *nca = new cCaDescriptor(d->getCaType(), d->getCaPid(), EsPid, d->privateData.getLength(), d->privateData.getData());
132  for (cCaDescriptor *ca = caDescriptors.First(); ca; ca = caDescriptors.Next(ca)) {
133  if (*ca == *nca) {
134  delete nca;
135  return;
136  }
137  }
138  AddCaId(nca->CaSystem());
139  caDescriptors.Add(nca);
140 //#define DEBUG_CA_DESCRIPTORS 1
141 #ifdef DEBUG_CA_DESCRIPTORS
142  char buffer[1024];
143  char *q = buffer;
144  q += sprintf(q, "CAM: %04X %5d %5d %04X %04X -", source, transponder, serviceId, d->getCaType(), EsPid);
145  for (int i = 0; i < nca->Length(); i++)
146  q += sprintf(q, " %02X", nca->Data()[i]);
147  dsyslog("%s", buffer);
148 #endif
149 }
150 
151 // EsPid is to select the "type" of CaDescriptor to be returned
152 // >0 - CaDescriptor for the particular esPid
153 // =0 - common CaDescriptor
154 // <0 - all CaDescriptors regardless of type (old default)
155 
156 int cCaDescriptors::GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
157 {
158  if (!CaSystemIds || !*CaSystemIds)
159  return 0;
160  if (BufSize > 0 && Data) {
161  int length = 0;
162  for (cCaDescriptor *d = caDescriptors.First(); d; d = caDescriptors.Next(d)) {
163  if (EsPid < 0 || d->EsPid() == EsPid) {
164  const int *caids = CaSystemIds;
165  do {
166  if (d->CaSystem() == *caids) {
167  if (length + d->Length() <= BufSize) {
168  memcpy(Data + length, d->Data(), d->Length());
169  length += d->Length();
170  }
171  else
172  return -1;
173  }
174  } while (*++caids);
175  }
176  }
177  return length;
178  }
179  return -1;
180 }
181 
182 // --- cCaDescriptorHandler --------------------------------------------------
183 
184 class cCaDescriptorHandler : public cList<cCaDescriptors> {
185 private:
187 public:
188  int AddCaDescriptors(cCaDescriptors *CaDescriptors);
189  // Returns 0 if this is an already known descriptor,
190  // 1 if it is an all new descriptor with actual contents,
191  // and 2 if an existing descriptor was changed.
192  int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid);
193  };
194 
196 {
197  cMutexLock MutexLock(&mutex);
198  for (cCaDescriptors *ca = First(); ca; ca = Next(ca)) {
199  if (ca->Is(CaDescriptors)) {
200  if (*ca == *CaDescriptors) {
201  delete CaDescriptors;
202  return 0;
203  }
204  Del(ca);
205  Add(CaDescriptors);
206  return 2;
207  }
208  }
209  Add(CaDescriptors);
210  return CaDescriptors->Empty() ? 0 : 1;
211 }
212 
213 int cCaDescriptorHandler::GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
214 {
215  cMutexLock MutexLock(&mutex);
216  for (cCaDescriptors *ca = First(); ca; ca = Next(ca)) {
217  if (ca->Is(Source, Transponder, ServiceId))
218  return ca->GetCaDescriptors(CaSystemIds, BufSize, Data, EsPid);
219  }
220  return 0;
221 }
222 
224 
225 int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
226 {
227  return CaDescriptorHandler.GetCaDescriptors(Source, Transponder, ServiceId, CaSystemIds, BufSize, Data, EsPid);
228 }
229 
230 // --- cPatFilter ------------------------------------------------------------
231 
232 //#define DEBUG_PAT_PMT
233 #ifdef DEBUG_PAT_PMT
234 #define DBGLOG(a...) { cString s = cString::sprintf(a); fprintf(stderr, "%s\n", *s); dsyslog("%s", *s); }
235 #else
236 #define DBGLOG(a...)
237 #endif
238 
240 {
241  Trigger(0);
242  Set(0x00, 0x00); // PAT
243 }
244 
246 {
247  cMutexLock MutexLock(&mutex);
248  DBGLOG("PAT filter set status %d", On);
249  cFilter::SetStatus(On);
250  Trigger();
251 }
252 
253 void cPatFilter::Trigger(int Sid)
254 {
255  cMutexLock MutexLock(&mutex);
256  patVersion = -1;
257  pmtIndex = -1;
258  numPmtEntries = 0;
259  if (Sid >= 0) {
260  sid = Sid;
261  DBGLOG("PAT filter trigger SID %d", Sid);
262  }
263 }
264 
265 bool cPatFilter::PmtVersionChanged(int PmtPid, int Sid, int Version, bool SetNewVersion)
266 {
267  int Id = MakePmtId(PmtPid, Sid);
268  for (int i = 0; i < numPmtEntries; i++) {
269  if (pmtId[i] == Id) {
270  if (pmtVersion[i] != Version) {
271  if (SetNewVersion)
272  pmtVersion[i] = Version;
273  else
274  DBGLOG("PMT %d %2d %5d %2d -> %2d", Transponder(), i, PmtPid, pmtVersion[i], Version);
275  return true;
276  }
277  break;
278  }
279  }
280  return false;
281 }
282 
284 {
285  if (pmtIndex >= 0) {
287  pmtIndex = (pmtIndex + 1) % numPmtEntries;
289  }
290 }
291 
292 void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
293 {
294  cMutexLock MutexLock(&mutex);
295  if (Pid == 0x00) {
296  if (Tid == SI::TableIdPAT) {
297  SI::PAT pat(Data, false);
298  if (!pat.CheckCRCAndParse())
299  return;
300  if (pat.getVersionNumber() != patVersion) {
301  DBGLOG("PAT %d %d -> %d", Transponder(), patVersion, pat.getVersionNumber());
302  if (pmtIndex >= 0) {
304  pmtIndex = -1;
305  }
306  numPmtEntries = 0;
307  SI::PAT::Association assoc;
308  for (SI::Loop::Iterator it; pat.associationLoop.getNext(assoc, it); ) {
309  if (!assoc.isNITPid() && numPmtEntries < MAXPMTENTRIES) {
310  DBGLOG(" PMT pid %2d %5d SID %5d", numPmtEntries, assoc.getPid(), assoc.getServiceId());
311  pmtId[numPmtEntries] = MakePmtId(assoc.getPid(), assoc.getServiceId());
313  if (sid == assoc.getServiceId()) {
315  DBGLOG("sid = %d pmtIndex = %d", sid, pmtIndex);
316  }
317  numPmtEntries++;
318  }
319  }
320  if (numPmtEntries > 0 && pmtIndex < 0)
321  pmtIndex = 0;
325  }
326  }
327  }
328  else if (Tid == SI::TableIdPMT && Source() && Transponder()) {
330  SI::PMT pmt(Data, false);
331  if (!pmt.CheckCRCAndParse())
332  return;
333  if (!PmtVersionChanged(Pid, pmt.getTableIdExtension(), pmt.getVersionNumber())) {
335  return;
336  }
337  if (!Channels.Lock(true, 10))
338  return;
339  PmtVersionChanged(Pid, pmt.getTableIdExtension(), pmt.getVersionNumber(), true);
342  if (Channel) {
343  SI::CaDescriptor *d;
344  cCaDescriptors *CaDescriptors = new cCaDescriptors(Channel->Source(), Channel->Transponder(), Channel->Sid());
345  // Scan the common loop:
347  CaDescriptors->AddCaDescriptor(d, 0);
348  delete d;
349  }
350  // Scan the stream-specific loop:
351  SI::PMT::Stream stream;
352  int Vpid = 0;
353  int Ppid = 0;
354  int Vtype = 0;
355  int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
356  int Atypes[MAXAPIDS + 1] = { 0 };
357  int Dpids[MAXDPIDS + 1] = { 0 };
358  int Dtypes[MAXDPIDS + 1] = { 0 };
359  int Spids[MAXSPIDS + 1] = { 0 };
360  uchar SubtitlingTypes[MAXSPIDS + 1] = { 0 };
361  uint16_t CompositionPageIds[MAXSPIDS + 1] = { 0 };
362  uint16_t AncillaryPageIds[MAXSPIDS + 1] = { 0 };
363  char ALangs[MAXAPIDS][MAXLANGCODE2] = { "" };
364  char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" };
365  char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" };
366  int Tpid = 0;
367  tTeletextSubtitlePage TeletextSubtitlePages[MAXTXTPAGES];
368  int NumTPages = 0;
369  int NumApids = 0;
370  int NumDpids = 0;
371  int NumSpids = 0;
372  for (SI::Loop::Iterator it; pmt.streamLoop.getNext(stream, it); ) {
373  bool ProcessCaDescriptors = false;
374  int esPid = stream.getPid();
375  switch (stream.getStreamType()) {
376  case 1: // STREAMTYPE_11172_VIDEO
377  case 2: // STREAMTYPE_13818_VIDEO
378  case 0x1B: // H.264
379  Vpid = esPid;
380  Ppid = pmt.getPCRPid();
381  Vtype = stream.getStreamType();
382  ProcessCaDescriptors = true;
383  break;
384  case 3: // STREAMTYPE_11172_AUDIO
385  case 4: // STREAMTYPE_13818_AUDIO
386  case 0x0F: // ISO/IEC 13818-7 Audio with ADTS transport syntax
387  case 0x11: // ISO/IEC 14496-3 Audio with LATM transport syntax
388  {
389  if (NumApids < MAXAPIDS) {
390  Apids[NumApids] = esPid;
391  Atypes[NumApids] = stream.getStreamType();
392  SI::Descriptor *d;
393  for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
394  switch (d->getDescriptorTag()) {
398  char *s = ALangs[NumApids];
399  int n = 0;
400  for (SI::Loop::Iterator it; ld->languageLoop.getNext(l, it); ) {
401  if (*ld->languageCode != '-') { // some use "---" to indicate "none"
402  if (n > 0)
403  *s++ = '+';
405  s += strlen(s);
406  if (n++ > 1)
407  break;
408  }
409  }
410  }
411  break;
412  default: ;
413  }
414  delete d;
415  }
416  NumApids++;
417  }
418  ProcessCaDescriptors = true;
419  }
420  break;
421  case 5: // STREAMTYPE_13818_PRIVATE
422  case 6: // STREAMTYPE_13818_PES_PRIVATE
423  //XXX case 8: // STREAMTYPE_13818_DSMCC
424  {
425  int dpid = 0;
426  int dtype = 0;
427  char lang[MAXLANGCODE1] = { 0 };
428  SI::Descriptor *d;
429  for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
430  switch (d->getDescriptorTag()) {
433  dpid = esPid;
434  dtype = d->getDescriptorTag();
435  ProcessCaDescriptors = true;
436  break;
438  if (NumSpids < MAXSPIDS) {
439  Spids[NumSpids] = esPid;
442  char *s = SLangs[NumSpids];
443  int n = 0;
444  for (SI::Loop::Iterator it; sd->subtitlingLoop.getNext(sub, it); ) {
445  if (sub.languageCode[0]) {
446  SubtitlingTypes[NumSpids] = sub.getSubtitlingType();
447  CompositionPageIds[NumSpids] = sub.getCompositionPageId();
448  AncillaryPageIds[NumSpids] = sub.getAncillaryPageId();
449  if (n > 0)
450  *s++ = '+';
452  s += strlen(s);
453  if (n++ > 1)
454  break;
455  }
456  }
457  NumSpids++;
458  }
459  break;
461  Tpid = esPid;
464  for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) {
465  bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05);
466  if ((NumTPages < MAXTXTPAGES) && ttxt.languageCode[0] && isSubtitlePage) {
467  strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1);
468  TeletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber();
469  TeletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber();
470  TeletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType();
471  NumTPages++;
472  }
473  }
474  }
475  break;
479  }
480  break;
481  default: ;
482  }
483  delete d;
484  }
485  if (dpid) {
486  if (NumDpids < MAXDPIDS) {
487  Dpids[NumDpids] = dpid;
488  Dtypes[NumDpids] = dtype;
489  strn0cpy(DLangs[NumDpids], lang, MAXLANGCODE1);
490  NumDpids++;
491  }
492  }
493  }
494  break;
495  case 0x80: // STREAMTYPE_USER_PRIVATE
496  if (Setup.StandardCompliance == STANDARD_ANSISCTE) { // DigiCipher II VIDEO (ANSI/SCTE 57)
497  Vpid = esPid;
498  Ppid = pmt.getPCRPid();
499  Vtype = 0x02; // compression based upon MPEG-2
500  ProcessCaDescriptors = true;
501  break;
502  }
503  // fall through
504  case 0x81: // STREAMTYPE_USER_PRIVATE
505  if (Setup.StandardCompliance == STANDARD_ANSISCTE) { // ATSC A/53 AUDIO (ANSI/SCTE 57)
506  char lang[MAXLANGCODE1] = { 0 };
507  SI::Descriptor *d;
508  for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
509  switch (d->getDescriptorTag()) {
513  }
514  break;
515  default: ;
516  }
517  delete d;
518  }
519  if (NumDpids < MAXDPIDS) {
520  Dpids[NumDpids] = esPid;
521  Dtypes[NumDpids] = SI::AC3DescriptorTag;
522  strn0cpy(DLangs[NumDpids], lang, MAXLANGCODE1);
523  NumDpids++;
524  }
525  ProcessCaDescriptors = true;
526  break;
527  }
528  // fall through
529  case 0x82: // STREAMTYPE_USER_PRIVATE
530  if (Setup.StandardCompliance == STANDARD_ANSISCTE) { // STANDARD SUBTITLE (ANSI/SCTE 27)
531  //TODO
532  break;
533  }
534  // fall through
535  case 0x83 ... 0xFF: // STREAMTYPE_USER_PRIVATE
536  {
537  char lang[MAXLANGCODE1] = { 0 };
538  bool IsAc3 = false;
539  SI::Descriptor *d;
540  for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
541  switch (d->getDescriptorTag()) {
544  // http://www.smpte-ra.org/mpegreg/mpegreg.html
545  switch (rd->getFormatIdentifier()) {
546  case 0x41432D33: // 'AC-3'
547  IsAc3 = true;
548  break;
549  default:
550  //printf("Format identifier: 0x%08X (pid: %d)\n", rd->getFormatIdentifier(), esPid);
551  break;
552  }
553  }
554  break;
558  }
559  break;
560  default: ;
561  }
562  delete d;
563  }
564  if (IsAc3) {
565  if (NumDpids < MAXDPIDS) {
566  Dpids[NumDpids] = esPid;
567  Dtypes[NumDpids] = SI::AC3DescriptorTag;
568  strn0cpy(DLangs[NumDpids], lang, MAXLANGCODE1);
569  NumDpids++;
570  }
571  ProcessCaDescriptors = true;
572  }
573  }
574  break;
575  default: ;//printf("PID: %5d %5d %2d %3d %3d\n", pmt.getServiceId(), stream.getPid(), stream.getStreamType(), pmt.getVersionNumber(), Channel->Number());
576  }
577  if (ProcessCaDescriptors) {
579  CaDescriptors->AddCaDescriptor(d, esPid);
580  delete d;
581  }
582  }
583  }
584  if (Setup.UpdateChannels >= 2) {
585  Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid);
586  if (NumTPages < MAXTXTPAGES) {
587  int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel);
588  if (manualPageNumber)
589  TeletextSubtitlePages[NumTPages++] = tTeletextSubtitlePage(manualPageNumber);
590  }
591  Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages);
592  Channel->SetCaIds(CaDescriptors->CaIds());
593  Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
594  }
595  Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors));
596  }
597  Channels.Unlock();
598  }
599  if (timer.TimedOut()) {
600  if (pmtIndex >= 0)
601  DBGLOG("PMT timeout %d", pmtIndex);
604  }
605 }
#define DBGLOG(a...)
Definition: pat.c:236
unsigned char uchar
Definition: tools.h:30
#define STANDARD_ANSISCTE
Definition: config.h:73
int GetPmtPid(int Index)
Definition: pat.h:29
cChannels Channels
Definition: channels.c:845
#define dsyslog(a...)
Definition: tools.h:36
int StandardCompliance
Definition: config.h:279
void Set(int Ms=0)
Definition: tools.c:689
int esPid
Definition: pat.c:24
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
Processes the data delivered to this filter.
Definition: pat.c:292
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:1945
void AddCaId(int CaId)
Definition: pat.c:117
cTimeMs timer
Definition: pat.h:22
cCaDescriptors(int Source, int Transponder, int ServiceId)
Definition: pat.c:85
StructureLoop< Association > associationLoop
Definition: section.h:39
uchar * data
Definition: pat.c:26
StructureLoop< Stream > streamLoop
Definition: section.h:71
void Add(u_short Pid, u_char Tid, u_char Mask=0xFF, bool Sticky=false)
Adds the given filter data to this filter.
Definition: filter.c:142
int getCaPid() const
Definition: descriptor.c:350
const cChannel * Channel(void)
Returns the channel of the data delivered to this filter.
Definition: filter.c:99
char * strn0cpy(char *dest, const char *src, size_t n)
Definition: tools.c:131
bool TimedOut(void)
Definition: tools.c:694
DescriptorLoop commonDescriptors
Definition: section.h:70
CharArray privateData
Definition: descriptor.h:147
#define MAXTXTPAGES
Definition: channels.h:38
cPatFilter(void)
Definition: pat.c:239
int pmtIndex
Definition: pat.h:24
DescriptorTag getDescriptorTag() const
Definition: si.c:100
int getServiceId() const
Definition: section.c:57
StructureLoop< Teletext > teletextLoop
Definition: descriptor.h:138
StructureLoop< Subtitling > subtitlingLoop
Definition: descriptor.h:331
int Count(void) const
Definition: tools.h:475
int GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
Definition: pat.c:156
void AddCaDescriptor(SI::CaDescriptor *d, int EsPid)
Definition: pat.c:129
int Transponder(void) const
Returns the transponder frequency in MHz, plus the polarization in case of sat.
Definition: channels.c:156
int pmtId[MAXPMTENTRIES]
Definition: pat.h:25
int getPid() const
Definition: section.c:65
int CaSystem(void)
Definition: pat.c:31
#define MALLOC(type, size)
Definition: tools.h:46
int getPid() const
Definition: section.c:34
#define PMT_SCAN_TIMEOUT
Definition: pat.c:17
virtual int ManualPageNumber(const cChannel *channel)
void Unlock(void)
Definition: thread.c:170
int Length(void) const
Definition: pat.c:33
void Trigger(int Sid=-1)
Definition: pat.c:253
T * Next(const T *object) const
Definition: tools.h:485
int getCaType() const
Definition: descriptor.c:346
void SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages)
Definition: channels.c:411
int Source(void) const
Definition: channels.h:163
#define MAXPMTENTRIES
Definition: pat.h:17
void Del(u_short Pid, u_char Tid, u_char Mask=0xFF)
Deletes the given filter data from this filter.
Definition: filter.c:150
int numCaIds
Definition: pat.c:70
int numPmtEntries
Definition: pat.h:27
int getTableIdExtension() const
Definition: si.c:72
int Source(void)
Returns the source of the data delivered to this filter.
Definition: filter.c:89
bool Is(int Source, int Transponder, int ServiceId)
Definition: pat.c:107
int getFormatIdentifier() const
Definition: descriptor.c:1137
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
Gets all CA descriptors for a given channel.
Definition: pat.c:225
void SwitchToNextPmtPid(void)
Definition: pat.c:283
cMutex mutex
Definition: pat.h:21
void SetCaDescriptors(int Level)
Definition: channels.c:452
static cVDRTtxtsubsHookListener * Hook(void)
cSetup Setup
Definition: config.c:373
bool Lock(bool Write, int TimeoutMs=0)
Definition: thread.c:155
StructureLoop< Language > languageLoop
Definition: descriptor.h:489
int source
Definition: pat.c:67
int MakePmtId(int PmtPid, int Sid)
Definition: pat.h:30
Definition: thread.h:63
cChannel * GetByServiceID(int Source, int Transponder, unsigned short ServiceID)
Definition: channels.c:959
int AddCaDescriptors(cCaDescriptors *CaDescriptors)
Definition: pat.c:195
#define MAXLANGCODE1
Definition: channels.h:40
void SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *CompositionPageIds, uint16_t *AncillaryPageIds)
Definition: channels.c:395
int getStreamType() const
Definition: section.c:69
#define MAXLANGCODE2
Definition: channels.h:41
bool CheckCRCAndParse()
Definition: si.c:65
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: pat.c:245
bool isNITPid() const
Definition: section.h:31
int getServiceId() const
Definition: section.c:30
int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid)
Definition: pat.c:213
virtual ~cCaDescriptor()
Definition: pat.c:53
virtual void SetStatus(bool On)
Turns this filter on or off, depending on the value of On.
Definition: filter.c:104
int patVersion
Definition: pat.h:23
#define MAXDPIDS
Definition: channels.h:35
T * First(void) const
Definition: tools.h:482
void Del(cListObject *Object, bool DeleteObject=true)
Definition: tools.c:1977
int sid
Definition: pat.h:28
cList< cCaDescriptor > caDescriptors
Definition: pat.c:72
int getVersionNumber() const
Definition: si.c:84
int caSystem
Definition: pat.c:23
bool Empty(void)
Definition: pat.c:79
unsigned char u_char
Definition: headers.h:24
int getPCRPid() const
Definition: section.c:61
int UpdateChannels
Definition: config.h:309
int caIds[MAXCAIDS+1]
Definition: pat.c:71
bool operator==(const cCaDescriptors &arg) const
Definition: pat.c:94
int serviceId
Definition: pat.c:69
DescriptorLoop streamDescriptors
Definition: section.h:63
int EsPid(void)
Definition: pat.c:32
int transponder
Definition: pat.c:68
#define MAXSPIDS
Definition: channels.h:36
int getLength() const
Definition: util.h:58
const int * CaIds(void)
Definition: pat.c:82
int Transponder(void)
Returns the transponder of the data delivered to this filter.
Definition: filter.c:94
void Set(u_short Pid, u_char Tid, u_char Mask=0xFF)
Sets the given filter data by calling Add() with Sticky = true.
Definition: filter.c:137
const uchar * Data(void) const
Definition: pat.c:34
cCaDescriptor(int CaSystem, int CaPid, int EsPid, int Length, const uchar *Data)
Definition: pat.c:37
int pmtVersion[MAXPMTENTRIES]
Definition: pat.h:26
bool PmtVersionChanged(int PmtPid, int Sid, int Version, bool SetNewVersion=false)
Definition: pat.c:265
#define MAXCAIDS
Definition: channels.h:37
void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid)
Definition: channels.c:330
int Sid(void) const
Definition: channels.h:189
bool operator==(const cCaDescriptor &arg) const
Definition: pat.c:58
int getTeletextMagazineNumber() const
Definition: descriptor.c:338
const char * I18nNormalizeLanguageCode(const char *Code)
Returns a 3 letter language code that may not be zero terminated.
Definition: i18n.c:238
const unsigned char * getData() const
Definition: util.h:51
void SetCaIds(const int *CaIds)
Definition: channels.c:431
Descriptor * getNext(Iterator &it)
Definition: si.c:112
cCaDescriptorHandler CaDescriptorHandler
Definition: pat.c:223
cMutex mutex
Definition: pat.c:186
int length
Definition: pat.c:25
#define MAXAPIDS
Definition: channels.h:34