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