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