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