37#define LOC QString("EITHelper: ")
38#define LOC_ID QString("EITHelper[%1]: ").arg(m_cardnum)
46 QString(
"EITHelper chunk size %1 and queue size %2 events")
53 QString(
"EITCache %1")
54 .arg(persistent ?
"in memory, backup to database" :
"in memory only"));
105 insertCount +=
event->UpdateDB(query, 1000);
118 QString(
"Added %1 events -- complete: %2 incomplete: %3")
125 QString(
"Added %1/%2 events, queued: %3")
126 .arg(insertCount).arg(eventCount).arg(
m_dbEvents.size()));
135 FixupKey atsc_key = (atsc_major << 16) | atsc_minor;
144 QStringList::const_iterator it;
145 for (it = langPref.begin(); it != langPref.end(); ++it)
147 if (!(*it).isEmpty())
171 uint atsc_key = (atsc_major << 16) | atsc_minor;
192 EventIDToATSCEvent::iterator it = events.find(eit->
EventID(i));
193 if (it != events.end())
195 delete [] (*it).m_desc;
199 auto *
tmp =
new unsigned char[ev.m_descLength];
202 events.insert(eit->
EventID(i), ev);
212 uint atsc_key = (atsc_major << 16) | atsc_minor;
216 EventIDToATSCEvent::iterator it = (*eits_it).find(ett->
EventID());
217 if (it != (*eits_it).end())
220 if (!it->IsStale()) {
222 atsc_major, atsc_minor, *it,
227 delete [] (*it).m_desc;
228 (*eits_it).erase(it);
234 QMap<uint,uint> languagePreferences,
235 QString &title, QString &subtitle,
236 QString &description, QMultiMap<QString,QString> &items)
238 const unsigned char *bestShortEvent =
292 subtitle = sed.
Text(enc);
296 std::vector<const unsigned char*> bestExtendedEvents =
301 for (
auto & best_event : bestExtendedEvents)
312 description += eed.
Text(enc);
315 items.unite (eed.
Items());
320 unsigned char &subtitle_type,
321 unsigned char &audio_properties,
322 unsigned char &video_properties)
326 for (
auto & comp : components)
363 uint descCompression = (eit->
TableID() > 0x80) ? 2 : 1;
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;
395 uint totalepisodes = 0;
396 QMultiMap<QString,QString> items;
402 const unsigned char *dish_event_name =
nullptr;
412 if (dend.IsValid() && dend.HasName())
413 title = dend.Name(descCompression);
415 const unsigned char *dish_event_description =
418 if (dish_event_description)
421 if (dedd.IsValid() && dedd.HasDescription())
422 description = dedd.Description(descCompression);
428 title, subtitle, description, items);
434 QString programId = QString(
"");
435 QString seriesId = QString(
"");
436 QString
rating = QString(
"");
437 QString rating_system = QString(
"");
438 QString advisory = QString(
"");
440 QDate originalairdate;
450 stars = mpaa.stars();
455 rating_system =
"MPAA";
456 advisory = mpaa.advisory();
468 rating_system =
"VCHIP";
469 advisory = vchip.advisory();
473 if (!advisory.isEmpty() && !
rating.isEmpty())
474 rating +=
", " + advisory;
475 else if (!advisory.isEmpty())
478 rating_system =
"advisory";
486 seriesId = tags.seriesid();
487 programId = tags.programid();
488 originalairdate = tags.originalairdate();
490 if (programId.startsWith(
"MV") || programId.startsWith(
"SP"))
499 subtitle_type |= properties.SubtitleProperties(descCompression);
500 audio_props |= properties.AudioProperties(descCompression);
504 const unsigned char *content_data =
526 category =
content.GetCategory();
530 static const std::array<const std::string,16> s_auGenres
531 {
"Unknown",
"Movie",
"News",
"Entertainment",
532 "Sport",
"Children",
"Music",
"Arts/Culture",
533 "Current Affairs",
"Education",
"Infotainment",
534 "Special",
"Comedy",
"Drama",
"Documentary",
539 category = QString::fromStdString(s_auGenres[
content.Nibble1(0)]);
540 category_type =
content.GetMythCategory(0);
545 static const std::array<const std::string,16>s_grGenres
546 {
"Unknown",
"Ταινία",
"Ενημερωτικό",
"Unknown",
547 "Αθλητικό",
"Παιδικό",
"Unknown",
"Unknown",
548 "Unknown",
"Ντοκιμαντέρ",
"Unknown",
"Unknown",
549 "Unknown",
"Unknown",
"Unknown",
"Unknown"};
553 category = QString::fromStdString(s_grGenres[
content.Nibble2(0)]);
554 category_type =
content.GetMythCategory(2);
562 category =
content.GetDescription(0);
564 category_type =
content.GetMythCategory(0);
572 for (
auto &
id : contentIds)
577 for (
size_t k = 0; k < desc.CRIDCount(); k++)
579 if (desc.ContentEncoding(k) == 0)
585 if (desc.ContentType(k) == 0x01 || desc.ContentType(k) == 0x31)
587 if (!desc.ContentId(k).startsWith (
"eventis.nl/"))
589 programId = desc.ContentId(k);
592 else if (desc.ContentType(k) == 0x02 || desc.ContentType(k) == 0x32)
594 if (!desc.ContentId(k).startsWith (
"eventis.nl/"))
596 seriesId = desc.ContentId(k);
605 if (subtitle.isEmpty()) {
609 for (
auto & specifier : private_data_specifiers) {
624 subtitle = desc.Text();
638 title, subtitle, description,
639 category, category_type,
640 starttime, endtime, fix,
645 season, episode, totalepisodes);
646 event->m_items = items;
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;
674 uint totalepisodes = 0;
675 QMultiMap<QString,QString> items;
682 title, subtitle, description, items);
687 const unsigned char *content_data =
699 else if(
content.UserNibble(0)==0x0)
702 category = QObject::tr(
"Sports");
707 category_type =
content.GetMythCategory(0);
708 category =
content.GetDescription(0);
713 category =
"Unknown";
727 for (
auto & trans : transmissions)
730 if (!transmission.IsValid())
732 uint networkid = transmission.OriginalNetworkID();
733 uint tsid = transmission.TSID();
734 uint serviceid = transmission.ServiceID();
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));
754 for (
uint k=0; k<transmission.TransmissionCount(); ++k)
756 QDateTime txstart = transmission.StartTimeUTC(k);
764 title, subtitle, description,
765 category, category_type,
771 season, episode, totalepisodes);
772 event->m_items = items;
812 QDateTime endtime = starttime.addSecs(event.
m_length);
815 unsigned char subtitle_type =
817 SUB_HARDHEAR : SUB_UNKNOWN;
818 unsigned char audio_properties = AUD_UNKNOWN;
819 unsigned char video_properties = VID_UNKNOWN;
821 uint atsc_key = (atsc_major << 16) | atsc_minor;
824 QString title =
event.m_title;
825 const QString& subtitle = ett;
828 m_fixup.value(atsc_key), subtitle_type,
829 audio_properties, video_properties));
838 uint64_t key = sourceid;
839 key |= ((uint64_t) atsc_minor) << 16;
840 key |= ((uint64_t) atsc_major) << 32;
842 ServiceToChanID::const_iterator it =
m_srvToChanid.constFind(key);
858 uint64_t key = sourceid;
859 key |= ((uint64_t) serviceid) << 16;
860 key |= ((uint64_t) networkid) << 32;
861 key |= ((uint64_t) tsid) << 48;
863 ServiceToChanID::const_iterator it =
m_srvToChanid.constFind(key);
879 uint64_t key = sourceid;
880 key |= ((uint64_t) program_number) << 16;
883 ServiceToChanID::const_iterator it =
m_srvToChanid.constFind(key);
898 "SELECT chanid, useonairguide "
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);
910 else if (query.
next())
912 bool useOnAirGuide = query.
value(1).toBool();
913 return (useOnAirGuide) ? query.
value(0).toUInt() : 0;
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";
937 query.
bindValue(
":SERVICEID", serviceid);
938 query.
bindValue(
":NETWORKID", networkid);
939 query.
bindValue(
":TRANSPORTID", transportid);
948 if (query.
size() > 1)
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")
954 .arg(sourceid).arg(networkid).arg(transportid).arg(serviceid));
960 bool useOnAirGuide = query.
value(1).toBool();
961 return useOnAirGuide ? chanid : 0;
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));
983 uint db_sourceid = 0;
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";
997 query.
bindValue(
":SERVICEID", serviceid);
1006 while (query.
next())
1010 bool useOnAirGuide = query.
value(1).toBool();
1011 db_sourceid = query.
value(2).toUInt();
1012 if (sourceid == db_sourceid)
1013 return useOnAirGuide ? chanid : 0;
1016 if (query.
size() > 0)
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));
1053 for (
int i = 2001; i <= 2035; ++i)
1058 for (
int i = 2037; i <= 2057; ++i)
1061 for (
int i = 2061; i <= 2069; ++i)
1066 for (
int i = 2089; i <= 2116; ++i)
1080 for (
int i = 2401; i <= 2413; ++i)
1124 fix[ 1089LL << 32 | 1 << 16] =
1125 fix[ 1041LL << 32 | 1 << 16] =
1126 fix[ 1057LL << 32 | 1 << 16] =
1193 fix[ 42249U << 16] =
1261 fix[ 9999 << 16 | 161LL << 32 | 12101 ] =
1262 fix[ 9999 << 16 | 161LL << 32 | 12104 ] =
1263 fix[ 9999 << 16 | 161LL << 32 | 12107 ] =
1264 fix[ 9999 << 16 | 161LL << 32 | 12109 ] =
1265 fix[ 9999 << 16 | 301LL << 32 | 30114 ] =
1267 fix[ 9999 << 16 | 191LL << 32 | 11102 ] =
1270 fix[ 9999 << 16 | 401LL << 32 | 29109 ] =
1273 fix[ 9999 << 16 | 121LL << 32 | 12107 ] =
1274 fix[ 9999 << 16 | 151LL << 32 | 15110 ] =
1275 fix[ 9999 << 16 | 161LL << 32 | 12107 ] =
1276 fix[ 9999 << 16 | 161LL << 32 | 12109 ] =
1277 fix[ 9999 << 16 | 171LL << 32 | 17119 ] =
1278 fix[ 9999 << 16 | 171LL << 32 | 27102 ] =
1279 fix[ 9999 << 16 | 181LL << 32 | 24108 ] =
1280 fix[ 9999 << 16 | 181LL << 32 | 25102 ] =
1281 fix[ 9999 << 16 | 191LL << 32 | 11102 ] =
1282 fix[ 9999 << 16 | 191LL << 32 | 12110 ] =
1283 fix[ 9999 << 16 | 191LL << 32 | 12111 ] =
1284 fix[ 9999 << 16 | 201LL << 32 | 27103 ] =
1285 fix[ 9999 << 16 | 211LL << 32 | 29108 ] =
1286 fix[ 9999 << 16 | 231LL << 32 | 23117 ] =
1287 fix[ 9999 << 16 | 231LL << 32 | 23115 ] =
1288 fix[ 9999 << 16 | 271LL << 32 | 27101 ] =
1289 fix[ 9999 << 16 | 541LL << 32 | 54101 ] =
1299 fix[ 1022LL << 32 | 1 << 16 | 6901 ] =
1300 fix[ 1022LL << 32 | 1 << 16 | 6905 ] =
1301 fix[ 1022LL << 32 | 1 << 16 | 6911 ] =
1302 fix[ 1072LL << 32 | 1 << 16 | 8201 ] =
1303 fix[ 1070LL << 32 | 1 << 16 | 8004 ] =
1304 fix[ 1091LL << 32 | 1 << 16 | 31220 ] =
1305 fix[ 1094LL << 32 | 1 << 16 | 17027 ] =
1306 fix[ 1094LL << 32 | 1 << 16 | 17028 ] =
1307 fix[ 1100LL << 32 | 1 << 16 | 8710 ] =
1317 fix[ 100LL << 32 | 8492LL << 16 ] =
1318 fix[ 102LL << 32 | 8492LL << 16 ] =
1319 fix[ 320LL << 32 | 8492LL << 16 ] =
1323 fix[ 2LL << 32 | 8492LL << 16 ] =
const unsigned char * m_desc
static uint GetMplexID(uint sourceid, const QString &channum)
uint VideoProperties(void) const
uint SubtitleType(void) const
uint AudioProperties(void) const
uint PruneOldEntries(uint utc_timestamp)
Prunes entries that describe events ending before timestamp time.
void SetPersistent(bool persistent)
bool IsNewEIT(uint chanid, uint tableid, uint version, uint eventid, uint endtime)
static void TimeFix(QDateTime &dt)
Corrects starttime to the multiple of a minute.
static void Fix(DBEventEIT &event)
void SetSourceID(uint sourceid)
static void PruneEITCache(uint timestamp)
uint GetListSize(void) const
void AddETT(uint, uint, const ExtendedTextTable *)
uint ProcessEvents(void)
Get events from queue and insert into DB after processing.
void SetFixup(uint atsc_major, uint atsc_minor, FixupValue eitfixup)
static EITCache * s_eitCache
static const uint kMaxQueueSize
uint GetChanID(uint atsc_major, uint atsc_minor)
void SetLanguagePreferences(const QStringList &langPref)
ServiceToChanID m_srvToChanid
void CompleteEvent(uint atsc_major, uint atsc_minor, const ATSCEvent &event, const QString &ett)
void RescheduleRecordings(void)
Tells scheduler about programming changes.
static void WriteEITCache(void)
MythDeque< DBEventEIT * > m_dbEvents
ATSCSRCToEvents m_incompleteEvents
QMap< uint, uint > m_languagePreferences
void AddEIT(uint, uint, const EventInformationTable *)
bool EventQueueFull(void) const
void SetChannelID(uint channelid)
QMultiMap< QString, QString > Items(void) const
ExtendedTextTable contain additional text not contained in EventInformationTables.
MultipleStringStructure ExtendedTextMessage() const
static desc_list_t FindAll(const desc_list_t &parsed, uint desc_tag)
static desc_list_t Parse(const unsigned char *data, uint len)
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.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
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)
T dequeue()
Removes item from front of list and returns a copy. O(1).
void enqueue(const T &d)
Adds item to the back of the list. O(1).
const unsigned char * Descriptors() const
uint DescriptorsLength() const
uint ContentID(void) const
uint DurationInSeconds() const
@ upc_event_episode_title
@ premiere_content_transmission
static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, const QDateTime &maxstarttime, const QString &why)
QString EventName(void) const
std::vector< uint8_t > enc_override
static void parse_dvb_component_descriptors(const desc_list_t &list, unsigned char &subtitle_type, unsigned char &audio_properties, unsigned char &video_properties)
static uint get_chan_id_from_db_dtv(uint sourceid, uint serviceid, uint tunedchanid)
static void init_fixup(FixupMap &fix)
static uint get_chan_id_from_db_atsc(uint sourceid, uint atsc_major, uint atsc_minor)
static uint get_chan_id_from_db_dvb(uint sourceid, uint serviceid, uint networkid, uint transportid)
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)
QMap< FixupKey, FixupValue > FixupMap
QMap< uint, ATSCEvent > EventIDToATSCEvent
int iso639_key_to_canonical_key(int iso639_2)
static int iso639_str3_to_key(const unsigned char *iso639_2)
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.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
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...
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
def rating(profile, smoonURL, gate)
const std::array< const std::string, 4 > subtitles