MythTV  master
mpegutils.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
23 // MythTV headers
24 #include "libmythbase/exitcodes.h"
33 #include "libmythtv/bytereader.h"
34 
35 
36 // Application local headers
37 #include "mpegutils.h"
38 
39 static QHash<uint,bool> extract_pids(const QString &pidsStr, bool required)
40 {
41  QHash<uint,bool> use_pid;
42  if (pidsStr.isEmpty())
43  {
44  if (required)
45  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --pids option\n");
46  }
47  else
48  {
49  QStringList pidsList = pidsStr.split(",");
50  for (const QString &pidStr : std::as_const(pidsList))
51  {
52  bool ok = false;
53  uint tmp = pidStr.toUInt(&ok, 0);
54  if (ok && (tmp < 0x2000))
55  use_pid[tmp] = true;
56  }
57  if (required && use_pid.empty())
58  {
59  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
60  "At least one pid must be specified\n");
61  }
62  }
63  return use_pid;
64 }
65 
66 static int resync_stream(
67  const char *buffer, int curr_pos, int len, int packet_size)
68 {
69  // Search for two sync bytes 188 bytes apart,
70  int pos = curr_pos;
71  int nextpos = pos + packet_size;
72  if (nextpos >= len)
73  return -1; // not enough bytes; caller should try again
74 
75  while (buffer[pos] != SYNC_BYTE || buffer[nextpos] != SYNC_BYTE)
76  {
77  pos++;
78  nextpos++;
79  if (nextpos == len)
80  return -2; // not found
81  }
82 
83  return pos;
84 }
85 
87 {
88  if (cmdline.toString("infile").isEmpty())
89  {
90  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --infile option\n");
92  }
93  QString src = cmdline.toString("infile");
94 
95  MythMediaBuffer *srcbuffer = MythMediaBuffer::Create(src, false);
96  if (!srcbuffer)
97  {
98  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Couldn't open input URL\n");
99  return GENERIC_EXIT_NOT_OK;
100  }
101 
102  uint packet_size = cmdline.toUInt("packetsize");
103  if (packet_size == 0)
104  {
105  packet_size = 188;
106  }
107  else if (packet_size != 188 &&
108  packet_size != (188+16) &&
109  packet_size != (188+20))
110  {
111  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
112  QString("Invalid packet size %1, must be 188, 204, or 208\n")
113  .arg(packet_size));
115  }
116 
117  const int kBufSize = 2 * 1024 * 1024;
118  std::array<uint64_t,0x2000> pid_count {};
119  char *buffer = new char[kBufSize];
120  int offset = 0;
121  long long total_count = 0;
122 
123  while (true)
124  {
125  int r = srcbuffer->Read(&buffer[offset], kBufSize - offset);
126  if (r <= 0)
127  break;
128  int pos = 0;
129  int len = offset + r;
130  while (pos + 187 < len) // while we have a whole packet left
131  {
132  if (buffer[pos] != SYNC_BYTE)
133  {
134  pos = resync_stream(buffer, pos+1, len, packet_size);
135  if (pos < 0)
136  {
137  break;
138  }
139  }
140  int pid = ((buffer[pos+1]<<8) | buffer[pos+2]) & 0x1fff;
141  pid_count[pid]++;
142  pos += packet_size;
143  total_count++;
144  }
145 
146  if (len - pos > 0)
147  {
148  memcpy(buffer, buffer + pos, len - pos);
149  offset = len - pos;
150  }
151  else
152  {
153  offset = 0;
154  }
155  LOG(VB_STDIO|VB_FLUSH, logLevel,
156  QString("\r \r"
157  "Processed %1 packets")
158  .arg(total_count));
159  }
160  LOG(VB_STDIO|VB_FLUSH, logLevel, "\n");
161 
162  delete[] buffer;
163  delete srcbuffer;
164 
165  for (uint i = 0; i < 0x2000; i++)
166  {
167  if (pid_count[i])
168  {
169  LOG(VB_STDIO|VB_FLUSH, LOG_CRIT,
170  QString("PID 0x%1 -- %2\n")
171  .arg(i,4,16,QChar('0'))
172  .arg(pid_count[i],11));
173  }
174  }
175 
176  return GENERIC_EXIT_OK;
177 }
178 
180 {
181  if (cmdline.toString("infile").isEmpty())
182  {
183  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --infile option\n");
185  }
186  QString src = cmdline.toString("infile");
187 
188  if (cmdline.toString("outfile").isEmpty())
189  {
190  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --outfile option\n");
192  }
193  QString dest = cmdline.toString("outfile");
194 
195  uint packet_size = cmdline.toUInt("packetsize");
196  if (packet_size == 0)
197  {
198  packet_size = 188;
199  }
200  else if (packet_size != 188 &&
201  packet_size != (188+16) &&
202  packet_size != (188+20))
203  {
204  LOG(VB_STDIO|VB_FLUSH, LOG_ERR,
205  QString("Invalid packet size %1, must be 188, 204, or 208\n")
206  .arg(packet_size));
208  }
209 
210  QHash<uint,bool> use_pid = extract_pids(cmdline.toString("pids"), true);
211  if (use_pid.empty())
213 
214  MythMediaBuffer *srcbuffer = MythMediaBuffer::Create(src, false);
215  if (!srcbuffer)
216  {
217  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Couldn't open input URL\n");
218  return GENERIC_EXIT_NOT_OK;
219  }
220 
222  if (!destRB)
223  {
224  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Couldn't open output URL\n");
225  delete srcbuffer;
226  return GENERIC_EXIT_NOT_OK;
227  }
228 
229  const int kBufSize = 2 * 1024 * 1024;
230  char *buffer = new char[kBufSize];
231  int offset = 0;
232  long long total_count = 0;
233  long long write_count = 0;
234 
235  while (true)
236  {
237  int r = srcbuffer->Read(&buffer[offset], kBufSize - offset);
238  if (r <= 0)
239  break;
240  int pos = 0;
241  int len = offset + r;
242  while (pos + 187 < len) // while we have a whole packet left
243  {
244  if (buffer[pos] != SYNC_BYTE)
245  {
246  pos = resync_stream(buffer, pos+1, len, packet_size);
247  if (pos < 0)
248  {
249  break;
250  }
251  }
252  int pid = ((buffer[pos+1]<<8) | buffer[pos+2]) & 0x1fff;
253  if (use_pid[pid])
254  {
255  destRB->Write(buffer+pos, packet_size);
256  write_count++;
257  }
258  pos += packet_size;
259  total_count++;
260  }
261 
262  if (len - pos > 0)
263  {
264  memcpy(buffer, buffer + pos, len - pos);
265  offset = len - pos;
266  }
267  else
268  {
269  offset = 0;
270  }
271  LOG(VB_STDIO|VB_FLUSH, logLevel,
272  QString("\r \r"
273  "Processed %1 packets")
274  .arg(total_count));
275  }
276  LOG(VB_STDIO|VB_FLUSH, logLevel, "\n");
277 
278  delete[] buffer;
279  delete srcbuffer;
280  delete destRB;
281 
282  LOG(VB_STDIO|VB_FLUSH, logLevel, QString("Wrote %1 of %2 packets\n")
283  .arg(write_count).arg(total_count));
284 
285  return GENERIC_EXIT_OK;
286 }
287 
288 class PTSListener :
289  public TSPacketListener,
290  public TSPacketListenerAV
291 {
292  public:
294  {
295  m_ptsCount.fill(0);
296  m_ptsFirst.fill(-1LL);
297  m_ptsLast.fill(-1LL);
298 
299  }
300  bool ProcessTSPacket(const TSPacket &tspacket) override; // TSPacketListener
301  bool ProcessVideoTSPacket(const TSPacket &tspacket) override // TSPacketListenerAV
302  { return ProcessTSPacket(tspacket); }
303  bool ProcessAudioTSPacket(const TSPacket &tspacket) override // TSPacketListenerAV
304  { return ProcessTSPacket(tspacket); }
305  int64_t GetFirstPTS(void) const
306  {
307  int64_t pts = -1LL;
308  uint32_t pts_count = 0;
309  for (uint stream : std::as_const(m_ptsStreams))
310  {
311  if(m_ptsCount[stream] > pts_count){
312  pts = m_ptsFirst[stream];
313  pts_count = m_ptsCount[stream];
314  }
315  }
316  return pts;
317  }
318  int64_t GetLastPTS(void) const
319  {
320  int64_t pts = -1LL;
321  uint32_t pts_count = 0;
322  for (uint stream : std::as_const(m_ptsStreams))
323  {
324  if(m_ptsCount[stream] > pts_count){
325  pts = m_ptsLast[stream];
326  pts_count = m_ptsCount[stream];
327  }
328  }
329  return pts;
330  }
331  int64_t GetElapsedPTS(void) const
332  {
333  int64_t elapsed = GetLastPTS() - GetFirstPTS();
334  return (elapsed < 0) ? elapsed + 0x1000000000LL : elapsed;
335  }
336 
337  public:
338  uint32_t m_startCode {0xFFFFFFFF};
339  QMap<uint,uint> m_ptsStreams;
340  std::array<uint32_t,256> m_ptsCount {};
341  std::array<int64_t,256> m_ptsFirst {};
342  std::array<int64_t,256> m_ptsLast {};
343 };
344 
345 
347 {
348  // if packet contains start of PES packet, start
349  // looking for first byte of MPEG start code (3 bytes 0 0 1)
350  // otherwise, pick up search where we left off.
351  const bool payloadStart = tspacket.PayloadStart();
352  m_startCode = (payloadStart) ? 0xffffffff : m_startCode;
353 
354  // Scan for PES header codes; specifically picture_start
355  // sequence_start (SEQ) and group_start (GOP).
356  // 00 00 01 C0-DF: audio stream
357  // 00 00 01 E0-EF: video stream
358  // (there are others that we don't care about)
359  const uint8_t *bufptr = tspacket.data() + tspacket.AFCOffset();
360  const uint8_t *bufend = tspacket.data() + TSPacket::kSize;
361 
362  while (bufptr < bufend)
363  {
364  bufptr = ByteReader::find_start_code_truncated(bufptr, bufend, &m_startCode);
365  int bytes_left = bufend - bufptr;
367  {
368  // At this point we have seen the start code 0 0 1
369  // the next byte will be the PES packet stream id.
370  const int stream_id = m_startCode & 0x000000ff;
371  if ((stream_id < 0xc0) || (stream_id > 0xef) ||
372  (bytes_left < 10))
373  {
374  continue;
375  }
376  bool has_pts = (bufptr[3] & 0x80) != 0;
377  if (has_pts && (bytes_left > 5+5))
378  {
379  int i = 5;
380  int64_t pts =
381  (uint64_t(bufptr[i+0] & 0x0e) << 29) |
382  (uint64_t(bufptr[i+1] ) << 22) |
383  (uint64_t(bufptr[i+2] & 0xfe) << 14) |
384  (uint64_t(bufptr[i+3] ) << 7) |
385  (uint64_t(bufptr[i+4] & 0xfe) >> 1);
386  m_ptsStreams[stream_id] = stream_id;
387  m_ptsLast[stream_id] = pts;
388  if (m_ptsCount[stream_id] < 30)
389  {
390  if ((!m_ptsCount[stream_id]) ||
391  (pts < m_ptsFirst[stream_id]))
392  m_ptsFirst[stream_id] = pts;
393  }
394  m_ptsCount[stream_id]++;
395  }
396  }
397  }
398 
399  return true;
400 }
401 
403 {
404  public:
405  PrintOutput(MythMediaBuffer *out, bool use_xml) :
406  m_out(out), m_useXml(use_xml)
407  {
408  }
409 
410  void Output(const QString &msg) const
411  {
412  if (m_out)
413  {
414  QByteArray ba = msg.toUtf8();
415  m_out->Write(ba.constData(), ba.size());
416  }
417  else
418  {
419  LOG(VB_STDIO|VB_FLUSH, logLevel, msg);
420  }
421  }
422 
423  void Output(const PSIPTable *psip) const
424  {
425  if (!psip)
426  return;
427  Output(((m_useXml) ? psip->toStringXML(0) : psip->toString()) + "\n");
428  }
429 
430  protected:
432  bool m_useXml;
433 };
434 
436 {
437  public:
439  MythMediaBuffer *out, PTSListener &ptsl, bool autopts,
440  MPEGStreamData *sd, const QHash<uint,bool> &use_pid, bool use_xml) :
441  PrintOutput(out, use_xml), m_ptsl(ptsl),
442  m_autopts(autopts), m_sd(sd), m_usePid(use_pid)
443  {
444  if (m_autopts)
446  }
447 
448  void HandlePAT(const ProgramAssociationTable *pat) override // MPEGStreamListener
449  {
450  if (pat && (!m_autopts || m_usePid[PID::MPEG_PAT_PID]))
451  Output(pat);
452  if (pat && m_autopts)
453  {
454  for (uint i = 0; i < pat->ProgramCount(); i++)
455  m_sd->AddListeningPID(pat->ProgramPID(i));
456  }
457  }
458 
459  void HandleCAT(const ConditionalAccessTable *cat) override // MPEGStreamListener
460  {
461  if (cat)
462  Output(cat);
463  }
464 
465  void HandlePMT(uint /*program_num*/, const ProgramMapTable *pmt) override // MPEGStreamListener
466  {
467  if (pmt && (!m_autopts || m_usePid[pmt->tsheader()->PID()]))
468  Output(pmt);
469  if (pmt && m_autopts)
470  {
471  uint video_pid = 0;
472  uint audio_pid = 0;
473  for (uint i = 0; i < pmt->StreamCount(); i++)
474  {
475  if (pmt->IsVideo(i, "mpeg"))
476  video_pid = pmt->StreamPID(i);
477  else if (pmt->IsAudio(i, "mpeg"))
478  audio_pid = pmt->StreamPID(i);
479  }
480  if (video_pid)
481  m_sd->AddWritingPID(video_pid);
482  else if (audio_pid)
483  m_sd->AddWritingPID(audio_pid);
484  else
485  {
486  LOG(VB_STDIO|VB_FLUSH, LOG_WARNING,
487  "Couldn't find PTS stream\n");
488  }
489  }
490  }
491 
492  void HandleEncryptionStatus(uint /*program_number*/, bool /*encrypted*/) override // MPEGStreamListener
493  {
494  }
495 
496  void HandleSplice(const SpliceInformationTable *sit) override // MPEGStreamListener
497  {
498  if (sit && m_useXml)
499  {
500  Output(sit->toStringXML(
501  0, m_ptsl.GetFirstPTS(), m_ptsl.GetLastPTS()) + "\n");
502  }
503  else if (sit)
504  {
505  QTime ot = QTime(0,0,0,0).addMSecs(m_ptsl.GetElapsedPTS()/90);
506  Output(
507  ot.toString("hh:mm:ss.zzz") + " " +
508  sit->toString(m_ptsl.GetFirstPTS(),
509  m_ptsl.GetLastPTS()) + "\n");
510  }
511  }
512 
513  private:
515  bool m_autopts;
517  const QHash<uint,bool> &m_usePid;
518 };
519 
521  public ATSCMainStreamListener, public PrintOutput
522 {
523  public:
525  PrintOutput(out, use_xml) { }
526 
527  void HandleSTT(const SystemTimeTable *stt) override // ATSCMainStreamListener
528  {
529  Output(stt);
530  }
531 
532  void HandleMGT(const MasterGuideTable *mgt) override // ATSCMainStreamListener
533  {
534  Output(mgt);
535  }
536 
537  void HandleVCT(uint /*pid*/, const VirtualChannelTable *vct) override // ATSCMainStreamListener
538  {
539  Output(vct);
540  }
541 };
542 
544  public SCTEMainStreamListener, public PrintOutput
545 {
546  public:
548  PrintOutput(out, use_xml) { }
549 
550  void HandleNIT(const SCTENetworkInformationTable *nit) override // SCTEMainStreamListener
551  {
552  Output(nit);
553  }
554 
555  void HandleSTT(const SCTESystemTimeTable *stt) override // SCTEMainStreamListener
556  {
557  Output(stt);
558  }
559 
560  void HandleNTT(const NetworkTextTable *ntt) override // SCTEMainStreamListener
561  {
562  Output(ntt);
563  }
564 
565  void HandleSVCT(const ShortVirtualChannelTable *svct) override // SCTEMainStreamListener
566  {
567  Output(svct);
568  }
569 
570  void HandlePIM(const ProgramInformationMessageTable *pim) override // SCTEMainStreamListener
571  {
572  Output(pim);
573  }
574 
575  void HandlePNM(const ProgramNameMessageTable *pnm) override // SCTEMainStreamListener
576  {
577  Output(pnm);
578  }
579 
580  void HandleADET(const AggregateDataEventTable *adet) override // SCTEMainStreamListener
581  {
582  Output(adet);
583  }
584 };
585 
587  public ATSCAuxStreamListener, public PrintOutput
588 {
589  public:
591  PrintOutput(out, use_xml) { }
592 
593  void HandleTVCT( uint /*pid*/,
594  const TerrestrialVirtualChannelTable */*tvct*/) override // ATSCAuxStreamListener
595  {
596  // already handled in HandleVCT
597  }
598 
599  void HandleCVCT(uint /*pid*/,
600  const CableVirtualChannelTable */*cvct*/) override // ATSCAuxStreamListener
601  {
602  // already handled in HandleVCT
603  }
604 
605  void HandleRRT(const RatingRegionTable *rrt) override // ATSCAuxStreamListener
606  {
607  Output(rrt);
608  }
609 
610  void HandleDCCT(const DirectedChannelChangeTable *dcct) override // ATSCAuxStreamListener
611  {
612  Output(dcct);
613  }
614 
616  const DirectedChannelChangeSelectionCodeTable *dccsct) override // ATSCAuxStreamListener
617  {
618  Output(dccsct);
619  }
620 };
621 
623  public ATSCEITStreamListener, public PrintOutput
624 {
625  public:
627  PrintOutput(out, use_xml) { }
628 
629  void HandleEIT(uint pid, const EventInformationTable *eit) override // ATSCEITStreamListener
630  {
631  if (eit)
632  Output(QString("EIT PID 0x%1\n").arg(pid,0,16) + eit->toString());
633  }
634 
635  void HandleETT(uint pid, const ExtendedTextTable *ett) override // ATSCEITStreamListener
636  {
637  if (ett)
638  Output(QString("ETT PID 0x%1\n").arg(pid,0,16) + ett->toString());
639  }
640 };
641 
643  public DVBMainStreamListener, public PrintOutput
644 {
645  public:
647  PrintOutput(out, use_xml) { }
648 
649  void HandleTDT(const TimeDateTable *tdt) override // DVBMainStreamListener
650  {
651  Output(tdt);
652  }
653 
654  void HandleNIT(const NetworkInformationTable *nit) override // DVBMainStreamListener
655  {
656  Output(nit);
657  }
658 
659  void HandleSDT(uint /*tsid*/, const ServiceDescriptionTable *sdt) override // DVBMainStreamListener
660  {
661  Output(sdt);
662  }
663 
664 };
665 
667  public DVBOtherStreamListener, public PrintOutput
668 {
669  public:
671  PrintOutput(out, use_xml) { }
672 
673  void HandleNITo(const NetworkInformationTable *nit) override // DVBOtherStreamListener
674  {
675  Output(nit);
676  }
677 
678  void HandleSDTo(uint /*tsid*/, const ServiceDescriptionTable *sdt) override // DVBOtherStreamListener
679  {
680  Output(sdt);
681  }
682 
683  void HandleBAT(const BouquetAssociationTable *bat) override // DVBOtherStreamListener
684  {
685  Output(bat);
686  }
687 
688 };
689 
691  public DVBEITStreamListener, public PrintOutput
692 {
693  public:
695  PrintOutput(out, use_xml) { }
696 
697  void HandleEIT(const DVBEventInformationTable *eit) override // DVBEITStreamListener
698  {
699  Output(eit);
700  }
701 
702  void HandleEIT(const PremiereContentInformationTable *pcit) override // DVBEITStreamListener
703  {
704  Output(pcit);
705  }
706 };
707 
709 {
710  if (cmdline.toString("infile").isEmpty())
711  {
712  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --infile option\n");
714  }
715  QString src = cmdline.toString("infile");
716 
717  MythMediaBuffer *srcRB = MythMediaBuffer::Create(src, false);
718  if (!srcRB)
719  {
720  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Couldn't open input URL\n");
721  return GENERIC_EXIT_NOT_OK;
722  }
723 
724  QHash<uint,bool> use_pid = extract_pids(cmdline.toString("pids"), true);
725  if (use_pid.empty())
727 
728  QHash<uint,bool> use_pid_for_pts =
729  extract_pids(cmdline.toString("ptspids"), false);
730 
731  QString dest = cmdline.toString("outfile");
732  MythMediaBuffer *out = nullptr;
733  if (!dest.isEmpty())
734  {
735  out = MythMediaBuffer::Create(dest, true);
736  if (!out)
737  {
738  LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Couldn't open output URL\n");
739  delete srcRB;
740  return GENERIC_EXIT_NOT_OK;
741  }
742  out->WriterSetBlocking(true);
743  }
744  bool autopts = !cmdline.toBool("noautopts");
745  bool use_xml = cmdline.toBool("xml");
746 
747  auto *sd = new ScanStreamData(true);
748  for (QHash<uint,bool>::iterator it = use_pid.begin();
749  it != use_pid.end(); ++it)
750  {
751  sd->AddListeningPID(it.key());
752  }
753 
754  for (QHash<uint,bool>::iterator it = use_pid_for_pts.begin();
755  it != use_pid_for_pts.end(); ++it)
756  {
757  sd->AddWritingPID(it.key());
758  }
759 
760  auto *ptsl = new PTSListener();
761  auto *pmsl = new PrintMPEGStreamListener(out, *ptsl, autopts, sd,
762  use_pid, use_xml);
763  auto *pasl = new PrintATSCMainStreamListener(out, use_xml);
764  auto *pssl = new PrintSCTEMainStreamListener(out, use_xml);
765  auto *paasl = new PrintATSCAuxStreamListener(out, use_xml);
766  auto *paesl = new PrintATSCEITStreamListener(out, use_xml);
767  auto *pdmsl = new PrintDVBMainStreamListener(out, use_xml);
768  auto *pdosl = new PrintDVBOtherStreamListener(out, use_xml);
769  auto *pdesl = new PrintDVBEITStreamListener(out, use_xml);
770 
771  sd->AddWritingListener(ptsl);
772  sd->AddMPEGListener(pmsl);
773  sd->AddATSCMainListener(pasl);
774  sd->AddSCTEMainListener(pssl);
775  sd->AddATSCAuxListener(paasl);
776  sd->AddATSCEITListener(paesl);
777  sd->AddDVBMainListener(pdmsl);
778  sd->AddDVBOtherListener(pdosl);
779  sd->AddDVBEITListener(pdesl);
780 
781  const int kBufSize = 2 * 1024 * 1024;
782  char *buffer = new char[kBufSize];
783  int offset = 0;
784  uint64_t totalBytes = 0ULL;
785 
786  if (use_xml) {
787  /* using a random instance of a sub class of PrintOutput */
788  pmsl->Output(QString(R"(<?xml version="1.0" encoding="UTF-8" ?>)"));
789  pmsl->Output(QString("<MPEGSections>"));
790  }
791 
792  while (true)
793  {
794  int r = srcRB->Read(&buffer[offset], kBufSize - offset);
795  if (r <= 0)
796  break;
797 
798  int len = offset + r;
799 
800  offset = sd->ProcessData((const unsigned char*)buffer, len);
801 
802  totalBytes += len - offset;
803  LOG(VB_STDIO|VB_FLUSH, logLevel,
804  QString("\r \r"
805  "Processed %1 bytes")
806  .arg(totalBytes));
807  }
808 
809  if (use_xml) {
810  /* using a random instance of a sub class of PrintOutput */
811  pmsl->Output(QString("</MPEGSections>"));
812  }
813 
814  LOG(VB_STDIO|VB_FLUSH, logLevel, "\n");
815 
816  if (ptsl->GetFirstPTS() >= 0)
817  {
818  QTime ot = QTime(0,0,0,0).addMSecs(ptsl->GetElapsedPTS()/90);
819 
820  LOG(VB_STDIO|VB_FLUSH, logLevel,
821  QString("First PTS %1, Last PTS %2, elapsed %3 %4\n")
822  .arg(ptsl->GetFirstPTS()).arg(ptsl->GetLastPTS())
823  .arg(ptsl->GetElapsedPTS())
824  .arg(ot.toString("hh:mm:ss.zzz")));
825  }
826 
827  delete sd;
828  delete pmsl;
829  delete pasl;
830  delete pssl;
831  delete paasl;
832  delete paesl;
833  delete pdmsl;
834  delete pdosl;
835  delete pdesl;
836  delete ptsl;
837 
838  delete srcRB;
839  delete out;
840 
841  return GENERIC_EXIT_OK;
842 }
843 
845 {
846  utilMap["pidcounter"] = &pid_counter;
847  utilMap["pidfilter"] = &pid_filter;
848  utilMap["pidprinter"] = &pid_printer;
849 }
bytereader.h
PrintDVBOtherStreamListener::PrintDVBOtherStreamListener
PrintDVBOtherStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:670
PrintSCTEMainStreamListener::HandleSVCT
void HandleSVCT(const ShortVirtualChannelTable *svct) override
Definition: mpegutils.cpp:565
VirtualChannelTable
This table contains information about the channels transmitted on this multiplex.
Definition: atsctables.h:193
PrintMPEGStreamListener::m_usePid
const QHash< uint, bool > & m_usePid
Definition: mpegutils.cpp:517
TSHeader::PayloadStart
bool PayloadStart(void) const
Definition: tspacket.h:87
build_compdb.dest
dest
Definition: build_compdb.py:9
PrintDVBMainStreamListener::HandleNIT
void HandleNIT(const NetworkInformationTable *nit) override
Definition: mpegutils.cpp:654
PrintSCTEMainStreamListener::HandleSTT
void HandleSTT(const SCTESystemTimeTable *stt) override
Definition: mpegutils.cpp:555
PrintDVBMainStreamListener::HandleTDT
void HandleTDT(const TimeDateTable *tdt) override
Definition: mpegutils.cpp:649
DVBEventInformationTable
Definition: dvbtables.h:293
PremiereContentInformationTable
Definition: premieretables.h:10
ATSCMainStreamListener
Definition: streamlisteners.h:112
PrintOutput::PrintOutput
PrintOutput(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:405
NetworkTextTable
Definition: sctetables.h:255
DirectedChannelChangeTable
No one has had time to decode this table yet...
Definition: atsctables.h:761
TimeDateTable
This table gives the current DVB stream time.
Definition: dvbtables.h:381
PrintATSCAuxStreamListener::HandleCVCT
void HandleCVCT(uint, const CableVirtualChannelTable *) override
Definition: mpegutils.cpp:599
cmdline
MythCommFlagCommandLineParser cmdline
Definition: mythcommflag.cpp:72
PTSListener::ProcessAudioTSPacket
bool ProcessAudioTSPacket(const TSPacket &tspacket) override
Definition: mpegutils.cpp:303
RatingRegionTable
No one has had time to decode this table yet...
Definition: atsctables.h:745
PrintDVBOtherStreamListener::HandleNITo
void HandleNITo(const NetworkInformationTable *nit) override
Definition: mpegutils.cpp:673
PrintMPEGStreamListener::HandleSplice
void HandleSplice(const SpliceInformationTable *sit) override
Definition: mpegutils.cpp:496
PrintSCTEMainStreamListener::HandleNTT
void HandleNTT(const NetworkTextTable *ntt) override
Definition: mpegutils.cpp:560
logLevel
LogLevel_t logLevel
Definition: logging.cpp:85
PrintDVBOtherStreamListener::HandleBAT
void HandleBAT(const BouquetAssociationTable *bat) override
Definition: mpegutils.cpp:683
PTSListener::m_ptsFirst
std::array< int64_t, 256 > m_ptsFirst
Definition: mpegutils.cpp:341
MythMediaBuffer::WriterSetBlocking
bool WriterSetBlocking(bool Lock=true)
Calls ThreadedFileWriter::SetBlocking(bool)
Definition: mythmediabuffer.cpp:1709
hardwareprofile.devicelist.cat
def cat(file_name)
Definition: devicelist.py:95
resync_stream
static int resync_stream(const char *buffer, int curr_pos, int len, int packet_size)
Definition: mpegutils.cpp:66
ProgramMapTable
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:694
mpegutils.h
SpliceInformationTable
Definition: mpegtables.h:1029
TSPacket::AFCOffset
unsigned int AFCOffset(void) const
Definition: tspacket.h:247
PrintDVBOtherStreamListener
Definition: mpegutils.cpp:666
PrintDVBEITStreamListener::HandleEIT
void HandleEIT(const DVBEventInformationTable *eit) override
Definition: mpegutils.cpp:697
SCTESystemTimeTable
This table contains the GPS time at the time of transmission.
Definition: sctetables.h:565
MythMediaBuffer::Write
int Write(const void *Buffer, uint Count)
Writes buffer to ThreadedFileWriter::Write(const void*,uint)
Definition: mythmediabuffer.cpp:1625
PTSListener::m_ptsLast
std::array< int64_t, 256 > m_ptsLast
Definition: mpegutils.cpp:342
PrintATSCEITStreamListener::HandleEIT
void HandleEIT(uint pid, const EventInformationTable *eit) override
Definition: mpegutils.cpp:629
MythMediaBuffer
Definition: mythmediabuffer.h:50
PrintDVBMainStreamListener::HandleSDT
void HandleSDT(uint, const ServiceDescriptionTable *sdt) override
Definition: mpegutils.cpp:659
ProgramNameMessageTable
Definition: sctetables.h:642
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
PrintSCTEMainStreamListener
Definition: mpegutils.cpp:543
PTSListener::GetLastPTS
int64_t GetLastPTS(void) const
Definition: mpegutils.cpp:318
TSPacketListener
Definition: streamlisteners.h:62
streamlisteners.h
DirectedChannelChangeSelectionCodeTable
No one has had time to decode this table yet...
Definition: atsctables.h:828
ScanStreamData
Definition: scanstreamdata.h:11
GENERIC_EXIT_OK
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:11
PTSListener::PTSListener
PTSListener()
Definition: mpegutils.cpp:293
MythUtilCommandLineParser
Definition: mythutil_commandlineparser.h:8
PrintMPEGStreamListener::PrintMPEGStreamListener
PrintMPEGStreamListener(MythMediaBuffer *out, PTSListener &ptsl, bool autopts, MPEGStreamData *sd, const QHash< uint, bool > &use_pid, bool use_xml)
Definition: mpegutils.cpp:438
PrintDVBOtherStreamListener::HandleSDTo
void HandleSDTo(uint, const ServiceDescriptionTable *sdt) override
Definition: mpegutils.cpp:678
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
PTSListener
Definition: mpegutils.cpp:288
PTSListener::m_startCode
uint32_t m_startCode
Definition: mpegutils.cpp:338
PrintATSCAuxStreamListener::HandleDCCT
void HandleDCCT(const DirectedChannelChangeTable *dcct) override
Definition: mpegutils.cpp:610
PrintOutput::Output
void Output(const PSIPTable *psip) const
Definition: mpegutils.cpp:423
sctetables.h
PrintATSCAuxStreamListener::PrintATSCAuxStreamListener
PrintATSCAuxStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:590
PSIPTable
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
Definition: mpegtables.h:409
PSIPTable::toString
virtual QString toString(void) const
Definition: mpegtables.cpp:763
PrintATSCEITStreamListener
Definition: mpegutils.cpp:622
PrintMPEGStreamListener::m_sd
MPEGStreamData * m_sd
Definition: mpegutils.cpp:516
PrintOutput::m_useXml
bool m_useXml
Definition: mpegutils.cpp:432
PrintMPEGStreamListener::HandlePMT
void HandlePMT(uint, const ProgramMapTable *pmt) override
Definition: mpegutils.cpp:465
mythlogging.h
PrintATSCAuxStreamListener::HandleRRT
void HandleRRT(const RatingRegionTable *rrt) override
Definition: mpegutils.cpp:605
PrintMPEGStreamListener::HandleCAT
void HandleCAT(const ConditionalAccessTable *cat) override
Definition: mpegutils.cpp:459
PrintDVBMainStreamListener
Definition: mpegutils.cpp:642
ShortVirtualChannelTable
Definition: sctetables.h:496
MPEGStreamListener
Definition: streamlisteners.h:81
TSPacketListenerAV
Definition: streamlisteners.h:71
scanstreamdata.h
TSPacket
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:205
ATSCAuxStreamListener
Definition: streamlisteners.h:122
MPEGStreamData
Encapsulates data about MPEG stream and emits events for each table.
Definition: mpegstreamdata.h:85
ServiceDescriptionTable
This table tells the decoder on which PIDs to find A/V data.
Definition: dvbtables.h:108
PrintDVBMainStreamListener::PrintDVBMainStreamListener
PrintDVBMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:646
PrintATSCAuxStreamListener::HandleTVCT
void HandleTVCT(uint, const TerrestrialVirtualChannelTable *) override
Definition: mpegutils.cpp:593
PSIPTable::toStringXML
virtual QString toStringXML(uint indent_level) const
Definition: mpegtables.cpp:781
PrintMPEGStreamListener
Definition: mpegutils.cpp:435
dvbtables.h
ProgramInformationMessageTable
Definition: sctetables.h:622
MythCommandLineParser::toUInt
uint toUInt(const QString &key) const
Returns stored QVariant as an unsigned integer, falling to default if not provided.
Definition: mythcommandlineparser.cpp:2236
PrintATSCMainStreamListener::HandleMGT
void HandleMGT(const MasterGuideTable *mgt) override
Definition: mpegutils.cpp:532
PrintSCTEMainStreamListener::PrintSCTEMainStreamListener
PrintSCTEMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:547
PrintATSCEITStreamListener::PrintATSCEITStreamListener
PrintATSCEITStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:626
EventInformationTable
EventInformationTables contain program titles, start times, and channel information.
Definition: atsctables.h:525
PrintDVBEITStreamListener
Definition: mpegutils.cpp:690
GENERIC_EXIT_NOT_OK
@ GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:12
extract_pids
static QHash< uint, bool > extract_pids(const QString &pidsStr, bool required)
MPEG-TS processing utilities (for debugging.) Copyright (c) 2003-2004, Daniel Thor Kristjansson Copyr...
Definition: mpegutils.cpp:39
uint
unsigned int uint
Definition: compat.h:81
PTSListener::GetFirstPTS
int64_t GetFirstPTS(void) const
Definition: mpegutils.cpp:305
AggregateDataEventTable
Definition: sctetables.h:662
ProgramAssociationTable
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:617
PrintATSCEITStreamListener::HandleETT
void HandleETT(uint pid, const ExtendedTextTable *ett) override
Definition: mpegutils.cpp:635
PrintATSCMainStreamListener::HandleSTT
void HandleSTT(const SystemTimeTable *stt) override
Definition: mpegutils.cpp:527
mythmediabuffer.h
ByteReader::start_code_is_valid
bool start_code_is_valid(uint32_t start_code)
Test whether a start code found by find_start_code() is valid.
Definition: bytereader.h:54
PTSListener::ProcessTSPacket
bool ProcessTSPacket(const TSPacket &tspacket) override
Definition: mpegutils.cpp:346
PrintATSCAuxStreamListener::HandleDCCSCT
void HandleDCCSCT(const DirectedChannelChangeSelectionCodeTable *dccsct) override
Definition: mpegutils.cpp:615
MythMediaBuffer::Read
int Read(void *Buffer, int Count)
This is the public method for reading from a file, it calls the appropriate read method if the file i...
Definition: mythmediabuffer.cpp:1487
registerMPEGUtils
void registerMPEGUtils(UtilMap &utilMap)
Definition: mpegutils.cpp:844
PrintMPEGStreamListener::m_ptsl
const PTSListener & m_ptsl
Definition: mpegutils.cpp:514
MasterGuideTable
This table tells the decoder on which PIDs to find other tables, and their sizes and each table's cur...
Definition: atsctables.h:79
PrintOutput
Definition: mpegutils.cpp:402
DVBMainStreamListener
Definition: streamlisteners.h:172
BouquetAssociationTable
Tells what channels can be found on each transponder for one bouquet (a bunch of channels from one pr...
Definition: dvbtables.h:187
MPEGStreamData::AddWritingPID
virtual void AddWritingPID(uint pid, PIDPriority priority=kPIDPriorityHigh)
Definition: mpegstreamdata.h:125
PTSListener::GetElapsedPTS
int64_t GetElapsedPTS(void) const
Definition: mpegutils.cpp:331
UtilMap
QMap< QString, UtilFunc > UtilMap
Definition: mythutil.h:15
SCTEMainStreamListener
Definition: streamlisteners.h:144
MythCommandLineParser::toString
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
Definition: mythcommandlineparser.cpp:2344
PrintMPEGStreamListener::m_autopts
bool m_autopts
Definition: mpegutils.cpp:515
PTSListener::m_ptsCount
std::array< uint32_t, 256 > m_ptsCount
Definition: mpegutils.cpp:340
MythCommandLineParser::toBool
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
Definition: mythcommandlineparser.cpp:2187
pid_counter
static int pid_counter(const MythUtilCommandLineParser &cmdline)
Definition: mpegutils.cpp:86
pid_printer
static int pid_printer(const MythUtilCommandLineParser &cmdline)
Definition: mpegutils.cpp:708
TerrestrialVirtualChannelTable
This table contains information about the terrestrial channels transmitted on this multiplex.
Definition: atsctables.h:350
PrintSCTEMainStreamListener::HandlePNM
void HandlePNM(const ProgramNameMessageTable *pnm) override
Definition: mpegutils.cpp:575
ConditionalAccessTable
The CAT is used to transmit additional ConditionalAccessDescriptor instances, in addition to the ones...
Definition: mpegtables.h:857
PrintOutput::Output
void Output(const QString &msg) const
Definition: mpegutils.cpp:410
PrintSCTEMainStreamListener::HandleNIT
void HandleNIT(const SCTENetworkInformationTable *nit) override
Definition: mpegutils.cpp:550
pid_filter
static int pid_filter(const MythUtilCommandLineParser &cmdline)
Definition: mpegutils.cpp:179
PrintSCTEMainStreamListener::HandlePIM
void HandlePIM(const ProgramInformationMessageTable *pim) override
Definition: mpegutils.cpp:570
PrintOutput::m_out
MythMediaBuffer * m_out
Definition: mpegutils.cpp:431
premieretables.h
MythMediaBuffer::Create
static MythMediaBuffer * Create(const QString &Filename, bool Write, bool UseReadAhead=true, std::chrono::milliseconds Timeout=kDefaultOpenTimeout, bool StreamOnly=false)
Creates a RingBuffer instance.
Definition: mythmediabuffer.cpp:98
mpeg::chrono::pts
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:55
PrintATSCMainStreamListener
Definition: mpegutils.cpp:520
atsctables.h
CableVirtualChannelTable
This table contains information about the cable channels transmitted on this multiplex.
Definition: atsctables.h:419
DVBOtherStreamListener
Definition: streamlisteners.h:182
ATSCEITStreamListener
Definition: streamlisteners.h:135
SystemTimeTable
This table contains the GPS time at the time of transmission.
Definition: atsctables.h:684
PrintMPEGStreamListener::HandleEncryptionStatus
void HandleEncryptionStatus(uint, bool) override
Definition: mpegutils.cpp:492
MPEGStreamData::AddListeningPID
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
Definition: mpegstreamdata.h:120
PrintATSCMainStreamListener::HandleVCT
void HandleVCT(uint, const VirtualChannelTable *vct) override
Definition: mpegutils.cpp:537
ExtendedTextTable
ExtendedTextTable contain additional text not contained in EventInformationTables.
Definition: atsctables.h:626
SCTENetworkInformationTable
Definition: sctetables.h:191
PrintDVBEITStreamListener::PrintDVBEITStreamListener
PrintDVBEITStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:694
SYNC_BYTE
static constexpr uint8_t SYNC_BYTE
Definition: tspacket.h:19
PID::MPEG_PAT_PID
@ MPEG_PAT_PID
Definition: mpegtables.h:211
exitcodes.h
DVBEITStreamListener
Definition: streamlisteners.h:192
GENERIC_EXIT_INVALID_CMDLINE
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:16
PrintATSCMainStreamListener::PrintATSCMainStreamListener
PrintATSCMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:524
PrintATSCAuxStreamListener
Definition: mpegutils.cpp:586
TSHeader::data
const unsigned char * data(void) const
Definition: tspacket.h:172
PrintSCTEMainStreamListener::HandleADET
void HandleADET(const AggregateDataEventTable *adet) override
Definition: mpegutils.cpp:580
PrintDVBEITStreamListener::HandleEIT
void HandleEIT(const PremiereContentInformationTable *pcit) override
Definition: mpegutils.cpp:702
PTSListener::m_ptsStreams
QMap< uint, uint > m_ptsStreams
Definition: mpegutils.cpp:339
ByteReader::find_start_code_truncated
const MTV_PUBLIC uint8_t * find_start_code_truncated(const uint8_t *p, const uint8_t *end, uint32_t *start_code)
By preserving the start_code value between subsequent calls, the caller can detect start codes across...
Definition: bytereader.cpp:81
PrintMPEGStreamListener::HandlePAT
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: mpegutils.cpp:448
TSPacket::kSize
static constexpr unsigned int kSize
Definition: tspacket.h:259
PTSListener::ProcessVideoTSPacket
bool ProcessVideoTSPacket(const TSPacket &tspacket) override
Definition: mpegutils.cpp:301
NetworkInformationTable
This table tells the decoder on which PIDs to find other tables.
Definition: dvbtables.h:28