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  dst[length++] = src[i];
101  // replace CR/LF with a space
102  else if (src[i] == 0x8A)
103  dst[length++] = 0x20;
104  }
105 
106  // Exit on empty string, sans formatting.
107 
108  QString sStr = (!length) ? "" : decode_text(dst, length);
109 
110  delete [] dst;
111 
112  return sStr;
113 }
114 
115 static QString decode_text(const unsigned char *buf, uint length)
116 {
117  // Only some of the QTextCodec calls are reentrant.
118  // If you use this please verify that you are using a reentrant call.
119  static const QTextCodec *s_iso8859Codecs[16] =
120  {
121  QTextCodec::codecForName("Latin1"),
122  QTextCodec::codecForName("ISO8859-1"), // Western
123  QTextCodec::codecForName("ISO8859-2"), // Central European
124  QTextCodec::codecForName("ISO8859-3"), // Central European
125  QTextCodec::codecForName("ISO8859-4"), // Baltic
126  QTextCodec::codecForName("ISO8859-5"), // Cyrillic
127  QTextCodec::codecForName("ISO8859-6"), // Arabic
128  QTextCodec::codecForName("ISO8859-7"), // Greek
129  QTextCodec::codecForName("ISO8859-8"), // Hebrew, visually ordered
130  QTextCodec::codecForName("ISO8859-9"), // Turkish
131  QTextCodec::codecForName("ISO8859-10"),
132  QTextCodec::codecForName("ISO8859-11"),
133  QTextCodec::codecForName("ISO8859-12"),
134  QTextCodec::codecForName("ISO8859-13"),
135  QTextCodec::codecForName("ISO8859-14"),
136  QTextCodec::codecForName("ISO8859-15"), // Western
137  };
138 
139  // Decode using the correct text codec
140  if (buf[0] >= 0x20)
141  {
142  return decode_iso6937(buf, length);
143  }
144  if ((buf[0] >= 0x01) && (buf[0] <= 0x0B))
145  {
146  return s_iso8859Codecs[4 + buf[0]]->toUnicode((char*)(buf + 1), length - 1);
147  }
148  if (buf[0] == 0x10)
149  {
150  // If the first byte of the text field has a value "0x10"
151  // then the following two bytes carry a 16-bit value (uimsbf) N
152  // to indicate that the remaining data of the text field is
153  // coded using the character code table specified by
154  // ISO Standard 8859, parts 1 to 9
155 
156  uint code = buf[1] << 8 | buf[2];
157  if (code <= 15)
158  return s_iso8859Codecs[code]->toUnicode((char*)(buf + 3), length - 3);
159  return QString::fromLocal8Bit((char*)(buf + 3), length - 3);
160  }
161  if (buf[0] == 0x15) // Already Unicode
162  {
163  return QString::fromUtf8((char*)(buf + 1), length - 1);
164  }
165 
166  // Unknown/invalid encoding - assume local8Bit
167  return QString::fromLocal8Bit((char*)(buf + 1), length - 1);
168 }
169 
170 
171 QString dvb_decode_short_name(const unsigned char *src, uint raw_length)
172 {
173  if (raw_length > 50)
174  {
175  LOG(VB_SIPARSER, LOG_WARNING,
176  QString("dvb_decode_short_name: name is %1 chars "
177  "long. Unlikely to be a short name.")
178  .arg(raw_length));
179  return "";
180  }
181 
182  if (((0x10 < src[0]) && (src[0] < 0x15)) ||
183  ((0x15 < src[0]) && (src[0] < 0x20)))
184  {
185  // TODO: Handle multi-byte encodings
186  LOG(VB_SIPARSER, LOG_ERR, "dvb_decode_short_name: "
187  "Multi-byte coded text is not yet supported.");
188  return "";
189  }
190 
191  auto *dst = new unsigned char[raw_length];
192  uint length = 0;
193 
194  // check for emphasis control codes
195  for (uint i = 0; i < raw_length; i++)
196  if (src[i] == 0x86)
197  while ((++i < raw_length) && (src[i] != 0x87))
198  {
199  if ((src[i] < 0x80) || (src[i] > 0x9F))
200  dst[length++] = src[i];
201  // replace CR/LF with a space
202  else if (src[i] == 0x8A)
203  dst[length++] = 0x20;
204  }
205 
206  QString sStr = (!length) ? dvb_decode_text(src, raw_length)
207  : decode_text(dst, length);
208 
209  delete [] dst;
210 
211  return sStr;
212 }
213 
215 QMap<uint,QString> ContentDescriptor::categoryDesc;
216 volatile bool ContentDescriptor::categoryDescExists = false;
217 
219 {
220  if (0x1 == Nibble1(i))
222  if (0x4 == Nibble1(i))
225 }
226 
227 const char *linkage_types[] =
228 {
229  "Reserved(0x00)",
230  "Information Service",
231  "EPG Service",
232  "CA Replacement Service",
233  "TS Containing Complete Network/Bouquet SI",
234  "Service Replacement Service",
235  "Data Broadcast Service",
236  "RCS Map",
237  "Mobile Hand-Over",
238  "System Software Update Service",
239  "TS Containing SSU, BAT or NIT",
240  "IP/MAC Notification Service",
241  "TS Containing INT, BAT or NIT",
242  "Event Linkage",
243 };
244 
245 
247 {
248  if (LinkageType() < (sizeof(linkage_types) / sizeof(const char*)))
249  return QString(linkage_types[LinkageType()]);
250  if ((LinkageType() <= 0x7f) || (LinkageType() == 0x7f))
251  return QString("Reserved(0x%1)").arg(LinkageType(),2,16,QChar('0'));
252  return QString("User Defined(0x%1)").arg(LinkageType(),2,16,QChar('0'));
253 }
254 
256 {
258  return "Hand-Over to an Identical Service";
260  return "Hand-Over to a Local Variation";
262  return "Hand-over to an Associated Service";
263  return "Reserved";
264 }
265 
267 {
268  if (!categoryDescExists)
269  Init();
270 
271  QMutexLocker locker(&categoryLock);
272 
273  // Try to get detailed description
274  QMap<uint,QString>::const_iterator it = categoryDesc.find(Nibble(i));
275  if (it != categoryDesc.end())
276  return *it;
277 
278  // Fall back to category description
279  it = categoryDesc.find(Nibble1(i)<<4);
280  if (it != categoryDesc.end())
281  return *it;
282 
283  // Found nothing? Just return empty string.
284  return "";
285 }
286 
288 {
289  QString tmp("ContentDescriptor: ");
290  for (uint i = 0; i < Count(); i++)
292  return tmp;
293 }
294 
296 {
297  QMutexLocker locker(&categoryLock);
298 
299  if (categoryDescExists)
300  return;
301 
302  //: %1 is the main category, %2 is the subcategory
303  QString subCatStr = QCoreApplication::translate("(Categories)",
304  "%1 - %2", "Category with subcategory display");
305 
306  categoryDesc[0x10] = QCoreApplication::translate("(Categories)", "Movie");
307  categoryDesc[0x11] = subCatStr
308  .arg(QCoreApplication::translate("(Categories)", "Movie"))
309  .arg(QCoreApplication::translate("(Categories)", "Detective/Thriller"));
310  categoryDesc[0x12] = subCatStr
311  .arg(QCoreApplication::translate("(Categories)", "Movie"))
312  .arg(QCoreApplication::translate("(Categories)",
313  "Adventure/Western/War"));
314  categoryDesc[0x13] = subCatStr
315  .arg(QCoreApplication::translate("(Categories)", "Movie"))
316  .arg(QCoreApplication::translate("(Categories)",
317  "Science Fiction/Fantasy/Horror"));
318  categoryDesc[0x14] = subCatStr
319  .arg(QCoreApplication::translate("(Categories)", "Movie"))
320  .arg(QCoreApplication::translate("(Categories)", "Comedy"));
321  categoryDesc[0x15] = subCatStr
322  .arg(QCoreApplication::translate("(Categories)", "Movie"))
323  .arg(QCoreApplication::translate("(Categories)",
324  "Soap/melodrama/folkloric"));
325  categoryDesc[0x16] = subCatStr
326  .arg(QCoreApplication::translate("(Categories)", "Movie"))
327  .arg(QCoreApplication::translate("(Categories)", "Romance"));
328  categoryDesc[0x17] = subCatStr
329  .arg(QCoreApplication::translate("(Categories)","Movie"))
330  .arg(QCoreApplication::translate("(Categories)",
331  "Serious/Classical/Religious/Historical Movie/Drama"));
332  categoryDesc[0x18] = subCatStr
333  .arg(QCoreApplication::translate("(Categories)","Movie"))
334  .arg(QCoreApplication::translate("(Categories)", "Adult",
335  "Adult Movie"));
336 
337  categoryDesc[0x20] = QCoreApplication::translate("(Categories)", "News");
338  categoryDesc[0x21] = QCoreApplication::translate("(Categories)",
339  "News/weather report");
340  categoryDesc[0x22] = QCoreApplication::translate("(Categories)",
341  "News magazine");
342  categoryDesc[0x23] = QCoreApplication::translate("(Categories)",
343  "Documentary");
344  categoryDesc[0x24] = QCoreApplication::translate("(Categories)",
345  "Intelligent Programs");
346 
347  categoryDesc[0x30] = QCoreApplication::translate("(Categories)",
348  "Entertainment");
349  categoryDesc[0x31] = QCoreApplication::translate("(Categories)",
350  "Game Show");
351  categoryDesc[0x32] = QCoreApplication::translate("(Categories)",
352  "Variety Show");
353  categoryDesc[0x33] = QCoreApplication::translate("(Categories)",
354  "Talk Show");
355 
356  categoryDesc[0x40] = QCoreApplication::translate("(Categories)",
357  "Sports");
358  categoryDesc[0x41] = QCoreApplication::translate("(Categories)",
359  "Special Events (World Cup, World Series, etc)");
360  categoryDesc[0x42] = QCoreApplication::translate("(Categories)",
361  "Sports Magazines");
362  categoryDesc[0x43] = QCoreApplication::translate("(Categories)",
363  "Football (Soccer)");
364  categoryDesc[0x44] = QCoreApplication::translate("(Categories)",
365  "Tennis/Squash");
366  categoryDesc[0x45] = QCoreApplication::translate("(Categories)",
367  "Misc. Team Sports");
368  // not football/soccer
369  categoryDesc[0x46] = QCoreApplication::translate("(Categories)",
370  "Athletics");
371  categoryDesc[0x47] = QCoreApplication::translate("(Categories)",
372  "Motor Sport");
373  categoryDesc[0x48] = QCoreApplication::translate("(Categories)",
374  "Water Sport");
375  categoryDesc[0x49] = QCoreApplication::translate("(Categories)",
376  "Winter Sports");
377  categoryDesc[0x4A] = QCoreApplication::translate("(Categories)",
378  "Equestrian");
379  categoryDesc[0x4B] = QCoreApplication::translate("(Categories)",
380  "Martial Sports");
381 
382  categoryDesc[0x50] = QCoreApplication::translate("(Categories)", "Kids");
383  categoryDesc[0x51] = QCoreApplication::translate("(Categories)",
384  "Pre-School Children's Programs");
385  categoryDesc[0x52] = QCoreApplication::translate("(Categories)",
386  "Entertainment Programs for 6 to 14");
387  categoryDesc[0x53] = QCoreApplication::translate("(Categories)",
388  "Entertainment Programs for 10 to 16");
389  categoryDesc[0x54] = QCoreApplication::translate("(Categories)",
390  "Informational/Educational");
391  categoryDesc[0x55] = QCoreApplication::translate("(Categories)",
392  "Cartoons/Puppets");
393 
394  categoryDesc[0x60] = QCoreApplication::translate("(Categories)",
395  "Music/Ballet/Dance");
396  categoryDesc[0x61] = QCoreApplication::translate("(Categories)",
397  "Rock/Pop");
398  categoryDesc[0x62] = QCoreApplication::translate("(Categories)",
399  "Classical Music");
400  categoryDesc[0x63] = QCoreApplication::translate("(Categories)",
401  "Folk Music");
402  categoryDesc[0x64] = QCoreApplication::translate("(Categories)",
403  "Jazz");
404  categoryDesc[0x65] = QCoreApplication::translate("(Categories)",
405  "Musical/Opera");
406  categoryDesc[0x66] = QCoreApplication::translate("(Categories)",
407  "Ballet");
408 
409  categoryDesc[0x70] = QCoreApplication::translate("(Categories)",
410  "Arts/Culture");
411  categoryDesc[0x71] = QCoreApplication::translate("(Categories)",
412  "Performing Arts");
413  categoryDesc[0x72] = QCoreApplication::translate("(Categories)",
414  "Fine Arts");
415  categoryDesc[0x73] = QCoreApplication::translate("(Categories)",
416  "Religion");
417  categoryDesc[0x74] = QCoreApplication::translate("(Categories)",
418  "Popular Culture/Traditional Arts");
419  categoryDesc[0x75] = QCoreApplication::translate("(Categories)",
420  "Literature");
421  categoryDesc[0x76] = QCoreApplication::translate("(Categories)",
422  "Film/Cinema");
423  categoryDesc[0x77] = QCoreApplication::translate("(Categories)",
424  "Experimental Film/Video");
425  categoryDesc[0x78] = QCoreApplication::translate("(Categories)",
426  "Broadcasting/Press");
427  categoryDesc[0x79] = QCoreApplication::translate("(Categories)",
428  "New Media");
429  categoryDesc[0x7A] = QCoreApplication::translate("(Categories)",
430  "Arts/Culture Magazines");
431  categoryDesc[0x7B] = QCoreApplication::translate("(Categories)", "Fashion");
432 
433  categoryDesc[0x80] = QCoreApplication::translate("(Categories)",
434  "Social/Policical/Economics");
435  categoryDesc[0x81] = QCoreApplication::translate("(Categories)",
436  "Magazines/Reports/Documentary");
437  categoryDesc[0x82] = QCoreApplication::translate("(Categories)",
438  "Economics/Social Advisory");
439  categoryDesc[0x83] = QCoreApplication::translate("(Categories)",
440  "Remarkable People");
441 
442  categoryDesc[0x90] = QCoreApplication::translate("(Categories)",
443  "Education/Science/Factual");
444  categoryDesc[0x91] = QCoreApplication::translate("(Categories)",
445  "Nature/animals/Environment");
446  categoryDesc[0x92] = QCoreApplication::translate("(Categories)",
447  "Technology/Natural Sciences");
448  categoryDesc[0x93] = QCoreApplication::translate("(Categories)",
449  "Medicine/Physiology/Psychology");
450  categoryDesc[0x94] = QCoreApplication::translate("(Categories)",
451  "Foreign Countries/Expeditions");
452  categoryDesc[0x95] = QCoreApplication::translate("(Categories)",
453  "Social/Spiritual Sciences");
454  categoryDesc[0x96] = QCoreApplication::translate("(Categories)",
455  "Further Education");
456  categoryDesc[0x97] = QCoreApplication::translate("(Categories)",
457  "Languages");
458 
459  categoryDesc[0xA0] = QCoreApplication::translate("(Categories)",
460  "Leisure/Hobbies");
461  categoryDesc[0xA1] = QCoreApplication::translate("(Categories)",
462  "Tourism/Travel");
463  categoryDesc[0xA2] = QCoreApplication::translate("(Categories)",
464  "Handicraft");
465  categoryDesc[0xA3] = QCoreApplication::translate("(Categories)",
466  "Motoring");
467  categoryDesc[0xA4] = QCoreApplication::translate("(Categories)",
468  "Fitness & Health");
469  categoryDesc[0xA5] = QCoreApplication::translate("(Categories)", "Cooking");
470  categoryDesc[0xA6] = QCoreApplication::translate("(Categories)",
471  "Advertizement/Shopping");
472  categoryDesc[0xA7] = QCoreApplication::translate("(Categories)",
473  "Gardening");
474  // Special
475  categoryDesc[0xB0] = QCoreApplication::translate("(Categories)",
476  "Original Language");
477  categoryDesc[0xB1] = QCoreApplication::translate("(Categories)",
478  "Black & White");
479  categoryDesc[0xB2] = QCoreApplication::translate("(Categories)",
480  "\"Unpublished\" Programs");
481  categoryDesc[0xB3] = QCoreApplication::translate("(Categories)",
482  "Live Broadcast");
483  // UK Freeview custom id
484  categoryDesc[0xF0] = QCoreApplication::translate("(Categories)",
485  "Drama");
486 
487  categoryDescExists = true;
488 }
489 
491 {
492  QString str = "FrequencyListDescriptor: frequencies: ";
493 
494  for (uint i = 0; i < FrequencyCount(); i++)
495  str.append(QString(" %1").arg(FrequencyHz(i)));
496 
497  return str;
498 }
499 
501 {
502  QString str = "";
503 
504  if (IsDTV())
505  str.append(" (TV)");
506  else if (IsDigitalAudio())
507  str.append(" (Radio)");
508  else if (IsHDTV())
509  str.append(" (HDTV)");
510  else if (IsUHDTV())
511  str.append(" (UHDTV)");
512  else if (IsTeletext())
513  str.append(" (Teletext)");
514  else
515  str.append(QString(" (Unknown 0x%1)").arg(ServiceType(),2,16,QChar('0')));
516 
517  return str;
518 }
519 
520 QString TeletextDescriptor::toString(void) const
521 {
522  QString str = QString("Teletext Descriptor: %1 pages")
523  .arg(StreamCount());
524 
525  for (uint i = 0; i < StreamCount(); i++)
526  {
527  if (1 != StreamCount())
528  str.append("\n ");
529 
530  str.append(QString(" type(%1) mag(%2) page(%3) lang(%4)")
531  .arg(TeletextType(i))
532  .arg(TeletextMagazineNum(i), 0, 16)
533  .arg(TeletextPageNum(i), 2, 16, QChar('0'))
534  .arg(LanguageString(i)));
535  }
536 
537  return str;
538 }
539 
541 {
542  QString str = QString("CableDeliverySystemDescriptor: ");
543 
544  str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
545  str.append(QString(" Mod=%1, SymbR=%2, FECInner=%3, FECOuter=%4")
546  .arg(ModulationString())
547  .arg(SymbolRateHz())
548  .arg(FECInnerString())
549  .arg(FECOuterString()));
550 
551  return str;
552 }
553 
555 {
556  QString str = QString("SatelliteDeliverySystemDescriptor: ");
557 
558  str.append(QString("Frequency: %1, Type: %2\n").arg(FrequencykHz())
559  .arg(ModulationSystemString()));
560  str.append(QString(" Mod=%1, SymbR=%2, FECInner=%3, Orbit=%4, Pol=%5")
561  .arg(ModulationString())
562  .arg(SymbolRateHz())
563  .arg(FECInnerString())
564  .arg(OrbitalPositionString())
565  .arg(PolarizationString()));
566 
567  return str;
568 }
569 
571 {
572  QString str = QString("TerrestrialDeliverySystemDescriptor: ");
573 
574  str.append(QString("Frequency: %1\n").arg(FrequencyHz()));
575  str.append(QString(" BW=%1k, C=%2, HP=%3, LP=%4, GI=%5, TransMode=%6k")
576  .arg(BandwidthString())
577  .arg(ConstellationString())
578  .arg(CodeRateHPString())
579  .arg(CodeRateLPString())
580  .arg(GuardIntervalString())
581  .arg(TransmissionModeString()));
582 
583  return str;
584 }
585 
587 {
588  QString ret = "UKChannelListDescriptor sid->chan_num: ";
589  for (uint i = 0; i < ChannelCount(); i++)
590  {
591  ret += QString("%1->%2").arg(ServiceID(i)).arg(ChannelNumber(i));
592  ret += (i+1 < ChannelCount()) ? (i+3)%10 ? ", " : ",\n " : "";
593  }
594  return ret;
595 }
596 
598 {
599  QString ret = "DVBSimulcastChannelDescriptor sid->chan_num: ";
600  for (uint i = 0; i < ChannelCount(); i++)
601  {
602  ret += QString("%1->%2").arg(ServiceID(i)).arg(ChannelNumber(i));
603  ret += (i+1 < ChannelCount()) ? (i+3)%10 ? ", " : ",\n " : "";
604  }
605  return ret;
606 }
607 
609 {
610  QString ret = "BSkyB Logical Channel Number Descriptor ";
611  ret += QString("(0x%1) ").arg(DescriptorTag(),2,16,QChar('0'));
612  ret += QString("length(%1)").arg(DescriptorLength());
613 
614  ret += QString("\n RegionID (%1) (0x%2) Raw (0x%3)")
615  .arg(RegionID()).arg(RegionID(),4,16,QChar('0')).arg(RegionRaw(),4,16,QChar('0'));
616 
617  for (uint i=0; i<ServiceCount(); i++)
618  {
619  ret += QString("\n ServiceID (%1) (0x%2) ").arg(ServiceID(i)).arg(ServiceID(i),4,16,QChar('0'));
620  ret += QString("ServiceType (0x%1) ").arg(ServiceType(i),2,16,QChar('0'));
621  ret += QString("LCN (%1) ").arg(LogicalChannelNumber(i));
622  ret += QString("U1(0x%1) ").arg(Unknown1(i),4,16,QChar('0'));
623  ret += QString("U2(0x%1) ").arg(Unknown2(i),4,16,QChar('0'));
624  }
625 
626  return ret;
627 }
628 
630 {
631  QString ret = "Freesat Logical Channel Number Descriptor ";
632  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
633  ret += QString(" length(%1)").arg(DescriptorLength());
634 
635  for (uint i=0; i<ServiceCount(); i++)
636  {
637  ret += QString("\n ServiceID (%1) (0x%2) ").arg(ServiceID(i)).arg(ServiceID(i),4,16,QChar('0'));
638  ret += QString("ChanID (0x%1)").arg(ChanID(i), 4, 16, QChar('0'));
639  for (uint j=0; j<LCNCount(i); j++)
640  {
641  ret += QString("\n LCN: %1 Region: %2").arg(LogicalChannelNumber(i,j),3).arg(RegionID(i,j));
642  }
643  }
644  return ret;
645 }
646 
648 {
649  QString ret = "Freesat Region Descriptor ";
650  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
651  ret += QString(" length(%1)").arg(DescriptorLength());
652 
653  for (uint i=0; i<RegionCount(); ++i)
654  {
655  uint region_id = RegionID(i);
656  QString language = Language(i);
657  QString region_name = RegionName(i);
658  ret += QString("\n Region (%1) (%2) '%3'")
659  .arg(region_id,2).arg(language).arg(region_name);
660  }
661  return ret;
662 }
663 
665 {
666  QString ret = QString("Freesat Callsign Descriptor ");
667  ret += QString("(0x%1)").arg(DescriptorTag(),2,16,QChar('0'));
668  ret += QString(" length(%1)").arg(DescriptorLength());
669  ret += QString(" (%1) '%2'").arg(Language()).arg(Callsign());
670  return ret;
671 }
672 
674 {
675  QString ret = QString("CAIdentifierDescriptor ");
676  for (uint i = 0; i < CASystemCount(); ++i)
677  {
678  ret += QString("ca_system_id(0x%1) ")
679  .arg(CASystemId(i), 0, 16);
680  }
681  return ret;
682 }
683 
685 {
686  QString ret = QString("DataBroadcastDescriptor: "
687  "data_broadcast_id(%1) "
688  "component_tag(%1) ")
689  .arg(DataBroadcastId(), 0, 10)
690  .arg(DataComponentTag(), 0, 10);
691 
692  ret += QString("selector(0x ");
693  for (uint i = 0; i < SelectorLength(); i++)
694  ret += QString("%1 ").arg(Selector()[i], 0, 16);
695  ret += ") ";
696 
697  ret += QString("ISO_639_language_code(%1) ")
698  .arg(LanguageString());
699 
700  ret += QString("text(%1) ") + Text();
701 
702  return ret;
703 }
704 
706 {
707  QString ret = QString("LocalTimeOffsetDescriptor ");
708  uint count = Count();
709  for (uint i = 0; i < count; ++i)
710  {
711  ret += QString("country_code(%1) country_region_id(0x%2) "
712  "local_time_offset_with_polarity(%3) "
713  "time_of_change(TODO)")
714  .arg(CountryCodeString(i))
715  .arg(CountryRegionId(i), 0, 16)
717  // TODO add time of change
718  }
719  return ret;
720 }
721 
723 {
724  QString ret = QString("NVODReferenceDescriptor ");
725  for (uint i = 0; i < Count(); ++i)
726  {
727  ret += QString("transport_stream_id(0x%1) original_network_id(0x%2) "
728  "service_id(0x%3) ")
729  .arg(TransportStreamId(i), 0, 16)
730  .arg(OriginalNetworkId(i), 0, 16)
731  .arg(ServiceId(i), 0, 16);
732  }
733  return ret;
734 }
735 
737 {
738  return QString("PartialTransportStreamDescriptor peak_rate(%1) "
739  "min_overall_smooth_rate(%2) max_overall_smooth_buf(3)")
740  .arg(PeakRate()).arg(SmoothRate()).arg(SmoothBuf());
741 }
742 
743 QString AC3Descriptor::toString(void) const
744 {
745  QString ret = QString("AC3DescriptorDescriptor ");
746  if (HasComponentType())
747  ret += QString("component_type(%1) ")
748  .arg(ComponentType(), 0, 10);
749  if (HasBSID())
750  ret += QString("bsid(0x%1) ").arg(BSID(),0,16);
751  if (HasMainID())
752  ret += QString("mainid(0x%1) ").arg(MainID(),0,16);
753  if (HasASVC())
754  ret += QString("asvc(%1) ").arg(ASVC());
755  return ret;
756 }
757 
758 QMap<QString,QString> ExtendedEventDescriptor::Items(void) const
759 {
760  QMap<QString, QString> ret;
761 
762  uint index = 0;
763 
764  /* handle all items
765  * minimum item size is for 8bit length + 8bit length
766  */
767  while (LengthOfItems() - index >= 2)
768  {
769  QString item_description = dvb_decode_text (&_data[8 + index], _data[7 + index]);
770  index += 1 + _data[7 + index];
771  QString item = dvb_decode_text (&_data[8 + index], _data[7 + index]);
772  index += 1 + _data[7 + index];
773  ret.insertMulti (item_description, item);
774  }
775 
776  return ret;
777 }
uint ServiceCount(void) const
uint ChanID(int i) const
bool HasASVC(void) const
uint Count(void) const
ProgramInfo::CategoryType GetMythCategory(uint i) const
QMap< QString, QString > Items(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
uint ServiceCount(void) const
int CASystemId(uint i) const
const QString Language(void) const
bool IsUHDTV(void) const
QString toString(void) const override
QString FECInnerString(void) const
uint DescriptorTag(void) const
uint ServiceId(uint i) 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
uint RegionID(void) const
static guint32 * tmp
Definition: goom_core.c:35
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]
const QString RegionName(uint i) const
static int x4
Definition: mythsocket.cpp:63
uint StreamCount(void) const
uint TransportStreamId(uint i) const
uint LogicalChannelNumber(int i, int j) const
uint ASVC(void) const
QString toString(void) const override
uint RegionCount(void) const
uint ServiceID(int i) 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
QString toString(void) const override
QString Text(void) const
uint Unknown2(int i) const
uint ChannelNumber(uint i) const
uint SelectorLength(void) const
QString toString(void) const
uint LengthOfItems(void) const
QString ModulationString(void) const
static volatile bool categoryDescExists
QString ConstellationString(void) const
QString toString(void) const override
unsigned int uint
Definition: compat.h:140
uint TeletextPageNum(uint i) const
int LocalTimeOffsetWithPolarity(uint i) const
static QMap< uint, QString > categoryDesc
QString GetDescription(uint i) const
bool HasBSID(void) const
QString Callsign(void) const
uint DataBroadcastId(void) const
uint ServiceType(void) const
bool IsDigitalAudio(void) const
uint DescriptorLength(void) const
uint ServiceID(int i) const
QString CountryCodeString(uint i) const
QString toString(void) const override
QString myth_category_type_to_string(ProgramInfo::CategoryType category_type)
uint RegionRaw(void) const
uint TeletextMagazineNum(uint i) const
uint OriginalNetworkId(uint i) const
uint ServiceType(int 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
const unsigned char * _data
bool HasMainID(void) const
QString LinkageTypeString(void) const
QString dvb_decode_short_name(const unsigned char *src, uint raw_length)
QString LanguageString(uint i) const
QString ModulationSystemString(void) const
uint Unknown1(int i) const
QString toString(void) const override
uint LCNCount(int i) const
int RegionID(uint i) const
QString toString(void) const override
uint LogicalChannelNumber(int i) const
const unsigned char * Selector(void) const
unsigned long long FrequencykHz(void) const
uint BSID(void) const
const QString Language(uint i) const
QString ModulationString(void) const
const uint16_t * iso6937table_secondary[256]
uint ComponentType(void) const
uint DataComponentTag(void) 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
QString toString(void) const override
static QMutex categoryLock
uint Nibble1(uint i) const
static int x1
Definition: mythsocket.cpp:60