MythTV master
mpegutils.cpp
Go to the documentation of this file.
1// -*- Mode: c++ -*-
23// MythTV headers
34
35
36// Application local headers
37#include "mpegutils.h"
38
39static 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
66static 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");
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
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:
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 {
482 m_sd->AddWritingPID(video_pid);
483 }
484 else if (audio_pid)
485 {
486 m_sd->AddWritingPID(audio_pid);
487 }
488 else
489 {
490 LOG(VB_STDIO|VB_FLUSH, LOG_WARNING,
491 "Couldn't find PTS stream\n");
492 }
493 }
494 }
495
496 void HandleEncryptionStatus(uint /*program_number*/, bool /*encrypted*/) override // MPEGStreamListener
497 {
498 }
499
500 void HandleSplice(const SpliceInformationTable *sit) override // MPEGStreamListener
501 {
502 if (sit && m_useXml)
503 {
504 Output(sit->toStringXML(
505 0, m_ptsl.GetFirstPTS(), m_ptsl.GetLastPTS()) + "\n");
506 }
507 else if (sit)
508 {
509 QTime ot = QTime(0,0,0,0).addMSecs(m_ptsl.GetElapsedPTS()/90);
510 Output(
511 ot.toString("hh:mm:ss.zzz") + " " +
512 sit->toString(m_ptsl.GetFirstPTS(),
513 m_ptsl.GetLastPTS()) + "\n");
514 }
515 }
516
517 private:
521 const QHash<uint,bool> &m_usePid;
522};
523
526{
527 public:
529 PrintOutput(out, use_xml) { }
530
531 void HandleSTT(const SystemTimeTable *stt) override // ATSCMainStreamListener
532 {
533 Output(stt);
534 }
535
536 void HandleMGT(const MasterGuideTable *mgt) override // ATSCMainStreamListener
537 {
538 Output(mgt);
539 }
540
541 void HandleVCT(uint /*pid*/, const VirtualChannelTable *vct) override // ATSCMainStreamListener
542 {
543 Output(vct);
544 }
545};
546
549{
550 public:
552 PrintOutput(out, use_xml) { }
553
554 void HandleNIT(const SCTENetworkInformationTable *nit) override // SCTEMainStreamListener
555 {
556 Output(nit);
557 }
558
559 void HandleSTT(const SCTESystemTimeTable *stt) override // SCTEMainStreamListener
560 {
561 Output(stt);
562 }
563
564 void HandleNTT(const NetworkTextTable *ntt) override // SCTEMainStreamListener
565 {
566 Output(ntt);
567 }
568
569 void HandleSVCT(const ShortVirtualChannelTable *svct) override // SCTEMainStreamListener
570 {
571 Output(svct);
572 }
573
574 void HandlePIM(const ProgramInformationMessageTable *pim) override // SCTEMainStreamListener
575 {
576 Output(pim);
577 }
578
579 void HandlePNM(const ProgramNameMessageTable *pnm) override // SCTEMainStreamListener
580 {
581 Output(pnm);
582 }
583
584 void HandleADET(const AggregateDataEventTable *adet) override // SCTEMainStreamListener
585 {
586 Output(adet);
587 }
588};
589
592{
593 public:
595 PrintOutput(out, use_xml) { }
596
597 void HandleTVCT( uint /*pid*/,
598 const TerrestrialVirtualChannelTable */*tvct*/) override // ATSCAuxStreamListener
599 {
600 // already handled in HandleVCT
601 }
602
603 void HandleCVCT(uint /*pid*/,
604 const CableVirtualChannelTable */*cvct*/) override // ATSCAuxStreamListener
605 {
606 // already handled in HandleVCT
607 }
608
609 void HandleRRT(const RatingRegionTable *rrt) override // ATSCAuxStreamListener
610 {
611 Output(rrt);
612 }
613
614 void HandleDCCT(const DirectedChannelChangeTable *dcct) override // ATSCAuxStreamListener
615 {
616 Output(dcct);
617 }
618
620 const DirectedChannelChangeSelectionCodeTable *dccsct) override // ATSCAuxStreamListener
621 {
622 Output(dccsct);
623 }
624};
625
628{
629 public:
631 PrintOutput(out, use_xml) { }
632
633 void HandleEIT(uint pid, const EventInformationTable *eit) override // ATSCEITStreamListener
634 {
635 if (eit)
636 Output(QString("EIT PID 0x%1\n").arg(pid,0,16) + eit->toString());
637 }
638
639 void HandleETT(uint pid, const ExtendedTextTable *ett) override // ATSCEITStreamListener
640 {
641 if (ett)
642 Output(QString("ETT PID 0x%1\n").arg(pid,0,16) + ett->toString());
643 }
644};
645
648{
649 public:
651 PrintOutput(out, use_xml) { }
652
653 void HandleTDT(const TimeDateTable *tdt) override // DVBMainStreamListener
654 {
655 Output(tdt);
656 }
657
658 void HandleNIT(const NetworkInformationTable *nit) override // DVBMainStreamListener
659 {
660 Output(nit);
661 }
662
663 void HandleSDT(uint /*tsid*/, const ServiceDescriptionTable *sdt) override // DVBMainStreamListener
664 {
665 Output(sdt);
666 }
667
668};
669
672{
673 public:
675 PrintOutput(out, use_xml) { }
676
677 void HandleNITo(const NetworkInformationTable *nit) override // DVBOtherStreamListener
678 {
679 Output(nit);
680 }
681
682 void HandleSDTo(uint /*tsid*/, const ServiceDescriptionTable *sdt) override // DVBOtherStreamListener
683 {
684 Output(sdt);
685 }
686
687 void HandleBAT(const BouquetAssociationTable *bat) override // DVBOtherStreamListener
688 {
689 Output(bat);
690 }
691
692};
693
695 public DVBEITStreamListener, public PrintOutput
696{
697 public:
699 PrintOutput(out, use_xml) { }
700
701 void HandleEIT(const DVBEventInformationTable *eit) override // DVBEITStreamListener
702 {
703 Output(eit);
704 }
705
706 void HandleEIT(const PremiereContentInformationTable *pcit) override // DVBEITStreamListener
707 {
708 Output(pcit);
709 }
710};
711
713{
714 if (cmdline.toString("infile").isEmpty())
715 {
716 LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --infile option\n");
718 }
719 QString src = cmdline.toString("infile");
720
721 MythMediaBuffer *srcRB = MythMediaBuffer::Create(src, false);
722 if (!srcRB)
723 {
724 LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Couldn't open input URL\n");
725 return GENERIC_EXIT_NOT_OK;
726 }
727
728 QHash<uint,bool> use_pid = extract_pids(cmdline.toString("pids"), true);
729 if (use_pid.empty())
731
732 QHash<uint,bool> use_pid_for_pts =
733 extract_pids(cmdline.toString("ptspids"), false);
734
735 QString dest = cmdline.toString("outfile");
736 MythMediaBuffer *out = nullptr;
737 if (!dest.isEmpty())
738 {
739 out = MythMediaBuffer::Create(dest, true);
740 if (!out)
741 {
742 LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Couldn't open output URL\n");
743 delete srcRB;
744 return GENERIC_EXIT_NOT_OK;
745 }
746 out->WriterSetBlocking(true);
747 }
748 bool autopts = !cmdline.toBool("noautopts");
749 bool use_xml = cmdline.toBool("xml");
750
751 auto *sd = new ScanStreamData(true);
752 for (QHash<uint,bool>::iterator it = use_pid.begin();
753 it != use_pid.end(); ++it)
754 {
755 sd->AddListeningPID(it.key());
756 }
757
758 for (QHash<uint,bool>::iterator it = use_pid_for_pts.begin();
759 it != use_pid_for_pts.end(); ++it)
760 {
761 sd->AddWritingPID(it.key());
762 }
763
764 auto *ptsl = new PTSListener();
765 auto *pmsl = new PrintMPEGStreamListener(out, *ptsl, autopts, sd,
766 use_pid, use_xml);
767 auto *pasl = new PrintATSCMainStreamListener(out, use_xml);
768 auto *pssl = new PrintSCTEMainStreamListener(out, use_xml);
769 auto *paasl = new PrintATSCAuxStreamListener(out, use_xml);
770 auto *paesl = new PrintATSCEITStreamListener(out, use_xml);
771 auto *pdmsl = new PrintDVBMainStreamListener(out, use_xml);
772 auto *pdosl = new PrintDVBOtherStreamListener(out, use_xml);
773 auto *pdesl = new PrintDVBEITStreamListener(out, use_xml);
774
775 sd->AddWritingListener(ptsl);
776 sd->AddMPEGListener(pmsl);
777 sd->AddATSCMainListener(pasl);
778 sd->AddSCTEMainListener(pssl);
779 sd->AddATSCAuxListener(paasl);
780 sd->AddATSCEITListener(paesl);
781 sd->AddDVBMainListener(pdmsl);
782 sd->AddDVBOtherListener(pdosl);
783 sd->AddDVBEITListener(pdesl);
784
785 const int kBufSize = 2 * 1024 * 1024;
786 char *buffer = new char[kBufSize];
787 int offset = 0;
788 uint64_t totalBytes = 0ULL;
789
790 if (use_xml) {
791 /* using a random instance of a sub class of PrintOutput */
792 pmsl->Output(QString(R"(<?xml version="1.0" encoding="UTF-8" ?>)"));
793 pmsl->Output(QString("<MPEGSections>"));
794 }
795
796 while (true)
797 {
798 int r = srcRB->Read(&buffer[offset], kBufSize - offset);
799 if (r <= 0)
800 break;
801
802 int len = offset + r;
803
804 offset = sd->ProcessData((const unsigned char*)buffer, len);
805
806 totalBytes += len - offset;
807 LOG(VB_STDIO|VB_FLUSH, logLevel,
808 QString("\r \r"
809 "Processed %1 bytes")
810 .arg(totalBytes));
811 }
812
813 if (use_xml) {
814 /* using a random instance of a sub class of PrintOutput */
815 pmsl->Output(QString("</MPEGSections>"));
816 }
817
818 LOG(VB_STDIO|VB_FLUSH, logLevel, "\n");
819
820 if (ptsl->GetFirstPTS() >= 0)
821 {
822 QTime ot = QTime(0,0,0,0).addMSecs(ptsl->GetElapsedPTS()/90);
823
824 LOG(VB_STDIO|VB_FLUSH, logLevel,
825 QString("First PTS %1, Last PTS %2, elapsed %3 %4\n")
826 .arg(ptsl->GetFirstPTS()).arg(ptsl->GetLastPTS())
827 .arg(ptsl->GetElapsedPTS())
828 .arg(ot.toString("hh:mm:ss.zzz")));
829 }
830
831 delete sd;
832 delete pmsl;
833 delete pasl;
834 delete pssl;
835 delete paasl;
836 delete paesl;
837 delete pdmsl;
838 delete pdosl;
839 delete pdesl;
840 delete ptsl;
841
842 delete srcRB;
843 delete out;
844
845 return GENERIC_EXIT_OK;
846}
847
849{
850 utilMap["pidcounter"] = &pid_counter;
851 utilMap["pidfilter"] = &pid_filter;
852 utilMap["pidprinter"] = &pid_printer;
853}
Overall structure.
This is in libmythtv because that is where the parsers, which are its main users, are.
Tells what channels can be found on each transponder for one bouquet (a bunch of channels from one pr...
Definition: dvbtables.h:193
This table contains information about the cable channels transmitted on this multiplex.
Definition: atsctables.h:421
The CAT is used to transmit additional ConditionalAccessDescriptor instances, in addition to the ones...
Definition: mpegtables.h:839
No one has had time to decode this table yet...
Definition: atsctables.h:830
No one has had time to decode this table yet...
Definition: atsctables.h:763
EventInformationTables contain program titles, start times, and channel information.
Definition: atsctables.h:527
ExtendedTextTable contain additional text not contained in EventInformationTables.
Definition: atsctables.h:628
Encapsulates data about MPEG stream and emits events for each table.
virtual void AddWritingPID(uint pid, PIDPriority priority=kPIDPriorityHigh)
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
This table tells the decoder on which PIDs to find other tables, and their sizes and each table's cur...
Definition: atsctables.h:81
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
uint toUInt(const QString &key) const
Returns stored QVariant as an unsigned integer, falling to default if not provided.
bool WriterSetBlocking(bool Lock=true)
Calls ThreadedFileWriter::SetBlocking(bool)
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...
static MythMediaBuffer * Create(const QString &Filename, bool Write, bool UseReadAhead=true, std::chrono::milliseconds Timeout=kDefaultOpenTimeout, bool StreamOnly=false)
Creates a RingBuffer instance.
int Write(const void *Buffer, uint Count)
Writes buffer to ThreadedFileWriter::Write(const void*,uint)
This table tells the decoder on which PIDs to find other tables.
Definition: dvbtables.h:34
@ MPEG_PAT_PID
Definition: mpegtables.h:211
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
Definition: mpegtables.h:410
virtual QString toStringXML(uint indent_level) const
Definition: mpegtables.cpp:810
virtual QString toString(void) const
Definition: mpegtables.cpp:792
int64_t GetLastPTS(void) const
Definition: mpegutils.cpp:318
int64_t GetFirstPTS(void) const
Definition: mpegutils.cpp:305
uint32_t m_startCode
Definition: mpegutils.cpp:338
std::array< int64_t, 256 > m_ptsFirst
Definition: mpegutils.cpp:341
QMap< uint, uint > m_ptsStreams
Definition: mpegutils.cpp:339
std::array< uint32_t, 256 > m_ptsCount
Definition: mpegutils.cpp:340
std::array< int64_t, 256 > m_ptsLast
Definition: mpegutils.cpp:342
bool ProcessAudioTSPacket(const TSPacket &tspacket) override
Definition: mpegutils.cpp:303
int64_t GetElapsedPTS(void) const
Definition: mpegutils.cpp:331
bool ProcessTSPacket(const TSPacket &tspacket) override
Definition: mpegutils.cpp:346
bool ProcessVideoTSPacket(const TSPacket &tspacket) override
Definition: mpegutils.cpp:301
void HandleDCCT(const DirectedChannelChangeTable *dcct) override
Definition: mpegutils.cpp:614
void HandleCVCT(uint, const CableVirtualChannelTable *) override
Definition: mpegutils.cpp:603
void HandleRRT(const RatingRegionTable *rrt) override
Definition: mpegutils.cpp:609
void HandleTVCT(uint, const TerrestrialVirtualChannelTable *) override
Definition: mpegutils.cpp:597
PrintATSCAuxStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:594
void HandleDCCSCT(const DirectedChannelChangeSelectionCodeTable *dccsct) override
Definition: mpegutils.cpp:619
void HandleETT(uint pid, const ExtendedTextTable *ett) override
Definition: mpegutils.cpp:639
PrintATSCEITStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:630
void HandleEIT(uint pid, const EventInformationTable *eit) override
Definition: mpegutils.cpp:633
void HandleSTT(const SystemTimeTable *stt) override
Definition: mpegutils.cpp:531
void HandleVCT(uint, const VirtualChannelTable *vct) override
Definition: mpegutils.cpp:541
PrintATSCMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:528
void HandleMGT(const MasterGuideTable *mgt) override
Definition: mpegutils.cpp:536
void HandleEIT(const DVBEventInformationTable *eit) override
Definition: mpegutils.cpp:701
void HandleEIT(const PremiereContentInformationTable *pcit) override
Definition: mpegutils.cpp:706
PrintDVBEITStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:698
PrintDVBMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:650
void HandleTDT(const TimeDateTable *tdt) override
Definition: mpegutils.cpp:653
void HandleSDT(uint, const ServiceDescriptionTable *sdt) override
Definition: mpegutils.cpp:663
void HandleNIT(const NetworkInformationTable *nit) override
Definition: mpegutils.cpp:658
void HandleSDTo(uint, const ServiceDescriptionTable *sdt) override
Definition: mpegutils.cpp:682
void HandleNITo(const NetworkInformationTable *nit) override
Definition: mpegutils.cpp:677
PrintDVBOtherStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:674
void HandleBAT(const BouquetAssociationTable *bat) override
Definition: mpegutils.cpp:687
void HandleEncryptionStatus(uint, bool) override
Definition: mpegutils.cpp:496
PrintMPEGStreamListener(MythMediaBuffer *out, PTSListener &ptsl, bool autopts, MPEGStreamData *sd, const QHash< uint, bool > &use_pid, bool use_xml)
Definition: mpegutils.cpp:438
void HandlePMT(uint, const ProgramMapTable *pmt) override
Definition: mpegutils.cpp:465
void HandleCAT(const ConditionalAccessTable *cat) override
Definition: mpegutils.cpp:459
const PTSListener & m_ptsl
Definition: mpegutils.cpp:518
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: mpegutils.cpp:448
const QHash< uint, bool > & m_usePid
Definition: mpegutils.cpp:521
MPEGStreamData * m_sd
Definition: mpegutils.cpp:520
void HandleSplice(const SpliceInformationTable *sit) override
Definition: mpegutils.cpp:500
MythMediaBuffer * m_out
Definition: mpegutils.cpp:431
PrintOutput(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:405
void Output(const PSIPTable *psip) const
Definition: mpegutils.cpp:423
void Output(const QString &msg) const
Definition: mpegutils.cpp:410
void HandlePNM(const ProgramNameMessageTable *pnm) override
Definition: mpegutils.cpp:579
void HandleSTT(const SCTESystemTimeTable *stt) override
Definition: mpegutils.cpp:559
void HandleNTT(const NetworkTextTable *ntt) override
Definition: mpegutils.cpp:564
void HandleNIT(const SCTENetworkInformationTable *nit) override
Definition: mpegutils.cpp:554
void HandleSVCT(const ShortVirtualChannelTable *svct) override
Definition: mpegutils.cpp:569
void HandlePIM(const ProgramInformationMessageTable *pim) override
Definition: mpegutils.cpp:574
void HandleADET(const AggregateDataEventTable *adet) override
Definition: mpegutils.cpp:584
PrintSCTEMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:551
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:599
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:676
No one has had time to decode this table yet...
Definition: atsctables.h:747
This table contains the GPS time at the time of transmission.
Definition: sctetables.h:573
This table tells the decoder on which PIDs to find A/V data.
Definition: dvbtables.h:114
This table contains the GPS time at the time of transmission.
Definition: atsctables.h:686
bool PayloadStart(void) const
Definition: tspacket.h:89
const unsigned char * data(void) const
Definition: tspacket.h:174
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:208
unsigned int AFCOffset(void) const
Definition: tspacket.h:249
static constexpr unsigned int kSize
Definition: tspacket.h:261
This table contains information about the terrestrial channels transmitted on this multiplex.
Definition: atsctables.h:352
This table gives the current DVB stream time.
Definition: dvbtables.h:387
This table contains information about the channels transmitted on this multiplex.
Definition: atsctables.h:195
unsigned int uint
Definition: compat.h:60
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:18
@ GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:14
LogLevel_t logLevel
Definition: logging.cpp:89
void registerMPEGUtils(UtilMap &utilMap)
Definition: mpegutils.cpp:848
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
static int resync_stream(const char *buffer, int curr_pos, int len, int packet_size)
Definition: mpegutils.cpp:66
static int pid_filter(const MythUtilCommandLineParser &cmdline)
Definition: mpegutils.cpp:179
static int pid_printer(const MythUtilCommandLineParser &cmdline)
Definition: mpegutils.cpp:712
static int pid_counter(const MythUtilCommandLineParser &cmdline)
Definition: mpegutils.cpp:86
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
QMap< QString, UtilFunc > UtilMap
Definition: mythutil.h:15
bool start_code_is_valid(uint32_t start_code)
Test whether a start code found by find_start_code() is valid.
Definition: bytereader.h:62
MTV_PUBLIC const 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:79
MythCommFlagCommandLineParser cmdline
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:44
static constexpr uint8_t SYNC_BYTE
Definition: tspacket.h:21