MythTV master
mpegdescriptors.cpp
Go to the documentation of this file.
1// -*- Mode: c++ -*-
2// Copyright (c) 2005, Daniel Thor Kristjansson
3
4#include <algorithm>
5#include <climits>
6#include <cstdint>
7
9
10#include "sctedescriptors.h"
11#include "atscdescriptors.h"
12#include "dvbdescriptors.h"
13
16QMap<QString,QString> RegistrationDescriptor::description_map;
17
19 const unsigned char *data, uint len)
20{
21 desc_list_t tmp;
22 uint off = 0;
23 while (off < len)
24 {
25 tmp.push_back(data+off);
26 MPEGDescriptor desc(data+off, len-off);
27 if (!desc.IsValid())
28 {
29 tmp.pop_back();
30 break;
31 }
32 off += desc.size();
33 }
34 return tmp;
35}
36
38 const unsigned char *data, uint len, int excluded_descid)
39{
40 desc_list_t tmp;
41 uint off = 0;
42 while (off < len)
43 {
44 if ((data+off)[0] != excluded_descid)
45 tmp.push_back(data+off);
46 MPEGDescriptor desc(data+off, len-off);
47 if (!desc.IsValid())
48 {
49 if ((data+off)[0] != excluded_descid)
50 tmp.pop_back();
51 break;
52 }
53 off += desc.size();
54 }
55 return tmp;
56}
57
59 const unsigned char *data, uint len, int excluded_descid)
60{
61 desc_list_t tmp;
62 uint off = 0;
63 while (off < len)
64 {
65 if ((data+off)[0] == excluded_descid)
66 tmp.push_back(data+off);
67 MPEGDescriptor desc(data+off, len-off);
68 if (!desc.IsValid())
69 {
70 if ((data+off)[0] == excluded_descid)
71 tmp.pop_back();
72 break;
73 }
74 off += desc.size();
75 }
76 return tmp;
77}
78
79const unsigned char *MPEGDescriptor::Find(const desc_list_t &parsed,
80 uint desc_tag)
81{
82 auto sametag = [desc_tag](const auto *item){ return item[0] == desc_tag; };
83 auto it = std::ranges::find_if(parsed, sametag);
84 return (it != parsed.cend()) ? *it : nullptr;
85}
86
87const unsigned char *MPEGDescriptor::FindExtension(const desc_list_t &parsed,
88 uint desc_tag)
89{
90 auto sametag = [desc_tag](const auto *item)
91 { return item[0] == DescriptorID::extension &&
92 item[1] > 1 &&
93 item[2] == desc_tag; };
94 auto it = std::ranges::find_if(parsed, sametag);
95 return (it != parsed.cend()) ? *it : nullptr;
96}
97
99{
100 desc_list_t tmp;
101 auto sametag = [desc_tag](const auto *item){ return item[0] == desc_tag; };
102 std::ranges::copy_if(parsed, std::back_inserter(tmp), sametag);
103 return tmp;
104}
105
106static uint maxPriority(const QMap<uint,uint> &langPrefs)
107{
108 uint max_pri = 0;
109 for (uint pref : langPrefs)
110 max_pri = std::max(max_pri, pref);
111 return max_pri;
112}
113
114const unsigned char *MPEGDescriptor::FindBestMatch(
115 const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPrefs)
116{
117 uint match_idx = 0;
118 uint match_pri = UINT_MAX;
119 int unmatched_idx = -1;
120
121 size_t i = (desc_tag == DescriptorID::short_event) ? 0 : parsed.size();
122 for (; i < parsed.size(); i++)
123 {
124 if (DescriptorID::short_event == parsed[i][0])
125 {
126 ShortEventDescriptor sed(parsed[i]);
127 if (!sed.IsValid())
128 continue;
129 QMap<uint,uint>::const_iterator it =
130 langPrefs.constFind(sed.CanonicalLanguageKey());
131
132 if ((it != langPrefs.constEnd()) && (*it < match_pri))
133 {
134 match_idx = i;
135 match_pri = *it;
136 }
137
138 if (unmatched_idx < 0)
139 unmatched_idx = i;
140 }
141 }
142
143 if (match_pri != UINT_MAX)
144 return parsed[match_idx];
145
146 if ((desc_tag == DescriptorID::short_event) && (unmatched_idx >= 0))
147 {
148 ShortEventDescriptor sed(parsed[unmatched_idx]);
149 if (sed.IsValid())
150 {
151 langPrefs[sed.CanonicalLanguageKey()] = maxPriority(langPrefs) + 1;
152 return parsed[unmatched_idx];
153 }
154 }
155
156 return nullptr;
157}
158
160 const desc_list_t &parsed, uint desc_tag, QMap<uint,uint> &langPrefs)
161{
162 uint match_pri = UINT_MAX;
163 int match_key = 0;
164 int unmatched_idx = -1;
165
166 size_t i = (desc_tag == DescriptorID::extended_event) ? 0 : parsed.size();
167 for (; i < parsed.size(); i++)
168 {
169 if (DescriptorID::extended_event == parsed[i][0])
170 {
171 ExtendedEventDescriptor eed(parsed[i]);
172 if (!eed.IsValid())
173 continue;
174 QMap<uint,uint>::const_iterator it =
175 langPrefs.constFind(eed.CanonicalLanguageKey());
176
177 if ((it != langPrefs.constEnd()) && (*it < match_pri))
178 {
179 match_key = eed.LanguageKey();
180 match_pri = *it;
181 }
182
183 if (unmatched_idx < 0)
184 unmatched_idx = i;
185 }
186 }
187
188 if ((desc_tag == DescriptorID::extended_event) &&
189 (match_key == 0) && (unmatched_idx >= 0))
190 {
191 ExtendedEventDescriptor eed(parsed[unmatched_idx]);
192 if (eed.IsValid())
193 {
194 langPrefs[eed.CanonicalLanguageKey()] = maxPriority(langPrefs) + 1;
195 match_key = eed.LanguageKey();
196 }
197 }
198
199 desc_list_t tmp;
200 if (match_pri == UINT_MAX)
201 return tmp;
202
203 for (const auto *j : parsed)
204 {
205 if ((DescriptorID::extended_event == desc_tag) &&
207 {
209 if (eed.IsValid() && (eed.LanguageKey() == match_key))
210 tmp.push_back(j);
211 }
212 }
213
214 return tmp;
215}
216
217#define EMPTY_STR_16 "","","","", "","","","", "","","","", "","","","",
218
219const std::array<const std::string,256> descriptor_tag_strings
220{
221 /* 0x00 */ "", /* 0x01 */ "",
222 /* 0x02 */ "Video", /* 0x03 */ "Audio",
223 /* 0x04 */ "Hierarchy", /* 0x05 */ "Registration",
224 /* 0x06 */ "Data Stream Alignment", /* 0x07 */ "Target Background Grid",
225 /* 0x08 */ "Video Window", /* 0x09 */ "Conditional Access",
226 /* 0x0A */ "ISO-639 Language", /* 0x0B */ "System Clock",
227 /* 0x0C */ "Multiplex Buffer Utilization", /* 0x0D */ "Copyright",
228 /* 0x0E */ "Maximum Bitrate", /* 0x0F */ "Private Data Indicator",
229
230 /* 0x10 */ "Smoothing Buffer", /* 0x11 */ "STD",
231 /* 0x12 */ "IBP", /* 0x13 */ "DSM-CC Carousel Identifier",
232 /* 0x14 */ "DSM-CC Association Tag",
233 /* 0x15 */ "DSM-CC Deferred Association Tag",
234 /* 0x16 */ "Reserved(0x16)", /* 0x17 */ "DSM-CC NPT Reference",
235 /* 0x18 */ "DSM-CC NPT Endpoint", /* 0x19 */ "DSM-CC Stream Mode",
236 /* 0x1A */ "DSM-CC Stream Event", /* 0x1B */ "MPEG-4 Video",
237 /* 0x1C */ "MPEG-4 Audio", /* 0x1D */ "IOD",
238 /* 0x1E */ "SL", /* 0x1F */ "FMC",
239
240 /* 0x20 */ "External ES ID", /* 0x21 */ "Multimpex Code",
241 /* 0x22 */ "FMX buffer Size", /* 0x23 */ "Multiplex Buffer",
242 /* 0x24 */ "Content Labeling", /* 0x25 */ "Metadata Pointer",
243 /* 0x26 */ "Metadata", /* 0x27 */ "Metadata Std",
244 /* 0x28 */ "AVC Video", /* 0x29 */ "IPMP DRM",
245 /* 0x2A */ "AVC Timing & HRD", /* 0x2B */ "AAC Audio",
246 /* 0x2C */ "Flex Mux Timing", /* 0x2D */ "",
247 /* 0x2E */ "", /* 0x2F */ "",
248
249 /* 0x30-0x3F */ EMPTY_STR_16
250
251 /* 0x40 */ "Network Name", /* 0x41 */ "Service List",
252 /* 0x42 */ "DVB Stuffing", /* 0x43 */ "Satellite Delivery System",
253 /* 0x44 */ "Cable Delivery System", /* 0x45 */ "VBI Data",
254 /* 0x46 */ "VBI Teletext", /* 0x47 */ "Bouquet Name",
255 /* 0x48 */ "Service", /* 0x49 */ "Country Availability",
256 /* 0x4A */ "Linkage", /* 0x4B */ "NVOD Reference",
257 /* 0x4C */ "DVB Time-shifted Service",/* 0x4D */ "Short Event",
258 /* 0x4E */ "Extended Event", /* 0x4F */ "Time-shifted Event",
259
260 /* 0x50 */ "Component", /* 0x51 */ "Mosaic",
261 /* 0x52 */ "Stream Identifier",
262 /* 0x53 */ "Conditional Access Identifier",
263 /* 0x54 */ "Content", /* 0x55 */ "Parental Rating",
264 /* 0x56 */ "Teletext", /* 0x57 */ "Telephone",
265 /* 0x58 */ "Local Time Offset", /* 0x59 */ "Subtitling",
266 /* 0x5A */ "Terrestrial Delivery System",
267 /* 0x5B */ "Multilingual Network Name",
268 /* 0x5C */ "Multilingual Bouquet Name",
269 /* 0x5D */ "Multilingual Service Name",
270 /* 0x5E */ "Multilingual Component",
271 /* 0x5F */ "Private Data Specifier",
272
273 /* 0x60 */ "Service Move", /* 0x61 */ "Short Smoothing Buffer",
274 /* 0x62 */ "Frequency List", /* 0x63 */ "Partial Transport Stream",
275 /* 0x64 */ "Data Broadcast", /* 0x65 */ "Scrambling",
276 /* 0x66 */ "Data Broadcast ID", /* 0x67 */ "Transport Stream",
277 /* 0x68 */ "DSNG", /* 0x69 */ "PDC",
278 /* 0x6A */ "AC-3", /* 0x6B */ "Ancillary Data",
279 /* 0x6C */ "Cell List", /* 0x6D */ "Cell Frequency Link",
280 /* 0x6E */ "Announcement Support", /* 0x6F */ "Application Signalling",
281
282 /* 0x70 */ "Adaptation Field Data", /* 0x71 */ "Service Identifier",
283 /* 0x72 */ "Service Availability", /* 0x73 */ "Default Authority",
284 /* 0x74 */ "Related Content", /* 0x75 */ "TVA ID",
285 /* 0x76 */ "DVB Content Identifier",/* 0x77 */ "Time Slice FEC Identifier",
286 /* 0x78 */ "ECM Repetition Rate", /* 0x79 */ "DVB-S2 Delivery Identifier",
287 /* 0x7A */ "E-AC-3", /* 0x7B */ "DTS",
288 /* 0x7C */ "AAC", /* 0x7D */ "XAIT location",
289 /* 0x7E */ "FTA content management",/* 0x7F */ "Extension",
290
291 /* 0x80 */ "ATSC Stuffing", /* 0x81 */ "AC-3 Audio",
292 /* 0x82 */ "SCTE Frame Rate", /* 0x83 */ "SCTE Extended Video",
293 /* 0x84 */ "SCTE Component Name", /* 0x85 */ "ATSC Program Identifier",
294 /* 0x86 */ "Caption Service", /* 0x87 */ "Content Advisory",
295 /* 0x88 */ "ATSC CA", /* 0x89 */ "ATSC Descriptor Tag",
296 /* 0x8A */ "SCTE CUE Identifier", /* 0x8B */ "",
297 /* 0x8C */ "TimeStamp", /* 0x8D */ "",
298 /* 0x8E */ "", /* 0x8F */ "",
299
300 /* 0x90 */ "SCTE Frequency Spec", /* 0x91 */ "SCTE Modulation Params",
301 /* 0x92 */ "SCTE TSID", /* 0x93 */ "SCTE Revision Detection",
302 /* 0x94 */ "SCTE Two part channel", /* 0x95 */ "SCTE Channel Properties",
303 /* 0x96 */ "SCTE Daylight Savings", /* 0x97 */ "SCTE AFD",
304 /* 0x98 */ "", /* 0x99 */ "",
305 /* 0x9A */ "", /* 0x9B */ "",
306 /* 0x9C */ "", /* 0x9D */ "",
307 /* 0x9E */ "", /* 0x9F */ "",
308
309 /* 0xA0 */ "Extended Channel Name", /* 0xA1 */ "Service Location",
310 /* 0xA2 */ "ATSC Time-shifted Service",/*0xA3*/"Component Name",
311 /* 0xA4 */ "ATSC Data Service", /* 0xA5 */ "ATSC PID Count",
312 /* 0xA6 */ "ATSC Download",
313 /* 0xA7 */ "ATSC Multiprotocol Encapsulation",
314 /* 0xA8 */ "DCC Departing Request", /* 0xA9 */ "DCC Arriving Request",
315 /* 0xAA */ "ATSC Restrictions Control",/*0xAB*/"ATSC Genre",
316 /* 0xAC */ "SCTE MAC Address List", /* 0xAD */ "ATSC Private Information",
317 /* 0xAE */ "ATSC Compatibility Wrap",/* 0xAF */"ATSC Broadcaster Policy",
318
319 /* 0xB0 */ "", /* 0xB1 */ "",
320 /* 0xB2 */ "", /* 0xB3 */ "",
321 /* 0xB4 */ "", /* 0xB5 */ "",
322 /* 0xB6 */ "ATSC Content ID", /* 0xB7 */ "",
323 /* 0xB8 */ "", /* 0xB9 */ "",
324 /* 0xBA */ "", /* 0xBB */ "",
325 /* 0xBC */ "", /* 0xBD */ "",
326 /* 0xBE */ "", /* 0xBF */ "",
327
328 /* 0xC0-0xCF */ EMPTY_STR_16
329 /* 0xD0-0xDF */ EMPTY_STR_16
330 /* 0xE0-0xEF */ EMPTY_STR_16
331 /* 0xF0-0xFF */ EMPTY_STR_16
332};
333
334static void comma_list_append(QString &str, const QString& extra)
335{
336 if (str.isEmpty())
337 str = extra;
338 else
339 str = str + ", " + extra;
340}
341
343{
344 QString str = QString::fromStdString(descriptor_tag_strings[DescriptorTag()]);
345
346 switch (DescriptorTag())
347 {
349 comma_list_append(str, "Possibly DVB Logical Channel Descriptor");
350 break;
352 comma_list_append(str, "Possibly Dishnet Rights");
353 break;
355 comma_list_append(str, "Possibly Dishnet MPAA");
356 break;
358 comma_list_append(str, "Possibly Dishnet EIT Name");
359 break;
361 comma_list_append(str, "Possibly Dishnet EIT Description");
362 break;
364 comma_list_append(str, "Possibly Dishnet Properties");
365 break;
367 comma_list_append(str, "Possibly Dishnet V-Chip");
368 break;
370 comma_list_append(str, "Possibly Dishnet Tag");
371 break;
373 comma_list_append(str, "Possibly DVB Sky/OpenTV Channel List");
374 break;
376 comma_list_append(str, "Possibly Premiere DE Content Order");
377 break;
379 comma_list_append(str, "Possibly Premiere DE Parental Information");
380 break;
382 comma_list_append(str, "Possibly Premiere DE Content Transmission");
383 break;
384 }
385
386 if (str.isEmpty())
387 str = QString("Unknown");
388
389 return str;
390}
391
392QString MPEGDescriptor::descrDump(const QString &name) const
393{
394 QString str;
395 str = QString("%1 Descriptor tag(0x%2) length(%3)")
396 .arg(name)
397 .arg(DescriptorTag(),2,16,QChar('0'))
398 .arg(DescriptorLength());
399 if (DescriptorLength() > 0)
400 {
401 str.append(" Dumping\n");
402 str.append(hexdump());
403 }
404 return str;
405}
406
407QString MPEGDescriptor::toString(void) const
408{
409 return toStringPD(0);
410}
411
412QString MPEGDescriptor::toStringPD(uint priv_dsid) const
413{
414 QString str;
415
416 if (!IsValid())
417 {
418 str = "Invalid Descriptor";
419 }
421 {
422 str = descrToString<VideoStreamDescriptor>();
423 }
425 {
426 str = descrToString<AudioStreamDescriptor>();
427 }
429 {
430 str = descrToString<RegistrationDescriptor>();
431 }
433 {
434 str = descrToString<DataStreamAlignmentDescriptor>();
435 }
437 {
438 str = descrToString<ConditionalAccessDescriptor>();
439 }
441 {
442 str = descrToString<ISO639LanguageDescriptor>();
443 }
445 {
446 str = descrToString<SystemClockDescriptor>();
447 }
449 {
450 str = descrToString<MaximumBitrateDescriptor>();
451 }
453 {
454 str = descrToString<SmoothingBufferDescriptor>();
455 }
457 {
458 str = descrToString<AVCVideoDescriptor>();
459 }
461 {
462 str = descrToString<HEVCVideoDescriptor>();
463 }
465 {
466 str = descrToString<NetworkNameDescriptor>();
467 }
469 {
470 str = descrToString<ServiceListDescriptor>();
471 }
473 {
474 str = descrToString<SatelliteDeliverySystemDescriptor>();
475 }
477 {
478 str = descrToString<CableDeliverySystemDescriptor>();
479 }
481 {
482 str = descrToString<BouquetNameDescriptor>();
483 }
485 {
486 str = descrToString<ServiceDescriptor>();
487 }
489 {
490 str = descrToString<CountryAvailabilityDescriptor>();
491 }
492 //else if (DescriptorID::linkage == DescriptorTag())
493 //{
494 // str = descrToString<LinkageDescriptor>();
495 //}
497 {
498 str = descrToString<StreamIdentifierDescriptor>();
499 }
501 {
502 str = descrToString<TeletextDescriptor>();
503 }
505 {
506 str = descrToString<SubtitlingDescriptor>();
507 }
509 {
510 str = descrToString<TerrestrialDeliverySystemDescriptor>();
511 }
513 {
514 str = descrToString<FrequencyListDescriptor>();
515 }
517 {
518 str = descrToString<ScramblingDescriptor>();
519 }
520 else if (DescriptorID::ac3 == DescriptorTag())
521 {
522 str = descrToString<AC3Descriptor>();
523 }
524 //else if (DescriptorID::ancillary_data == DescriptorTag())
525 //{
526 // str = descrToString<AncillaryDataDescriptor>();
527 //}
529 {
530 str = descrToString<ApplicationSignallingDescriptor>();
531 }
533 {
534 str = descrToString<AdaptationFieldDataDescriptor>();
535 }
537 {
538 str = descrToString<DefaultAuthorityDescriptor>();
539 }
541 {
542 str = descrToString<S2SatelliteDeliverySystemDescriptor>();
543 }
544 //
545 // Extension descriptors for extension 0x7F
548 {
549 str = descrToString<ImageIconDescriptor>();
550 }
553 {
554 str = descrToString<T2DeliverySystemDescriptor>();
555 }
558 {
559 str = descrToString<SHDeliverySystemDescriptor>();
560 }
563 {
564 str = descrToString<SupplementaryAudioDescriptor>();
565 }
568 {
569 str = descrToString<NetworkChangeNotifyDescriptor>();
570 }
573 {
574 str = descrToString<MessageDescriptor>();
575 }
578 {
579 str = descrToString<TargetRegionDescriptor>();
580 }
583 {
584 str = descrToString<TargetRegionNameDescriptor>();
585 }
588 {
589 str = descrToString<ServiceRelocatedDescriptor>();
590 }
593 {
594 str = descrToString<C2DeliverySystemDescriptor>();
595 }
598 {
599 str = descrToString<S2XSatelliteDeliverySystemDescriptor>();
600 }
601 //
602 // User Defined DVB descriptors, range 0x80-0xFE
603 else if (priv_dsid == PrivateDataSpecifierID::SES &&
605 {
606 str = descrDump("NorDig Content Protection");
607 }
608 else if (priv_dsid == PrivateDataSpecifierID::OTV &&
609 0x80 <= DescriptorTag() && DescriptorTag() < 0xFF)
610 {
611 str = descrDump("OpenTV Private ");
612 }
613 else if (priv_dsid == PrivateDataSpecifierID::BSB1 &&
615 {
616 str = descrToString<SkyLCNDescriptor>();
617 }
618 else if (priv_dsid == PrivateDataSpecifierID::FSAT &&
620 {
621 str = descrToString<FreesatRegionDescriptor>();
622 }
623 else if (priv_dsid == PrivateDataSpecifierID::FSAT &&
625 {
626 str = descrToString<FreesatLCNDescriptor>();
627 }
628 else if (priv_dsid == PrivateDataSpecifierID::FSAT &&
630 {
631 str = descrToString<FreesatCallsignDescriptor>();
632 }
633 else if (priv_dsid == PrivateDataSpecifierID::CASEMA &&
635 {
636 str = descrDump("Video on Demand");
637 }
638 else if (priv_dsid == PrivateDataSpecifierID::CASEMA &&
640 {
641 str = descrDump("Ziggo Package");
642 }
643 else if ((priv_dsid == PrivateDataSpecifierID::EACEM ||
644 priv_dsid == PrivateDataSpecifierID::NORDIG ||
645 priv_dsid == PrivateDataSpecifierID::ITC ) &&
647 {
648 str = descrToString<DVBSimulcastChannelDescriptor>();
649 }
650 else if ((priv_dsid == PrivateDataSpecifierID::EACEM ||
651 priv_dsid == PrivateDataSpecifierID::NORDIG ||
652 priv_dsid == PrivateDataSpecifierID::ITC ) &&
654 {
655 str = descrToString<DVBLogicalChannelDescriptor>();
656 }
657 else if (priv_dsid == PrivateDataSpecifierID::CIPLUS &&
659 {
660 str = descrDump("CI Protection");
661 }
662 // All not otherwise specified private descriptors
663 else if (priv_dsid > 0 && DescriptorTag() > 0x80)
664 {
665 str = descrDump("User Defined");
666 }
667 //
668 // POSSIBLY UNSAFE ! -- begin
669 // ATSC/SCTE descriptors, range 0x80-0xFE
671 {
672 str = descrToString<AC3AudioStreamDescriptor>();
673 }
675 {
676 str = descrToString<CaptionServiceDescriptor>();
677 }
679 {
680 str = descrToString<CueIdentifierDescriptor>();
681 }
683 {
684 str = descrToString<RevisionDetectionDescriptor>();
685 }
687 {
688 str = descrToString<ExtendedChannelNameDescriptor>();
689 }
690 else if (priv_dsid == 0 &&
692 {
693 str = descrToString<ComponentNameDescriptor>();
694 }
695 // POSSIBLY UNSAFE ! -- end
696 else
697 {
699 }
700 return str;
701}
702
706{
707 QString indent_0 = StringUtil::indentSpaces(level);
708 QString indent_1 = StringUtil::indentSpaces(level+1);
709 QString str;
710
711 str += indent_0 + "<Descriptor>\n";
712 str += indent_1 + QString("<Tag>0x%1</Tag>\n")
713 .arg(DescriptorTag(),2,16,QChar('0'));
714 str += indent_1 + QString("<Description>%1</Description>\n")
715 .arg(DescriptorTagString());
716
717 str += indent_1 + "<Data>";
718 for (uint i = 0; i < DescriptorLength(); i++)
719 {
720 if (((i%8) == 0) && i)
721 str += "\n" + indent_1 + " ";
722 str += QString("0x%1 ").arg(m_data[i+2],2,16,QChar('0'));
723 }
724
725 str += "\n" + indent_1 + "</Data>\n";
726 str += indent_1 + "<Decoded>" + toString().toHtmlEscaped() + "</Decoded>\n";
727 str += indent_0 + "</Descriptor>";
728
729 return str;
730}
731
732// Dump the descriptor in the same format as hexdump -C
733QString MPEGDescriptor::hexdump(void) const
734{
735 uint i = 0;
736 QString str;
737 QString hex;
738 QString prt;
739 for (i=0; i<DescriptorLength(); i++)
740 {
741 uint8_t ch = m_data[i+2];
742 hex.append(QString(" %1").arg(ch, 2, 16, QChar('0')));
743 prt.append(QString("%1").arg(isprint(ch) ? QChar(ch) : '.'));
744 if (((i+1) % 8) == 0)
745 hex.append(" ");
746 if (((i+1) % 16) == 0)
747 {
748 str.append(QString(" %1 %2 |%3|")
749 .arg(i - (i % 16),3,16,QChar('0'))
750 .arg(hex, prt));
751 hex.clear();
752 prt.clear();
753 if (i < (DescriptorLength() - 1))
754 {
755 str.append("\n");
756 }
757 }
758 }
759 if (!hex.isEmpty())
760 {
761 str.append(QString(" %1 %2 |%3|")
762 .arg(i - (i % 16),3,16,QChar('0'))
763 .arg(hex,-50,' ').arg(prt));
764 }
765 return str;
766}
767
769{
770 QString str = QString("Video Stream Descriptor: frame_rate(%1) MPEG-1(%2)")
771 .arg(FrameRateCode())
772 .arg(MPEG1OnlyFlag());
773 if (!MPEG1OnlyFlag())
774 {
775 str.append(QString(" still_picture(%1) profile(%2)")
776 .arg(StillPictureFlag())
778 }
779 return str;
780}
781
783{
784 return QString("Audio Stream Descriptor: free_format(%1) ID(%2) layer(%3) variable_rate(%4)")
785 .arg(FreeFormatFlag())
786 .arg(ID())
787 .arg(Layer())
789}
790
792{
793 QMutexLocker locker(&description_map_lock);
795 return;
796
797 description_map["AC-3"] = "ATSC audio stream A/52";
798 description_map["AVSV"] = "China A/V Working Group";
799 description_map["BDC0"] = "Broadcast Data Corporation Software Data Service";
800 description_map["BSSD"] = "SMPTE 302M-1998 Audio data as specified in (AES3)";
801 description_map["CAPO"] = "SMPTE 315M-1999 Camera Positioning Information";
802 description_map["CUEI"] = "SCTE 35 2003, Cable Digital Program Insertion Cueing Message";
803 description_map["DDED"] = "LGEUS Digital Delivery with encryption and decryption";
804 description_map["DISH"] = "EchoStar MPEG streams";
805 description_map["DRA1"] = "Chinese EIS SJ/T11368-2006 DRA digital audio";
806 description_map["DTS1"] = "DTS Frame size of 512 bytes";
807 description_map["DTS2"] = "DTS Frame size of 1024 bytes";
808 description_map["DTS3"] = "DTS Frame size of 2048";
809 description_map["DVDF"] = "DVD compatible MPEG2-TS";
810 description_map["ETV1"] = "CableLabs ETV info is present";
811 description_map["GA94"] = "ATSC program ID A/53";
812 description_map["GWKS"] = "GuideWorks EPG info";
813 description_map["HDMV"] = "Blu-Ray A/V for read-only media (H.264 TS)";
814 description_map["HDMX"] = "Matsushita-TS";
815 description_map["KLVA"] = "SMPTE RP 217-2001 MXF KLV packets present";
816 description_map["LU-A"] = "SMPTE RDD-11 HDSDI HD serial/video data";
817 description_map["MTRM"] = "D-VHS compatible MPEG2-TS";
818 description_map["NMR1"] = "Nielsen content identifier";
819 description_map["PAUX"] = "Philips ES containing low-speed data";
820 description_map["PMSF"] = "MPEG-TS stream modified by STB";
821 description_map["PRMC"] = "Philips ES containing remote control data";
822 description_map["SCTE"] = "SCTE 54 2003 Digital Video Service Multiplex and TS for Cable";
823 description_map["SEN1"] = "ATSC Private Information identifies source of stream";
824 description_map["SESF"] = "Blu-Ray A/V for ReWritable media (H.264 TS)";
825 description_map["SPLC"] = "SMPTE Proposed 312M Splice Point compatible TS";
826 description_map["SVMD"] = "SMPTE Proposed Video Metatdata Dictionary for MPEG2-TS";
827 description_map["SZMI"] = "ATSC Private Info from Building B";
828 description_map["TRIV"] = "ATSC Private Info from Triveni Digital";
829 description_map["TSBV"] = "Toshiba self-encoded H.264 TS";
830 description_map["TSHV"] = "Sony self-encoded MPEG-TS and private data";
831 description_map["TSMV"] = "Sony self-encoded MPEG-TS and private data";
832 description_map["TVG1"] = "TV Guide EPG Data";
833 description_map["TVG2"] = "TV Guide EPG Data";
834 description_map["TVG3"] = "TV Guide EPG Data";
835 description_map["ULE1"] = "IETF RFC4326 compatible MPEG2-TS";
836 description_map["VC-1"] = "SMPTE Draft RP 227 VC-1 Bitstream Transport Encodings";
837
838 for (uint i = 0; i <= 99; i++)
839 {
840 description_map[QString("US%1").arg(i, 2, 16, QLatin1Char('0'))] =
841 "NIMA, Unspecified military application";
842 }
843
845}
846
847QString RegistrationDescriptor::GetDescription(const QString &fmt)
848{
850
851 QString ret;
852 {
853 QMutexLocker locker(&description_map_lock);
854 QMap<QString,QString>::const_iterator it = description_map.constFind(fmt);
855 if (it != description_map.constEnd())
856 ret = *it;
857 }
858
859 return ret;
860}
861
863{
864 QString fmt = FormatIdentifierString();
865 QString msg = QString("Registration Descriptor: '%1' ").arg(fmt);
866
867 QString msg2 = GetDescription(fmt);
868 if (msg2.isEmpty())
869 msg2 = "Unknown, see http://www.smpte-ra.org/mpegreg/mpegreg.html";
870
871 return msg + msg2;
872}
873
875{
876 return QString("Data Stream Alignment Descriptor: alignment_type(%1)")
877 .arg(AlignmentType());
878}
879
881{
882 return QString("Conditional Access: sid(0x%1) pid(0x%2) data_size(%3)")
883 .arg(SystemID(),0,16).arg(PID(),0,16).arg(DataSize());
884}
885
887{
888 return QString("ISO-639 Language: code(%1) canonical(%2) eng(%3)")
891}
892
894{
895 return QString("System Clock Descriptor: extref(%1) accuracy(%2e-%3 ppm)")
898 .arg(ClockAccuracyExponent());
899}
900
902{
903 return QString("Maximum Bitrate Descriptor: maximum_bitrate(0x%1) %2 Mbit/s")
904 .arg(MaximumBitrate(),6,16,QChar('0'))
905 .arg(MaximumBitrate() * 1.0 * 50 * 8 / 1e6);
906}
907
909{
910 QString str = QString("Smoothing Buffer Descriptor ");
911 str += QString("tag(0x%1) ").arg(DescriptorTag(),2,16,QChar('0'));
912 str += QString("length(%1) ").arg(DescriptorLength());
913
914 str +=
915 QString("sb_leak_rate(0x%1) %2 kB/s ")
916 .arg(SBLeakRate(),6,16,QChar('0'))
917 .arg(SBLeakRate() * 400.0 / (8 * 1e3)) +
918 QString("sb_size(0x%1) %2 kB")
919 .arg(SBSize(),6,16,QChar('0'))
920 .arg(SBSize() / 1e3);
921 return str;
922}
923
925{
926 return QString("AVC Video: IDC prof(%1) IDC level(%2) sets(%3%4%5) "
927 "compat(%6) still(%7) 24hr(%8) FramePacking(%9)")
928 .arg(ProfileIDC()).arg(LevelIDC())
929 .arg(static_cast<int>(ConstraintSet0()))
930 .arg(static_cast<int>(ConstraintSet1()))
931 .arg(static_cast<int>(ConstraintSet2()))
932 .arg(AVCCompatible())
933 .arg(static_cast<int>(AVCStill()))
934 .arg(static_cast<int>(AVC24HourPicture()))
935 .arg(static_cast<int>(FramePackingSEINotPresentFlag()));
936}
937
939{
940 QString str = QString("HEVC Video: ProfileSpace(%1) Tier(%2) ProfileIDC(%3)")
941 .arg(ProfileSpace()).arg(Tier()).arg(ProfileIDC());
942 str.append(" Dumping\n");
943 str.append(hexdump());
944 return str;
945}
bool AVCStill(void) const
uint LevelIDC(void) const
bool FramePackingSEINotPresentFlag(void) const
QString toString() const override
bool ConstraintSet1(void) const
bool ConstraintSet2(void) const
bool AVC24HourPicture(void) const
bool ConstraintSet0(void) const
uint AVCCompatible(void) const
uint ProfileIDC(void) const
bool FreeFormatFlag(void) const
QString toString() const override
bool ID(void) const
uint Layer(void) const
bool VariableRateAudioIndicator(void) const
QString toString() const override
QString toString() const override
@ terrestrial_delivery_system
@ s2x_satellite_delivery_system
@ s2_satellite_delivery_system
int LanguageKey(void) const
int CanonicalLanguageKey(void) const
QString toString() const override
uint ProfileSpace(void) const
uint ProfileIDC(void) const
bool Tier(void) const
QString LanguageString(void) const
QString CanonicalLanguageString(void) const
int CanonicalLanguageKey(void) const
QString toString() const override
static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag)
uint DescriptorLength(void) const
static const unsigned char * FindExtension(const desc_list_t &parsed, uint desc_tag)
static desc_list_t Parse(const unsigned char *data, uint len)
static desc_list_t ParseAndExclude(const unsigned char *data, uint len, int excluded_descid)
QString hexdump(void) const
uint DescriptorTag(void) const
bool IsValid(void) const
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
uint size(void) const
uint DescriptorTagExtension(void) const
QString descrDump(const QString &name) const
static desc_list_t FindBestMatches(const desc_list_t &parsed, uint desc_tag, QMap< uint, uint > &langPref)
static const unsigned char * FindBestMatch(const desc_list_t &parsed, uint desc_tag, QMap< uint, uint > &langPref)
virtual QString toStringPD(uint priv_dsid) const
QString DescriptorTagString(void) const
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
virtual QString toStringXML(uint indent_level) const
Returns XML representation of string the TS Reader XML format.
virtual QString toString(void) const
const unsigned char * m_data
uint MaximumBitrate(void) const
QString toString() const override
static QMap< QString, QString > description_map
static void InitializeDescriptionMap(void)
static QMutex description_map_lock
static QString GetDescription(const QString &fmt)
static bool description_map_initialized
QString toString() const override
QString FormatIdentifierString(void) const
int CanonicalLanguageKey(void) const
QString toString(void) const override
uint SBLeakRate(void) const
uint ClockAccuracyExponent(void) const
bool ExternalClockReferenceIndicator(void) const
uint ClockAccuracyInteger(void) const
QString toString() const override
QString toString() const override
uint ProfileAndLevelIndication(void) const
uint FrameRateCode(void) const
bool MPEG1OnlyFlag(void) const
bool StillPictureFlag(void) const
unsigned int uint
Definition: compat.h:60
QString iso639_key_toName(int iso639_2)
Converts a canonical key to language name in English.
Definition: iso639.cpp:114
const std::array< const std::string, 256 > descriptor_tag_strings
static uint maxPriority(const QMap< uint, uint > &langPrefs)
static void comma_list_append(QString &str, const QString &extra)
#define EMPTY_STR_16
std::vector< const unsigned char * > desc_list_t
QString indentSpaces(unsigned int level, unsigned int size=4)
Definition: stringutil.h:40