MythTV  master
eithelper.cpp
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 
3 // Std C++ headers
4 #include <algorithm>
5 using namespace std;
6 
7 // MythTV includes
8 #include "eithelper.h"
9 #include "eitfixup.h"
10 #include "eitcache.h"
11 #include "mythdb.h"
12 #include "atsctables.h"
13 #include "dvbtables.h"
14 #include "premieretables.h"
15 #include "dishdescriptors.h"
16 #include "premieredescriptors.h"
17 #include "channelutil.h" // for ChannelUtil
18 #include "mythdate.h"
19 #include "programdata.h"
20 #include "programinfo.h" // for subtitle types and audio and video properties
21 #include "scheduledrecording.h" // for ScheduledRecording
22 #include "compat.h" // for gmtime_r on windows.
23 
24 const uint EITHelper::kChunkSize = 20;
26 
27 static uint get_chan_id_from_db_atsc(uint sourceid,
28  uint atsc_major, uint atsc_minor);
29 static uint get_chan_id_from_db_dvb(uint sourceid, uint serviceid,
30  uint networkid, uint transportid);
31 static uint get_chan_id_from_db_dtv(uint sourceid,
32  uint serviceid, uint tunedchanid);
33 static void init_fixup(FixupMap &fix);
34 
35 #define LOC QString("EITHelper: ")
36 
38  eitfixup(new EITFixUp()),
39  gps_offset(-1 * GPS_LEAP_SECONDS),
40  sourceid(0), channelid(0),
41  maxStarttime(QDateTime()), seenEITother(false)
42 {
44 }
45 
47 {
48  QMutexLocker locker(&eitList_lock);
49  while (!db_events.empty())
50  delete db_events.dequeue();
51 
52  delete eitfixup;
53 }
54 
56 {
57  QMutexLocker locker(&eitList_lock);
58  return db_events.size();
59 }
60 
67 {
68  QMutexLocker locker(&eitList_lock);
69  uint insertCount = 0;
70 
71  if (db_events.empty())
72  return 0;
73 
75  for (uint i = 0; (i < kChunkSize) && (!db_events.empty()); i++)
76  {
77  DBEventEIT *event = db_events.dequeue();
78  eitList_lock.unlock();
79 
80  eitfixup->Fix(*event);
81 
82  insertCount += event->UpdateDB(query, 1000);
83  maxStarttime = max (maxStarttime, event->m_starttime);
84 
85  delete event;
86  eitList_lock.lock();
87  }
88 
89  if (!insertCount)
90  return 0;
91 
92  if (!incomplete_events.empty())
93  {
94  LOG(VB_EIT, LOG_INFO,
95  LOC + QString("Added %1 events -- complete: %2 incomplete: %3")
96  .arg(insertCount).arg(db_events.size())
97  .arg(incomplete_events.size()));
98  }
99  else
100  {
101  LOG(VB_EIT, LOG_INFO,
102  LOC + QString("Added %1 events").arg(insertCount));
103  }
104 
105  return insertCount;
106 }
107 
108 void EITHelper::SetFixup(uint atsc_major, uint atsc_minor, FixupValue drheitfixup)
109 {
110  QMutexLocker locker(&eitList_lock);
111  FixupKey atsc_key = (atsc_major << 16) | atsc_minor;
112  fixup[atsc_key] = drheitfixup;
113 }
114 
115 void EITHelper::SetLanguagePreferences(const QStringList &langPref)
116 {
117  QMutexLocker locker(&eitList_lock);
118 
119  uint priority = 1;
120  QStringList::const_iterator it;
121  for (it = langPref.begin(); it != langPref.end(); ++it)
122  {
123  if (!(*it).isEmpty())
124  {
125  uint language_key = iso639_str3_to_key(*it);
126  uint canonoical_key = iso639_key_to_canonical_key(language_key);
127  languagePreferences[canonoical_key] = priority++;
128  }
129  }
130 }
131 
133 {
134  QMutexLocker locker(&eitList_lock);
135  sourceid = _sourceid;
136 }
137 
139 {
140  QMutexLocker locker(&eitList_lock);
141  channelid = _channelid;
142 }
143 
144 void EITHelper::AddEIT(uint atsc_major, uint atsc_minor,
145  const EventInformationTable *eit)
146 {
147  uint atsc_key = (atsc_major << 16) | atsc_minor;
148  EventIDToATSCEvent &events = incomplete_events[atsc_key];
149 
150  for (uint i = 0; i < eit->EventCount(); i++)
151  {
152  ATSCEvent ev(eit->StartTimeRaw(i), eit->LengthInSeconds(i),
153  eit->ETMLocation(i),
155  eit->Descriptors(i), eit->DescriptorsLength(i));
156 
157  // Create an event immediately if the ETM_location specifies
158  // that there is no ETT event coming; otherwise save the EIT
159  // event in the incomplete_events for this channel.
160  if (!ev.m_etm)
161  {
162  CompleteEvent(atsc_major, atsc_minor, ev, "");
163  }
164  else
165  {
166  // If there is an existing EIT event with this event_id then
167  // delete the descriptor to avoid a memory leak.
168  EventIDToATSCEvent::iterator it = events.find(eit->EventID(i));
169  if (it != events.end())
170  {
171  delete [] (*it).m_desc;
172  }
173 
174  // Save the EIT event in the incomplete_events for this channel.
175  unsigned char *tmp = new unsigned char[ev.m_desc_length];
176  memcpy(tmp, eit->Descriptors(i), ev.m_desc_length);
177  ev.m_desc = tmp;
178  events.insert(eit->EventID(i), ev);
179  }
180  }
181 }
182 
183 void EITHelper::AddETT(uint atsc_major, uint atsc_minor,
184  const ExtendedTextTable *ett)
185 {
186  // Find the matching incomplete EIT event for this ETT
187  // If we have no EIT event then just discard the ETT.
188  uint atsc_key = (atsc_major << 16) | atsc_minor;
189  ATSCSRCToEvents::iterator eits_it = incomplete_events.find(atsc_key);
190  if (eits_it != incomplete_events.end())
191  {
192  EventIDToATSCEvent::iterator it = (*eits_it).find(ett->EventID());
193  if (it != (*eits_it).end())
194  {
195  // Only consider EIT events from the very recent past.
196  if (!it->IsStale()) {
198  atsc_major, atsc_minor, *it,
200  }
201 
202  // Remove EIT event from the incomplete_event list.
203  delete [] (*it).m_desc;
204  (*eits_it).erase(it);
205  }
206  }
207 }
208 
210  QMap<uint,uint> languagePreferences,
211  QString &title, QString &subtitle,
212  QString &description, QMap<QString,QString> &items)
213 {
214  const unsigned char *bestShortEvent =
216  list, DescriptorID::short_event, languagePreferences);
217 
218  // from EN 300 468, Appendix A.2 - Selection of character table
219  unsigned char enc_1[3] = { 0x10, 0x00, 0x01 };
220  unsigned char enc_2[3] = { 0x10, 0x00, 0x02 };
221  unsigned char enc_7[3] = { 0x10, 0x00, 0x07 }; // Latin/Greek Alphabet
222  unsigned char enc_9[3] = { 0x10, 0x00, 0x09 }; // could use { 0x05 } instead
223  unsigned char enc_15[3] = { 0x10, 0x00, 0x0f }; // could use { 0x0B } instead
224  int enc_len = 0;
225  const unsigned char *enc = nullptr;
226 
227  // Is this BellExpressVU EIT (Canada) ?
228  // Use an encoding override of ISO 8859-1 (Latin1)
230  {
231  enc = enc_1;
232  enc_len = sizeof(enc_1);
233  }
234 
235  // Is this broken DVB provider in Central Europe?
236  // Use an encoding override of ISO 8859-2 (Latin2)
238  {
239  enc = enc_2;
240  enc_len = sizeof(enc_2);
241  }
242 
243  // Is this broken DVB provider in Western Europe?
244  // Use an encoding override of ISO 8859-9 (Latin5)
246  {
247  enc = enc_9;
248  enc_len = sizeof(enc_9);
249  }
250 
251  // Is this broken DVB provider in Western Europe?
252  // Use an encoding override of ISO 8859-15 (Latin9)
254  {
255  enc = enc_15;
256  enc_len = sizeof(enc_15);
257  }
258 
259  // Is this broken DVB provider in Greece?
260  // Use an encoding override of ISO 8859-7 (Latin/Greek)
262  {
263  enc = enc_7;
264  enc_len = sizeof(enc_7);
265  }
266 
267  if (bestShortEvent)
268  {
269  ShortEventDescriptor sed(bestShortEvent);
270  if (sed.IsValid())
271  {
272  if (enc)
273  {
274  title = sed.EventName(enc, enc_len);
275  subtitle = sed.Text(enc, enc_len);
276  }
277  else
278  {
279  title = sed.EventName();
280  subtitle = sed.Text();
281  }
282  }
283  }
284 
285  vector<const unsigned char*> bestExtendedEvents =
287  list, DescriptorID::extended_event, languagePreferences);
288 
289  description = "";
290  for (size_t j = 0; j < bestExtendedEvents.size(); j++)
291  {
292  if (!bestExtendedEvents[j])
293  {
294  description = "";
295  break;
296  }
297 
298  ExtendedEventDescriptor eed(bestExtendedEvents[j]);
299  if (eed.IsValid())
300  {
301  if (enc)
302  description += eed.Text(enc, enc_len);
303  else
304  description += eed.Text();
305  }
306  // add items from the decscriptor to the items
307  items.unite (eed.Items());
308  }
309 }
310 
311 static inline void parse_dvb_component_descriptors(const desc_list_t& list,
312  unsigned char &subtitle_type,
313  unsigned char &audio_properties,
314  unsigned char &video_properties)
315 {
316  desc_list_t components =
318  for (size_t j = 0; j < components.size(); j++)
319  {
320  ComponentDescriptor component(components[j]);
321  if (!component.IsValid())
322  continue;
323  video_properties |= component.VideoProperties();
324  audio_properties |= component.AudioProperties();
325  subtitle_type |= component.SubtitleType();
326  }
327 }
328 
330 {
331  uint chanid = 0;
332  if ((eit->TableID() == TableID::PF_EIT) ||
333  ((eit->TableID() >= TableID::SC_EITbeg) && (eit->TableID() <= TableID::SC_EITend)))
334  {
335  // EITa(ctive)
336  chanid = GetChanID(eit->ServiceID());
337  }
338  else
339  {
340  // EITo(ther)
341  chanid = GetChanID(eit->ServiceID(), eit->OriginalNetworkID(), eit->TSID());
342  // do not reschedule if its only present+following
343  if (eit->TableID() != TableID::PF_EITo)
344  {
345  seenEITother = true;
346  }
347  }
348  if (!chanid)
349  return;
350 
351  uint descCompression = (eit->TableID() > 0x80) ? 2 : 1;
352  FixupValue fix = fixup.value((FixupKey)eit->OriginalNetworkID() << 16);
353  fix |= fixup.value((((FixupKey)eit->TSID()) << 32) |
354  ((FixupKey)eit->OriginalNetworkID() << 16));
355  fix |= fixup.value(((FixupKey)eit->OriginalNetworkID() << 16) |
356  (FixupKey)eit->ServiceID());
357  fix |= fixup.value((((FixupKey)eit->TSID()) << 32) |
358  ((FixupKey)eit->OriginalNetworkID() << 16) |
359  (FixupKey)eit->ServiceID());
361 
362  uint tableid = eit->TableID();
363  uint version = eit->Version();
364  for (uint i = 0; i < eit->EventCount(); i++)
365  {
366  // Skip event if we have already processed it before...
367  if (!s_eitcache->IsNewEIT(chanid, tableid, version, eit->EventID(i),
368  eit->EndTimeUnixUTC(i)))
369  {
370  continue;
371  }
372 
373  QString title = QString("");
374  QString subtitle = QString("");
375  QString description = QString("");
376  QString category = QString("");
378  unsigned char subtitle_type=0, audio_props=0, video_props=0;
379  uint season = 0, episode = 0, totalepisodes = 0;
380  QMap<QString,QString> items;
381 
382  // Parse descriptors
384  eit->Descriptors(i), eit->DescriptorsLength(i));
385 
386  const unsigned char *dish_event_name = nullptr;
387  if (EITFixUp::kFixDish & fix)
388  {
389  dish_event_name = MPEGDescriptor::Find(
391  }
392 
393  if (dish_event_name)
394  {
395  DishEventNameDescriptor dend(dish_event_name);
396  if (dend.IsValid() && dend.HasName())
397  title = dend.Name(descCompression);
398 
399  const unsigned char *dish_event_description =
402  if (dish_event_description)
403  {
404  DishEventDescriptionDescriptor dedd(dish_event_description);
405  if (dedd.HasDescription())
406  description = dedd.Description(descCompression);
407  }
408  }
409  else
410  {
412  title, subtitle, description, items);
413  }
414 
415  parse_dvb_component_descriptors(list, subtitle_type, audio_props,
416  video_props);
417 
418  QString programId = QString("");
419  QString seriesId = QString("");
420  QString rating = QString("");
421  QString rating_system = QString("");
422  QString advisory = QString("");
423  float stars = 0.0;
424  QDate originalairdate;
425 
426  if (EITFixUp::kFixDish & fix)
427  {
428  const unsigned char *mpaa_data = MPEGDescriptor::Find(
430  if (mpaa_data)
431  {
432  DishEventMPAADescriptor mpaa(mpaa_data);
433  stars = mpaa.stars();
434 
435  if (stars) // Only movies for now
436  {
437  rating = mpaa.rating();
438  rating_system = "MPAA";
439  advisory = mpaa.advisory();
440  }
441  }
442 
443  if (!stars) // Not MPAA rated, check VCHIP
444  {
445  const unsigned char *vchip_data = MPEGDescriptor::Find(
447  if (vchip_data)
448  {
449  DishEventVCHIPDescriptor vchip(vchip_data);
450  rating = vchip.rating();
451  rating_system = "VCHIP";
452  advisory = vchip.advisory();
453  }
454  }
455 
456  if (!advisory.isEmpty() && !rating.isEmpty())
457  rating += ", " + advisory;
458  else if (!advisory.isEmpty())
459  {
460  rating = advisory;
461  rating_system = "advisory";
462  }
463 
464  const unsigned char *tags_data = MPEGDescriptor::Find(
466  if (tags_data)
467  {
468  DishEventTagsDescriptor tags(tags_data);
469  seriesId = tags.seriesid();
470  programId = tags.programid();
471  originalairdate = tags.originalairdate(); // future use
472 
473  if (programId.startsWith("MV") || programId.startsWith("SP"))
474  seriesId = "";
475  }
476 
477  const unsigned char *properties_data = MPEGDescriptor::Find(
479  if (properties_data)
480  {
481  DishEventPropertiesDescriptor properties(properties_data);
482  subtitle_type |= properties.SubtitleProperties(descCompression);
483  audio_props |= properties.AudioProperties(descCompression);
484  }
485  }
486 
487  const unsigned char *content_data =
489  if (content_data)
490  {
491  if ((EITFixUp::kFixDish & fix) || (EITFixUp::kFixBell & fix))
492  {
493  DishContentDescriptor content(content_data);
494  switch (content.GetTheme())
495  {
496  case kThemeMovie :
497  category_type = ProgramInfo::kCategoryMovie;
498  break;
499  case kThemeSeries :
500  category_type = ProgramInfo::kCategorySeries;
501  break;
502  case kThemeSports :
503  category_type = ProgramInfo::kCategorySports;
504  break;
505  default :
506  category_type = ProgramInfo::kCategoryNone;
507  }
508  if (EITFixUp::kFixDish & fix)
509  category = content.GetCategory();
510  }
511  else if (EITFixUp::kFixAUDescription & fix)//AU Freeview assigned genres
512  {
513  static const char *AUGenres[] =
514  {/* 0*/"Unknown", "Movie", "News", "Entertainment",
515  /* 4*/"Sport", "Children", "Music", "Arts/Culture",
516  /* 8*/"Current Affairs", "Education", "Infotainment",
517  /*11*/"Special", "Comedy", "Drama", "Documentary",
518  /*15*/"Unknown"};
519  ContentDescriptor content(content_data);
520  if (content.IsValid())
521  {
522  category = AUGenres[content.Nibble1(0)];
523  category_type = content.GetMythCategory(0);
524  }
525  }
526  else if (EITFixUp::kFixGreekEIT & fix)//Greek
527  {
528  static const char *GrGenres[] =
529  {/* 0*/"Unknown", "Ταινία", "Ενημερωτικό", "Unknown",
530  /* 4*/"Αθλητικό", "Παιδικό", "Unknown", "Unknown",
531  /* 8*/"Unknown", "Ντοκιμαντέρ", "Unknown", "Unknown",
532  /*12*/"Unknown", "Unknown", "Unknown", "Unknown"};
533  ContentDescriptor content(content_data);
534  if (content.IsValid())
535  {
536  category = GrGenres[content.Nibble2(0)];
537  category_type = content.GetMythCategory(2);
538  }
539  }
540  else
541  {
542  ContentDescriptor content(content_data);
543  if (content.IsValid())
544  {
545  category = content.GetDescription(0);
546 #if 0 /* there is no category_type in DVB EIT */
547  category_type = content.GetMythCategory(0);
548 #endif
549  }
550  }
551  }
552 
553  desc_list_t contentIds =
555  for (size_t j = 0; j < contentIds.size(); j++)
556  {
557  DVBContentIdentifierDescriptor desc(contentIds[j]);
558  if (!desc.IsValid())
559  continue;
560  for (size_t k = 0; k < desc.CRIDCount(); k++)
561  {
562  if (desc.ContentEncoding(k) == 0)
563  {
564  // The CRID is a URI. It could contain UTF8 sequences encoded
565  // as %XX but there's no advantage in decoding them.
566  // The BBC currently uses private types 0x31 and 0x32.
567  // IDs from the authority eventis.nl are not fit for our scheduler
568  if (desc.ContentType(k) == 0x01 || desc.ContentType(k) == 0x31)
569  {
570  if (!desc.ContentId(k).startsWith ("eventis.nl/"))
571  {
572  programId = desc.ContentId(k);
573  }
574  }
575  else if (desc.ContentType(k) == 0x02 || desc.ContentType(k) == 0x32)
576  {
577  if (!desc.ContentId(k).startsWith ("eventis.nl/"))
578  {
579  seriesId = desc.ContentId(k);
580  }
581  category_type = ProgramInfo::kCategorySeries;
582  }
583  }
584  }
585  }
586 
587  /* if we don't have a subtitle, try to parse one from private descriptors */
588  if (subtitle.isEmpty()) {
589  bool isUPC = false;
590  /* is this event carrying UPC private data? */
592  for (size_t j = 0; j < private_data_specifiers.size(); j++) {
593  PrivateDataSpecifierDescriptor desc(private_data_specifiers[j]);
594  if (!desc.IsValid())
595  continue;
597  isUPC = true;
598  }
599  }
600 
601  if (isUPC) {
603  for (size_t j = 0; j < subtitles.size(); j++) {
605  if (!desc.IsValid())
606  continue;
607  subtitle = desc.Text();
608  }
609  }
610  }
611 
612 
613  QDateTime starttime = eit->StartTimeUTC(i);
614  // fix starttime only if the duration is a multiple of a minute
615  if (!(eit->DurationInSeconds(i) % 60))
616  EITFixUp::TimeFix(starttime);
617  QDateTime endtime = starttime.addSecs(eit->DurationInSeconds(i));
618 
619  DBEventEIT *event = new DBEventEIT(
620  chanid,
621  title, subtitle, description,
622  category, category_type,
623  starttime, endtime, fix,
624  subtitle_type,
625  audio_props,
626  video_props, stars,
627  seriesId, programId,
628  season, episode, totalepisodes);
629  event->m_items = items;
630 
631  db_events.enqueue(event);
632  }
633 }
634 
635 // This function gets special EIT data from the German provider Premiere
636 // for the option channels Premiere Sport and Premiere Direkt
638 {
639  // set fixup for Premiere
640  FixupValue fix = fixup.value(133 << 16);
642 
643  QString title = QString("");
644  QString subtitle = QString("");
645  QString description = QString("");
646  QString category = QString("");
648  unsigned char subtitle_type=0, audio_props=0, video_props=0;
649  uint season = 0, episode = 0, totalepisodes = 0;
650  QMap<QString,QString> items;
651 
652  // Parse descriptors
654  cit->Descriptors(), cit->DescriptorsLength());
655 
657  title, subtitle, description, items);
658 
659  parse_dvb_component_descriptors(list, subtitle_type, audio_props,
660  video_props);
661 
662  const unsigned char *content_data =
664  if (content_data)
665  {
666  ContentDescriptor content(content_data);
667  // fix events without real content data
668  if (content.IsValid() && (content.Nibble(0)==0x00))
669  {
670  if(content.UserNibble(0)==0x1)
671  {
672  category_type = ProgramInfo::kCategoryMovie;
673  }
674  else if(content.UserNibble(0)==0x0)
675  {
676  category_type = ProgramInfo::kCategorySports;
677  category = QObject::tr("Sports");
678  }
679  }
680  else
681  {
682  category_type = content.GetMythCategory(0);
683  category = content.GetDescription(0);
684  }
685  }
686 
687  uint tableid = cit->TableID();
688  uint version = cit->Version();
689  uint contentid = cit->ContentID();
690  // fake endtime
691 #if QT_VERSION < QT_VERSION_CHECK(5,8,0)
692  uint endtime = MythDate::current().addDays(1).toTime_t();
693 #else
694  uint endtime = MythDate::current().addDays(1).toSecsSinceEpoch();
695 #endif
696 
697  // Find Transmissions
698  desc_list_t transmissions =
701  for(size_t j=0; j< transmissions.size(); j++)
702  {
703  PremiereContentTransmissionDescriptor transmission(transmissions[j]);
704  if (!transmission.IsValid())
705  continue;
706  uint networkid = transmission.OriginalNetworkID();
707  uint tsid = transmission.TSID();
708  uint serviceid = transmission.ServiceID();
709 
710  uint chanid = GetChanID(serviceid, networkid, tsid);
711 
712  if (!chanid)
713  {
714  LOG(VB_EIT, LOG_INFO, LOC +
715  QString("Premiere EIT for NIT %1, TID %2, SID %3, "
716  "count %4, title: %5. Channel not found!")
717  .arg(networkid).arg(tsid).arg(serviceid)
718  .arg(transmission.TransmissionCount()).arg(title));
719  continue;
720  }
721 
722  // Skip event if we have already processed it before...
723  if (!s_eitcache->IsNewEIT(chanid, tableid, version, contentid, endtime))
724  {
725  continue;
726  }
727 
728  for (uint k=0; k<transmission.TransmissionCount(); ++k)
729  {
730  QDateTime txstart = transmission.StartTimeUTC(k);
731  // fix txstart only if the duration is a multiple of a minute
732  if (!(cit->DurationInSeconds() % 60))
733  EITFixUp::TimeFix(txstart);
734  QDateTime txend = txstart.addSecs(cit->DurationInSeconds());
735 
736  DBEventEIT *event = new DBEventEIT(
737  chanid,
738  title, subtitle, description,
739  category, category_type,
740  txstart, txend, fix,
741  subtitle_type,
742  audio_props,
743  video_props, 0.0,
744  "", "",
745  season, episode, totalepisodes);
746  event->m_items = items;
747 
748  db_events.enqueue(event);
749  }
750  }
751 }
752 
753 
755 {
756  s_eitcache->PruneOldEntries(timestamp);
757 }
758 
760 {
762 }
763 
765 // private methods and functions below this line //
767 
768 void EITHelper::CompleteEvent(uint atsc_major, uint atsc_minor,
769  const ATSCEvent &event,
770  const QString &ett)
771 {
772  uint chanid = GetChanID(atsc_major, atsc_minor);
773  if (!chanid)
774  return;
775 
776 #if QT_VERSION < QT_VERSION_CHECK(5,8,0)
777  QDateTime starttime = MythDate::fromTime_t(
778  event.m_start_time + GPS_EPOCH + gps_offset);
779 #else
780  QDateTime starttime = MythDate::fromSecsSinceEpoch(
781  event.m_start_time + GPS_EPOCH + gps_offset);
782 #endif
783 
784  // fix starttime only if the duration is a multiple of a minute
785  if (!(event.m_length % 60))
786  EITFixUp::TimeFix(starttime);
787  QDateTime endtime = starttime.addSecs(event.m_length);
788 
790  unsigned char subtitle_type =
793  unsigned char audio_properties = AUD_UNKNOWN;
794  unsigned char video_properties = VID_UNKNOWN;
795 
796  uint atsc_key = (atsc_major << 16) | atsc_minor;
797 
798  QMutexLocker locker(&eitList_lock);
799  QString title = event.m_title;
800  const QString& subtitle = ett;
801  db_events.enqueue(new DBEventEIT(chanid, title, subtitle,
802  starttime, endtime,
803  fixup.value(atsc_key), subtitle_type,
804  audio_properties, video_properties));
805 }
806 
807 uint EITHelper::GetChanID(uint atsc_major, uint atsc_minor)
808 {
809  uint64_t key;
810  key = ((uint64_t) sourceid);
811  key |= ((uint64_t) atsc_minor) << 16;
812  key |= ((uint64_t) atsc_major) << 32;
813 
814  ServiceToChanID::const_iterator it = srv_to_chanid.find(key);
815  if (it != srv_to_chanid.end())
816  return *it;
817 
818  uint chanid = get_chan_id_from_db_atsc(sourceid, atsc_major, atsc_minor);
819  srv_to_chanid[key] = chanid;
820 
821  return chanid;
822 }
823 
824 uint EITHelper::GetChanID(uint serviceid, uint networkid, uint tsid)
825 {
826  uint64_t key;
827  key = ((uint64_t) sourceid);
828  key |= ((uint64_t) serviceid) << 16;
829  key |= ((uint64_t) networkid) << 32;
830  key |= ((uint64_t) tsid) << 48;
831 
832  ServiceToChanID::const_iterator it = srv_to_chanid.find(key);
833  if (it != srv_to_chanid.end())
834  return *it;
835 
836  uint chanid = get_chan_id_from_db_dvb(sourceid, serviceid, networkid, tsid);
837  srv_to_chanid[key] = chanid;
838 
839  return chanid;
840 }
841 
843 {
844  uint64_t key;
845  key = ((uint64_t) sourceid);
846  key |= ((uint64_t) program_number) << 16;
847  key |= ((uint64_t) channelid) << 32;
848 
849  ServiceToChanID::const_iterator it = srv_to_chanid.find(key);
850  if (it != srv_to_chanid.end())
851  return *it;
852 
853  uint chanid = get_chan_id_from_db_dtv(sourceid, program_number, channelid);
854  srv_to_chanid[key] = chanid;
855 
856  return chanid;
857 }
858 
860  uint atsc_major, uint atsc_minor)
861 {
862  MSqlQuery query(MSqlQuery::InitCon());
863  query.prepare(
864  "SELECT chanid, useonairguide "
865  "FROM channel "
866  "WHERE atsc_major_chan = :MAJORCHAN AND "
867  " atsc_minor_chan = :MINORCHAN AND "
868  " sourceid = :SOURCEID");
869  query.bindValue(":MAJORCHAN", atsc_major);
870  query.bindValue(":MINORCHAN", atsc_minor);
871  query.bindValue(":SOURCEID", sourceid);
872 
873  if (!query.exec() || !query.isActive())
874  MythDB::DBError("Looking up chanid 1", query);
875  else if (query.next())
876  {
877  bool useOnAirGuide = query.value(1).toBool();
878  return (useOnAirGuide) ? query.value(0).toUInt() : 0;
879  }
880 
881  return 0;
882 }
883 
884 // Figure out the chanid for this channel
885 static uint get_chan_id_from_db_dvb(uint sourceid, uint serviceid,
886  uint networkid, uint transportid)
887 {
888  uint chanid = 0;
889  bool useOnAirGuide = false;
890  MSqlQuery query(MSqlQuery::InitCon());
891 
892  // DVB Link to chanid
893  QString qstr =
894  "SELECT chanid, useonairguide, channel.sourceid "
895  "FROM channel, dtv_multiplex "
896  "WHERE serviceid = :SERVICEID AND "
897  " networkid = :NETWORKID AND "
898  " transportid = :TRANSPORTID AND "
899  " channel.mplexid = dtv_multiplex.mplexid";
900 
901  query.prepare(qstr);
902  query.bindValue(":SERVICEID", serviceid);
903  query.bindValue(":NETWORKID", networkid);
904  query.bindValue(":TRANSPORTID", transportid);
905 
906  if (!query.exec() || !query.isActive())
907  MythDB::DBError("Looking up chanID", query);
908 
909  if (query.size() == 0) {
910  // Attempt fuzzy matching, by skipping the tsid
911  // DVB Link to chanid
912  qstr =
913  "SELECT chanid, useonairguide, channel.sourceid "
914  "FROM channel, dtv_multiplex "
915  "WHERE serviceid = :SERVICEID AND "
916  " networkid = :NETWORKID AND "
917  " channel.mplexid = dtv_multiplex.mplexid";
918 
919  query.prepare(qstr);
920  query.bindValue(":SERVICEID", serviceid);
921  query.bindValue(":NETWORKID", networkid);
922  if (!query.exec() || !query.isActive())
923  MythDB::DBError("Looking up chanID in fuzzy mode", query);
924  }
925 
926  while (query.next())
927  {
928  // Check to see if we are interested in this channel
929  chanid = query.value(0).toUInt();
930  useOnAirGuide = query.value(1).toBool();
931  if (sourceid == query.value(2).toUInt())
932  return useOnAirGuide ? chanid : 0;
933  }
934 
935  if (query.size() > 1)
936  {
937  LOG(VB_EIT, LOG_INFO,
938  LOC + QString("found %1 channels for networkid %2, "
939  "transportid %3, serviceid %4 but none "
940  "for current sourceid %5.")
941  .arg(query.size()).arg(networkid).arg(transportid)
942  .arg(serviceid).arg(sourceid));
943  }
944 
945  return useOnAirGuide ? chanid : 0;
946 }
947 
948 /* Figure out the chanid for this channel from the sourceid,
949  * program_number/service_id and the chanid of the channel we are tuned to
950  *
951  * TODO for SPTS (e.g. HLS / IPTV) it would be useful to match without an entry
952  * in dtv_multiplex
953  */
954 static uint get_chan_id_from_db_dtv(uint sourceid, uint serviceid,
955  uint tunedchanid)
956 {
957  uint chanid = 0;
958  bool useOnAirGuide = false;
959  MSqlQuery query(MSqlQuery::InitCon());
960 
961  // DVB Link to chanid
962  QString qstr =
963  "SELECT c1.chanid, c1.useonairguide, c1.sourceid "
964  "FROM channel c1, dtv_multiplex m, channel c2 "
965  "WHERE c1.serviceid = :SERVICEID AND "
966  " c1.mplexid = m.mplexid AND "
967  " m.mplexid = c2.mplexid AND "
968  " c2.chanid = :CHANID";
969 
970  query.prepare(qstr);
971  query.bindValue(":SERVICEID", serviceid);
972  query.bindValue(":CHANID", tunedchanid);
973 
974  if (!query.exec() || !query.isActive())
975  MythDB::DBError("Looking up chanID", query);
976 
977  while (query.next())
978  {
979  // Check to see if we are interested in this channel
980  chanid = query.value(0).toUInt();
981  useOnAirGuide = query.value(1).toBool();
982  if (sourceid == query.value(2).toUInt())
983  return useOnAirGuide ? chanid : 0;
984  }
985 
986  if (query.size() > 1)
987  {
988  LOG(VB_EIT, LOG_INFO,
989  LOC + QString("found %1 channels for multiplex of chanid %2, "
990  "serviceid %3 but none "
991  "for current sourceid %4.")
992  .arg(query.size()).arg(tunedchanid)
993  .arg(serviceid).arg(sourceid));
994  }
995 
996  return useOnAirGuide ? chanid : 0;
997 }
998 
999 static void init_fixup(FixupMap &fix)
1000 {
1002  // Fixups to make EIT provided listings more useful
1003  // transport_id<<32 | original_network_id<<16 | service_id
1004 
1005  // Bell Express VU Canada
1006  fix[ 256U << 16] = EITFixUp::kFixBell;
1007  fix[ 257U << 16] = EITFixUp::kFixBell;
1008  fix[ 4100U << 16] = EITFixUp::kFixBell;
1009  fix[ 4101U << 16] = EITFixUp::kFixBell;
1010  fix[ 4102U << 16] = EITFixUp::kFixBell;
1011  fix[ 4103U << 16] = EITFixUp::kFixBell;
1012  fix[ 4104U << 16] = EITFixUp::kFixBell;
1013  fix[ 4105U << 16] = EITFixUp::kFixBell;
1014  fix[ 4106U << 16] = EITFixUp::kFixBell;
1015  fix[ 4107U << 16] = EITFixUp::kFixBell;
1016  fix[ 4097U << 16] = EITFixUp::kFixBell;
1017  fix[ 4098U << 16] = EITFixUp::kFixBell;
1018 
1019  // United Kingdom - DVB-T/T2
1020  fix[ 9018U << 16] = EITFixUp::kFixUK;
1021 
1022  // UK - Astra 28.2
1023  for (int i = 2001; i <= 2035; ++i)
1024  fix[ (long long)i << 32 | 2U << 16] = EITFixUp::kFixUK;
1025 
1026  fix[ 2036LL << 32 | 2U << 16] = EITFixUp::kFixUK | EITFixUp::kFixHTML;
1027 
1028  for (int i = 2037; i <= 2057; ++i)
1029  fix[ (long long)i << 32 | 2U << 16] = EITFixUp::kFixUK;
1030  fix[ 2059LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1031  fix[ 2061LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1032  for (int i = 2063; i <= 2069; ++i)
1033  fix[ (long long)i << 32 | 2U << 16] = EITFixUp::kFixUK;
1034  fix[ 2071LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1035  fix[ 2076LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1036  fix[ 2081LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1037  for (int i = 2089; i <= 2092; ++i)
1038  fix[ (long long)i << 32 | 2U << 16] = EITFixUp::kFixUK;
1039  for (int i = 2094; i <= 2099; ++i)
1040  fix[ (long long)i << 32 | 2U << 16] = EITFixUp::kFixUK;
1041  for (int i = 2102; i <= 2110; ++i)
1042  fix[ (long long)i << 32 | 2U << 16] = EITFixUp::kFixUK;
1043  fix[ 2112LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1044  fix[ 2116LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1045  fix[ 2301LL << 32 | 2U << 16] = EITFixUp::kFixUK | EITFixUp::kFixHTML;
1046  fix[ 2302LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1047  fix[ 2303LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1048  fix[ 2304LL << 32 | 2U << 16] = EITFixUp::kFixUK | EITFixUp::kFixHTML;
1049  fix[ 2305LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1050  fix[ 2306LL << 32 | 2U << 16] = EITFixUp::kFixUK | EITFixUp::kFixHTML;
1051  fix[ 2311LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1052  fix[ 2312LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1053  fix[ 2313LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1054  fix[ 2314LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1055  fix[ 2315LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1056  fix[ 2316LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1057  for (int i = 2401; i <= 2413; ++i)
1058  fix[ (long long)i << 32 | 2U << 16] = EITFixUp::kFixUK;
1059  fix[ 2601LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1060  fix[ 2602LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1061  fix[ 2603LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1062  fix[ 2604LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1063  fix[ 2612LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1064  fix[ 2614LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1065  fix[ 2611LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1066  fix[ 2612LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1067  fix[ 2613LL << 32 | 2U << 16] = EITFixUp::kFixUK;
1068 
1069  // R.caroline
1070  fix[ 2315LL << 32 | 59U << 16] = EITFixUp::kFixUK;
1071 
1072  // ComHem Sweden
1073  fix[40999U << 16 ] = EITFixUp::kFixComHem;
1074  fix[40999U << 16 | 1070] = EITFixUp::kFixSubtitle;
1075  fix[40999U << 16 | 1308] = EITFixUp::kFixSubtitle;
1076  fix[40999U << 16 | 1041] = EITFixUp::kFixSubtitle;
1077  fix[40999U << 16 | 1306] = EITFixUp::kFixSubtitle;
1078  fix[40999U << 16 | 1307] = EITFixUp::kFixSubtitle;
1079  fix[40999U << 16 | 1030] = EITFixUp::kFixSubtitle;
1080  fix[40999U << 16 | 1016] = EITFixUp::kFixSubtitle;
1081  fix[40999U << 16 | 1131] = EITFixUp::kFixSubtitle;
1082  fix[40999U << 16 | 1068] = EITFixUp::kFixSubtitle;
1083  fix[40999U << 16 | 1069] = EITFixUp::kFixSubtitle;
1084 
1085  // Australia
1086  fix[ 4096U << 16] = EITFixUp::kFixAUStar;
1087  fix[ 4096U << 16] = EITFixUp::kFixAUStar;
1088  fix[ 4112U << 16] = EITFixUp::kFixAUDescription | EITFixUp::kFixAUFreeview; // ABC Brisbane
1089  fix[ 4114U << 16] = EITFixUp::kFixAUDescription | EITFixUp::kFixAUFreeview | EITFixUp::kFixAUNine;; // Nine Brisbane
1090  fix[ 4115U << 16] = EITFixUp::kFixAUDescription | EITFixUp::kFixAUSeven; //Seven
1091  fix[ 4116U << 16] = EITFixUp::kFixAUDescription; //Ten
1092  fix[ 12801U << 16] = EITFixUp::kFixAUFreeview | EITFixUp::kFixAUDescription; //ABC
1093  fix[ 12802U << 16] = EITFixUp::kFixAUDescription; //SBS
1095  fix[ 12842U << 16] = EITFixUp::kFixAUDescription; // 31 Brisbane
1096  fix[ 12862U << 16] = EITFixUp::kFixAUDescription; //WestTV
1097 
1098  // MultiChoice Africa
1099  fix[ 6144U << 16] = EITFixUp::kFixMCA;
1100 
1101  // RTL Subtitle parsing
1102  fix[ 1089LL << 32 | 1 << 16] = // DVB-S
1103  fix[ 1041LL << 32 | 1 << 16] = // DVB-S RTL Group HD Austria Transponder
1104  fix[ 1057LL << 32 | 1 << 16] = // DVB-S RTL Group HD Transponder
1105  fix[ 773LL << 32 | 8468U << 16] = // DVB-T Berlin/Brandenburg
1106  fix[ 2819LL << 32 | 8468U << 16] = // DVB-T Niedersachsen + Bremen
1107  fix[ 8706LL << 32 | 8468U << 16] = // DVB-T NRW
1108  fix[ 12801LL << 32 | 8468U << 16] = // DVB-T Bayern
1110 
1111  // Mark HD+ channels as HDTV
1112  fix[ 1041LL << 32 | 1 << 16] = EITFixUp::kFixHDTV;
1113  fix[ 1055LL << 32 | 1 << 16] = EITFixUp::kFixHDTV;
1114  fix[ 1057LL << 32 | 1 << 16] = EITFixUp::kFixHDTV;
1115  fix[ 1109LL << 32 | 1 << 16] = EITFixUp::kFixHDTV;
1116 
1117  // PRO7/SAT.1
1118  fix[ 1017LL << 32 | 1 << 16] = EITFixUp::kFixHDTV | EITFixUp::kFixP7S1;
1119  fix[ 1031LL << 32 | 1 << 16 | 5300] = EITFixUp::kFixHDTV | EITFixUp::kFixP7S1;
1120  fix[ 1031LL << 32 | 1 << 16 | 5301] = EITFixUp::kFixHDTV | EITFixUp::kFixP7S1;
1121  fix[ 1031LL << 32 | 1 << 16 | 5302] = EITFixUp::kFixHDTV | EITFixUp::kFixP7S1;
1122  fix[ 1031LL << 32 | 1 << 16 | 5303] = EITFixUp::kFixHDTV | EITFixUp::kFixP7S1;
1123  fix[ 1031LL << 32 | 1 << 16 | 5310] = EITFixUp::kFixP7S1;
1124  fix[ 1031LL << 32 | 1 << 16 | 5311] = EITFixUp::kFixP7S1;
1125  fix[ 1107LL << 32 | 1 << 16] = EITFixUp::kFixP7S1;
1126  fix[ 1082LL << 32 | 1 << 16] = EITFixUp::kFixP7S1;
1127  fix[ 5LL << 32 | 133 << 16 | 776] = EITFixUp::kFixP7S1;
1128  fix[ 8468 << 16 | 16426] = EITFixUp::kFixP7S1; // ProSieben MAXX - DVB-T Rhein/Main
1129  fix[ 8707LL << 32 | 8468 << 16] = EITFixUp::kFixP7S1; // ProSieben Sat.1 Mux - DVB-T Rhein/Main
1130 
1131  // ATV / ATV2
1132  fix[ 1117LL << 32 | 1 << 16 | 13012 ] = EITFixUp::kFixATV; // ATV
1133  fix[ 1003LL << 32 | 1 << 16 | 13223 ] = EITFixUp::kFixATV; // ATV2
1134  fix[ 1003LL << 32 | 1 << 16 | 13228 ] = EITFixUp::kFixHDTV | EITFixUp::kFixATV; // ATV HD
1135 
1136  // Disney Channel Germany
1137  fix[ 1055LL << 32 | 1 << 16 | 5500 ] = EITFixUp::kFixHDTV | EITFixUp::kFixDisneyChannel; // Disney Channel HD
1138  fix[ 1055LL << 32 | 1 << 16 | 5510 ] = EITFixUp::kFixHDTV | EITFixUp::kFixDisneyChannel; // Disney Channel HD Austria
1139  fix[ 5LL << 32 | 133 << 16 | 1793 ] = EITFixUp::kFixDisneyChannel; // Disney Channel HD Austria
1140  fix[ 1109LL << 32 | 1 << 16 | 5401 ] = EITFixUp::kFixHDTV | EITFixUp::kFixDisneyChannel; // Tele 5 HD
1141  fix[ 1109LL << 32 | 1 << 16 | 5421 ] = EITFixUp::kFixHDTV | EITFixUp::kFixDisneyChannel; // Tele 5 HD Austria
1142  fix[ 33LL << 32 | 133 << 16 | 51 ] = EITFixUp::kFixDisneyChannel; // Tele 5
1143 
1144  // Premiere EIT processing
1145  fix[ 1LL << 32 | 133 << 16] = EITFixUp::kFixPremiere;
1146  fix[ 2LL << 32 | 133 << 16] = EITFixUp::kFixPremiere;
1147  fix[ 3LL << 32 | 133 << 16] = EITFixUp::kFixPremiere;
1148  fix[ 4LL << 32 | 133 << 16] = EITFixUp::kFixPremiere;
1149  fix[ 6LL << 32 | 133 << 16] = EITFixUp::kFixPremiere | EITFixUp::kFixHDTV;
1150  fix[ 8LL << 32 | 133 << 16] = EITFixUp::kFixPremiere | EITFixUp::kFixHDTV;
1151  fix[ 9LL << 32 | 133 << 16] = EITFixUp::kFixPremiere | EITFixUp::kFixHDTV;
1152  fix[ 10LL << 32 | 133 << 16] = EITFixUp::kFixPremiere | EITFixUp::kFixHDTV;
1153  fix[ 11LL << 32 | 133 << 16] = EITFixUp::kFixPremiere | EITFixUp::kFixHDTV;
1154  fix[ 12LL << 32 | 133 << 16] = EITFixUp::kFixPremiere | EITFixUp::kFixHDTV;
1155  fix[ 13LL << 32 | 133 << 16] = EITFixUp::kFixPremiere | EITFixUp::kFixHDTV;
1156  fix[ 14LL << 32 | 133 << 16] = EITFixUp::kFixPremiere | EITFixUp::kFixHDTV;
1157  fix[ 15LL << 32 | 133 << 16] = EITFixUp::kFixPremiere;
1158  fix[ 17LL << 32 | 133 << 16] = EITFixUp::kFixPremiere;
1159  // Mark Premiere HD, AXN HD and Discovery HD as HDTV
1160  fix[ 6LL << 32 | 133 << 16 | 129] = EITFixUp::kFixHDTV;
1161  fix[ 6LL << 32 | 133 << 16 | 130] = EITFixUp::kFixHDTV;
1162  fix[ 10LL << 32 | 133 << 16 | 125] = EITFixUp::kFixHDTV;
1163 
1164  // Netherlands DVB-C
1165  fix[ 1000U << 16] = EITFixUp::kFixNL;
1166  // Canal Digitaal DVB-S 19.2 Dutch/Belgian ONID 53 covers all CanalDigitaal TiD
1167  fix[ 53U << 16] = EITFixUp::kFixNL;
1168  // Canal Digitaal DVB-S 23.5 Dutch/Belgian
1169  fix[ 3202LL << 32 | 3U << 16] = EITFixUp::kFixNL;
1170  fix[ 3208LL << 32 | 3U << 16] = EITFixUp::kFixNL;
1171  fix[ 3211LL << 32 | 3U << 16] = EITFixUp::kFixNL;
1172  fix[ 3222LL << 32 | 3U << 16] = EITFixUp::kFixNL;
1173  fix[ 3225LL << 32 | 3U << 16] = EITFixUp::kFixNL;
1174 
1175  // Finland
1176  fix[ 8438U << 16] = // DVB-T Espoo
1177  fix[ 42249U << 16] = // DVB-C Welho
1178  fix[ 15U << 16] = // DVB-C Welho
1180 
1181  // DVB-C YouSee (Denmark)
1182  fix[65024U << 16] = EITFixUp::kFixDK;
1183 
1184  // DVB-S(2) Thor 0.8W Norwegian
1185  fix[70U << 16] = EITFixUp::kFixNO;
1186 
1187  // DVB-T NTV/NRK (Norway)
1188  fix[910LL << 32 | 8770U << 16 | 0x006f] = EITFixUp::kFixNRK_DVBT; //NRK Folkemusikk
1189  fix[910LL << 32 | 8770U << 16 | 0x0070] = EITFixUp::kFixNRK_DVBT; //NRK Stortinget
1190  fix[910LL << 32 | 8770U << 16 | 0x0071] = EITFixUp::kFixNRK_DVBT; //NRK Super
1191  fix[910LL << 32 | 8770U << 16 | 0x0072] = EITFixUp::kFixNRK_DVBT; //NRK Sport
1192  fix[910LL << 32 | 8770U << 16 | 0x0073] = EITFixUp::kFixNRK_DVBT; //NRK Gull
1193  fix[910LL << 32 | 8770U << 16 | 0x0074] = EITFixUp::kFixNRK_DVBT; //NRK Jazz
1194  fix[910LL << 32 | 8770U << 16 | 0x0067] = EITFixUp::kFixNRK_DVBT; //NRK Super / NRK3
1195  fix[910LL << 32 | 8770U << 16 | 0x0068] = EITFixUp::kFixNRK_DVBT; //NRK Tegnspr�
1196  fix[910LL << 32 | 8770U << 16 | 0x0069] = EITFixUp::kFixNRK_DVBT; //NRK P2
1197  fix[910LL << 32 | 8770U << 16 | 0x006a] = EITFixUp::kFixNRK_DVBT; //NRK P3
1198  fix[910LL << 32 | 8770U << 16 | 0x006b] = EITFixUp::kFixNRK_DVBT; //NRK Alltid Nyheter
1199  fix[910LL << 32 | 8770U << 16 | 0x006c] = EITFixUp::kFixNRK_DVBT; //NRK mP3
1200  fix[910LL << 32 | 8770U << 16 | 0x006d] = EITFixUp::kFixNRK_DVBT; //NRK Klassisk
1201  fix[910LL << 32 | 8770U << 16 | 0x006e] = EITFixUp::kFixNRK_DVBT; //NRK S�i Radio
1202  fix[910LL << 32 | 8770U << 16 | 0x0066] = EITFixUp::kFixNRK_DVBT; //NRK2
1203  fix[910LL << 32 | 8770U << 16 | 0x03f0] = EITFixUp::kFixNRK_DVBT; //NRK1 M�e og Romsdal
1204  fix[910LL << 32 | 8770U << 16 | 0x0455] = EITFixUp::kFixNRK_DVBT; //NRK P1 Tr�delag
1205  fix[910LL << 32 | 8770U << 16 | 0x03f1] = EITFixUp::kFixNRK_DVBT; //NRK1 Midtnytt
1206 
1208  // Special Early fixups for providers that break DVB EIT spec.
1209  // transport_id<<32 | network_id<<16 | service_id
1210 
1211  // Bell Express VU Canada
1212  fix[ 256U << 16] |= EITFixUp::kEFixForceISO8859_1;
1213  fix[ 257U << 16] |= EITFixUp::kEFixForceISO8859_1;
1214  fix[4100U << 16] |= EITFixUp::kEFixForceISO8859_1;
1215  fix[4101U << 16] |= EITFixUp::kEFixForceISO8859_1;
1216  fix[4102U << 16] |= EITFixUp::kEFixForceISO8859_1;
1217  fix[4103U << 16] |= EITFixUp::kEFixForceISO8859_1;
1218  fix[4104U << 16] |= EITFixUp::kEFixForceISO8859_1;
1219  fix[4105U << 16] |= EITFixUp::kEFixForceISO8859_1;
1220  fix[4106U << 16] |= EITFixUp::kEFixForceISO8859_1;
1221  fix[4107U << 16] |= EITFixUp::kEFixForceISO8859_1;
1222  fix[4097U << 16] |= EITFixUp::kEFixForceISO8859_1;
1223  fix[4098U << 16] |= EITFixUp::kEFixForceISO8859_1;
1224 
1225  //DVB-T Germany Berlin HSE/MonA TV
1226  fix[ 772LL << 32 | 8468 << 16 | 16387] = EITFixUp::kEFixForceISO8859_15;
1227  //DVB-T Germany Ruhrgebiet Tele 5
1228  //fix[ 8707LL << 32 | 8468 << 16 | 16413] = EITFixUp::kEFixForceISO8859_15; // they are sending the ISO 8859-9 signalling now
1229  // ANIXE
1230  fix[ 8707LL << 32 | 8468U << 16 | 16426 ] = // DVB-T Rhein-Main
1232 
1233  // DVB-C Kabel Deutschland encoding fixes Germany
1234  fix[ 112LL << 32 | 61441U << 16] = EITFixUp::kEFixForceISO8859_15;
1235  fix[ 10000LL << 32 | 61441U << 16] = EITFixUp::kEFixForceISO8859_15;
1236  fix[ 10001LL << 32 | 61441U << 16] = EITFixUp::kEFixForceISO8859_15;
1237  fix[ 10002LL << 32 | 61441U << 16] = EITFixUp::kEFixForceISO8859_15;
1238  fix[ 10003LL << 32 | 61441U << 16] = EITFixUp::kEFixForceISO8859_15;
1239  fix[ 10006LL << 32 | 61441U << 16] = EITFixUp::kEFixForceISO8859_15;
1240  fix[ 10009LL << 32 | 61441U << 16] = EITFixUp::kEFixForceISO8859_15;
1241  fix[ 10010LL << 32 | 61441U << 16] = EITFixUp::kEFixForceISO8859_15;
1242  // Mark program on the HD transponders as HDTV
1243  fix[ 10012LL << 32 | 61441U << 16] = EITFixUp::kFixHDTV;
1244  fix[ 10013LL << 32 | 61441U << 16] = EITFixUp::kFixHDTV;
1245  // On transport 10004 only DMAX needs no fixing:
1246  fix[10004LL<<32 | 61441U << 16 | 50403] = // BBC World Service
1247  fix[10004LL<<32 | 61441U << 16 | 53101] = // BBC Prime (engl)
1248  fix[10004LL<<32 | 61441U << 16 | 53108] = // Toon Disney (engl)
1249  fix[10004LL<<32 | 61441U << 16 | 53109] = // Sky News (engl)
1250  fix[10004LL<<32 | 61441U << 16 | 53406] = // BBC Prime
1251  fix[10004LL<<32 | 61441U << 16 | 53407] = // Boomerang (engl)
1252  fix[10004LL<<32 | 61441U << 16 | 53404] = // Boomerang
1253  fix[10004LL<<32 | 61441U << 16 | 53408] = // TCM Classic Movies (engl)
1254  fix[10004LL<<32 | 61441U << 16 | 53409] = // Extreme Sports
1255  fix[10004LL<<32 | 61441U << 16 | 53410] = // CNBC Europe (engl)
1256  fix[10004LL<<32 | 61441U << 16 | 53503] = // Detski Mir
1257  fix[10004LL<<32 | 61441U << 16 | 53411] = // Sat.1 Comedy
1258  fix[10004LL<<32 | 61441U << 16 | 53412] = // kabel eins classics
1259  fix[10004LL<<32 | 61441U << 16 | 53112] = // Extreme Sports (engl)
1260  fix[10004LL<<32 | 61441U << 16 | 53513] = // Playhouse Disney (engl)
1261  fix[10004LL<<32 | 61441U << 16 | 53618] = // K1010
1262  fix[10004LL<<32 | 61441U << 16 | 53619] = // GemsTV
1264  // On transport 10005 QVC and Giga Digital needs no fixing:
1265  fix[10005LL<<32 | 61441U << 16 | 50104] = // E! Entertainment
1266  fix[10005LL<<32 | 61441U << 16 | 50107] = // 13th Street (KD)
1267  fix[10005LL<<32 | 61441U << 16 | 50301] = // ESPN Classic
1268  fix[10005LL<<32 | 61441U << 16 | 50302] = // VH1 Classic
1269  fix[10005LL<<32 | 61441U << 16 | 50303] = // Wein TV
1270  fix[10005LL<<32 | 61441U << 16 | 50304] = // AXN
1271  fix[10005LL<<32 | 61441U << 16 | 50305] = // Silverline
1272  fix[10005LL<<32 | 61441U << 16 | 50306] = // NASN
1273  fix[10005LL<<32 | 61441U << 16 | 50307] = // Disney Toon
1274  fix[10005LL<<32 | 61441U << 16 | 53105] = // NASN (engl)
1275  fix[10005LL<<32 | 61441U << 16 | 53115] = // VH1 Classic (engl)
1276  fix[10005LL<<32 | 61441U << 16 | 53405] = // ESPN Classic (engl)
1277  fix[10005LL<<32 | 61441U << 16 | 53402] = // AXN (engl)
1278  fix[10005LL<<32 | 61441U << 16 | 53613] = // CNN (engl)
1279  fix[10005LL<<32 | 61441U << 16 | 53516] = // Voyages Television
1280  fix[10005LL<<32 | 61441U << 16 | 53611] = // Der Schmuckkanal
1281  fix[10005LL<<32 | 61441U << 16 | 53104] = // Jukebox
1283  // On transport 10007 only following channels need fixing:
1284  fix[10007LL<<32| 61441U << 16 | 53607] = // Eurosport
1285  fix[10007LL<<32| 61441U << 16 | 53608] = // Das Vierte
1286  fix[10007LL<<32| 61441U << 16 | 53609] = // Viva
1287  fix[10007LL<<32| 61441U << 16 | 53628] = // COMEDY CENTRAL
1289  // RTL Subtitle parsing
1290  fix[10007LL<<32| 61441U << 16 | 53601] = // RTL
1291  fix[10007LL<<32| 61441U << 16 | 53602] = // Super RTL
1292  fix[10007LL<<32| 61441U << 16 | 53604] = // VOX
1293  fix[10007LL<<32| 61441U << 16 | 53606] = // n-tv
1295  // On transport 10008 only following channels need fixing:
1296  fix[ 10008LL<<32 | 61441U << 16 | 53002] = // Tele 5
1298 
1299  // DVB-C Unitymedia Germany
1300  fix[ 9999 << 16 | 161LL << 32 | 12101 ] = // RTL Television
1301  fix[ 9999 << 16 | 161LL << 32 | 12104 ] = // VOX
1302  fix[ 9999 << 16 | 161LL << 32 | 12107 ] = // Super RTL
1303  fix[ 9999 << 16 | 161LL << 32 | 12109 ] = // n-tv
1304  fix[ 9999 << 16 | 301LL << 32 | 30114 ] = // RTL NITRO
1306  fix[ 9999 << 16 | 191LL << 32 | 11102 ] = // DAS VIERTE
1308  // on this transport are only HD services, two TBD, arte and ServusTV, I think arte properly signals HD!
1309  fix[ 9999 << 16 | 401LL << 32 | 29109 ] = // ServusTV HD
1311  // generic Unitymedia / Liberty Global / Eventis.nl?
1312  fix[ 9999 << 16 | 121LL << 32 | 12107 ] = // Super RTL
1313  fix[ 9999 << 16 | 151LL << 32 | 15110 ] = // Bibel TV
1314  fix[ 9999 << 16 | 161LL << 32 | 12107 ] = // Super RTL
1315  fix[ 9999 << 16 | 161LL << 32 | 12109 ] = // n-tv
1316  fix[ 9999 << 16 | 171LL << 32 | 17119 ] = // RiC
1317  fix[ 9999 << 16 | 171LL << 32 | 27102 ] = // DELUXE MUSIC
1318  fix[ 9999 << 16 | 181LL << 32 | 24108 ] = // DMAX
1319  fix[ 9999 << 16 | 181LL << 32 | 25102 ] = // TV5MONDE Europe
1320  fix[ 9999 << 16 | 191LL << 32 | 11102 ] = // Disney SD
1321  fix[ 9999 << 16 | 191LL << 32 | 12110 ] = // N24
1322  fix[ 9999 << 16 | 191LL << 32 | 12111 ] = // Tele 5
1323  fix[ 9999 << 16 | 201LL << 32 | 27103 ] = // TLC
1324  fix[ 9999 << 16 | 211LL << 32 | 29108 ] = // Astro TV
1325  fix[ 9999 << 16 | 231LL << 32 | 23117 ] = // Deutsches Musik Fernsehen
1326  fix[ 9999 << 16 | 231LL << 32 | 23115 ] = // Family TV
1327  fix[ 9999 << 16 | 271LL << 32 | 27101 ] = // DIE NEUE ZEIT TV
1328  fix[ 9999 << 16 | 541LL << 32 | 54101 ] = // HR HD
1330 
1331  // DVB-S Astra 19.2E DMAX Germany
1332  fix[ 1113LL << 32 | 1 << 16 | 12602] = EITFixUp::kEFixForceISO8859_15;
1333 
1334  // Premiere
1335  fix[133 << 16] = EITFixUp::kEFixForceISO8859_15;
1336 
1337  // DVB-S Astra 19.2E French channels
1338  fix[ 1022LL << 32 | 1 << 16 | 6901 ] = // DIRECT 8
1339  fix[ 1022LL << 32 | 1 << 16 | 6905 ] = // France 24 (en Francais)
1340  fix[ 1022LL << 32 | 1 << 16 | 6911 ] = // DIRECT 8
1341  fix[ 1072LL << 32 | 1 << 16 | 8201 ] = // CANAL+
1342  fix[ 1070LL << 32 | 1 << 16 | 8004 ] = // EURONEWS
1343  fix[ 1091LL << 32 | 1 << 16 | 31220 ] = // EuroNews
1344  fix[ 1094LL << 32 | 1 << 16 | 17027 ] = // LCP
1345  fix[ 1094LL << 32 | 1 << 16 | 17028 ] = // NT1
1346  fix[ 1100LL << 32 | 1 << 16 | 8710 ] = // NRJ 12
1348 
1349  // DVB-C T-Kábel Hungary
1350  // FIXME this should be more specific. Is the encoding really wrong for all services?
1351  fix[ 100 << 16] = EITFixUp::kEFixForceISO8859_2;
1352 
1353  // DVB-T Greece
1354  // Pelion Transmitter
1355  // transport_id<<32 | netword_id<<16 | service_id
1356  fix[ 100LL << 32 | 8492LL << 16 ] = // Ant1,Alpha,Art,10E
1357  fix[ 102LL << 32 | 8492LL << 16 ] = // Mega,Star,SKAI,M.tv
1358  fix[ 320LL << 32 | 8492LL << 16 ] = // Astra,Thessalia,TRT,TV10,ZEYS
1362  fix[ 2LL << 32 | 8492LL << 16 ] = // N1,Nplus,NHD,Vouli
1363  EITFixUp::kEFixForceISO8859_7 | // it is encoded in cp-1253
1364  EITFixUp::kFixGreekSubtitle | // Subtitle has too much info and is
1365  EITFixUp::kFixGreekEIT | // cut in db. Will move to descr.
1367 
1368  //DVB-S & S2 Greek Nova Provider
1369  // Hotbird 11823H DVB-S
1370  fix[ 5500LL << 32 | 318LL << 16 ] = EITFixUp::kEFixForceISO8859_7;
1371  // Hotbird 11938H DVB-S
1372  fix[ 6100LL << 32 | 318LL << 16 ] = EITFixUp::kEFixForceISO8859_7;
1373  // Hotbird 12130H DVB-S2
1374  fix[ 7100LL << 32 | 318LL << 16 ] = EITFixUp::kEFixForceISO8859_7;
1375  // Hotbird 12169H DVB-S2
1376  fix[ 7300LL << 32 | 318LL << 16 ] = EITFixUp::kEFixForceISO8859_7;
1377 
1378  // DVB-S Star One C2 70W (Brazil)
1379  // it has original_network_id = 1 like Astra on 19.2E, but transport_id does
1380  // not collide at the moment
1381  fix[ 1LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1382  fix[ 2LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1383  fix[ 3LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1384  fix[ 4LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1385  fix[ 50LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1386  fix[ 51LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1387  fix[ 52LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1388  fix[ 53LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1389  fix[ 54LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1390  fix[ 55LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1391  fix[ 56LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1392  fix[ 57LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1393  fix[ 58LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1394  fix[ 59LL << 32 | 1LL << 16 ] = EITFixUp::kEFixForceISO8859_1;
1395 }
1396 
1402 {
1405  maxStarttime, "EITScanner");
1406  seenEITother = false;
1407  maxStarttime = QDateTime();
1408 }
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:782
uint Version(void) const
Definition: mpegtables.h:503
ProgramInfo::CategoryType GetMythCategory(uint i) const
QMap< QString, QString > Items(void) const
uint TSID(void) const
Definition: dvbtables.h:308
DishThemeType GetTheme(void) const
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:863
uint GetChanID(uint atsc_major, uint atsc_minor)
Definition: eithelper.cpp:807
void CompleteEvent(uint atsc_major, uint atsc_minor, const ATSCEvent &event, const QString &ett)
Definition: eithelper.cpp:768
uint SubtitleProperties(uint compression_type) const
QString EventName(void) const
uint32_t m_length
Definition: eithelper.h:39
static void init_fixup(FixupMap &fix)
Definition: eithelper.cpp:999
#define GPS_EPOCH
Seconds between start of GPS time and the start of UNIX time.
Definition: mpegtables.h:28
QMap< FixupKey, FixupValue > FixupMap
Definition: eithelper.h:78
QMap< uint, uint > languagePreferences
Definition: eithelper.h:158
#define LOC
Definition: eithelper.cpp:35
unsigned char SubtitleType(void) const
uint32_t m_desc_length
Definition: eithelper.h:41
uint32_t m_start_time
Definition: eithelper.h:38
ExtendedTextTable contain additional text not contained in EventInformationTables.
Definition: atsctables.h:625
const char * subtitles[4]
Definition: vbilut.cpp:202
uint UserNibble(uint i) const
#define GPS_LEAP_SECONDS
Leap seconds as of June 30th, 2012.
Definition: mpegtables.h:31
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
int size(void) const
Definition: mythdbcon.h:203
QString ContentId(size_t n=0) const
const unsigned char * Descriptors(uint i) const
Definition: dvbtables.h:357
bool HasName(void) const
unsigned char VideoProperties(void) const
unsigned int uint
Definition: compat.h:140
static int iso639_str3_to_key(const unsigned char *iso639_2)
Definition: iso639.h:63
static const unsigned char * FindBestMatch(const desc_list_t &parsed, uint desc_tag, QMap< uint, uint > &langPref)
vector< const unsigned char * > desc_list_t
int iso639_key_to_canonical_key(int iso639_2)
Definition: iso639.cpp:121
EITHelper(void)
Definition: eithelper.cpp:37
void SetLanguagePreferences(const QStringList &langPref)
Definition: eithelper.cpp:115
static void TimeFix(QDateTime &dt)
Corrects starttime to the multiple of a minute.
Definition: eitfixup.h:83
QMutex eitList_lock
EIT List lock.
Definition: eithelper.h:139
MythDeque< DBEventEIT * > db_events
Definition: eithelper.h:156
static void parse_dvb_event_descriptors(const desc_list_t &list, FixupValue fix, QMap< uint, uint > languagePreferences, QString &title, QString &subtitle, QString &description, QMap< QString, QString > &items)
Definition: eithelper.cpp:209
static guint32 * tmp
Definition: goom_core.c:35
static uint GetMplexID(uint sourceid, const QString &channum)
void enqueue(T d)
Adds item to the back of the list. O(1).
Definition: mythdeque.h:42
uint GetListSize(void) const
Definition: eithelper.cpp:55
void AddEIT(uint atsc_major, uint atsc_minor, const EventInformationTable *eit)
Definition: eithelper.cpp:144
uint EventCount() const
Definition: atsctables.h:553
QDateTime StartTimeUTC(uint i) const
Definition: dvbtables.h:331
QString Text(void) const
QString advisory(void) const
Overall structure.
QVariant value(int i) const
Definition: mythdbcon.h:198
uint64_t FixupKey
Definition: eithelper.h:76
void WriteEITCache(void)
Definition: eithelper.cpp:759
uint EventCount() const
Definition: dvbtables.h:322
uint channelid
id of the channel
Definition: eithelper.h:149
QString seriesid(void) const
const unsigned char * m_desc
Definition: eithelper.h:43
ATSCSRCToEvents incomplete_events
Definition: eithelper.h:154
def rating(profile, smoonURL, gate)
Definition: scan.py:25
MBASE_PUBLIC QDateTime fromSecsSinceEpoch(uint seconds)
This function takes the number of seconds since the start of the epoch and returns a QDateTime with t...
Definition: mythdate.cpp:88
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
uint ServiceID(void) const
Definition: dvbtables.h:305
uint ETMLocation(uint i) const
Definition: atsctables.h:579
static uint get_chan_id_from_db_dtv(uint sourceid, uint serviceid, uint tunedchanid)
Definition: eithelper.cpp:954
void WriteToDB(void)
Definition: eitcache.cpp:308
uint DescriptorsLength(uint i) const
Definition: dvbtables.h:353
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
T dequeue()
Removes item from front of list and returns a copy. O(1).
Definition: mythdeque.h:32
static uint get_chan_id_from_db_atsc(uint sourceid, uint atsc_major, uint atsc_minor)
Definition: eithelper.cpp:859
void AddETT(uint atsc_major, uint atsc_minor, const ExtendedTextTable *ett)
Definition: eithelper.cpp:183
bool isActive(void) const
Definition: mythdbcon.h:204
uint EventID(uint i) const
Definition: atsctables.h:558
QString Name(uint) const
uint OriginalNetworkID(void) const
Definition: dvbtables.h:312
int gps_offset
Definition: eithelper.h:145
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
static void parse_dvb_component_descriptors(const desc_list_t &list, unsigned char &subtitle_type, unsigned char &audio_properties, unsigned char &video_properties)
Definition: eithelper.cpp:311
EITFixUp * eitfixup
Definition: eithelper.h:142
EIT Fix Up Functions.
Definition: eitfixup.h:13
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
QString GetDescription(uint i) const
void SetSourceID(uint _sourceid)
Definition: eithelper.cpp:132
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
QDate originalairdate(void) const
EventInformationTables contain program titles, start times, and channel information.
Definition: atsctables.h:521
FixupMap fixup
Definition: eithelper.h:153
uint PruneOldEntries(uint utc_timestamp)
Prunes entries that describe events ending before timestamp time.
Definition: eitcache.cpp:412
ServiceToChanID srv_to_chanid
Definition: eithelper.h:140
uint Nibble2(uint i) const
bool seenEITother
if false we only reschedule the active mplex
Definition: eithelper.h:151
QString GetBestMatch(QMap< uint, uint > &langPrefs) const
QString Text(void) const
uint sourceid
id of the video source
Definition: eithelper.h:148
uint AudioProperties(uint compression_type) const
uint TableID(void) const
Definition: mpegtables.h:479
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:807
uint32_t PrivateDataSpecifier(void) const
uint StartTimeRaw(uint i) const
Definition: atsctables.h:563
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
bool IsNewEIT(uint chanid, uint tableid, uint version, uint eventid, uint endtime)
Definition: eitcache.cpp:337
const unsigned char * Descriptors(uint i) const
Definition: atsctables.h:607
uint LengthInSeconds(uint i) const
Definition: atsctables.h:584
virtual ~EITHelper(void)
Definition: eithelper.cpp:46
void PruneEITCache(uint timestamp)
Definition: eithelper.cpp:754
uint DurationInSeconds(uint i) const
Definition: dvbtables.h:342
time_t EndTimeUnixUTC(uint i) const
Definition: dvbtables.h:335
QString rating(void) const
QDateTime maxStarttime
latest starttime of changed events
Definition: eithelper.h:150
static const uint kChunkSize
Maximum number of DB inserts per ProcessEvents call.
Definition: eithelper.h:161
uint ContentType(size_t n=0) const
uint Nibble(uint i) const
uint EventID(uint i) const
Definition: dvbtables.h:326
uint EventID(void) const
Definition: atsctables.h:663
uint64_t FixupValue
Definition: eithelper.h:77
QString GetCategory(void) const
QString programid(void) const
const MultipleStringStructure ExtendedTextMessage() const
Definition: atsctables.h:667
static uint get_chan_id_from_db_dvb(uint sourceid, uint serviceid, uint networkid, uint transportid)
Definition: eithelper.cpp:885
void SetChannelID(uint _channelid)
Definition: eithelper.cpp:138
uint ContentEncoding(size_t n=0) const
uint DescriptorsLength(uint i) const
Definition: atsctables.h:599
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
bool IsValid(void) const
uint ProcessEvents(void)
Inserts events in EIT list.
Definition: eithelper.cpp:66
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
static desc_list_t FindBestMatches(const desc_list_t &parsed, uint desc_tag, QMap< uint, uint > &langPref)
static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag)
MultipleStringStructure title(int i) const
Definition: atsctables.h:593
static desc_list_t Parse(const unsigned char *data, uint len)
unsigned char AudioProperties(void) const
const unsigned char * Descriptors() const
void Fix(DBEventEIT &event) const
Definition: eitfixup.cpp:253
QMap< uint, ATSCEvent > EventIDToATSCEvent
Definition: eithelper.h:71
QString rating(void) const
void RescheduleRecordings(void)
Tells scheduler about programming changes.
Definition: eithelper.cpp:1401
static EITCache * s_eitcache
Definition: eithelper.h:143
uint Nibble1(uint i) const
void SetFixup(uint atsc_major, uint atsc_minor, FixupValue eitfixup)
Definition: eithelper.cpp:108
QString advisory(void) const