MythTV  master
mpegtables.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2003-2004, Daniel Thor Kristjansson
3 
4 #include "splicedescriptors.h"
5 #include "atscdescriptors.h"
6 #include "mythmiscutil.h" // for xml_indent
7 #include "mythlogging.h"
8 #include "mpegtables.h"
9 
10 const unsigned char DEFAULT_PAT_HEADER[8] =
11 {
12  0x00, // TableID::PAT
13  0xb0, // Syntax indicator
14  0x00, // Length (set separately)
15  0x00, // Transport stream ID top bits
16 
17  0x00, // Transport stream ID bottom bits
18  0xc1, // current | reserved
19  0x00, // Current Section
20  0x00, // Last Section
21 };
22 
23 const unsigned char DEFAULT_PMT_HEADER[12] =
24 {
25  0x02, // TableID::PMT
26  0xb0, // Syntax indicator
27  0x00, // Length (set separately)
28  0x00, // MPEG Program number top bits (set separately)
29 
30  0x00, // MPEG Program number bottom bits (set separately)
31  0xc1, // Version + Current/Next
32  0x00, // Current Section
33  0x00, // Last Section
34  0xff, 0xff, // PCR pid
35  0x00, 0x00, // Program Info Length
36 };
37 
38 static const uint len_for_alloc[] =
39 {
41  - 1 /* for start of field pointer */
42  - 3 /* for data before data last byte of pes length */,
43  4000,
44 };
45 
46 uint StreamID::Normalize(uint stream_id, const desc_list_t &desc,
47  const QString &sistandard)
48 {
49  if ((sistandard != "dvb") && (OpenCableVideo == stream_id))
50  return MPEG2Video;
51 
52  /* normalize DVB style signalling to ATSC style signalling to make
53  * IsAudio work with either, see A/52:2010 A4 vs A5 */
55  return AC3Audio;
56 
57  /* normalize DVB style signalling to ATSC style signalling to make
58  * IsAudio work with either */
60  return EAC3Audio;
61 
62  QString reg;
63  const unsigned char *d = MPEGDescriptor::Find(
65  if (d)
66  {
68  if (rd.IsValid())
69  reg = rd.FormatIdentifierString();
70  }
71 
72  /* normalize all three DTS frame sizes, via http://www.smpte-ra.org/mpegreg/mpegreg.html */
73  if ((reg == "DTS1") || (reg == "DTS2") || (reg == "DTS3"))
74  return DTSAudio;
75 
76  /* normalize AC-3 signalling according to A/52:2010 A4 */
77  if (reg == "AC-3")
78  return AC3Audio;
79 
80  /* normalize E-AC-3 signalling with guesswork via http://www.smpte-ra.org/mpegreg/mpegreg.html */
81  if (reg == "EAC3")
82  return EAC3Audio;
83 
84 #if 0
85  // not needed while there is no specific stream id for these
88  return stream_id;
89 #endif
90 
91  return stream_id;
92 }
93 
94 bool PSIPTable::HasCRC(void) const
95 {
96  // default is false, but gets set to true for 0x80-0xfe at the end!
97  bool has_crc = false;
98 
99  switch (TableID())
100  {
101  // MPEG
102  case TableID::PAT: // NOLINT(bugprone-branch-clone)
103  case TableID::CAT:
104  case TableID::PMT:
105  has_crc = true;
106  break;
107 // case TableID::TSDT
108 
109  // DVB manditory
110  case TableID::NIT:
111  case TableID::SDT:
112  case TableID::PF_EIT:
113  has_crc = true;
114  break;
115  case TableID::TDT:
116  has_crc = false;
117  break;
118 
119  // DVB optional
120  case TableID::NITo:
121  case TableID::SDTo:
122  case TableID::BAT:
123  case TableID::PF_EITo:
124  has_crc = true;
125  break;
126  case TableID::RST:
127  case TableID::ST:
128  has_crc = false;
129  break;
130  case TableID::TOT:
131  has_crc = true;
132  break;
133 // case TableID::RNT:
134 // case TableID::CT:
135 // case TableID::RCT:
136 // case TableID::CIT:
137 // case TableID::MPEFEC:
138  case TableID::DIT:
139  has_crc = false;
140  break;
141  case TableID::SIT: // NOLINT(bugprone-branch-clone)
142  has_crc = true;
143  break;
144 
145  // SCTE
146  case TableID::NITscte:
147  case TableID::NTT:
148  case TableID::SVCTscte:
149  case TableID::STTscte:
150  case TableID::SITscte:
151  has_crc = true;
152  break;
153  case TableID::ADET:
154  has_crc = false;
155  break;
156 
157  // ATSC
158  case TableID::MGT:
159  case TableID::TVCT:
160  case TableID::CVCT:
161  case TableID::RRT:
162  case TableID::EIT:
163  case TableID::ETT:
164  case TableID::STT:
165  case TableID::DET:
166  case TableID::DST:
167 
168  //case TableID::PIT:
169  case TableID::NRT:
170  case TableID::LTST:
171  case TableID::DCCT:
172  case TableID::DCCSCT:
173  //case TableID::SITatsc:
174  case TableID::AEIT:
175  case TableID::AETT:
176  case TableID::SVCT:
177  has_crc = true;
178  break;
179 
180  default:
181  {
182  // DVB Longterm EIT data
183  if (TableID::SC_EITbeg <= TableID() &&
185  {
186  has_crc = true;
187  }
188 
189  // FIXME Dishnet Longterm EIT data, only on PID 0x300! Forces
190  // table_id 0x80-0xfe to true, unless handled before or after!
191  if (TableID::DN_EITbego <= TableID() &&
193  {
194  has_crc = true;
195  }
196 
197  // ATSC/DVB conditional access ECM/EMM, reset to false after Dishnet
198  if (TableID::ECM0 <= TableID() &&
200  {
201  has_crc = false;
202  }
203  }
204  break;
205  }
206 
207  return has_crc;
208 }
209 
211 {
212  bool has_sn = false;
213  switch (TableID())
214  {
215  // MPEG
216  case TableID::PAT:
217  case TableID::CAT:
218  case TableID::PMT:
219  // ATSC
220  case TableID::MGT:
221  case TableID::TVCT:
222  case TableID::CVCT:
223  case TableID::RRT:
224  case TableID::EIT:
225  case TableID::ETT:
226  case TableID::STT:
227  case TableID::DET:
228  case TableID::DST:
229  has_sn = true;
230  break;
231  }
232 
233  return has_sn;
234 }
235 
236 bool PSIPTable::VerifyPSIP(bool verify_crc) const
237 {
238  if (verify_crc && (CalcCRC() != CRC()))
239  {
240  LOG(VB_SIPARSER, LOG_ERR,
241  QString("PSIPTable: Failed CRC check 0x%1 != 0x%2 "
242  "for StreamID = 0x%3")
243  .arg(CRC(),0,16).arg(CalcCRC(),0,16).arg(StreamID(),0,16));
244  return false;
245  }
246 
247  unsigned char *bufend = _fullbuffer + _allocSize;
248 
249  if ((_pesdata + 2) >= bufend)
250  return false; // can't query length
251 
252  if (psipdata() >= bufend)
253  return false; // data outside buffer
254 
255  if (TableID::PAT == TableID())
256  {
257  uint pcnt = (SectionLength() - PSIP_OFFSET - 2) >> 2;
258  bool ok = (psipdata() + (pcnt << 2) + 3 < bufend);
259  if (!ok)
260  {
261  LOG(VB_SIPARSER, LOG_ERR,
262  "PSIPTable: PAT: program list extends past end of buffer");
263  return false;
264  }
265 
266  if ((Length() == 0xfff) && (TableIDExtension() == 0xffff) &&
267  (Section() == 0xff) && (LastSection() == 0xff))
268  {
269  LOG(VB_SIPARSER, LOG_ERR, "PSIPTable: PAT: All values at maximums");
270  return false;
271  }
272 
273  return true;
274  }
275 
276  if (TableID::PMT == TableID())
277  {
278  if (psipdata() + 3 >= bufend)
279  {
280  LOG(VB_SIPARSER, LOG_ERR,
281  "PSIPTable: PMT: can't query program info length");
282  return false;
283  }
284 
285  if (psipdata() + Length() - 9 > bufend)
286  {
287  LOG(VB_SIPARSER, LOG_ERR,
288  "PSIPTable: PMT: reported length too large");
289  return false;
290  }
291 
292  uint proginfolen = ((psipdata()[2]<<8) | psipdata()[3]) & 0x0fff;
293  const unsigned char *proginfo = psipdata() + 4;
294  const unsigned char *cpos = proginfo + proginfolen;
295  if (cpos > bufend)
296  {
297  LOG(VB_SIPARSER, LOG_ERR,
298  "PSIPTable: PMT: program info extends past end of buffer");
299  return false;
300  }
301 
302  const unsigned char *pos = cpos;
303  uint i = 0;
304  for (; pos < psipdata() + Length() - 9; i++)
305  {
306  const unsigned char *ptr = pos;
307  if (pos + 4 > bufend)
308  {
309  LOG(VB_SIPARSER, LOG_ERR,
310  QString("PSIPTable: PMT: stream info %1 extends "
311  "past end of buffer").arg(i));
312  return false;
313  }
314  pos += 5 + (((ptr[3] << 8) | ptr[4]) & 0x0fff);
315  }
316  if (pos > bufend)
317  {
318  LOG(VB_SIPARSER, LOG_ERR,
319  QString("PSIPTable: PMT: last stream info %1 extends "
320  "past end of buffer").arg(i));
321  return false;
322  }
323 
324  return true;
325  }
326 
327  return true;
328 }
329 
331 {
332  (void) smallPacket; // currently always a small packet..
334  memcpy(tspacket->data() + sizeof(TSHeader) + 1/* start of field pointer */,
336  PSIPTable psip = PSIPTable::View(*tspacket);
337  psip.SetLength(TSPacket::kPayloadSize
338  - 1 /* for start of field pointer */
339  - 3 /* for data before data last byte of pes length */);
340  auto *pat = new ProgramAssociationTable(psip);
341  pat->SetTotalLength(sizeof(DEFAULT_PAT_HEADER));
342  delete tspacket;
343  return pat;
344 }
345 
347  uint tsid, uint version,
348  const vector<uint>& pnum, const vector<uint>& pid)
349 {
350  const uint count = min(pnum.size(), pid.size());
352  pat->SetVersionNumber(version);
353  pat->SetTranportStreamID(tsid);
354  pat->SetTotalLength(PSIP_OFFSET + (count * 4));
355 
356  // create PAT data
357  if ((count * 4) >= (184 - (PSIP_OFFSET+1)))
358  { // old PAT must be in single TS for this create function
359  LOG(VB_GENERAL, LOG_ERR,
360  "PAT::Create: Error, old PAT size exceeds maximum PAT size.");
361  delete pat;
362  return nullptr;
363  }
364 
365  uint offset = PSIP_OFFSET;
366  for (uint i = 0; i < count; i++)
367  {
368  // pnum
369  pat->pesdata()[offset++] = pnum[i]>>8;
370  pat->pesdata()[offset++] = pnum[i] & 0xff;
371  // pid
372  pat->pesdata()[offset++] = ((pid[i]>>8) & 0x1f) | 0xe0;
373  pat->pesdata()[offset++] = pid[i] & 0xff;
374  }
375 
376  pat->Finalize();
377 
378  return pat;
379 }
380 
382 {
383  ProgramMapTable *pmt = nullptr;
385  memcpy(tspacket->data() + sizeof(TSHeader) + 1/* start of field pointer */,
387 
388  if (smallPacket)
389  {
390  PSIPTable psip = PSIPTable::View(*tspacket);
391  psip.SetLength(len_for_alloc[0]);
392  pmt = new ProgramMapTable(psip);
393  }
394  else
395  {
396  PSIPTable psip(*tspacket);
397  psip.SetLength(len_for_alloc[1]);
398  pmt = new ProgramMapTable(psip);
399  }
400 
401  pmt->SetTotalLength(sizeof(DEFAULT_PMT_HEADER));
402  delete tspacket;
403  return pmt;
404 }
405 
407  uint programNumber, uint basepid, uint pcrpid, uint version,
408  vector<uint> pids, vector<uint> types)
409 {
410  const uint count = min(pids.size(), types.size());
411  ProgramMapTable* pmt = CreateBlank(false);
412  pmt->tsheader()->SetPID(basepid);
413 
414  pmt->RemoveAllStreams();
415  pmt->SetProgramNumber(programNumber);
416  pmt->SetPCRPID(pcrpid);
417  pmt->SetVersionNumber(version);
418 
419  for (uint i=0; i<count; i++)
420  pmt->AppendStream(pids[i], types[i]);
421  pmt->Finalize();
422 
423  return pmt;
424 }
425 
427  uint programNumber, uint basepid, uint pcrpid, uint version,
428  const desc_list_t &global_desc,
429  const vector<uint> &pids,
430  const vector<uint> &types,
431  const vector<desc_list_t> &prog_desc)
432 {
433  const uint count = min(pids.size(), types.size());
434  ProgramMapTable* pmt = CreateBlank(false);
435  pmt->tsheader()->SetPID(basepid);
436 
437  pmt->RemoveAllStreams();
438  pmt->SetProgramNumber(programNumber);
439  pmt->SetPCRPID(pcrpid);
440  pmt->SetVersionNumber(version);
441 
442  vector<unsigned char> gdesc;
443  for (size_t i=0; i<global_desc.size(); i++)
444  {
445  uint len = global_desc[i][1] + 2;
446  gdesc.insert(gdesc.end(), global_desc[i], global_desc[i] + len);
447  }
448  pmt->SetProgramInfo(gdesc.data(), gdesc.size());
449 
450  for (uint i = 0; i < count; i++)
451  {
452  vector<unsigned char> pdesc;
453  for (size_t j = 0; j < prog_desc[i].size(); j++)
454  {
455  uint len = prog_desc[i][j][1] + 2;
456  pdesc.insert(pdesc.end(),
457  prog_desc[i][j], prog_desc[i][j] + len);
458  }
459 
460  pmt->AppendStream(pids[i], types[i], pdesc.data(), pdesc.size());
461  }
462  pmt->Finalize();
463 
464  LOG(VB_SIPARSER, LOG_INFO, "Created PMT \n" + pmt->toString());
465 
466  return pmt;
467 }
468 
470 {
471  _ptrs.clear();
472  const unsigned char *cpos = psipdata() + pmt_header + ProgramInfoLength();
473  auto *pos = const_cast<unsigned char*>(cpos);
474  for (uint i = 0; pos < psipdata() + Length() - 9; i++)
475  {
476  _ptrs.push_back(pos);
477  pos += 5 + StreamInfoLength(i);
478 #if 0
479  LOG(VB_SIPARSER, LOG_DEBUG, QString("Parsing PMT(0x%1) i(%2) len(%3)")
480  .arg((uint64_t)this, 0, 16) .arg(i) .arg(StreamInfoLength(i)));
481 #endif
482  }
483  _ptrs.push_back(pos);
484 #if 0
485  LOG(VB_SIPARSER, LOG_DEBUG, QString("Parsed PMT(0x%1)\n%2")
486  .arg((uint64_t)this, 0, 16) .arg(toString()));
487 #endif
488 }
489 
491  uint pid, uint type,
492  unsigned char* streamInfo, uint infoLength)
493 {
494  if (!StreamCount())
495  _ptrs.push_back(psipdata() + pmt_header + ProgramInfoLength());
496  memset(_ptrs[StreamCount()], 0xff, 5);
497  SetStreamPID(StreamCount(), pid);
499  SetStreamProgramInfo(StreamCount(), streamInfo, infoLength);
502 }
503 
514 bool ProgramMapTable::IsVideo(uint i, const QString& sistandard) const
515 {
517  return true;
518 
521  uint stream_id = StreamID::Normalize(StreamType(i), list, sistandard);
522 
523  return StreamID::IsVideo(stream_id);
524 }
525 
536 bool ProgramMapTable::IsAudio(uint i, const QString& sistandard) const
537 {
539  return true;
540 
543  uint stream_id = StreamID::Normalize(StreamType(i), list, sistandard);
544 
545  return StreamID::IsAudio(stream_id);
546 }
547 
552 bool ProgramMapTable::IsEncrypted(const QString& sistandard) const
553 {
554  bool encrypted = IsProgramEncrypted();
555 
556  for (uint i = 0; !encrypted && i < StreamCount(); i++) {
557  /* Only check audio/video streams */
558  if (IsAudio(i,sistandard) || IsVideo(i,sistandard))
559  encrypted |= IsStreamEncrypted(i);
560  }
561 
562  return encrypted;
563 }
564 
569 {
572 
573  uint encrypted = 0;
574  QMap<uint,uint> encryption_system;
575  for (size_t i = 0; i < descs.size(); i++)
576  {
577  ConditionalAccessDescriptor cad(descs[i]);
578  if (!cad.IsValid())
579  continue;
580  encryption_system[cad.PID()] = cad.SystemID();
581  encrypted |= cad.SystemID();
582 
583 #if 0
584  LOG(VB_GENERAL, LOG_INFO, "DTVsm: " + cad.toString());
585 #endif
586  }
587 
588  return encrypted != 0;
589 }
590 
597 {
600 
601  uint encrypted = 0;
602  QMap<uint,uint> encryption_system;
603  for (size_t j = 0; j < descs.size(); j++)
604  {
605  ConditionalAccessDescriptor cad(descs[j]);
606  if (!cad.IsValid())
607  continue;
608  encryption_system[cad.PID()] = cad.SystemID();
609  encrypted |= cad.SystemID();
610 #if 0
611  LOG(VB_GENERAL, LOG_INFO, "DTVsm: " + cad.toString());
612 #endif
613  }
614 
615  return encrypted != 0;
616 }
617 
618 bool ProgramMapTable::IsStillPicture(const QString& sistandard) const
619 {
620  static constexpr unsigned char kStillPictureFlag = 0x01;
621 
622  for (uint i = 0; i < StreamCount(); i++)
623  {
624  if (IsVideo(i, sistandard))
625  {
626  return StreamInfoLength(i) > 2 &&
627  ((StreamInfo(i)[2] & kStillPictureFlag) != 0);
628  }
629  }
630  return false;
631 }
632 
633 
643  vector<uint> &pids,
644  const QString &sistandard) const
645 {
647  {
648  for (uint i=0; i < StreamCount(); i++)
649  if (type == StreamType(i))
650  pids.push_back(StreamPID(i));
651  }
652  else if (StreamID::AnyVideo == type)
653  {
654  for (uint i=0; i < StreamCount(); i++)
655  if (IsVideo(i, sistandard))
656  pids.push_back(StreamPID(i));
657  }
658  else if (StreamID::AnyAudio == type)
659  {
660  for (uint i=0; i < StreamCount(); i++)
661  if (IsAudio(i, sistandard))
662  pids.push_back(StreamPID(i));
663  }
664 
665  return pids.size();
666 }
667 
679  vector<uint> &pids,
680  vector<uint> &types,
681  const QString &sistandard,
682  bool normalize) const
683 {
684  uint pids_start = pids.size();
685 
687  {
688  for (uint i=0; i < StreamCount(); i++)
689  if (type == StreamType(i))
690  {
691  pids.push_back(StreamPID(i));
692  types.push_back(StreamType(i));
693  }
694  }
695  else if (StreamID::AnyVideo == type)
696  {
697  for (uint i=0; i < StreamCount(); i++)
698  if (IsVideo(i, sistandard))
699  {
700  pids.push_back(StreamPID(i));
701  types.push_back(StreamType(i));
702  }
703  }
704  else if (StreamID::AnyAudio == type)
705  {
706  for (uint i=0; i < StreamCount(); i++)
707  if (IsAudio(i, sistandard))
708  {
709  pids.push_back(StreamPID(i));
710  types.push_back(StreamType(i));
711  }
712  }
713 
714  if (!normalize)
715  return pids.size();
716 
717  for (size_t i = pids_start; i < pids.size(); i++)
718  {
719  int index = FindPID(pids[i]);
720  if (index >= 0)
721  {
724  types[i] = StreamID::Normalize(types[i], desc, sistandard);
725  }
726  }
727 
728  return pids.size();
729 }
730 
732 {
733  uint pid = desired_pid;
734  if (pid >= MPEG_NULL_PID)
735  pid = 0x20;
736 
737  while (FindPID(pid) != -1)
738  pid += 0x10;
739 
740  if (pid < MPEG_NULL_PID)
741  return pid;
742 
743  pid = desired_pid;
744  while (FindPID(pid) != -1)
745  pid += 1;
746 
747  if (pid < MPEG_NULL_PID)
748  return pid;
749 
750  pid = 0x20;
751  while (FindPID(pid) != -1)
752  pid += 1;
753 
754  return pid & 0x1fff;
755 }
756 
757 QString PSIPTable::toString(void) const
758 {
759  QString str;
760  str.append(QString(" PSIP tableID(0x%1) length(%2) extension(0x%3)\n")
761  .arg(TableID(), 0, 16).arg(Length())
762  .arg(TableIDExtension(), 0, 16));
763  str.append(QString(" version(%1) current(%2) "
764  "section(%3) last_section(%4)\n")
765  .arg(Version()).arg(IsCurrent())
766  .arg(Section()).arg(LastSection()));
767  if ((TableID() >= TableID::MGT) && (TableID() <= TableID::SRM))
768  {
769  str.append(QString(" atsc_protocol_version(%1)\n")
770  .arg(ATSCProtocolVersion()));
771  }
772  return str;
773 }
774 
775 QString PSIPTable::toStringXML(uint indent_level) const
776 {
777  QString indent = xml_indent(indent_level);
778  return indent + "<PSIPSection " + XMLValues(indent_level + 1) + " />";
779 }
780 
781 QString PSIPTable::XMLValues(uint indent_level) const
782 {
783  QString indent = xml_indent(indent_level);
784 
785  QString str = QString(
786  "table_id=\"0x%1\" length=\"%2\"")
787  .arg(TableID(), 2, 16, QChar('0'))
788  .arg(Length());
789 
790  if (HasSectionNumber())
791  {
792  str += QString(" section=\"%4\" last_section=\"%5\"")
793  .arg(Section()).arg(LastSection());
794  }
795 
796  if ((TableID() >= TableID::MGT) && (TableID() <= TableID::SRM))
797  {
798  str += QString("\n%1version=\"%2\" current=\"%3\" "
799  "protocol_version=\"%4\" extension=\"0x%5\"")
800  .arg(indent)
801  .arg(Version()).arg(xml_bool_to_string(IsCurrent()))
802  .arg(ATSCProtocolVersion())
803  .arg(TableIDExtension(), 0, 16);
804  }
805 
806  return str;
807 }
808 
810 {
811  QString str;
812  str.append(QString("Program Association Section\n"));
813  str.append(PSIPTable::toString());
814  str.append(QString(" tsid(%1) ").arg(TransportStreamID()));
815  str.append(QString("programCount(%1)\n").arg(ProgramCount()));
816 
817  uint cnt0 = 0, cnt1fff = 0;
818  for (uint i = 0; i < ProgramCount(); i++)
819  {
820  if (0x1fff == ProgramPID(i))
821  {
822  cnt1fff++;
823  continue;
824  }
825 
826  if (0x0 == ProgramPID(i))
827  {
828  cnt0++;
829  continue;
830  }
831 
832  str += QString(" program number %1 has PID 0x%2\n")
833  .arg(ProgramNumber(i),5)
834  .arg(ProgramPID(i),4,16,QChar('0'));
835  }
836 
837  if (cnt0 || cnt1fff)
838  {
839  str.append(QString(" also contains %1 dummy programs\n")
840  .arg(cnt0 + cnt1fff));
841  }
842 
843  return str;
844 }
845 
846 QString ProgramAssociationTable::toStringXML(uint indent_level) const
847 {
848  QString indent_0 = xml_indent(indent_level);
849  QString indent_1 = xml_indent(indent_level + 1);
850 
851  QString str = QString(
852  "%1<ProgramAssociationSection tsid=\"0x%2\" program_count=\"%3\""
853  "\n%4%5>\n")
854  .arg(indent_0)
855  .arg(TransportStreamID(),4,16,QChar('0'))
856  .arg(ProgramCount())
857  .arg(indent_1)
858  .arg(PSIPTable::XMLValues(indent_level + 1));
859 
860  for (uint i = 0; i < ProgramCount(); i++)
861  {
862  bool dummy = (0x1fff == ProgramPID(i)) || (0x0 == ProgramPID(i));
863  str += QString("%1<Program number=\"%2\" pid=\"0x%3\" %4/>\n")
864  .arg(indent_1)
865  .arg(ProgramNumber(i))
866  .arg(ProgramPID(i),4,16,QChar('0'))
867  .arg(dummy ? "comment=\"Dummy Program\" " : "");
868  }
869 
870  return str + indent_0 + "</ProgramAssociationSection>";
871 }
872 
873 QString ProgramMapTable::toString(void) const
874 {
875  QString str =
876  QString("Program Map Section"
877  "\n%1"
878  " pnum(%2) pid(0x%3) pcrpid(0x%4)\n")
879  .arg(PSIPTable::toString())
880  .arg(ProgramNumber())
881  .arg(tsheader()->PID(),0,16)
882  .arg(PCRPID(),0,16);
883 
884  vector<const unsigned char*> desc =
886  for (size_t i = 0; i < desc.size(); i++)
887  {
888  str.append(QString(" %1\n")
889  .arg(MPEGDescriptor(desc[i], 300).toString()));
890  }
891 
892  for (uint i = 0; i < StreamCount(); i++)
893  {
894  str.append(QString(" Stream #%1 pid(0x%2) type(0x%3 %4)\n")
895  .arg(i).arg(StreamPID(i), 0, 16)
896  .arg(StreamType(i), 2, 16, QChar('0'))
897  .arg(StreamTypeString(i)));
899  for (size_t j = 0; j < desc.size(); j++)
900  {
901  str.append(QString(" %1\n")
902  .arg(MPEGDescriptor(desc[j], 300).toString()));
903  }
904  }
905  return str;
906 }
907 
908 QString ProgramMapTable::toStringXML(uint indent_level) const
909 {
910  QString indent_0 = xml_indent(indent_level);
911  QString indent_1 = xml_indent(indent_level + 1);
912 
913  QString str = QString(
914  "%1<ProgramMapSection pcr_pid=\"0x%2\" program_number=\"%3\"\n"
915  "%4program_info_length=\"%5\" stream_count=\"%7\"%8>\n")
916  .arg(indent_0)
917  .arg(PCRPID(),0,16)
918  .arg(ProgramNumber())
919  .arg(indent_1)
920  .arg(ProgramInfoLength())
921  .arg(StreamCount())
922  .arg(PSIPTable::XMLValues(indent_level + 1));
923 
924  vector<const unsigned char*> gdesc =
926  for (size_t i = 0; i < gdesc.size(); i++)
927  {
928  str += MPEGDescriptor(gdesc[i], 300)
929  .toStringXML(indent_level + 1) + "\n";
930  }
931 
932  for (uint i = 0; i < StreamCount(); i++)
933  {
934  str += QString("%1<Stream pid=\"0x%2\" type=\"0x%3\" "
935  "type_desc=\"%4\" stream_info_length=\"%5\"")
936  .arg(indent_1)
937  .arg(StreamPID(i),2,16,QChar('0'))
938  .arg(StreamType(i),2,16,QChar('0'))
939  .arg(StreamTypeString(i))
940  .arg(StreamInfoLength(i));
941  vector<const unsigned char*> ldesc =
943  str += (ldesc.empty()) ? " />\n" : ">\n";
944  for (size_t j = 0; j < ldesc.size(); j++)
945  {
946  str += MPEGDescriptor(ldesc[j], 300)
947  .toStringXML(indent_level + 2) + "\n";
948  }
949  if (!ldesc.empty())
950  str += indent_1 + "</Stream>\n";
951  }
952 
953  return str + indent_0 + "</ProgramMapSection>";
954 }
955 
956 const char *StreamID::toString(uint streamID)
957 {
958  // valid for some ATSC/DVB stuff too
959  switch (streamID)
960  {
962  return "video-mpeg2";
964  return "video-mpeg1";
966  return "video-mpeg4";
967  case StreamID::H264Video:
968  return "video-h264";
969  case StreamID::H265Video:
970  return "video-h265";
972  return "video-opencable";
973 
974  // audio
975  case StreamID::AC3Audio:
976  return "audio-ac3"; // EIT, PMT
977  case StreamID::EAC3Audio:
978  return "audio-eac3"; // EIT, PMT
980  return "audio-mp2-layer[1,2,3]"; // EIT, PMT
982  return "audio-mp1-layer[1,2,3]"; // EIT, PMT
984  return "audio-aac-latm"; // EIT, PMT
986  return "audio-aac"; // EIT, PMT
987  case StreamID::DTSAudio:
988  return "audio-dts"; // EIT, PMT
989 
990  // other
991  case StreamID::PrivSec:
992  return "private-sec";
993  case StreamID::PrivData:
994  return "private-data";
995 
996  // DSMCC Object Carousel
997  case StreamID::DSMCC_A:
998  return "dsmcc-a encap";
999  case StreamID::DSMCC_B:
1000  return "dsmcc-b std data";
1001  case StreamID::DSMCC_C:
1002  return "dsmcc-c NPD data";
1003  case StreamID::DSMCC_D:
1004  return "dsmcc-d data";
1005 
1006  // Can be in any MPEG stream ATSC, DVB, or ARIB ; but defined in SCTE 35
1007  case StreamID::Splice:
1008  return "splice"; // PMT
1009 
1010  //case TableID::STUFFING: XXX: Duplicate?
1011  // return "stuffing"; // optionally in any
1012  //case TableID::CENSOR: FIXME collides with StreamID::EAC3Audio
1013  // return "censor"; // EIT, optionally in PMT
1014  case TableID::ECN:
1015  return "extended channel name";
1016  case TableID::SRVLOC:
1017  return "service location"; // required in VCT
1018  case TableID::TSS: // other channels with same stuff
1019  return "time-shifted service";
1020  case TableID::CMPNAME:
1021  return "component name"; //??? PMT
1022  }
1023  return "unknown";
1024 }
1025 
1026 QString StreamID::GetDescription(uint stream_id)
1027 {
1028  // valid for some ATSC/DVB stuff too
1029  switch (stream_id)
1030  {
1031  // video
1032  case StreamID::MPEG1Video:
1033  return "11172-2 MPEG-1 Video";
1034  case StreamID::MPEG2Video:
1035  return "13818-2 MPEG-2 Video";
1036  case StreamID::MPEG4Video:
1037  return "14492-2 MPEG-4 Video";
1038  case StreamID::H264Video:
1039  return "H.264 Video";
1040  case StreamID::H265Video:
1041  return "H.265 Video";
1043  return "OpenCable Video";
1044  case StreamID::VC1Video:
1045  return "VC-1 Video";
1046 
1047  // audio
1048  case StreamID::MPEG1Audio:
1049  return "11172-2 MPEG-1 Audio";
1050  case StreamID::MPEG2Audio:
1051  return "13818-3 MPEG-2 Audio";
1053  return "13818-7 AAC MPEG-2 Audio";
1055  return "13818-3 AAC LATM MPEG-2 Audio";
1056  case StreamID::AC3Audio:
1057  return "AC3 Audio";
1058  case StreamID::EAC3Audio:
1059  return "E-AC3 Audio";
1060  case StreamID::DTSAudio:
1061  return "DTS Audio";
1062 
1063  // DSMCC Object Carousel
1064  case StreamID::DSMCC:
1065  return "13818-1 DSM-CC";
1066  case StreamID::DSMCC_A:
1067  return "13818-6 DSM-CC Type A";
1068  case StreamID::DSMCC_B:
1069  return "13818-6 DSM-CC Type B";
1070  case StreamID::DSMCC_C:
1071  return "13818-6 DSM-CC Type C";
1072  case StreamID::DSMCC_D:
1073  return "13818-6 DSM-CC Type D";
1074  case StreamID::DSMCC_DL:
1075  return "13818-6 Download";
1076  case StreamID::MetaDataPES:
1077  return "13818-6 Metadata in PES";
1078  case StreamID::MetaDataSec:
1079  return "13818-6 Metadata in Sections";
1080  case StreamID::MetaDataDC:
1081  return "13818-6 Metadata in Data Carousel";
1082  case StreamID::MetaDataOC:
1083  return "13818-6 Metadata in Obj Carousel";
1084  case StreamID::MetaDataDL:
1085  return "13818-6 Metadata in Download";
1086 
1087  // other
1088  case StreamID::PrivSec:
1089  return "13818-1 Private Sections";
1090  case StreamID::PrivData:
1091  return "13818-3 Private Data";
1092  case StreamID::MHEG:
1093  return "13522 MHEG";
1094  case StreamID::H222_1:
1095  return "ITU H.222.1";
1096  case StreamID::MPEG2Aux:
1097  return "13818-1 Aux & ITU H.222.0";
1098  case StreamID::FlexMuxPES:
1099  return "14496-1 SL/FlexMux in PES";
1100  case StreamID::FlexMuxSec:
1101  return "14496-1 SL/FlexMux in Sections";
1102  case StreamID::MPEG2IPMP:
1103  return "13818-10 IPMP";
1104  case StreamID::MPEG2IPMP2:
1105  return "13818-10 IPMP2";
1106 
1107  case AnyMask: return QString();
1108  case AnyVideo: return "video";
1109  case AnyAudio: return "audio";
1110  }
1111 
1112  return QString();
1113 }
1114 
1116 {
1117  const desc_list_t list = MPEGDescriptor::Parse(
1118  StreamInfo(i), StreamInfoLength(i));
1119  const unsigned char *lang_desc = MPEGDescriptor::Find(
1121 
1122  if (!lang_desc)
1123  return QString();
1124 
1125  ISO639LanguageDescriptor iso_lang(lang_desc);
1126  if (!iso_lang.IsValid())
1127  return "";
1128  return iso_lang.CanonicalLanguageString();
1129 }
1130 
1132 {
1133  const desc_list_t list = MPEGDescriptor::Parse(
1134  StreamInfo(i), StreamInfoLength(i));
1135  const unsigned char *lang_desc = MPEGDescriptor::Find(
1137 
1138  if (!lang_desc)
1139  return 0;
1140 
1141  ISO639LanguageDescriptor iso_lang(lang_desc);
1142  if (!iso_lang.IsValid())
1143  return 0;
1144 
1145  // Hack for non-standard AD labelling on UK Satellite and Irish DTTV
1146  // Language string of 'nar' for narrative indicates an AD track
1147  if (iso_lang.AudioType() == 0x0 &&
1148  iso_lang.LanguageString() == "nar")
1149  return 0x03;
1150 
1151  return iso_lang.AudioType();
1152 }
1153 
1154 QString ProgramMapTable::StreamDescription(uint i, const QString& sistandard) const
1155 {
1156  desc_list_t list;
1157 
1159  uint type = StreamID::Normalize(StreamType(i), list, sistandard);
1160  QString desc = StreamID::toString(type);
1161  QString lang = GetLanguage(i);
1162 
1163  if (!lang.isEmpty())
1164  desc += QString(" (%1)").arg(lang);
1165 
1166  return desc;
1167 }
1168 
1170 {
1171  QString str =
1172  QString("Condiditional Access Section %1")
1173  .arg(PSIPTable::toString());
1174 
1175  vector<const unsigned char*> gdesc =
1177  for (size_t i = 0; i < gdesc.size(); i++)
1178  str += " " + MPEGDescriptor(gdesc[i], 300).toString() + "\n";
1179 
1180  str += "\n";
1181 
1182  return str;
1183 }
1184 
1185 QString ConditionalAccessTable::toStringXML(uint indent_level) const
1186 {
1187  QString indent_0 = xml_indent(indent_level);
1188 
1189  QString str =
1190  QString("%1<ConditionalAccessSection %3")
1191  .arg(indent_0)
1192  .arg(PSIPTable::XMLValues(indent_level + 1));
1193 
1194  vector<const unsigned char*> gdesc =
1196  str += (gdesc.empty()) ? " />\n" : ">\n";
1197  for (size_t i = 0; i < gdesc.size(); i++)
1198  {
1199  str += MPEGDescriptor(gdesc[i], 300)
1200  .toStringXML(indent_level + 1) + "\n";
1201  }
1202  if (!gdesc.empty())
1203  str += indent_0 + "</ConditionalAccessSection>\n";
1204 
1205  return str;
1206 }
1207 
1208 QString SpliceTimeView::toString(int64_t first, int64_t last) const
1209 {
1210  if (!IsTimeSpecified())
1211  return QString("splice_time(N/A)");
1212 
1213  int64_t abs_pts_time = PTSTime();
1214  if ((first > 0) && (last > 0))
1215  {
1216  int64_t elapsed = abs_pts_time - first;
1217  elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1218  QTime abs = QTime(0,0,0,0).addMSecs(elapsed/90);
1219 
1220  elapsed = abs_pts_time - last; /* rel_pts_time */
1221  elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1222  QTime rel = QTime(0,0,0,0).addMSecs(elapsed/90);
1223 
1224  return QString("splice_time(pts: %1 abs: %2, rel: +%3)")
1225  .arg(abs_pts_time)
1226  .arg(abs.toString("hh:mm:ss.zzz"))
1227  .arg(rel.toString("hh:mm:ss.zzz"));
1228  }
1229 
1230  return QString("splice_time(pts: %1)").arg(abs_pts_time);
1231 }
1232 
1234  uint indent_level, int64_t first, int64_t last) const
1235 {
1236  QString indent = xml_indent(indent_level);
1237 
1238  if (!IsTimeSpecified())
1239  return indent + "<SpliceTime />";
1240 
1241  int64_t abs_pts_time = PTSTime();
1242 
1243  QString abs_str;
1244  if (first > 0)
1245  {
1246  int64_t elapsed = abs_pts_time - first;
1247  elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1248  QTime abs = QTime(0,0,0,0).addMSecs(elapsed/90);
1249  abs_str = QString("absolute=\"%1\" ")
1250  .arg(abs.toString("hh:mm:ss.zzz"));
1251  }
1252 
1253  QString rel_str;
1254  if (last > 0)
1255  {
1256  int64_t elapsed = abs_pts_time - last; /* rel_pts_time */
1257  elapsed = (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
1258  QTime rel = QTime(0,0,0,0).addMSecs(elapsed/90);
1259  rel_str = QString("relative=\"+%1\" ")
1260  .arg(rel.toString("hh:mm:ss.zzz"));
1261  }
1262 
1263  return QString("%1<SpliceTime pts=\"%2\" %3%4/>")
1264  .arg(indent).arg(abs_pts_time).arg(abs_str).arg(rel_str);
1265 }
1266 
1269  const QString &/*codeWord*/)
1270 {
1271  // TODO
1272  return nullptr;
1273 }
1274 
1276 {
1277  _epilog = nullptr;
1278  _ptrs0.clear();
1279  _ptrs1.clear();
1280 
1281  if (TableID::SITscte != TableID())
1282  return false;
1283 
1284  if (SpliceProtocolVersion() != 0)
1285  return false;
1286 
1287  if (IsEncryptedPacket())
1288  return true; // it's "parsed" but you can't read encrypted portion
1289 
1292  {
1293  _epilog = pesdata() + 14;
1294  }
1295  else if (kSCTTimeSignal == type)
1296  {
1297  _epilog = pesdata() + 14 + TimeSignal().size();
1298  }
1299  else if (kSCTSpliceSchedule == type)
1300  {
1301  uint splice_count = pesdata()[14];
1302  const unsigned char *cur = pesdata() + 15;
1303  for (uint i = 0; i < splice_count; i++)
1304  {
1305  _ptrs0.push_back(cur);
1306  bool event_cancel = (cur[4] & 0x80) != 0;
1307  if (event_cancel)
1308  {
1309  _ptrs1.push_back(nullptr);
1310  cur += 5;
1311  continue;
1312  }
1313  bool program_slice = (cur[5] & 0x40) != 0;
1314  uint component_count = cur[6];
1315  _ptrs1.push_back(cur + (program_slice ? 10 : 7 * component_count));
1316  }
1317  if (splice_count)
1318  {
1319  bool duration = (_ptrs0.back()[5] & 0x2) != 0;
1320  _epilog = _ptrs1.back() + ((duration) ? 9 : 4);
1321  }
1322  else
1323  {
1324  _epilog = cur;
1325  }
1326  }
1327  else if (kSCTSpliceInsert == type)
1328  {
1329  _ptrs1.push_back(pesdata() + 14);
1330  bool splice_cancel = (pesdata()[18] & 0x80) != 0;
1331  if (splice_cancel)
1332  {
1333  _epilog = pesdata() + 19;
1334  }
1335  else
1336  {
1337  bool program_splice = (pesdata()[19] & 0x40) != 0;
1338  bool duration = (pesdata()[19] & 0x20) != 0;
1339  bool splice_immediate = (pesdata()[19] & 0x10) != 0;
1340  const unsigned char *cur = pesdata() + 20;
1341  if (program_splice && !splice_immediate)
1342  {
1343  cur += SpliceTimeView(cur).size();
1344  }
1345  else if (!program_splice)
1346  {
1347  uint component_count = pesdata()[20];
1348  cur = pesdata() + 21;
1349  for (uint i = 0; i < component_count; i++)
1350  {
1351  _ptrs0.push_back(cur);
1352  cur += (splice_immediate) ?
1353  1 : 1 + SpliceTimeView(cur).size();
1354  }
1355  }
1356  _ptrs1.push_back(cur);
1357  _ptrs1.push_back(cur + (duration ? 5 : 0));
1358  }
1359  }
1360  else
1361  {
1362  _epilog = nullptr;
1363  }
1364 
1365  return _epilog != nullptr;
1366 }
1367 
1369 {
1370  uint alg = EncryptionAlgorithm();
1371  switch (alg)
1372  {
1373  case kNoEncryption: return "None";
1374  case kECB: return "DES-ECB";
1375  case kCBC: return "DES-CBC";
1376  case k3DES: return "3DES";
1377  default:
1378  return QString((alg<32) ? "Reserved(%1)" : "Private(%1)").arg(alg);
1379  }
1380 }
1381 
1383 {
1385  switch (type)
1386  {
1387  case kSCTNull:
1388  return "Null";
1389  case kSCTSpliceSchedule:
1390  return "SpliceSchedule";
1391  case kSCTSpliceInsert:
1392  return "SpliceInsert";
1393  case kSCTTimeSignal:
1394  return "TimeSignal";
1396  return "BandwidthReservation";
1397  case kSCTPrivateCommand:
1398  return "Private";
1399  default:
1400  return QString("Reserved(%1)").arg(type);
1401  };
1402 }
1403 
1404 QString SpliceInformationTable::toString(int64_t first, int64_t last) const
1405 {
1406  QString str =
1407  QString("SpliceInformationSection enc_alg(%1) pts_adj(%2)")
1409  .arg(PTSAdjustment());
1410  str += IsEncryptedPacket() ? QString(" cw_index(%1)") : QString("");
1411  str += QString(" command_len(%1) command_type(%2) scte_pid(0x%3)")
1412  .arg(SpliceCommandLength())
1414  .arg(getSCTEPID(), 0, 16));
1415 
1416  if (IsEncryptedPacket())
1417  return str;
1418 
1419  switch (SpliceCommandType())
1420  {
1421  case kSCTSpliceSchedule:
1422  break;
1423  case kSCTSpliceInsert:
1424  {
1425  str += "\n " + SpliceInsert().toString(first, last);
1426  break;
1427  }
1428  case kSCTTimeSignal:
1429  break;
1430  }
1431 
1432  return str;
1433 }
1434 
1435 QString SpliceInsertView::toString(int64_t first, int64_t last) const
1436 {
1437  QString str =
1438  QString("eventid(0x%1) cancel(%2) "
1439  "out_of_network(%3) program_splice(%4) "
1440  "duration(%5) immediate(%6)\n ")
1441  .arg(SpliceEventID(),0,16)
1442  .arg(IsSpliceEventCancel()?"yes":"no")
1443  .arg(IsOutOfNetwork()?"yes":"no")
1444  .arg(IsProgramSplice()?"yes":"no")
1445  .arg(IsDuration()?"yes":"no")
1446  .arg(IsSpliceImmediate()?"yes":"no");
1447 
1448  if (IsProgramSplice() && !IsSpliceImmediate())
1449  str += SpliceTime().toString(first, last);
1450 
1451  str += QString(" unique_program_id(%1)")
1452  .arg(UniqueProgramID());
1453 
1454  str += QString(" avail(%1/%2)")
1455  .arg(AvailNum()).arg(AvailsExpected());
1456 
1457  return str;
1458 }
1459 
1461  uint indent_level, int64_t first, int64_t last) const
1462 {
1463  QString indent = xml_indent(indent_level);
1464 
1465  QString cap_time = "";
1466  if (first >= 0)
1467  {
1468  cap_time = QString("pts=\"%1\" ").arg(first);
1469  if (last >= 0)
1470  {
1471  QTime abs = QTime(0,0,0,0).addMSecs((last - first)/90);
1472  cap_time += QString("capture_time=\"%1\" ")
1473  .arg(abs.toString("hh:mm:ss.zzz"));
1474  }
1475  }
1476 
1477  QString str = QString(
1478  "%1<SpliceInformationSection %2 encryption_algorithm=\"%3\" "
1479  "pts_adjustment=\"%4\" code_word_index=\"%5\" command_type=\"%6\" scte_pid=\"0x%7\" >\n")
1480  .arg(indent)
1481  .arg(cap_time)
1483  .arg(PTSAdjustment())
1484  .arg(CodeWordIndex())
1485  .arg(SpliceCommandTypeString())
1486  .arg(getSCTEPID(), 0 ,16);
1487 
1488  if (IsEncryptedPacket())
1489  return str + indent + "</SpliceInformationSection>";
1490 
1491  switch (SpliceCommandType())
1492  {
1493  case kSCTSpliceSchedule:
1494  break;
1495  case kSCTSpliceInsert:
1496  {
1497  str += SpliceInsert().toStringXML(indent_level + 1, first, last);
1498  str += "\n";
1499  break;
1500  }
1501  case kSCTTimeSignal:
1502  break;
1503  }
1504 
1505  str += indent + "</SpliceInformationSection>";
1506  return str;
1507 }
1508 
1510  uint indent_level, int64_t first, int64_t last) const
1511 {
1512  QString indent_0 = xml_indent(indent_level);
1513  QString indent_1 = xml_indent(indent_level + 1);
1514  QString str = QString(
1515  "%1<SpliceInsert eventid=\"0x%2\" cancel=\"%3\"\n")
1516  .arg(indent_0)
1517  .arg(SpliceEventID(),0,16)
1519 
1520  str += QString(
1521  "%1out_of_network=\"%2\" program_splice=\"%3\" duration=\"%4\"\n")
1522  .arg(indent_1)
1525  .arg(xml_bool_to_string(IsDuration()));
1526 
1527  str += QString(
1528  "%1immediate=\"%2\" unique_program_id=\"%3\"\n"
1529  "%4avail_num=\"%5\" avails_expected=\"%6\">\n")
1530  .arg(indent_1)
1532  .arg(UniqueProgramID())
1533  .arg(indent_1)
1534  .arg(AvailNum())
1535  .arg(AvailsExpected());
1536 
1537  if (IsProgramSplice() && !IsSpliceImmediate())
1538  {
1539  str += SpliceTime().toStringXML(indent_level + 1, first, last) + "\n";
1540  }
1541 
1542  str += indent_0 + "</SpliceInsert>";
1543  return str;
1544 }
const unsigned char DEFAULT_PMT_HEADER[12]
Definition: mpegtables.cpp:23
uint SpliceEventID(void) const
Definition: mpegtables.h:938
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:166
uint AvailNum(void) const
Definition: mpegtables.h:976
const unsigned char * pesdata() const
Definition: pespacket.h:163
static uint Normalize(uint stream_id, const desc_list_t &desc, const QString &sistandard)
Definition: mpegtables.cpp:46
const unsigned char * psipdata(void) const
Definition: mpegtables.h:522
const TSHeader * tsheader() const
Definition: pespacket.h:89
uint Version(void) const
Definition: mpegtables.h:503
const unsigned char DEFAULT_PAT_HEADER[8]
Definition: mpegtables.cpp:10
ISO 13818-3/AMD-1 Audio using LATM syntax.
Definition: mpegtables.h:124
uint Length() const
Definition: pespacket.h:98
QString SpliceCommandTypeString(void) const
void SetLength(uint len)
Definition: pespacket.h:170
static TSPacket * CreatePayloadOnlyPacket(void)
Definition: tspacket.h:174
ProgramMapTable(const ProgramMapTable &table)
Definition: mpegtables.h:660
uint ProgramCount(void) const
Definition: mpegtables.h:600
static const PSIPTable View(const TSPacket &tspacket)
Definition: mpegtables.h:467
uint SpliceProtocolVersion(void) const
Definition: mpegtables.h:1019
QString toString(void) const override
Definition: mpegtables.h:1155
ISO 13818-1 auxiliary & ITU H.222.0.
Definition: mpegtables.h:149
uint FindUnusedPID(uint desired_pid=0x20)
Definition: mpegtables.cpp:731
ProgramAssociationTable(const ProgramAssociationTable &table)
Definition: mpegtables.h:582
QString toString() const override
unsigned char * _fullbuffer
Pointer to allocated data.
Definition: pespacket.h:218
void Parse(void) const
Definition: mpegtables.cpp:469
Meta data in PES packets.
Definition: mpegtables.h:136
uint TableIDExtension(void) const
Definition: mpegtables.h:496
QString CanonicalLanguageString(void) const
unsigned char * _pesdata
Pointer to PES data in full buffer.
Definition: pespacket.h:217
QString EncryptionAlgorithmString(void) const
bool IsEncrypted(const QString &sistandard) const
Returns true iff PMT contains CA descriptor for a vid/aud stream.
Definition: mpegtables.cpp:552
uint SectionLength(void) const
Definition: mpegtables.h:490
QString toString(void) const override
Definition: mpegtables.cpp:873
uint AvailsExpected(void) const
Definition: mpegtables.h:978
bool IsOutOfNetwork(void) const
Definition: mpegtables.h:948
uint EncryptionAlgorithm(void) const
Definition: mpegtables.h:1037
static bool IsAudio(uint type)
Returns true iff audio is MPEG1/2, AAC, AC3 or DTS audio stream.
Definition: mpegtables.h:176
void SetStreamType(uint i, uint type)
Definition: mpegtables.h:732
uint ProgramNumber(uint i) const
Definition: mpegtables.h:607
uint LastSection(void) const
Definition: mpegtables.h:515
ISO 13818-7 Audio w/ADTS syntax.
Definition: mpegtables.h:123
bool IsEncryptedPacket(void) const
Definition: mpegtables.h:1022
static const uint PSIP_OFFSET
Definition: mpegtables.h:555
bool IsStillPicture(const QString &sistandard) const
Returns true iff PMT contains a still-picture video stream.
Definition: mpegtables.cpp:618
ISO 13818-1 private tables & ITU H.222.0.
Definition: mpegtables.h:143
virtual QString toString(void) const
ISO 13818-6 type C NPT DSMCC Data.
Definition: mpegtables.h:133
const unsigned char * Descriptors(void) const
Definition: mpegtables.h:843
int getSCTEPID(void) const
Definition: mpegtables.h:1008
vector< const unsigned char * > desc_list_t
virtual QString toString(int64_t first, int64_t last) const
bool IsCurrent(void) const
Definition: mpegtables.h:509
ANSI/SCTE 35 2007.
Definition: mpegtables.h:157
uint CalcCRC(void) const
Definition: pespacket.cpp:145
uint SpliceCommandType(void) const
Definition: mpegtables.h:1090
uint PCRPID(void) const
stream that contains program clock reference.
Definition: mpegtables.h:690
Used to access header of a TSPacket.
Definition: tspacket.h:24
static QString GetDescription(uint stream_id)
ISO 14496-1 SL/FlexMux in PES packets.
Definition: mpegtables.h:151
uint Section(void) const
Definition: mpegtables.h:512
vector< unsigned char * > _ptrs
Definition: mpegtables.h:811
bool IsSpliceEventCancel(void) const
Definition: mpegtables.h:944
QString GetLanguage(uint i) const
Returns the canonical language if we find the iso639 descriptor.
static const unsigned int kPayloadSize
Definition: tspacket.h:221
static const uint pmt_header
Definition: mpegtables.h:810
uint UniqueProgramID(void) const
Definition: mpegtables.h:973
static bool IsVideo(uint type)
Returns true iff video is an MPEG1/2/3, H264 or open cable video stream.
Definition: mpegtables.h:165
Meta data in metadata_section's.
Definition: mpegtables.h:137
uint StreamInfoLength(uint i) const
Definition: mpegtables.h:708
uint StreamType(uint i) const
Definition: mpegtables.h:702
static ProgramAssociationTable * Create(uint tsid, uint version, const vector< uint > &pnum, const vector< uint > &pid)
Definition: mpegtables.cpp:346
void SetTotalLength(uint len)
Definition: pespacket.h:175
static ProgramMapTable * Create(uint programNumber, uint basepid, uint pcrpid, uint version, vector< uint > pids, vector< uint > types)
Definition: mpegtables.cpp:406
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
Definition: mpegtables.h:371
ISO 13818-1 PES private data & ITU H.222.0.
Definition: mpegtables.h:144
vector< const unsigned char * > _ptrs0
Definition: mpegtables.h:1164
uint StreamPID(uint i) const
Definition: mpegtables.h:705
bool IsProgramSplice(void) const
Definition: mpegtables.h:950
uint StreamID() const
Definition: pespacket.h:97
QString toStringXML(uint indent_level) const override
Definition: mpegtables.cpp:908
ISO 13818-6 Metadata in Download Protocol.
Definition: mpegtables.h:140
virtual QString toStringXML(uint indent_level, int64_t first, int64_t last) const
uint StreamCount(void) const
Definition: mpegtables.h:714
const unsigned char * StreamInfo(uint i) const
Definition: mpegtables.h:711
SpliceTimeView SpliceTime(void) const
Definition: mpegtables.h:958
SMPTE 421M video codec (aka VC1) in Blu-Ray.
Definition: mpegtables.h:118
ISO 11172-3.
Definition: mpegtables.h:121
static const uint16_t * d
QString toStringXML(uint indent_level) const override
Definition: mpegtables.cpp:846
static ProgramAssociationTable * CreateBlank(bool smallPacket=true)
Definition: mpegtables.cpp:330
ISO 23008-2 & ITU H.265 (aka HEVC, Ultra HD)
Definition: mpegtables.h:116
uint _allocSize
Total number of bytes we allocated.
Definition: pespacket.h:223
uint SpliceCommandLength(void) const
Definition: mpegtables.h:1067
static const uint len_for_alloc[]
Definition: mpegtables.cpp:38
uint GetAudioType(uint i) const
Returns the audio type from the iso 639 descriptor.
uint FindPIDs(uint type, vector< uint > &pids, const QString &sistandard) const
Finds all pids matching type.
Definition: mpegtables.cpp:642
uint DescriptorsLength(void) const
Definition: mpegtables.h:841
const unsigned char * _epilog
Definition: mpegtables.h:1166
ISO 14496-1 SL/FlexMux in 14496_sections.
Definition: mpegtables.h:152
static QString indent(uint level)
ISO 13818-10 Digital Restrictions Mangment.
Definition: mpegtables.h:155
uint CodeWordIndex(void) const
Definition: mpegtables.h:1063
void SetStreamProgramInfo(uint i, unsigned char *streamInfo, uint infoLength)
Definition: mpegtables.h:789
ISO 13818-3.
Definition: mpegtables.h:122
unsigned int uint
Definition: compat.h:140
A/53 Part 3:2009 6.7.1.
Definition: mpegtables.h:125
vector< const unsigned char * > _ptrs1
Definition: mpegtables.h:1165
bool IsTimeSpecified(void) const
Definition: mpegtables.h:856
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:579
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
uint TransportStreamID(void) const
Definition: mpegtables.h:598
ISO 13818-6 type D Any DSMCC Data.
Definition: mpegtables.h:134
QString toString(void) const override
void SetStreamPID(uint i, uint pid)
Definition: mpegtables.h:726
uint CRC(void) const
Definition: pespacket.h:188
const unsigned char * data(void) const
Definition: tspacket.h:152
ISO 14492-2 (aka MPEG-4)
Definition: mpegtables.h:114
bool IsDuration(void) const
Definition: mpegtables.h:952
QString StreamTypeString(uint i) const
Returns a string representation of type at stream index i.
Definition: mpegtables.h:744
QString FormatIdentifierString(void) const
ISO 13818-6 Metadata in Object Carousel.
Definition: mpegtables.h:139
uint TableID(void) const
Definition: mpegtables.h:479
ISO 14492-10 & ITU H.264 (aka MPEG-4-AVC)
Definition: mpegtables.h:115
ISO 13818-6 Download Protocol.
Definition: mpegtables.h:135
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
virtual QString toString(int64_t first, int64_t last) const
QString StreamDescription(uint i, const QString &sistandard) const
Returns a better (and more expensive) string representation of type at stream index i than StreamType...
int FindPID(uint pid) const
Locates stream index of pid.
Definition: mpegtables.h:761
static int x0
Definition: mythsocket.cpp:59
bool VerifyPSIP(bool verify_crc) const
Definition: mpegtables.cpp:236
QString toString(void) const override
Definition: mpegtables.cpp:809
static ProgramMapTable * CreateBlank(bool smallPacket=true)
Definition: mpegtables.cpp:381
QString XMLValues(uint indent_level) const
Definition: mpegtables.cpp:781
uint ProgramNumber(void) const
Definition: mpegtables.h:693
ISO 13818-1 Annex A DSM-CC & ITU H.222.0.
Definition: mpegtables.h:130
void AppendStream(uint pid, uint type, unsigned char *streamInfo=nullptr, uint infoLength=0)
Definition: mpegtables.cpp:490
ISO 13818-6 Metadata in Data Carousel.
Definition: mpegtables.h:138
uint ProgramInfoLength(void) const
Definition: mpegtables.h:696
static const char * toString(uint streamID)
Definition: mpegtables.cpp:956
bool IsSpliceImmediate(void) const
Definition: mpegtables.h:954
static SpliceInformationTable * GetDecrypted(const QString &codeWord)
Returns decrypted version of this packet.
virtual QString toString(void) const
Definition: mpegtables.cpp:757
ISO 13522 MHEG.
Definition: mpegtables.h:146
uint64_t PTSTime(void) const
Definition: mpegtables.h:860
ISO 13818-10 Digital Restrictions Mangment.
Definition: mpegtables.h:154
QString toStringXML(uint indent_level) const override
Definition: mpegtables.h:1157
uint64_t PTSAdjustment(void) const
Definition: mpegtables.h:1045
static QString xml_bool_to_string(bool val)
Definition: mythmiscutil.h:60
bool HasSectionNumber(void) const
Definition: mpegtables.cpp:210
bool IsValid(void) const
bool IsVideo(uint i, const QString &sistandard) const
Returns true iff the stream at index i is a video stream.
Definition: mpegtables.cpp:514
The all-ones PID value 0x1FFF indicates a Null TS Packet introduced to maintain a constant bit rate o...
Definition: mpegtables.h:233
QString LanguageString(void) const
uint size(void) const
Definition: mpegtables.h:875
uint ATSCProtocolVersion(void) const
Definition: mpegtables.h:519
ISO 13818-2 & ITU H.262 (aka MPEG-2)
Definition: mpegtables.h:113
SpliceInsertView SpliceInsert(void) const
Definition: mpegtables.h:1109
virtual QString toStringXML(uint indent_level) const
Returns XML representation of string the TS Reader XML format.
ISO 13818-6 type A Multi-protocol Encap.
Definition: mpegtables.h:131
A/53 Part 3:2009 6.7.3.
Definition: mpegtables.h:126
bool HasCRC(void) const override
1 bit Cyclic Redundancy Check present
Definition: mpegtables.cpp:94
virtual QString toStringXML(uint indent_level) const
Definition: mpegtables.cpp:775
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:656
static desc_list_t Parse(const unsigned char *data, uint len)
bool IsStreamEncrypted(uint pid) const
Returns true iff PMT contains CA descriptor.
Definition: mpegtables.cpp:596
const unsigned char * ProgramInfo(void) const
Definition: mpegtables.h:699
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
QString toStringXML(uint indent_level) const override
ISO 11172-2 (aka MPEG-1)
Definition: mpegtables.h:112
ISO 13818-6 type B Std DSMCC Data.
Definition: mpegtables.h:132
QString xml_indent(uint level)
bool IsAudio(uint i, const QString &sistandard) const
Returns true iff the stream at index i is an audio stream.
Definition: mpegtables.cpp:536
virtual QString toStringXML(uint indent_level, int64_t first, int64_t last) const
bool IsProgramEncrypted(void) const
Returns true iff PMT's ProgramInfo contains CA descriptor.
Definition: mpegtables.cpp:568
ITU H.222.1.
Definition: mpegtables.h:147
SpliceTimeView TimeSignal(void) const
Definition: mpegtables.h:1115
uint ProgramPID(uint i) const
Definition: mpegtables.h:610
Always MPEG-2??
Definition: mpegtables.h:117