MythTV  master
dvbdescriptors.cpp
Go to the documentation of this file.
1 // C headers
2 #include <unistd.h>
3 #include <algorithm>
4 
5 // Qt headers
6 #include <QTextCodec>
7 #include <QCoreApplication>
8 
9 // MythTV headers
10 #include "dvbdescriptors.h"
11 #include "iso6937tables.h"
12 #include "freesat_huffman.h"
13 #include "mythlogging.h"
14 #include "programinfo.h"
15 
16 
17 static QString decode_iso6937(const unsigned char *buf, uint length)
18 {
19  // ISO/IEC 6937 to unicode (UCS2) convertor...
20  // This is a composed encoding - accent first then plain character
21  QString result = "";
22  ushort ch = 0x20;
23  for (uint i = 0; (i < length) && buf[i]; i++)
24  {
25  if (ch == 0xFFFF)
26  {
27  // Process second byte of two byte character
28  ch = iso6937table_secondary[buf[i-1]][buf[i]];
29  if (ch == 0xFFFF)
30  {
31  // If no valid code found in secondary table,
32  // reprocess this second byte as first byte.
33  ch = iso6937table_base[buf[i]];
34  if (ch == 0xFFFF)
35  continue; // process second byte
36  }
37  }
38  else
39  {
40  // Process first character of two possible characters.
41  // double byte characters have a sentinel (0xffff) in this table.
42  ch = iso6937table_base[buf[i]];
43  if (ch == 0xFFFF)
44  continue; // process second byte
45 
46  }
47  result += QChar(ch);
48  }
49  return result;
50 }
51 
52 static QString decode_text(const unsigned char *buf, uint length);
53 
54 // Decode a text string according to ETSI EN 300 468 Annex A
55 QString dvb_decode_text(const unsigned char *src, uint raw_length,
56  const unsigned char *encoding_override,
57  uint encoding_override_length)
58 {
59  if (!raw_length)
60  return "";
61 
62  if (src[0] == 0x1f)
63  return freesat_huffman_to_string(src, raw_length);
64 
65  /* UCS-2 aka ISO/IEC 10646-1 Basic Multilingual Plane */
66  if (src[0] == 0x11)
67  {
68  size_t length = (raw_length - 1) / 2;
69  auto *to = new QChar[length];
70  for (size_t i=0; i<length; i++)
71  to[i] = (src[1 + i*2] << 8) + src[1 + i*2 + 1];
72  QString to2(to, length);
73  delete [] to;
74  return to2;
75  }
76 
77  if (((0x11 < src[0]) && (src[0] < 0x15)) ||
78  ((0x15 < src[0]) && (src[0] < 0x1f)))
79  {
80  // TODO: Handle multi-byte encodings
81  LOG(VB_SIPARSER, LOG_ERR,
82  "dvb_decode_text: Multi-byte coded text is not yet supported.");
83  return "";
84  }
85 
86  // if a override encoding is specified and the default ISO 6937 encoding
87  // would be used copy the override encoding in front of the text
88  auto *dst = new unsigned char[raw_length + encoding_override_length];
89 
90  uint length = 0;
91  if (encoding_override && src[0] >= 0x20) {
92  memcpy(dst, encoding_override, encoding_override_length);
93  length = encoding_override_length;
94  }
95 
96  // Strip formatting characters
97  for (uint i = 0; i < raw_length; i++)
98  {
99  if ((src[i] < 0x80) || (src[i] > 0x9F))
100  {
101  dst[length++] = src[i];
102  // replace CR/LF with a space
103  }
104  else if (src[i] == 0x8A)
105  {
106  dst[length++] = 0x20;
107  }
108  }
109 
110  // Exit on empty string, sans formatting.
111 
112  QString sStr = (!length) ? "" : decode_text(dst, length);
113 
114  delete [] dst;
115 
116  return sStr;
117 }
118 
119 static QString decode_text(const unsigned char *buf, uint length)
120 {
121  // Only some of the QTextCodec calls are reentrant.
122  // If you use this please verify that you are using a reentrant call.
123  static const QTextCodec *s_iso8859Codecs[16] =
124  {
125  QTextCodec::codecForName("Latin1"),
126  QTextCodec::codecForName("ISO8859-1"), // Western
127  QTextCodec::codecForName("ISO8859-2"), // Central European
128  QTextCodec::codecForName("ISO8859-3"), // Central European
129  QTextCodec::codecForName("ISO8859-4"), // Baltic
130  QTextCodec::codecForName("ISO8859-5"), // Cyrillic
131  QTextCodec::codecForName("ISO8859-6"), // Arabic
132  QTextCodec::codecForName("ISO8859-7"), // Greek
133  QTextCodec::codecForName("ISO8859-8"), // Hebrew, visually ordered
134  QTextCodec::codecForName("ISO8859-9"), // Turkish
135  QTextCodec::codecForName("ISO8859-10"),
136  QTextCodec::codecForName("ISO8859-11"),
137  QTextCodec::codecForName("ISO8859-12"),
138  QTextCodec::codecForName("ISO8859-13"),
139  QTextCodec::codecForName("ISO8859-14"),
140  QTextCodec::codecForName("ISO8859-15"), // Western
141  };
142 
143  // Decode using the correct text codec
144  if (buf[0] >= 0x20)
145  {
146  return decode_iso6937(buf, length);
147  }
148  if ((buf[0] >= 0x01) && (buf[0] <= 0x0B))
149  {
150  return s_iso8859Codecs[4 + buf[0]]->toUnicode((char*)(buf + 1), length - 1);
151  }
152  if (buf[0] == 0x10)
153  {
154  // If the first byte of the text field has a value "0x10"
155  // then the following two bytes carry a 16-bit value (uimsbf) N
156  // to indicate that the remaining data of the text field is
157  // coded using the character code table specified by
158  // ISO Standard 8859, parts 1 to 9
159 
160  uint code = buf[1] << 8 | buf[2];
161  if (code <= 15)
162  return s_iso8859Codecs[code]->toUnicode((char*)(buf + 3), length - 3);
163  return QString::fromLocal8Bit((char*)(buf + 3), length - 3);
164  }
165  if (buf[0] == 0x15) // Already Unicode
166  {
167  return QString::fromUtf8((char*)(buf + 1), length - 1);
168  }
169 
170  // Unknown/invalid encoding - assume local8Bit
171  return QString::fromLocal8Bit((char*)(buf + 1), length - 1);
172 }
173 
174 
175 QString dvb_decode_short_name(const unsigned char *src, uint raw_length)
176 {
177  if (raw_length > 50)
178  {
179  LOG(VB_SIPARSER, LOG_WARNING,
180  QString("dvb_decode_short_name: name is %1 chars "
181  "long. Unlikely to be a short name.")
182  .arg(raw_length));
183  return "";
184  }
185 
186  if (((0x10 < src[0]) && (src[0] < 0x15)) ||
187  ((0x15 < src[0]) && (src[0] < 0x20)))
188  {
189  // TODO: Handle multi-byte encodings
190  LOG(VB_SIPARSER, LOG_ERR, "dvb_decode_short_name: "
191  "Multi-byte coded text is not yet supported.");
192  return "";
193  }
194 
195  auto *dst = new unsigned char[raw_length];
196  uint length = 0;
197 
198  // check for emphasis control codes
199  for (uint i = 0; i < raw_length; i++)
200  {
201  if (src[i] == 0x86)
202  {
203  while ((++i < raw_length) && (src[i] != 0x87))
204  {
205  if ((src[i] < 0x80) || (src[i] > 0x9F))
206  {
207  dst[length++] = src[i];
208  }
209  // replace CR/LF with a space
210  else if (src[i] == 0x8A)
211  {
212  dst[length++] = 0x20;
213  }
214  }
215  }
216  }
217 
218  QString sStr = (!length) ? dvb_decode_text(src, raw_length)
219  : decode_text(dst, length);
220 
221  delete [] dst;
222 
223  return sStr;
224 }
225 
227 QMap<uint,QString> ContentDescriptor::s_categoryDesc;
228 volatile bool ContentDescriptor::s_categoryDescExists = false;
229 
231 {
232  if (0x1 == Nibble1(i))
234  if (0x4 == Nibble1(i))
237 }
238 
239 const char *linkage_types[] =
240 {
241  "Reserved(0x00)",
242  "Information Service",
243  "EPG Service",
244  "CA Replacement Service",
245  "TS Containing Complete Network/Bouquet SI",
246  "Service Replacement Service",
247  "Data Broadcast Service",
248  "RCS Map",
249  "Mobile Hand-Over",
250  "System Software Update Service",
251  "TS Containing SSU, BAT or NIT",
252  "IP/MAC Notification Service",
253  "TS Containing INT, BAT or NIT",
254  "Event Linkage",
255 };
256 
257 
259 {
260  if (LinkageType() < (sizeof(linkage_types) / sizeof(const char*)))
261  return QString(linkage_types[LinkageType()]);
262  if ((LinkageType() <= 0x7f) || (LinkageType() == 0x7f))
263  return QString("Reserved(0x%1)").arg(LinkageType(),2,16,QChar('0'));
264  return QString("User Defined(0x%1)").arg(LinkageType(),2,16,QChar('0'));
265 }
266 
268 {
270  return "Hand-Over to an Identical Service";
272  return "Hand-Over to a Local Variation";
274  return "Hand-over to an Associated Service";
275  return "Reserved";
276 }
277 
279 {
281  Init();
282 
283  QMutexLocker locker(&s_categoryLock);
284 
285  // Try to get detailed description
286  QMap<uint,QString>::const_iterator it = s_categoryDesc.find(Nibble(i));
287  if (it != s_categoryDesc.end())
288  return *it;
289 
290  // Fall back to category description
291  it = s_categoryDesc.find(Nibble1(i)<<4);
292  if (it != s_categoryDesc.end())
293  return *it;
294 
295  // Found nothing? Just return empty string.
296  return "";
297 }
298 
300 {
301  QString tmp("ContentDescriptor: ");
302  for (uint i = 0; i < Count(); i++)
304  return tmp;
305 }
306 
308 {
309  QMutexLocker locker(&s_categoryLock);
310 
312  return;
313 
314  //: %1 is the main category, %2 is the subcategory
315  QString subCatStr = QCoreApplication::translate("(Categories)",
316  "%1 - %2", "Category with subcategory display");
317 
318  s_categoryDesc[0x10] = QCoreApplication::translate("(Categories)", "Movie");
319  s_categoryDesc[0x11] = subCatStr
320  .arg(QCoreApplication::translate("(Categories)", "Movie"))
321  .arg(QCoreApplication::translate("(Categories)", "Detective/Thriller"));
322  s_categoryDesc[0x12] = subCatStr
323  .arg(QCoreApplication::translate("(Categories)", "Movie"))
324  .arg(QCoreApplication::translate("(Categories)",
325  "Adventure/Western/War"));
326  s_categoryDesc[0x13] = subCatStr
327  .arg(QCoreApplication::translate("(Categories)", "Movie"))
328  .arg(QCoreApplication::translate("(Categories)",
329  "Science Fiction/Fantasy/Horror"));
330  s_categoryDesc[0x14] = subCatStr
331  .arg(QCoreApplication::translate("(Categories)", "Movie"))
332  .arg(QCoreApplication::translate("(Categories)", "Comedy"));
333  s_categoryDesc[0x15] = subCatStr
334  .arg(QCoreApplication::translate("(Categories)", "Movie"))
335  .arg(QCoreApplication::translate("(Categories)",
336  "Soap/melodrama/folkloric"));
337  s_categoryDesc[0x16] = subCatStr
338  .arg(QCoreApplication::translate("(Categories)", "Movie"))
339  .arg(QCoreApplication::translate("(Categories)", "Romance"));
340  s_categoryDesc[0x17] = subCatStr
341  .arg(QCoreApplication::translate("(Categories)","Movie"))
342  .arg(QCoreApplication::translate("(Categories)",
343  "Serious/Classical/Religious/Historical Movie/Drama"));
344  s_categoryDesc[0x18] = subCatStr
345  .arg(QCoreApplication::translate("(Categories)","Movie"))
346  .arg(QCoreApplication::translate("(Categories)", "Adult",
347  "Adult Movie"));
348 
349  s_categoryDesc[0x20] = QCoreApplication::translate("(Categories)", "News");
350  s_categoryDesc[0x21] = QCoreApplication::translate("(Categories)",
351  "News/weather report");
352  s_categoryDesc[0x22] = QCoreApplication::translate("(Categories)",
353  "News magazine");
354  s_categoryDesc[0x23] = QCoreApplication::translate("(Categories)",
355  "Documentary");
356  s_categoryDesc[0x24] = QCoreApplication::translate("(Categories)",
357  "Intelligent Programs");
358 
359  s_categoryDesc[0x30] = QCoreApplication::translate("(Categories)",
360  "Entertainment");
361  s_categoryDesc[0x31] = QCoreApplication::translate("(Categories)",
362  "Game Show");
363  s_categoryDesc[0x32] = QCoreApplication::translate("(Categories)",
364  "Variety Show");
365  s_categoryDesc[0x33] = QCoreApplication::translate("(Categories)",
366  "Talk Show");
367 
368  s_categoryDesc[0x40] = QCoreApplication::translate("(Categories)",
369  "Sports");
370  s_categoryDesc[0x41] = QCoreApplication::translate("(Categories)",
371  "Special Events (World Cup, World Series, etc)");
372  s_categoryDesc[0x42] = QCoreApplication::translate("(Categories)",
373  "Sports Magazines");
374  s_categoryDesc[0x43] = QCoreApplication::translate("(Categories)",
375  "Football (Soccer)");
376  s_categoryDesc[0x44] = QCoreApplication::translate("(Categories)",
377  "Tennis/Squash");
378  s_categoryDesc[0x45] = QCoreApplication::translate("(Categories)",
379  "Misc. Team Sports");
380  // not football/soccer
381  s_categoryDesc[0x46] = QCoreApplication::translate("(Categories)",
382  "Athletics");
383  s_categoryDesc[0x47] = QCoreApplication::translate("(Categories)",
384  "Motor Sport");
385  s_categoryDesc[0x48] = QCoreApplication::translate("(Categories)",
386  "Water Sport");
387  s_categoryDesc[0x49] = QCoreApplication::translate("(Categories)",
388  "Winter Sports");
389  s_categoryDesc[0x4A] = QCoreApplication::translate("(Categories)",
390  "Equestrian");
391  s_categoryDesc[0x4B] = QCoreApplication::translate("(Categories)",
392  "Martial Sports");
393 
394  s_categoryDesc[0x50] = QCoreApplication::translate("(Categories)", "Kids");
395  s_categoryDesc[0x51] = QCoreApplication::translate("(Categories)",
396  "Pre-School Children's Programs");
397  s_categoryDesc[0x52] = QCoreApplication::translate("(Categories)",
398  "Entertainment Programs for 6 to 14");
399  s_categoryDesc[0x53] = QCoreApplication::translate("(Categories)",
400  "Entertainment Programs for 10 to 16");
401  s_categoryDesc[0x54] = QCoreApplication::translate("(Categories)",
402  "Informational/Educational");
403  s_categoryDesc[0x55] = QCoreApplication::translate("(Categories)",
404  "Cartoons/Puppets");
405 
406  s_categoryDesc[0x60] = QCoreApplication::translate("(Categories)",
407  "Music/Ballet/Dance");
408  s_categoryDesc[0x61] = QCoreApplication::translate("(Categories)",
409  "Rock/Pop");
410  s_categoryDesc[0x62] = QCoreApplication::translate("(Categories)",
411  "Classical Music");
412  s_categoryDesc[0x63] = QCoreApplication::translate("(Categories)",
413  "Folk Music");
414  s_categoryDesc[0x64] = QCoreApplication::translate("(Categories)",
415  "Jazz");
416  s_categoryDesc[0x65] = QCoreApplication::translate("(Categories)",
417  "Musical/Opera");
418  s_categoryDesc[0x66] = QCoreApplication::translate("(Categories)",
419  "Ballet");
420 
421  s_categoryDesc[0x70] = QCoreApplication::translate("(Categories)",
422  "Arts/Culture");
423  s_categoryDesc[0x71] = QCoreApplication::translate("(Categories)",
424  "Performing Arts");
425  s_categoryDesc[0x72] = QCoreApplication::translate("(Categories)",
426  "Fine Arts");
427  s_categoryDesc[0x73] = QCoreApplication::translate("(Categories)",
428  "Religion");
429  s_categoryDesc[0x74] = QCoreApplication::translate("(Categories)",
430  "Popular Culture/Traditional Arts");
431  s_categoryDesc[0x75] = QCoreApplication::translate("(Categories)",
432  "Literature");
433  s_categoryDesc[0x76] = QCoreApplication::translate("(Categories)",
434  "Film/Cinema");
435  s_categoryDesc[0x77] = QCoreApplication::translate("(Categories)",
436  "Experimental Film/Video");
437  s_categoryDesc[0x78] = QCoreApplication::translate("(Categories)",
438  "Broadcasting/Press");
439  s_categoryDesc[0x79] = QCoreApplication::translate("(Categories)",
440  "New Media");
441  s_categoryDesc[0x7A] = QCoreApplication::translate("(Categories)",
442  "Arts/Culture Magazines");
443  s_categoryDesc[0x7B] = QCoreApplication::translate("(Categories)", "Fashion");
444 
445  s_categoryDesc[0x80] = QCoreApplication::translate("(Categories)",
446  "Social/Policical/Economics");
447  s_categoryDesc[0x81] = QCoreApplication::translate("(Categories)",
448  "Magazines/Reports/Documentary");
449  s_categoryDesc[0x82] = QCoreApplication::translate("(Categories)",
450  "Economics/Social Advisory");
451  s_categoryDesc[0x83] = QCoreApplication::translate("(Categories)",
452  "Remarkable People");
453 
454  s_categoryDesc[0x90] = QCoreApplication::translate("(Categories)",
455  "Education/Science/Factual");
456  s_categoryDesc[0x91] = QCoreApplication::translate("(Categories)",
457  "Nature/animals/Environment");
458  s_categoryDesc[0x92] = QCoreApplication::translate("(Categories)",
459  "Technology/Natural Sciences");
460  s_categoryDesc[0x93] = QCoreApplication::translate("(Categories)",
461  "Medicine/Physiology/Psychology");
462  s_categoryDesc[0x94] = QCoreApplication::translate("(Categories)",
463  "Foreign Countries/Expeditions");
464  s_categoryDesc[0x95] = QCoreApplication::translate("(Categories)",
465  "Social/Spiritual Sciences");
466  s_categoryDesc[0x96] = QCoreApplication::translate("(Categories)",
467  "Further Education");
468  s_categoryDesc[0x97] = QCoreApplication::translate("(Categories)",
469  "Languages");
470 
471  s_categoryDesc[0xA0] = QCoreApplication::translate("(Categories)",
472  "Leisure/Hobbies");
473  s_categoryDesc[0xA1] = QCoreApplication::translate("(Categories)",
474  "Tourism/Travel");
475  s_categoryDesc[0xA2] = QCoreApplication::translate("(Categories)",
476  "Handicraft");
477  s_categoryDesc[0xA3] = QCoreApplication::translate("(Categories)",
478  "Motoring");
479  s_categoryDesc[0xA4] = QCoreApplication::translate("(Categories)",
480  "Fitness & Health");
481  s_categoryDesc[0xA5] = QCoreApplication::translate("(Categories)", "Cooking");
482  s_categoryDesc[0xA6] = QCoreApplication::translate("(Categories)",
483  "Advertizement/Shopping");
484  s_categoryDesc[0xA7] = QCoreApplication::translate("(Categories)",
485  "Gardening");
486  // Special
487  s_categoryDesc[0xB0] = QCoreApplication::translate("(Categories)",
488  "Original Language");
489  s_categoryDesc[0xB1] = QCoreApplication::translate("(Categories)",
490  "Black & White");
491  s_categoryDesc[0xB2] = QCoreApplication::translate("(Categories)",
492  "\"Unpublished\" Programs");
493  s_categoryDesc[0xB3] = QCoreApplication::translate("(Categories)",
494  "Live Broadcast");
495  // UK Freeview custom id
496  s_categoryDesc[0xF0] = QCoreApplication::translate("(Categories)",
497  "Drama");
498 
499  s_categoryDescExists = true;
500 }
501 
503 {
504  QString str = "FrequencyListDescriptor: frequencies: ";
505 
506  for (uint i = 0; i < FrequencyCount(); i++)
507  {
508  str += QString("%1").arg(FrequencyHz(i));
509  str += (i+1 < FrequencyCount()) ? (i+4)%10 ? ", " : ",\n " : "";
510  }
511 
512  return str;
513 }
514 
516 {
517  QString str = "";
518 
519  if (IsDTV())
520  str.append(" (TV)");
521  else if (IsDigitalAudio())
522  str.append(" (Radio)");
523  else if (IsHDTV())
524  str.append(" (HDTV)");
525  else if (IsUHDTV())
526  str.append(" (UHDTV)");
527  else if (IsTeletext())
528  str.append(" (Teletext)");
529  else
530  str.append(QString(" (Unknown 0x%1)").arg(ServiceType(),2,16,QChar('0')));
531 
532  return str;
533 }
534 
535 QString TeletextDescriptor::toString(void) const
536 {
537  QString str = QString("Teletext Descriptor: %1 pages")
538  .arg(StreamCount());
539 
540  for (uint i = 0; i < StreamCount(); i++)
541  {
542  if (1 != StreamCount())
543  str.append("\n ");
544 
545  str.append(QString(" type(%1) mag(%2) page(%3) lang(%4)")
546  .arg(TeletextType(i))
547  .arg(TeletextMagazineNum(i), 0, 16)
548  .arg(TeletextPageNum(i), 2, 16, QChar('0'))
549  .arg(LanguageString(i)));
550  }
551 
552  return str;
553 }
554 
556 {
557  QString str = QString("CableDeliverySystemDescriptor: ");
558 
559  str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
560  str.append(QString(" Mod=%1, SymbR=%2, FECInner=%3, FECOuter=%4")
561  .arg(ModulationString())
562  .arg(SymbolRateHz())
563  .arg(FECInnerString())
564  .arg(FECOuterString()));
565 
566  return str;
567 }
568 
570 {
571  QString str = QString("SatelliteDeliverySystemDescriptor: ");
572 
573  str.append(QString("Frequency: %1, Type: %2\n").arg(FrequencykHz())
574  .arg(ModulationSystemString()));
575  str.append(QString(" Mod=%1, SymbR=%2, FECInner=%3, Orbit=%4, Pol=%5")
576  .arg(ModulationString())
577  .arg(SymbolRateHz())
578  .arg(FECInnerString())
579  .arg(OrbitalPositionString())
580  .arg(PolarizationString()));
581 
582  return str;
583 }
584 
586 {
587  QString str = QString("TerrestrialDeliverySystemDescriptor: ");
588 
589  str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
590  str.append(QString(" BW=%1MHz C=%2 HP=%3 LP=%4 GI=%5 TransMode=%6k")
591  .arg(BandwidthString())
592  .arg(ConstellationString())
593  .arg(CodeRateHPString())
594  .arg(CodeRateLPString())
595  .arg(GuardIntervalString())
596  .arg(TransmissionModeString()));
597 
598  return str;
599 }
600 
601 // 0x7F 0x00
603 {
604  QString str = QString("ImageIconDescriptor ");
605  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
606  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
607  str += QString("length(%1) ").arg(DescriptorLength());
608  str += QString("number %1/%2").arg(DescriptorNumber()).arg(LastDescriptorNumber());
609  //
610  // TBD
611  //
612  str.append(" Dumping\n");
613  str.append(hexdump());
614  return str;
615 }
616 
617 // 0x7F 0x04
619 {
620  m_cellPtrs.clear();
621  m_subCellPtrs.clear();
622 
623  const unsigned char *cp = m_data + 8;
624  for (uint i=0; (cp - m_data + 4) < DescriptorLength(); i++)
625  {
626  m_cellPtrs.push_back(cp);
627  cp += TFSFlag() ? (2 + 1 + FrequencyLoopLength(i)) : (2 + 4);
628  m_subCellPtrs.push_back(cp);
629  cp += 1 + SubcellInfoLoopLength(i);
630  }
631 }
632 
634 {
635  QString str = QString("T2DeliverySystemDescriptor ");
636  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
637  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
638  str += QString("length(%1) ").arg(DescriptorLength());
639  str += QString("plp_id(%1) ").arg(PlpID());
640  str += QString("T2_system_id(%1)").arg(T2SystemID());
641  if (DescriptorLength() > 4)
642  {
643  str += QString("\n %1 ").arg(SisoMisoString());
644  str += QString("BW=%1MHz ").arg(BandwidthString());
645  str += QString("GI=%1 ").arg(GuardIntervalString());
646  str += QString("TransMode=%1 ").arg(TransmissionModeString());
647  str += QString("OF=%1 ").arg(OtherFrequencyFlag());
648  str += QString("TFS=%1 ").arg(TFSFlag());
649  }
650  if (DescriptorLength() > 6)
651  {
652  for (uint i=0; i < NumCells(); i++)
653  {
654  str += QString("\n ");
655  str += QString("cell_id:%1 ").arg(CellID(i));
656  str += QString("centre_frequency:");
657  if (TFSFlag())
658  {
659  for (uint j=0; j<FrequencyLoopLength(i)/4; j++)
660  {
661  str += QString(" %1").arg(CentreFrequency(i,j));
662  }
663  }
664  else
665  {
666  str += QString(" %1").arg(CentreFrequency(i));
667  }
668  for (uint j=0; j<SubcellInfoLoopLength(i)/5; j++)
669  {
670  str += QString("\n ");
671  str += QString("cell_id_extension:%1 ").arg(CellIDExtension(i,j));
672  str += QString("transposer_frequency:%1").arg(TransposerFrequency(i,j));
673  }
674  }
675  }
676  str.append(" Dumping\n");
677  str.append(hexdump());
678  return str;
679 }
680 
681 // 0x7F 0x05
683 {
684  QString str = QString("SHDeliverySystemDescriptor ");
685  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
686  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
687  str += QString("length(%1)").arg(DescriptorLength());
688  //
689  // TBD
690  //
691  str.append(" Dumping\n");
692  str.append(hexdump());
693  return str;
694 }
695 
696 // 0x7F 0x06
698 {
699  QString str = QString("SupplementaryAudioDescriptor ");
700  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
701  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
702  str += QString("length(%1)").arg(DescriptorLength());
703  str += QString("\n ");
704  str += QString("mix_type(%1) ").arg(MixType());
705  str += QString("editorial_classification(%1)").arg(EditorialClassification());
706  str += QString("\n ");
707  str += QString("language_code_present(%1)").arg(LanguageCodePresent());
708  if (LanguageCodePresent() && DescriptorLength() >= 4)
709  {
710  str += QString(" language_code(%1)").arg(LanguageString());
711  }
712  //
713  str.append(" Dumping\n");
714  str.append(hexdump());
715  return str;
716 }
717 
718 // 0x7F 0x07
720 {
721  QString str = QString("NetworkChangeNotiyDescriptor ");
722  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
723  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
724  //
725  str.append(" Dumping\n");
726  str.append(hexdump());
727  return str;
728 }
729 
730 // 0x7F 0x08
732 {
733  QString str = QString("MessageDescriptor ");
734  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
735  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
736  str += QString("length(%1)").arg(DescriptorLength());
737  str += QString("\n ");
738  str += QString("message_id(%1) ").arg(MessageID());
739  str += QString("language_code(%1)").arg(LanguageString());
740  str += QString("\n ");
741  str += QString("text_char(\"%1\")").arg(Message());
742  //
743  str.append(" Dumping\n");
744  str.append(hexdump());
745  return str;
746 }
747 
748 // 0x7F 0x09
750 {
751  QString str = QString("TargetRegionDescriptor ");
752  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
753  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
754  str += QString("length(%1)").arg(DescriptorLength());
755  str += QString("\n ");
756  str += QString("country_code(%1) ").arg(CountryCodeString());
757  //
758  // TBD
759  //
760  str.append(" Dumping\n");
761  str.append(hexdump());
762  return str;
763 }
764 
765 // 0x7F 0x0A
767 {
768  QString str = QString("TargetRegionNameDescriptor ");
769  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
770  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
771  str += QString("length(%1)").arg(DescriptorLength());
772  str += QString("\n ");
773  str += QString("country_code(%1) ").arg(CountryCodeString());
774  str += QString("language_code(%1)").arg(LanguageString());
775  //
776  // TBD
777  //
778  str.append(" Dumping\n");
779  str.append(hexdump());
780  return str;
781 }
782 
783 // 0x7F 0x0B
785 {
786  QString str = QString("ServiceRelocatedDescriptor ");
787  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
788  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
789  str += QString("length(%1)").arg(DescriptorLength());
790  str += QString("\n ");
791  str += QString("old_original_network_id(%1) ").arg(OldOriginalNetworkID());
792  str += QString("old_transport_id(%1) ").arg(OldTransportID());
793  str += QString("old_service_id(%1) ").arg(OldServiceID());
794  //
795  str.append(" Dumping\n");
796  str.append(hexdump());
797  return str;
798 }
799 
800 // 0x7F 0x0D
802 {
803  QString str = QString("C2DeliverySystemDescriptor ");
804  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
805  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
806  str += QString("length(%1)").arg(DescriptorLength());
807  //
808  // TBD
809  //
810  str.append(" Dumping\n");
811  str.append(hexdump());
812  return str;
813 }
814 
815 // 0x7F 0x17
817 {
818  QString str = QString("S2XSatelliteDeliverySystemDescriptor ");
819  str += QString("(0x%1 ").arg(DescriptorTag(),2,16,QChar('0'));
820  str += QString("0x%1) ").arg(DescriptorTagExtension(),2,16,QChar('0'));
821  str += QString("length(%1)").arg(DescriptorLength());
822  //
823  // TBD
824  //
825  str.append(" Dumping\n");
826  str.append(hexdump());
827  return str;
828 }
829 
831 {
832  QString ret = "UKChannelListDescriptor sid->chan_num: ";
833  for (uint i = 0; i < ChannelCount(); i++)
834  {
835  ret += QString("%1->%2").arg(ServiceID(i)).arg(ChannelNumber(i));
836  ret += (i+1 < ChannelCount()) ? (i+4)%10 ? ", " : ",\n " : "";
837  }
838  return ret;
839 }
840 
842 {
843  QString ret = "DVBSimulcastChannelDescriptor sid->chan_num: ";
844  for (uint i = 0; i < ChannelCount(); i++)
845  {
846  ret += QString("%1->%2").arg(ServiceID(i)).arg(ChannelNumber(i));
847  ret += (i+1 < ChannelCount()) ? (i+3)%10 ? ", " : ",\n " : "";
848  }
849  return ret;
850 }
851 
853 {
854  QString ret = "Sky Logical Channel Number Descriptor ";
855  ret += QString("(0x%1) ").arg(DescriptorTag(),2,16,QChar('0'));
856  ret += QString("length(%1)").arg(DescriptorLength());
857 
858  ret += QString("\n RegionID (%1) (0x%2) Raw (0x%3)")
859  .arg(RegionID()).arg(RegionID(),4,16,QChar('0')).arg(RegionRaw(),4,16,QChar('0'));
860 
861  for (uint i=0; i<ServiceCount(); i++)
862  {
863  ret += QString("\n ServiceID (%1) (0x%2) ").arg(ServiceID(i)).arg(ServiceID(i),4,16,QChar('0'));
864  ret += QString("ServiceType (0x%1) ").arg(ServiceType(i),2,16,QChar('0'));
865  ret += QString("LCN (%1) ").arg(LogicalChannelNumber(i));
866  ret += QString("ChannelID(0x%1) ").arg(ChannelID(i),4,16,QChar('0'));
867  ret += QString("Flags(0x%1) ").arg(Flags(i),4,16,QChar('0'));
868  }
869 
870  return ret;
871 }
872 
874 {
875  QString ret = "Freesat Logical Channel Number Descriptor ";
876  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
877  ret += QString(" length(%1)").arg(DescriptorLength());
878 
879  for (uint i=0; i<ServiceCount(); i++)
880  {
881  ret += QString("\n ServiceID (%1) (0x%2) ").arg(ServiceID(i)).arg(ServiceID(i),4,16,QChar('0'));
882  ret += QString("ChanID (0x%1)").arg(ChanID(i), 4, 16, QChar('0'));
883  for (uint j=0; j<LCNCount(i); j++)
884  {
885  ret += QString("\n LCN: %1 Region: %2").arg(LogicalChannelNumber(i,j),3).arg(RegionID(i,j));
886  }
887  }
888  return ret;
889 }
890 
892 {
893  QString ret = "Freesat Region Descriptor ";
894  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
895  ret += QString(" length(%1)").arg(DescriptorLength());
896 
897  for (uint i=0; i<RegionCount(); ++i)
898  {
899  uint region_id = RegionID(i);
900  QString language = Language(i);
901  QString region_name = RegionName(i);
902  ret += QString("\n Region (%1) (%2) '%3'")
903  .arg(region_id,2).arg(language).arg(region_name);
904  }
905  return ret;
906 }
907 
909 {
910  QString ret = QString("Freesat Callsign Descriptor ");
911  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
912  ret += QString(" length(%1)").arg(DescriptorLength());
913  ret += QString(" (%1) '%2'").arg(Language()).arg(Callsign());
914  return ret;
915 }
916 
918 {
919  QString ret = QString("OpenTV ChannelList Descriptor region: %1 sid->chan_num(id): ").arg(RegionID());
920  for (uint i = 0; i < ChannelCount(); i++)
921  {
922  ret += QString("%1->%2(%3)").arg(ServiceID(i)).arg(ChannelNumber(i)).arg(ChannelID(i));
923  ret += (i+1<ChannelCount()) ? ", " : "";
924  }
925  return ret;
926 }
927 
929 {
930  QString ret = QString("CAIdentifierDescriptor ");
931  for (uint i = 0; i < CASystemCount(); ++i)
932  {
933  ret += QString("ca_system_id(0x%1) ")
934  .arg(CASystemId(i), 0, 16);
935  }
936  return ret;
937 }
938 
940 {
941  QString ret = QString("DataBroadcastDescriptor: "
942  "data_broadcast_id(%1) "
943  "component_tag(%1) ")
944  .arg(DataBroadcastId(), 0, 10)
945  .arg(DataComponentTag(), 0, 10);
946 
947  ret += QString("selector(0x ");
948  for (uint i = 0; i < SelectorLength(); i++)
949  ret += QString("%1 ").arg(Selector()[i], 0, 16);
950  ret += ") ";
951 
952  ret += QString("ISO_639_language_code(%1) ")
953  .arg(LanguageString());
954 
955  ret += QString("text(%1) ") + Text();
956 
957  return ret;
958 }
959 
961 {
962  QString ret = QString("LocalTimeOffsetDescriptor ");
963  uint count = Count();
964  for (uint i = 0; i < count; ++i)
965  {
966  ret += QString("country_code(%1) country_region_id(0x%2) "
967  "local_time_offset_with_polarity(%3) "
968  "time_of_change(TODO)")
969  .arg(CountryCodeString(i))
970  .arg(CountryRegionId(i), 0, 16)
972  // TODO add time of change
973  }
974  return ret;
975 }
976 
978 {
979  QString ret = QString("NVODReferenceDescriptor ");
980  for (uint i = 0; i < Count(); ++i)
981  {
982  ret += QString("transport_stream_id(0x%1) original_network_id(0x%2) "
983  "service_id(0x%3) ")
984  .arg(TransportStreamId(i), 0, 16)
985  .arg(OriginalNetworkId(i), 0, 16)
986  .arg(ServiceId(i), 0, 16);
987  }
988  return ret;
989 }
990 
992 {
993  return QString("PartialTransportStreamDescriptor peak_rate(%1) "
994  "min_overall_smooth_rate(%2) max_overall_smooth_buf(3)")
995  .arg(PeakRate()).arg(SmoothRate()).arg(SmoothBuf());
996 }
997 
998 QString AC3Descriptor::toString(void) const
999 {
1000  QString ret = QString("AC3DescriptorDescriptor ");
1001  if (HasComponentType())
1002  ret += QString("component_type(%1) ")
1003  .arg(ComponentType(), 0, 10);
1004  if (HasBSID())
1005  ret += QString("bsid(0x%1) ").arg(BSID(),0,16);
1006  if (HasMainID())
1007  ret += QString("mainid(0x%1) ").arg(MainID(),0,16);
1008  if (HasASVC())
1009  ret += QString("asvc(%1) ").arg(ASVC());
1010  return ret;
1011 }
1012 
1013 QMap<QString,QString> ExtendedEventDescriptor::Items(void) const
1014 {
1015  QMap<QString, QString> ret;
1016 
1017  uint index = 0;
1018 
1019  /* handle all items
1020  * minimum item size is for 8bit length + 8bit length
1021  */
1022  while (LengthOfItems() - index >= 2)
1023  {
1024  QString item_description = dvb_decode_text (&m_data[8 + index], m_data[7 + index]);
1025  index += 1 + m_data[7 + index];
1026  QString item = dvb_decode_text (&m_data[8 + index], m_data[7 + index]);
1027  index += 1 + m_data[7 + index];
1028  ret.insertMulti (item_description, item);
1029  }
1030 
1031  return ret;
1032 }
uint SubcellInfoLoopLength(uint i) const
uint TransposerFrequency(uint i, uint j) const
uint ChanID(int i) const
uint LastDescriptorNumber(void) const
QString toString(void) const override
bool HasASVC(void) const
uint Count(void) const
ProgramInfo::CategoryType GetMythCategory(uint i) const
QMap< QString, QString > Items(void) const
QString RegionName(uint i) const
QString LanguageString(void) const
QString CountryCodeString(void) const
uint OldTransportID(void) const
QString LanguageString(void) const
QString freesat_huffman_to_string(const unsigned char *compressed, uint size)
bool HasComponentType(void) const
unsigned long long FrequencyHz(uint i) const
QString TransmissionModeString(void) const
QString GuardIntervalString(void) const
static QMutex s_categoryLock
QString LanguageString(void) const
QString toString(void) const override
uint MessageID(void) const
uint ChannelID(int i) const
uint ServiceCount(void) const
uint OldServiceID(void) const
int CASystemId(uint i) const
uint CentreFrequency(uint i) const
bool IsUHDTV(void) const
QString toString(void) const override
QString FECInnerString(void) const
uint DescriptorTag(void) const
uint ServiceId(uint i) const
uint RegionID(void) const
QString dvb_decode_text(const unsigned char *src, uint raw_length, const unsigned char *encoding_override, uint encoding_override_length)
QString toString(void) const override
static QString decode_text(const unsigned char *buf, uint length)
uint ServiceID(uint i) const
static guint32 * tmp
Definition: goom_core.cpp:30
QString toString(void) const override
uint ServiceID(uint i) const
uint MainID(void) const
static QString decode_iso6937(const unsigned char *buf, uint length)
uint OtherFrequencyFlag(void) const
uint CountryRegionId(uint i) const
const uint16_t iso6937table_base[256]
vector< const unsigned char * > m_cellPtrs
uint ServiceCount(void) const
static int x4
Definition: mythsocket.cpp:63
QString Message(void) const
uint StreamCount(void) const
uint TransportStreamId(uint i) const
uint ChannelNumber(uint i) const
uint LogicalChannelNumber(int i, int j) const
QString toString(void) const override
QString toString(void) const override
uint ASVC(void) const
QString toString(void) const override
uint EditorialClassification(void) const
const unsigned char * m_data
QString toString(void) const override
uint ChannelID(uint i) const
uint RegionCount(void) const
QString LanguageString(void) const
QString toString(void) const override
static void Init(void)
uint Count(void) const
QString toString(void) const override
uint TeletextType(uint i) const
bool IsTeletext(void) const
QString toString(void) const override
QString toString(void) const override
uint RegionRaw(void) const
QString toString(void) const override
QString Text(void) const
uint ChannelNumber(uint i) const
uint SelectorLength(void) const
QString toString(void) const
uint LengthOfItems(void) const
QString toString(void) const override
uint Flags(int i) const
QString ModulationString(void) const
QString ConstellationString(void) const
QString toString(void) const override
uint ServiceType(int i) const
unsigned int uint
Definition: compat.h:140
uint TeletextPageNum(uint i) const
int LocalTimeOffsetWithPolarity(uint i) const
QString GetDescription(uint i) const
bool HasBSID(void) const
QString Callsign(void) const
uint DataBroadcastId(void) const
uint ServiceType(void) const
QString Language(uint i) const
bool IsDigitalAudio(void) const
static volatile bool s_categoryDescExists
uint DescriptorLength(void) const
uint DescriptorNumber(void) const
uint ServiceID(int i) const
QString Language(void) const
QString CountryCodeString(uint i) const
QString toString(void) const override
vector< const unsigned char * > m_subCellPtrs
QString toString(void) const override
QString myth_category_type_to_string(ProgramInfo::CategoryType category_type)
static QMap< uint, QString > s_categoryDesc
uint TeletextMagazineNum(uint i) const
uint OriginalNetworkId(uint i) const
uint RegionID(int i, int j) const
QString toString(void) const override
QString toString(void) const override
QString SisoMisoString(void) const
QString TransmissionModeString(void) const
QString MobileHandOverTypeString(void) const
QString CountryCodeString(void) const
QString toString(void) const override
uint DescriptorTagExtension(void) const
QString FECOuterString(void) const
QString toString(void) const override
const char * linkage_types[]
QString FECInnerString(void) const
uint Nibble(uint i) const
unsigned long long FrequencyHz(void) const
bool HasMainID(void) const
QString LinkageTypeString(void) const
uint ServiceID(int i) const
uint FrequencyLoopLength(uint i) const
uint CellIDExtension(uint i, uint j) const
QString toString(void) const override
QString dvb_decode_short_name(const unsigned char *src, uint raw_length)
QString LanguageString(uint i) const
uint OldOriginalNetworkID(void) const
QString ModulationSystemString(void) const
uint CellID(uint i) const
QString toString(void) const override
uint LCNCount(int i) const
int RegionID(uint i) const
QString toString(void) const override
const unsigned char * Selector(void) const
QString toString(void) const override
QString hexdump(void) const
unsigned long long FrequencykHz(void) const
uint BSID(void) const
QString ModulationString(void) const
const uint16_t * iso6937table_secondary[256]
uint ComponentType(void) const
uint DataComponentTag(void) const
uint LogicalChannelNumber(int i) const
uint LinkageType(void) const
QString toString(void) const override
QString toString(void) const override
QString toString(void) const override
uint MobileHandOverType(void) const
uint ChannelNumber(uint i) const
uint LanguageCodePresent(void) const
uint CASystemCount(void) const
QString OrbitalPositionString(void) const
uint Nibble1(uint i) const
QString toString(void) const override
QString BandwidthString(void) const
static int x1
Definition: mythsocket.cpp:60
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23