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