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  str.append(QString(" %1").arg(FrequencyHz(i)));
508 
509  return str;
510 }
511 
513 {
514  QString str = "";
515 
516  if (IsDTV())
517  str.append(" (TV)");
518  else if (IsDigitalAudio())
519  str.append(" (Radio)");
520  else if (IsHDTV())
521  str.append(" (HDTV)");
522  else if (IsUHDTV())
523  str.append(" (UHDTV)");
524  else if (IsTeletext())
525  str.append(" (Teletext)");
526  else
527  str.append(QString(" (Unknown 0x%1)").arg(ServiceType(),2,16,QChar('0')));
528 
529  return str;
530 }
531 
532 QString TeletextDescriptor::toString(void) const
533 {
534  QString str = QString("Teletext Descriptor: %1 pages")
535  .arg(StreamCount());
536 
537  for (uint i = 0; i < StreamCount(); i++)
538  {
539  if (1 != StreamCount())
540  str.append("\n ");
541 
542  str.append(QString(" type(%1) mag(%2) page(%3) lang(%4)")
543  .arg(TeletextType(i))
544  .arg(TeletextMagazineNum(i), 0, 16)
545  .arg(TeletextPageNum(i), 2, 16, QChar('0'))
546  .arg(LanguageString(i)));
547  }
548 
549  return str;
550 }
551 
553 {
554  QString str = QString("CableDeliverySystemDescriptor: ");
555 
556  str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
557  str.append(QString(" Mod=%1, SymbR=%2, FECInner=%3, FECOuter=%4")
558  .arg(ModulationString())
559  .arg(SymbolRateHz())
560  .arg(FECInnerString())
561  .arg(FECOuterString()));
562 
563  return str;
564 }
565 
567 {
568  QString str = QString("SatelliteDeliverySystemDescriptor: ");
569 
570  str.append(QString("Frequency: %1, Type: %2\n").arg(FrequencykHz())
571  .arg(ModulationSystemString()));
572  str.append(QString(" Mod=%1, SymbR=%2, FECInner=%3, Orbit=%4, Pol=%5")
573  .arg(ModulationString())
574  .arg(SymbolRateHz())
575  .arg(FECInnerString())
576  .arg(OrbitalPositionString())
577  .arg(PolarizationString()));
578 
579  return str;
580 }
581 
583 {
584  QString str = QString("TerrestrialDeliverySystemDescriptor: ");
585 
586  str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
587  str.append(QString(" BW=%1k, C=%2, HP=%3, LP=%4, GI=%5, TransMode=%6k")
588  .arg(BandwidthString())
589  .arg(ConstellationString())
590  .arg(CodeRateHPString())
591  .arg(CodeRateLPString())
592  .arg(GuardIntervalString())
593  .arg(TransmissionModeString()));
594 
595  return str;
596 }
597 
599 {
600  QString ret = "UKChannelListDescriptor sid->chan_num: ";
601  for (uint i = 0; i < ChannelCount(); i++)
602  {
603  ret += QString("%1->%2").arg(ServiceID(i)).arg(ChannelNumber(i));
604  ret += (i+1 < ChannelCount()) ? (i+3)%10 ? ", " : ",\n " : "";
605  }
606  return ret;
607 }
608 
610 {
611  QString ret = "DVBSimulcastChannelDescriptor sid->chan_num: ";
612  for (uint i = 0; i < ChannelCount(); i++)
613  {
614  ret += QString("%1->%2").arg(ServiceID(i)).arg(ChannelNumber(i));
615  ret += (i+1 < ChannelCount()) ? (i+3)%10 ? ", " : ",\n " : "";
616  }
617  return ret;
618 }
619 
621 {
622  QString ret = "Sky Logical Channel Number Descriptor ";
623  ret += QString("(0x%1) ").arg(DescriptorTag(),2,16,QChar('0'));
624  ret += QString("length(%1)").arg(DescriptorLength());
625 
626  ret += QString("\n RegionID (%1) (0x%2) Raw (0x%3)")
627  .arg(RegionID()).arg(RegionID(),4,16,QChar('0')).arg(RegionRaw(),4,16,QChar('0'));
628 
629  for (uint i=0; i<ServiceCount(); i++)
630  {
631  ret += QString("\n ServiceID (%1) (0x%2) ").arg(ServiceID(i)).arg(ServiceID(i),4,16,QChar('0'));
632  ret += QString("ServiceType (0x%1) ").arg(ServiceType(i),2,16,QChar('0'));
633  ret += QString("LCN (%1) ").arg(LogicalChannelNumber(i));
634  ret += QString("ChannelID(0x%1) ").arg(ChannelID(i),4,16,QChar('0'));
635  ret += QString("Flags(0x%1) ").arg(Flags(i),4,16,QChar('0'));
636  }
637 
638  return ret;
639 }
640 
642 {
643  QString ret = "Freesat Logical Channel Number Descriptor ";
644  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
645  ret += QString(" length(%1)").arg(DescriptorLength());
646 
647  for (uint i=0; i<ServiceCount(); i++)
648  {
649  ret += QString("\n ServiceID (%1) (0x%2) ").arg(ServiceID(i)).arg(ServiceID(i),4,16,QChar('0'));
650  ret += QString("ChanID (0x%1)").arg(ChanID(i), 4, 16, QChar('0'));
651  for (uint j=0; j<LCNCount(i); j++)
652  {
653  ret += QString("\n LCN: %1 Region: %2").arg(LogicalChannelNumber(i,j),3).arg(RegionID(i,j));
654  }
655  }
656  return ret;
657 }
658 
660 {
661  QString ret = "Freesat Region Descriptor ";
662  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
663  ret += QString(" length(%1)").arg(DescriptorLength());
664 
665  for (uint i=0; i<RegionCount(); ++i)
666  {
667  uint region_id = RegionID(i);
668  QString language = Language(i);
669  QString region_name = RegionName(i);
670  ret += QString("\n Region (%1) (%2) '%3'")
671  .arg(region_id,2).arg(language).arg(region_name);
672  }
673  return ret;
674 }
675 
677 {
678  QString ret = QString("Freesat Callsign Descriptor ");
679  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
680  ret += QString(" length(%1)").arg(DescriptorLength());
681  ret += QString(" (%1) '%2'").arg(Language()).arg(Callsign());
682  return ret;
683 }
684 
686 {
687  QString ret = QString("OpenTV ChannelList Descriptor region: %1 sid->chan_num(id): ").arg(RegionID());
688  for (uint i = 0; i < ChannelCount(); i++)
689  {
690  ret += QString("%1->%2(%3)").arg(ServiceID(i)).arg(ChannelNumber(i)).arg(ChannelID(i));
691  ret += (i+1<ChannelCount()) ? ", " : "";
692  }
693  return ret;
694 }
695 
697 {
698  QString ret = QString("CAIdentifierDescriptor ");
699  for (uint i = 0; i < CASystemCount(); ++i)
700  {
701  ret += QString("ca_system_id(0x%1) ")
702  .arg(CASystemId(i), 0, 16);
703  }
704  return ret;
705 }
706 
708 {
709  QString ret = QString("DataBroadcastDescriptor: "
710  "data_broadcast_id(%1) "
711  "component_tag(%1) ")
712  .arg(DataBroadcastId(), 0, 10)
713  .arg(DataComponentTag(), 0, 10);
714 
715  ret += QString("selector(0x ");
716  for (uint i = 0; i < SelectorLength(); i++)
717  ret += QString("%1 ").arg(Selector()[i], 0, 16);
718  ret += ") ";
719 
720  ret += QString("ISO_639_language_code(%1) ")
721  .arg(LanguageString());
722 
723  ret += QString("text(%1) ") + Text();
724 
725  return ret;
726 }
727 
729 {
730  QString ret = QString("LocalTimeOffsetDescriptor ");
731  uint count = Count();
732  for (uint i = 0; i < count; ++i)
733  {
734  ret += QString("country_code(%1) country_region_id(0x%2) "
735  "local_time_offset_with_polarity(%3) "
736  "time_of_change(TODO)")
737  .arg(CountryCodeString(i))
738  .arg(CountryRegionId(i), 0, 16)
740  // TODO add time of change
741  }
742  return ret;
743 }
744 
746 {
747  QString ret = QString("NVODReferenceDescriptor ");
748  for (uint i = 0; i < Count(); ++i)
749  {
750  ret += QString("transport_stream_id(0x%1) original_network_id(0x%2) "
751  "service_id(0x%3) ")
752  .arg(TransportStreamId(i), 0, 16)
753  .arg(OriginalNetworkId(i), 0, 16)
754  .arg(ServiceId(i), 0, 16);
755  }
756  return ret;
757 }
758 
760 {
761  return QString("PartialTransportStreamDescriptor peak_rate(%1) "
762  "min_overall_smooth_rate(%2) max_overall_smooth_buf(3)")
763  .arg(PeakRate()).arg(SmoothRate()).arg(SmoothBuf());
764 }
765 
766 QString AC3Descriptor::toString(void) const
767 {
768  QString ret = QString("AC3DescriptorDescriptor ");
769  if (HasComponentType())
770  ret += QString("component_type(%1) ")
771  .arg(ComponentType(), 0, 10);
772  if (HasBSID())
773  ret += QString("bsid(0x%1) ").arg(BSID(),0,16);
774  if (HasMainID())
775  ret += QString("mainid(0x%1) ").arg(MainID(),0,16);
776  if (HasASVC())
777  ret += QString("asvc(%1) ").arg(ASVC());
778  return ret;
779 }
780 
781 QMap<QString,QString> ExtendedEventDescriptor::Items(void) const
782 {
783  QMap<QString, QString> ret;
784 
785  uint index = 0;
786 
787  /* handle all items
788  * minimum item size is for 8bit length + 8bit length
789  */
790  while (LengthOfItems() - index >= 2)
791  {
792  QString item_description = dvb_decode_text (&m_data[8 + index], m_data[7 + index]);
793  index += 1 + m_data[7 + index];
794  QString item = dvb_decode_text (&m_data[8 + index], m_data[7 + index]);
795  index += 1 + m_data[7 + index];
796  ret.insertMulti (item_description, item);
797  }
798 
799  return ret;
800 }
uint ChanID(int i) 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 freesat_huffman_to_string(const unsigned char *compressed, uint size)
bool HasComponentType(void) const
unsigned long long FrequencyHz(uint i) const
static QMutex s_categoryLock
uint ChannelID(int i) const
uint ServiceCount(void) const
int CASystemId(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.c:35
uint ServiceID(uint i) const
uint MainID(void) const
static QString decode_iso6937(const unsigned char *buf, uint length)
uint CountryRegionId(uint i) const
const uint16_t iso6937table_base[256]
uint ServiceCount(void) const
static int x4
Definition: mythsocket.cpp:63
uint StreamCount(void) const
uint TransportStreamId(uint i) const
uint ChannelNumber(uint i) const
uint LogicalChannelNumber(int i, int j) const
uint ASVC(void) const
const unsigned char * m_data
QString toString(void) const override
uint ChannelID(uint i) const
uint RegionCount(void) const
QString toString(void) const override
static void Init(void)
uint Count(void) const
uint TeletextType(uint i) const
bool IsTeletext(void) const
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
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 ServiceID(int i) const
QString Language(void) const
QString CountryCodeString(uint i) const
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
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
uint RegionID(int i, int j) const
QString toString(void) const override
QString toString(void) const override
QString TransmissionModeString(void) const
QString MobileHandOverTypeString(void) const
QString toString(void) const override
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
QString dvb_decode_short_name(const unsigned char *src, uint raw_length)
QString LanguageString(uint i) const
QString ModulationSystemString(void) 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
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 CASystemCount(void) const
QString OrbitalPositionString(void) const
uint Nibble1(uint i) const
QString toString(void) const override
static int x1
Definition: mythsocket.cpp:60