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 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:
517 const QHash<uint,bool> &m_usePid;
518};
519
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
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
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
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
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
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}
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:423
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:832
No one has had time to decode this table yet...
Definition: atsctables.h:765
EventInformationTables contain program titles, start times, and channel information.
Definition: atsctables.h:529
ExtendedTextTable contain additional text not contained in EventInformationTables.
Definition: atsctables.h:630
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:83
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:807
virtual QString toString(void) const
Definition: mpegtables.cpp:789
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:610
void HandleCVCT(uint, const CableVirtualChannelTable *) override
Definition: mpegutils.cpp:599
void HandleRRT(const RatingRegionTable *rrt) override
Definition: mpegutils.cpp:605
void HandleTVCT(uint, const TerrestrialVirtualChannelTable *) override
Definition: mpegutils.cpp:593
PrintATSCAuxStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:590
void HandleDCCSCT(const DirectedChannelChangeSelectionCodeTable *dccsct) override
Definition: mpegutils.cpp:615
void HandleETT(uint pid, const ExtendedTextTable *ett) override
Definition: mpegutils.cpp:635
PrintATSCEITStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:626
void HandleEIT(uint pid, const EventInformationTable *eit) override
Definition: mpegutils.cpp:629
void HandleSTT(const SystemTimeTable *stt) override
Definition: mpegutils.cpp:527
void HandleVCT(uint, const VirtualChannelTable *vct) override
Definition: mpegutils.cpp:537
PrintATSCMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:524
void HandleMGT(const MasterGuideTable *mgt) override
Definition: mpegutils.cpp:532
void HandleEIT(const DVBEventInformationTable *eit) override
Definition: mpegutils.cpp:697
void HandleEIT(const PremiereContentInformationTable *pcit) override
Definition: mpegutils.cpp:702
PrintDVBEITStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:694
PrintDVBMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:646
void HandleTDT(const TimeDateTable *tdt) override
Definition: mpegutils.cpp:649
void HandleSDT(uint, const ServiceDescriptionTable *sdt) override
Definition: mpegutils.cpp:659
void HandleNIT(const NetworkInformationTable *nit) override
Definition: mpegutils.cpp:654
void HandleSDTo(uint, const ServiceDescriptionTable *sdt) override
Definition: mpegutils.cpp:678
void HandleNITo(const NetworkInformationTable *nit) override
Definition: mpegutils.cpp:673
PrintDVBOtherStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:670
void HandleBAT(const BouquetAssociationTable *bat) override
Definition: mpegutils.cpp:683
void HandleEncryptionStatus(uint, bool) override
Definition: mpegutils.cpp:492
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:514
void HandlePAT(const ProgramAssociationTable *pat) override
Definition: mpegutils.cpp:448
const QHash< uint, bool > & m_usePid
Definition: mpegutils.cpp:517
MPEGStreamData * m_sd
Definition: mpegutils.cpp:516
void HandleSplice(const SpliceInformationTable *sit) override
Definition: mpegutils.cpp:496
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:575
void HandleSTT(const SCTESystemTimeTable *stt) override
Definition: mpegutils.cpp:555
void HandleNTT(const NetworkTextTable *ntt) override
Definition: mpegutils.cpp:560
void HandleNIT(const SCTENetworkInformationTable *nit) override
Definition: mpegutils.cpp:550
void HandleSVCT(const ShortVirtualChannelTable *svct) override
Definition: mpegutils.cpp:565
void HandlePIM(const ProgramInformationMessageTable *pim) override
Definition: mpegutils.cpp:570
void HandleADET(const AggregateDataEventTable *adet) override
Definition: mpegutils.cpp:580
PrintSCTEMainStreamListener(MythMediaBuffer *out, bool use_xml)
Definition: mpegutils.cpp:547
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:749
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:688
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:354
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:197
@ 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
unsigned int uint
Definition: freesurround.h:24
static guint32 * tmp
Definition: goom_core.cpp:26
LogLevel_t logLevel
Definition: logging.cpp:85
void registerMPEGUtils(UtilMap &utilMap)
Definition: mpegutils.cpp:844
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:708
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:54
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:74
MythCommFlagCommandLineParser cmdline
std::chrono::duration< CHRONO_TYPE, std::ratio< 1, 90000 > > pts
Definition: mythchrono.h:55
static constexpr uint8_t SYNC_BYTE
Definition: tspacket.h:21