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