Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OpenTV] #3466

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/dvb/epgcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1947,25 +1947,25 @@ void eEPGCache::submitEventData(const std::vector<eServiceReferenceDVB>& service
service->m_flags |= eDVBService::dxNoEIT;
}
}
submitEventData(sids, chids, start, duration, title, short_summary, long_description, event_types, parental_ratings, EPG_IMPORT, event_id);
submitEventData(sids, chids, start, duration, title, short_summary, long_description, event_types, parental_ratings, event_id, EPG_IMPORT);
}

void eEPGCache::submitEventData(const std::vector<int>& sids, const std::vector<eDVBChannelID>& chids, long start,
long duration, const char* title, const char* short_summary,
const char* long_description, char event_type, int source, uint16_t event_id)
const char* long_description, char event_type, uint16_t event_id, int source)
{
std::vector<uint8_t> event_types;
std::vector<eit_parental_rating> parental_ratings;
if(event_type != 0)
{
event_types.push_back(event_type);
}
submitEventData(sids, chids, start, duration, title, short_summary, long_description, event_types, parental_ratings, source, event_id);
submitEventData(sids, chids, start, duration, title, short_summary, long_description, event_types, parental_ratings, event_id, source);
}

void eEPGCache::submitEventData(const std::vector<int>& sids, const std::vector<eDVBChannelID>& chids, long start,
long duration, const char* title, const char* short_summary,
const char* long_description, std::vector<uint8_t> event_types, std::vector<eit_parental_rating> parental_ratings, int source, uint16_t event_id)
const char* long_description, std::vector<uint8_t> event_types, std::vector<eit_parental_rating> parental_ratings, uint16_t event_id, int source)
{
if (!title)
return;
Expand Down
4 changes: 2 additions & 2 deletions lib/dvb/epgcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ class eEPGCache: public eMainloop, private eThread, public sigc::trackable

void gotMessage(const Message &message);
void cleanLoop();
void submitEventData(const std::vector<int>& sids, const std::vector<eDVBChannelID>& chids, long start, long duration, const char* title, const char* short_summary, const char* long_description, char event_type, int source, uint16_t event_id=0);
void submitEventData(const std::vector<int>& sids, const std::vector<eDVBChannelID>& chids, long start, long duration, const char* title, const char* short_summary, const char* long_description, std::vector<uint8_t> event_types, std::vector<eit_parental_rating> parental_ratings, int source, uint16_t event_id=0);
void submitEventData(const std::vector<int>& sids, const std::vector<eDVBChannelID>& chids, long start, long duration, const char* title, const char* short_summary, const char* long_description, char event_type, uint16_t event_id, int source);
void submitEventData(const std::vector<int>& sids, const std::vector<eDVBChannelID>& chids, long start, long duration, const char* title, const char* short_summary, const char* long_description, std::vector<uint8_t> event_types, std::vector<eit_parental_rating> parental_ratings, uint16_t event_id, int source);
void clearCompleteEPGCache();

eServiceReferenceDVB *m_timeQueryRef;
Expand Down
64 changes: 61 additions & 3 deletions lib/dvb/epgchanneldata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2366,7 +2366,7 @@ void eEPGChannelData::ATSC_checkCompletion()
sids.push_back(m_ATSC_VCT_map[sourceid]);
chids.push_back(channel->getChannelID());
if (eEPGCache::getInstance())
eEPGCache::getInstance()->submitEventData(sids, chids, it->second.startTime, it->second.lengthInSeconds, it->second.title.c_str(), "", m_ATSC_ETT_map[it->first].c_str(), 0, eEPGCache::ATSC_EIT, it->second.eventId);
eEPGCache::getInstance()->submitEventData(sids, chids, it->second.startTime, it->second.lengthInSeconds, it->second.title.c_str(), "", m_ATSC_ETT_map[it->first].c_str(), 0, it->second.eventId, eEPGCache::ATSC_EIT);
}
m_ATSC_EIT_map.clear();
m_ATSC_ETT_map.clear();
Expand Down Expand Up @@ -2575,13 +2575,17 @@ void eEPGChannelData::OPENTV_checkCompletion(uint32_t data_crc)
{
std::vector<int> sids;
std::vector<eDVBChannelID> chids;
std::vector<uint8_t> event_types;
std::vector<eit_parental_rating> parental_ratings;
eDVBChannelID chid = channel->getChannelID();
chid.transport_stream_id = m_OPENTV_channels_map[channelid].transportStreamId;
chid.original_network_id = m_OPENTV_channels_map[channelid].originalNetworkId;
chids.push_back(chid);
sids.push_back(m_OPENTV_channels_map[channelid].serviceId);
event_types.push_back(it->second.genreId);
parental_ratings.push_back(getOpenTvParentalRating(chid.dvbnamespace.get(), it->second.parentalRating));
if (eEPGCache::getInstance())
eEPGCache::getInstance()->submitEventData(sids, chids, it->second.startTime, it->second.duration, m_OPENTV_descriptors_map[it->second.title_crc].c_str(), "", "", 0, eEPGCache::OPENTV, it->second.eventId);
eEPGCache::getInstance()->submitEventData(sids, chids, it->second.startTime, it->second.duration, m_OPENTV_descriptors_map[it->second.title_crc].c_str(), "", "", event_types, parental_ratings, it->second.eventId, eEPGCache::OPENTV);
}
}
m_OPENTV_descriptors_map.clear();
Expand Down Expand Up @@ -2649,6 +2653,8 @@ void eEPGChannelData::OPENTV_TitlesSection(const uint8_t *d)
ote.startTime = (*title)->getStartTime();
ote.duration = (*title)->getDuration();
ote.title_crc = (*title)->getCRC32();
ote.genreId = (*title)->getGenreId();
ote.parentalRating = (*title)->getParentalRating();
m_OPENTV_EIT_map[etm] = ote;

if (m_OPENTV_descriptors_map.find(ote.title_crc) == m_OPENTV_descriptors_map.end())
Expand Down Expand Up @@ -2680,19 +2686,23 @@ void eEPGChannelData::OPENTV_SummariesSection(const uint8_t *d)
{
std::vector<int> sids;
std::vector<eDVBChannelID> chids;
std::vector<uint8_t> event_types;
std::vector<eit_parental_rating> parental_ratings;
eDVBChannelID chid = channel->getChannelID();
chid.transport_stream_id = m_OPENTV_channels_map[channelid].transportStreamId;
chid.original_network_id = m_OPENTV_channels_map[channelid].originalNetworkId;
chids.push_back(chid);
sids.push_back(m_OPENTV_channels_map[channelid].serviceId);
event_types.push_back(ote.genreId);
parental_ratings.push_back(getOpenTvParentalRating(chid.dvbnamespace.get(), ote.parentalRating));

// hack to fix split titles
std::string sTitle = m_OPENTV_descriptors_map[ote.title_crc];
std::string sSummary = (*summary)->getSummary();
undoAbbreviation(sTitle, sSummary);

if (eEPGCache::getInstance())
eEPGCache::getInstance()->submitEventData(sids, chids, ote.startTime, ote.duration, sTitle.c_str(), "", sSummary.c_str(), 0, eEPGCache::OPENTV, ote.eventId);
eEPGCache::getInstance()->submitEventData(sids, chids, ote.startTime, ote.duration, sTitle.c_str(), "", sSummary.c_str(), event_types, parental_ratings, ote.eventId, eEPGCache::OPENTV);
}
m_OPENTV_EIT_map.erase(otce);
}
Expand All @@ -2702,6 +2712,54 @@ void eEPGChannelData::OPENTV_SummariesSection(const uint8_t *d)

OPENTV_checkCompletion(otss.getCrc32());
}
eit_parental_rating eEPGChannelData::getOpenTvParentalRating(int dvbnamespace, int parental_rating)
{
eit_parental_rating epr;

switch ((dvbnamespace >> 16) & 0xffff)
{
case 0x011A: // country code 'GBR'
/* 28.2e sends data {0,1,2,3,4,5}
classification {"",U,PG,12,15,18}
convert to ETSI min age with 3x */
parental_rating = parental_rating * 3;
epr.country_code[0] = 'O';
epr.country_code[1] = 'T';
epr.country_code[2] = '1';
break;
case 0x0082: // country code 'ITA'
/* 13.0e sends data {0,1,2,3,4,5}
classification {"",T,BA,12,14,18}
convert to ETSI min age with 3x */
epr.country_code[0] = 'O';
epr.country_code[1] = 'T';
epr.country_code[2] = '2';
parental_rating = parental_rating * 3;
break;
case 0x0618: // country code 'AUS'
epr.country_code[0] = 'O';
epr.country_code[1] = 'T';
epr.country_code[2] = '3';
break;
case 0x0640: // country code 'NZL'
epr.country_code[0] = 'O';
epr.country_code[1] = 'T';
epr.country_code[2] = '4';
break;
default: // country code 'ETSI'
epr.country_code[0] = 'O';
epr.country_code[1] = 'T';
epr.country_code[2] = 'V';
break;
}

if (parental_rating > 15)
epr.rating = 0;
else
epr.rating = parental_rating;

return epr;
}

void eEPGChannelData::cleanupOPENTV()
{
Expand Down
3 changes: 3 additions & 0 deletions lib/dvb/epgchanneldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,16 @@ class eEPGChannelData: public sigc::trackable
uint32_t startTime;
uint32_t duration;
uint32_t title_crc;
uint8_t genreId;
uint8_t parentalRating;
};
OpenTvDescriptorMap m_OPENTV_descriptors_map;
std::map<uint16_t, struct opentv_channel> m_OPENTV_channels_map;
std::map<uint32_t, struct opentv_event> m_OPENTV_EIT_map;
ePtr<eTimer> m_OPENTV_Timer;
ePtr<iDVBSectionReader> m_OPENTV_ChannelsReader, m_OPENTV_TitlesReader, m_OPENTV_SummariesReader;
ePtr<eConnection> m_OPENTV_ChannelsConn, m_OPENTV_TitlesConn, m_OPENTV_SummariesConn;
eit_parental_rating getOpenTvParentalRating(int dvbnamespace, int parental_rating);
void OPENTV_checkCompletion(const uint32_t data_crc);
void OPENTV_ChannelsSection(const uint8_t *d);
void OPENTV_TitlesSection(const uint8_t *d);
Expand Down
36 changes: 24 additions & 12 deletions lib/dvb/opentv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,25 +157,27 @@ OpenTvTitle::OpenTvTitle(const uint8_t * const buffer, uint16_t startMjd)
uint8_t descriptor_length = buffer[1];
uint8_t titleLength = descriptor_length > 7 ? descriptor_length-7 : 0;

uint32_t startSecond = (UINT16(&buffer[2]) << 1);
// HACK: startSecond is detected as being from the previous
// mjd date when the h:m:s is sent as greater than 1 day.
// when this occurs, shifted two's complement has a negative
// sign bit of a signed integer, and is not a positive number.

startTimeBcd = ((startMjd - 40587) * 86400) + startSecond;
int32_t startSecond = UINT16(&buffer[2]) << 1;

// if h:m:s is sent as greater than 1 day in seconds,
// first bit is a negative sign bit without padding.

// HACK ALERT: There is a bug somewhere in the data that causes some
// events to be cataloged 0x20000 seconds further into the future
// than they should be. In these cases "startSecond" will have a value
// of 86400 seconds or greater. i.e. more than one day. When this
// happens it indicates that the bug is present for the current event
// and therefore the excess 0x20000 seconds is removed from "startTimeBcd".
if (startSecond >= 86400)
startTimeBcd -= 0x20000;
startSecond = 0xFFFE0000 | (startSecond & 0x1FFFF);

startTimeBcd = ((startMjd - 40587) * 86400) + startSecond;

duration = UINT16(&buffer[4]) << 1;

//genre content
//uint8_t flag1 = buffer[6];
//uint8_t flag2 = buffer[7];
//uint8_t flag3 = buffer[8];
genreId = buffer[6];
//uint8_t flag = buffer[7];
parentalRating = buffer[8] & 0x0f;

char tmp[OPENTV_EVENT_TITLE_LENGTH];
memset(tmp, '\0', OPENTV_EVENT_TITLE_LENGTH);
Expand Down Expand Up @@ -229,6 +231,16 @@ uint32_t OpenTvTitle::getDuration(void) const
return duration;
}

uint8_t OpenTvTitle::getGenreId(void) const
{
return genreId;
}

uint8_t OpenTvTitle::getParentalRating(void) const
{
return parentalRating;
}

void OpenTvTitle::setChannelId(uint16_t channelid)
{
channelId = channelid;
Expand Down
4 changes: 4 additions & 0 deletions lib/dvb/opentv.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ class OpenTvTitle : public DescriptorContainer
unsigned startTimeBcd : 32;
unsigned duration : 24;
unsigned crc32 : 32;
unsigned genreId : 8;
unsigned parentalRating : 8;
std::string title;

public:
Expand All @@ -78,6 +80,8 @@ class OpenTvTitle : public DescriptorContainer
uint32_t getStartTime(void) const;
uint16_t getEventId(void) const;
uint32_t getDuration(void) const;
uint8_t getGenreId(void) const;
uint8_t getParentalRating(void) const;
void setChannelId(uint16_t channelid);
void setEventId(uint16_t eventId);
};
Expand Down
73 changes: 69 additions & 4 deletions lib/python/Components/Converter/EventInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,54 @@ def __init__(self):
self.update([(index, (classification, longText[classification], images[classification])) for index, classification in enumerate(shortText)])


class GBrClassifications(dict):
def __init__(self):
# British Board of Film Classification
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
shortText = ("", "", "", "U", "U", "U", "PG", "PG", "PG", "12", "12", "12", "15", "15", "15", "18")
longText = {
"": _("Not Classified"),
"U": _("U - Suitable for all"),
"PG": _("PG - Parental Guidance"),
"12": _("Suitable for ages 12+"),
"15": _("Suitable for ages 15+"),
"18": _("Suitable only for Adults")
}
images = {
"": "ratings/blank.png",
"U": "ratings/GBR-U.png",
"PG": "ratings/GBR-PG.png",
"12": "ratings/GBR-12.png",
"15": "ratings/GBR-15.png",
"18": "ratings/GBR-18.png"
}
self.update([(index, (classification, longText[classification], images[classification])) for index, classification in enumerate(shortText)])


class ItaClassifications(dict):
def __init__(self):
# The classifications used by Sky Italia
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
shortText = ("", "", "", "T", "T", "T", "BA", "BA", "BA", "12", "12", "12", "14", "14", "14", "18")
longText = {
"": _("Non Classificato"),
"T": _("Per Tutti"),
"BA": _("Bambini Accompagnati"),
"12": _("Dai 12 anni in su"),
"14": _("Dai 14 anni in su"),
"18": _("Dai 18 anni in su")
}
images = {
"": "ratings/blank.png",
"T": "ratings/ITA-T.png",
"BA": "ratings/ITA-BA.png",
"12": "ratings/ITA-12.png",
"14": "ratings/ITA-14.png",
"18": "ratings/ITA-18.png"
}
self.update([(index, (classification, longText[classification], images[classification])) for index, classification in enumerate(shortText)])


# Each country classification object in the map tuple must be an object that
# supports obj.get(key[, default]). It need not actually be a dict object.
#
Expand All @@ -78,7 +126,20 @@ def __init__(self):
#
COUNTRIES = {
"ETSI": (ETSIClassifications(), lambda age: (_("bc%d") % age, _("Rating defined by broadcaster - %d") % age, "ratings/ETSI-na.png")),
"AUS": (AusClassifications(), lambda age: (_("BC%d") % age, _("Rating defined by broadcaster - %d") % age, "ratings/AUS-na.png"))
"AUS": (AusClassifications(), lambda age: (_("BC%d") % age, _("Rating defined by broadcaster - %d") % age, "ratings/AUS-na.png")),
"GBR": (GBrClassifications(), lambda age: (_("BC%d") % age, _("Rating defined by broadcaster - %d") % age, "ratings/GBR-na.png")),
"ITA": (ItaClassifications(), lambda age: (_("BC%d") % age, _("Rating defined by broadcaster - %d") % age, "ratings/ITA-na.png"))
}


# OpenTV country codes: epgchanneldata.cpp
# eEPGChannelData::getOpenTvParentalRating
OPENTV_COUNTRIES = {
"OT1": "GBR",
"OT2": "ITA",
"OT3": "AUS",
"OT4": "NZL",
"OTV": "ETSI"
}


Expand Down Expand Up @@ -306,9 +367,13 @@ def getEPGData():
genres = genres[0:1]
rating = event.getParentalData()
country = rating.getCountryCode().upper() if rating else "ETSI"
if config.misc.epggenrecountry.value:
country = config.misc.epggenrecountry.value
result = self.separator.join((genreText for genreText in (trimText(getGenreStringSub(genre[0], genre[1], country=country)) for genre in genres) if genreText))
if country in OPENTV_COUNTRIES:
country = OPENTV_COUNTRIES[country] + "OpenTV"
result = self.separator.join((genretext for genretext in (trimText(getGenreStringSub(genre[0], genre[1], country=country)) for genre in genres) if genretext))
else:
if config.misc.epggenrecountry.value:
country = config.misc.epggenrecountry.value
result = self.separator.join((genretext for genretext in (trimText(getGenreStringSub(genre[0], genre[1], country=country)) for genre in genres) if genretext))
case self.ID:
result = trimText(event.getEventId())
case self.MEDIA_PATH:
Expand Down
Loading