summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitar Petrovski <dimeptr@gmail.com>2012-10-18 12:32:04 (GMT)
committerDimitar Petrovski <dimeptr@gmail.com>2012-10-18 12:32:04 (GMT)
commit6810f79e1b5f78a0b3d2389714924738295a6497 (patch)
tree951670799a35d3bfa389e5f9f65ba46c3c582ec8
parentcee549473dacfa3e82cb13bd9bbe1c8f0e8c1a6a (diff)
downloadvdr-plugin-eepg-6810f79e1b5f78a0b3d2389714924738295a6497.tar.gz
vdr-plugin-eepg-6810f79e1b5f78a0b3d2389714924738295a6497.tar.bz2
fix compile
-rw-r--r--eepg.c95
-rw-r--r--eepg.h15
-rw-r--r--eit2.c1110
-rw-r--r--eit2.h43
-rw-r--r--log.h3
-rw-r--r--util.c23
-rw-r--r--util.h80
7 files changed, 693 insertions, 676 deletions
diff --git a/eepg.c b/eepg.c
index c438969..6091915 100644
--- a/eepg.c
+++ b/eepg.c
@@ -65,14 +65,6 @@
static const char *VERSION = "0.0.6pre";
static const char *DESCRIPTION = trNOOP ("Parses Extended EPG data");
-template <class T> T REALLOC(T Var, size_t Size)
-{
- T p = (T)realloc(Var, Size);
- if (!p)
- free(Var);
- return p;
-}
-
using namespace std;
using namespace util;
@@ -101,7 +93,6 @@ char *cs_hexdump (int m, const uchar * buf, int n)
}
cSetupEEPG* SetupPE = cSetupEEPG::getInstance();
-cEquivHandler* EquivHandler;
// --- cMenuSetupPremiereEpg ------------------------------------------------------------
@@ -313,21 +304,21 @@ void syslog_with_tid (int priority, const char *format, ...) __attribute__ ((for
-struct hufftab {
- unsigned int value;
- short bits;
- char next;
-};
-
-#define START '\0'
-#define STOP '\0'
-#define ESCAPE '\1'
+//struct hufftab {
+// unsigned int value;
+// short bits;
+// char next;
+//};
+//
+//#define START '\0'
+//#define STOP '\0'
+//#define ESCAPE '\1'
-int freesat_decode_error = 0; /* If set an error has occurred during decoding */
+//int freesat_decode_error = 0; /* If set an error has occurred during decoding */
-static struct hufftab *tables[2][128];
-static int table_size[2][128];
+//static struct hufftab *tables[2][128];
+//static int table_size[2][128];
static sNodeH* sky_tables[2];
/** \brief Convert a textual character description into a value
@@ -569,7 +560,7 @@ static bool load_sky_file (const char *filename)
char *freesat_huffman_decode (const unsigned char *src, size_t size)
{
int tableid;
- freesat_decode_error = 0;
+// freesat_decode_error = 0;
if (src[0] == 0x1f && (src[1] == 1 || src[1] == 2)) {
int uncompressed_len = 30;
@@ -839,44 +830,28 @@ bool cFilterEEPG::InitDictionary (void)
return true;
}
-void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize)
-{
- if (from[0] == 0x1f) {
- char *temp = freesat_huffman_decode (from, len);
- if (temp) {
- len = strlen (temp);
- len = len < buffsize - 1 ? len : buffsize - 1;
- strncpy (buffer, temp, len);
- buffer[len] = 0;
- free (temp);
- return;
- }
- }
-
- SI::String convStr;
- SI::CharArray charArray;
- charArray.assign(from, len);
- convStr.setData(charArray, len);
- //LogE(5, prep("decodeText2 from %s - length %d"), from, len);
- convStr.getText(buffer, buffsize);
- //LogE(5, prep("decodeText2 buffer %s - buffsize %d"), buffer, buffsize);
-}
-
-void sortSchedules(cSchedules * Schedules, tChannelID channelID){
-
- LogD(3, prep("Start sortEquivalent %s"), *channelID.ToString());
-
- cChannel *pChannel = GetChannelByID (channelID, false);
- cSchedule *pSchedule;
- if (pChannel) {
- pSchedule = (cSchedule *) (Schedules->GetSchedule(pChannel, true));
- pSchedule->Sort();
- Schedules->SetModified(pSchedule);
- }
- if (EquivHandler->getEquiChanMap().count(*channelID.ToString()) > 0)
- EquivHandler->sortEquivalents(channelID, Schedules);
-}
-
+//void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize)
+//{
+// if (from[0] == 0x1f) {
+// char *temp = freesat_huffman_decode (from, len);
+// if (temp) {
+// len = strlen (temp);
+// len = len < buffsize - 1 ? len : buffsize - 1;
+// strncpy (buffer, temp, len);
+// buffer[len] = 0;
+// free (temp);
+// return;
+// }
+// }
+//
+// SI::String convStr;
+// SI::CharArray charArray;
+// charArray.assign(from, len);
+// convStr.setData(charArray, len);
+// //LogE(5, prep("decodeText2 from %s - length %d"), from, len);
+// convStr.getText(buffer, buffsize);
+// //LogE(5, prep("decodeText2 buffer %s - buffsize %d"), buffer, buffsize);
+//}
/**
* \brief Get MHW channels
diff --git a/eepg.h b/eepg.h
index 18690de..7e1cc74 100644
--- a/eepg.h
+++ b/eepg.h
@@ -17,21 +17,6 @@
//#define NAGRA 6
//#define HIGHEST_FORMAT 6
-enum EFormat {
-//First all batchmode, load ONCE protocols:
- MHW1 = 0,
- MHW2 ,
- SKY_IT ,
- SKY_UK ,
- NAGRA ,
-//Than all CONTinuous protocols, so they will be processed LAST:
- PREMIERE ,
- FREEVIEW ,
- DISH_BEV ,
- EIT ,
-//the highest number of EPG-formats that is supported by this plugin
- HIGHEST_FORMAT = EIT
-} Format;
#define NAGRA_TABLE_ID 0x55 //the lower the table Id, the more "current" it is; table_id 0x00 never gets overwritten, now/next are at 0x4e or 0x4f!
#define DEFAULT_TABLE_ID 0x30
diff --git a/eit2.c b/eit2.c
index 6c88594..12a7a95 100644
--- a/eit2.c
+++ b/eit2.c
@@ -11,6 +11,7 @@
#include "log.h"
#include "util.h"
#include "dish.h"
+#include "equivhandler.h"
using namespace std;
using namespace util;
@@ -18,624 +19,625 @@ using namespace util;
namespace SI
{
- cEvent* cEIT2::ProcessEitEvent(cSchedule* pSchedule,const SI::EIT::Event* EitEvent,
- uchar Tid, uchar versionNumber)
- {
- bool ExternalData = false;
- // Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number.
- if (EitEvent->getStartTime () == 0 || (EitEvent->getStartTime () > 0 && EitEvent->getDuration () == 0))
+cEvent* cEIT2::ProcessEitEvent(cSchedule* pSchedule,const SI::EIT::Event* EitEvent,
+ uchar Tid, uchar versionNumber)
+{
+ bool ExternalData = false;
+ // Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number.
+ if (EitEvent->getStartTime () == 0 || (EitEvent->getStartTime () > 0 && EitEvent->getDuration () == 0))
+ return NULL;
+ Empty = false;
+ if (!SegmentStart)
+ SegmentStart = EitEvent->getStartTime ();
+ SegmentEnd = EitEvent->getStartTime () + EitEvent->getDuration ();
+ // int versionNumber = getVersionNumber();
+
+ cEvent *newEvent = NULL;
+ cEvent *pEvent = (cEvent *) pSchedule->GetEvent (EitEvent->getEventId (), EitEvent->getStartTime ());
+ if (!pEvent) {
+ if (OnlyRunningStatus)
return NULL;
- Empty = false;
- if (!SegmentStart)
- SegmentStart = EitEvent->getStartTime ();
- SegmentEnd = EitEvent->getStartTime () + EitEvent->getDuration ();
-// int versionNumber = getVersionNumber();
-
- cEvent *newEvent = NULL;
- cEvent *pEvent = (cEvent *) pSchedule->GetEvent (EitEvent->getEventId (), EitEvent->getStartTime ());
- if (!pEvent) {
- if (OnlyRunningStatus)
- return NULL;
- // If we don't have that event yet, we create a new one.
- // Otherwise we copy the information into the existing event anyway, because the data might have changed.
- pEvent = newEvent = new cEvent (EitEvent->getEventId ());
- if (!pEvent)
- return NULL;
- } else {
- //LogD(3, prep("existing event channelID: %s Title: %s TableID 0x%02X new TID 0x%02X Version %i, new version %i"), *channel->GetChannelID().ToString(), pEvent->Title(), pEvent->TableID(), Tid, pEvent->Version(), versionNumber);
- // We have found an existing event, either through its event ID or its start time.
- pEvent->SetSeen ();
-
- // If the existing event has a zero table ID it was defined externally and shall
- // not be overwritten.
- if (pEvent->TableID () == 0x00) {
- if (pEvent->Version () == versionNumber)
- return NULL;
- /*HasExternalData = */ExternalData = true;
- }
- // If the new event has a higher table ID, let's skip it.
- // The lower the table ID, the more "current" the information.
- else if (Tid > pEvent->TableID())
- return NULL;
- // If the new event comes from the same table and has the same version number
- // as the existing one, let's skip it to avoid unnecessary work.
- // Unfortunately some stations (like, e.g. "Premiere") broadcast their EPG data on several transponders (like
- // the actual Premiere transponder and the Sat.1/Pro7 transponder), but use different version numbers on
- // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned
- // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers.
- else if (Tid == pEvent->TableID() && pEvent->Version() == versionNumber)
+ // If we don't have that event yet, we create a new one.
+ // Otherwise we copy the information into the existing event anyway, because the data might have changed.
+ pEvent = newEvent = new cEvent (EitEvent->getEventId ());
+ if (!pEvent)
+ return NULL;
+ } else {
+ //LogD(3, prep("existing event channelID: %s Title: %s TableID 0x%02X new TID 0x%02X Version %i, new version %i"), *channel->GetChannelID().ToString(), pEvent->Title(), pEvent->TableID(), Tid, pEvent->Version(), versionNumber);
+ // We have found an existing event, either through its event ID or its start time.
+ pEvent->SetSeen ();
+
+ // If the existing event has a zero table ID it was defined externally and shall
+ // not be overwritten.
+ if (pEvent->TableID () == 0x00) {
+ if (pEvent->Version () == versionNumber)
return NULL;
+ /*HasExternalData = */ExternalData = true;
}
- if (!ExternalData) {
- pEvent->SetEventID (EitEvent->getEventId ()); // unfortunately some stations use different event ids for the same event in different tables :-(
- pEvent->SetTableID (Tid);
- pEvent->SetStartTime (EitEvent->getStartTime ());
- pEvent->SetDuration (EitEvent->getDuration ());
- }
- if (newEvent)
- pSchedule->AddEvent (newEvent);
- if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
- if (EitEvent->getRunningStatus () >= SI::RunningStatusNotRunning)
- pSchedule->SetRunningStatus (pEvent, EitEvent->getRunningStatus (), channel);
- }
- if (OnlyRunningStatus)
- return NULL; // do this before setting the version, so that the full update can be done later
- pEvent->SetVersion (versionNumber);
+ // If the new event has a higher table ID, let's skip it.
+ // The lower the table ID, the more "current" the information.
+ else if (Tid > pEvent->TableID())
+ return NULL;
+ // If the new event comes from the same table and has the same version number
+ // as the existing one, let's skip it to avoid unnecessary work.
+ // Unfortunately some stations (like, e.g. "Premiere") broadcast their EPG data on several transponders (like
+ // the actual Premiere transponder and the Sat.1/Pro7 transponder), but use different version numbers on
+ // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned
+ // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers.
+ else if (Tid == pEvent->TableID() && pEvent->Version() == versionNumber)
+ return NULL;
+ }
+ if (!ExternalData) {
+ pEvent->SetEventID (EitEvent->getEventId ()); // unfortunately some stations use different event ids for the same event in different tables :-(
+ pEvent->SetTableID (Tid);
+ pEvent->SetStartTime (EitEvent->getStartTime ());
+ pEvent->SetDuration (EitEvent->getDuration ());
+ }
+ if (newEvent)
+ pSchedule->AddEvent (newEvent);
+ if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
+ if (EitEvent->getRunningStatus () >= SI::RunningStatusNotRunning)
+ pSchedule->SetRunningStatus (pEvent, EitEvent->getRunningStatus (), channel);
+ }
+ if (OnlyRunningStatus)
+ return NULL; // do this before setting the version, so that the full update can be done later
+ pEvent->SetVersion (versionNumber);
- ProcessEventDescriptors(ExternalData, channel->Source(), Tid, EitEvent,
- pEvent, Schedules, channel);
+ ProcessEventDescriptors(ExternalData, channel->Source(), Tid, EitEvent,
+ pEvent, Schedules, channel);
- Modified = true;
- return pEvent;
- }
+ Modified = true;
+ return pEvent;
+}
- void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source,
- u_char Tid, const SI::EIT::Event* SiEitEvent, cEvent* pEvent,
- cSchedules* Schedules, cChannel* channel)
- {
+void cEIT2::ProcessEventDescriptors(bool ExternalData, int Source,
+ u_char Tid, const SI::EIT::Event* SiEitEvent, cEvent* pEvent,
+ cSchedules* Schedules, cChannel* channel)
+{
- cEvent *rEvent = NULL;
- int LanguagePreferenceShort = -1;
- int LanguagePreferenceExt = -1;
- unsigned char nDescriptorTag;
- bool UseExtendedEventDescriptor = false;
- SI::Descriptor * d;
- SI::ExtendedEventDescriptors * ExtendedEventDescriptors = NULL;
- SI::ShortEventDescriptor * ShortEventDescriptor = NULL;
- //SI::DishDescriptor *DishExtendedEventDescriptor = NULL;
- SI::DishDescriptor *DishEventDescriptor = NULL;
- //uchar DishTheme = 0, DishCategory = 0;
+ cEvent *rEvent = NULL;
+ int LanguagePreferenceShort = -1;
+ int LanguagePreferenceExt = -1;
+ unsigned char nDescriptorTag;
+ bool UseExtendedEventDescriptor = false;
+ SI::Descriptor * d;
+ SI::ExtendedEventDescriptors * ExtendedEventDescriptors = NULL;
+ SI::ShortEventDescriptor * ShortEventDescriptor = NULL;
+ //SI::DishDescriptor *DishExtendedEventDescriptor = NULL;
+ SI::DishDescriptor *DishEventDescriptor = NULL;
+ //uchar DishTheme = 0, DishCategory = 0;
- cLinkChannels *LinkChannels = NULL;
- cComponents *Components = NULL;
+ cLinkChannels *LinkChannels = NULL;
+ cComponents *Components = NULL;
- DescriptorLoop dl = SiEitEvent->eventDescriptors;
- for (SI::Loop::Iterator it2; (d = dl.getNext(it2)); )
+ DescriptorLoop dl = SiEitEvent->eventDescriptors;
+ for (SI::Loop::Iterator it2; (d = dl.getNext(it2)); )
+ {
+ if (ExternalData && d->getDescriptorTag() != SI::ComponentDescriptorTag)
{
- if (ExternalData && d->getDescriptorTag() != SI::ComponentDescriptorTag)
+ delete d;
+ LogD(2, prep("continue:d->getDescriptorTAG():%x)"), d->getDescriptorTag ());
+ continue;
+ }
+
+ //LogD(2, prep("EEPGDEBUG:d->getDescriptorTAG():%x)"), d->getDescriptorTag ());
+ nDescriptorTag = d->getDescriptorTag();
+ switch (nDescriptorTag)
+ {
+ case SI::ExtendedEventDescriptorTag:
+ {
+ SI::ExtendedEventDescriptor * eed =
+ (SI::ExtendedEventDescriptor *) d;
+ if (I18nIsPreferredLanguage(Setup.EPGLanguages, eed->languageCode,
+ LanguagePreferenceExt) || !ExtendedEventDescriptors)
{
- delete d;
- LogD(2, prep("continue:d->getDescriptorTAG():%x)"), d->getDescriptorTag ());
- continue;
+ delete ExtendedEventDescriptors;
+ ExtendedEventDescriptors = new SI::ExtendedEventDescriptors;
+ UseExtendedEventDescriptor = true;
}
-
- //LogD(2, prep("EEPGDEBUG:d->getDescriptorTAG():%x)"), d->getDescriptorTag ());
- nDescriptorTag = d->getDescriptorTag();
- switch (nDescriptorTag)
- {
- case SI::ExtendedEventDescriptorTag:
- {
- SI::ExtendedEventDescriptor * eed =
- (SI::ExtendedEventDescriptor *) d;
- if (I18nIsPreferredLanguage(Setup.EPGLanguages, eed->languageCode,
- LanguagePreferenceExt) || !ExtendedEventDescriptors)
- {
- delete ExtendedEventDescriptors;
- ExtendedEventDescriptors = new SI::ExtendedEventDescriptors;
- UseExtendedEventDescriptor = true;
- }
- if (UseExtendedEventDescriptor)
- {
- ExtendedEventDescriptors->Add(eed);
- d = NULL; // so that it is not deleted
- }
- if (eed->getDescriptorNumber() == eed->getLastDescriptorNumber())
- UseExtendedEventDescriptor = false;
- }
- break;
- case SI::ShortEventDescriptorTag:
- {
- SI::ShortEventDescriptor * sed = (SI::ShortEventDescriptor *) d;
- if (I18nIsPreferredLanguage(Setup.EPGLanguages, sed->languageCode,
- LanguagePreferenceShort) || !ShortEventDescriptor)
- {
- delete ShortEventDescriptor;
- ShortEventDescriptor = sed;
- d = NULL; // so that it is not deleted
- }
- }
- break;
+ if (UseExtendedEventDescriptor)
+ {
+ ExtendedEventDescriptors->Add(eed);
+ d = NULL; // so that it is not deleted
+ }
+ if (eed->getDescriptorNumber() == eed->getLastDescriptorNumber())
+ UseExtendedEventDescriptor = false;
+ }
+ break;
+ case SI::ShortEventDescriptorTag:
+ {
+ SI::ShortEventDescriptor * sed = (SI::ShortEventDescriptor *) d;
+ if (I18nIsPreferredLanguage(Setup.EPGLanguages, sed->languageCode,
+ LanguagePreferenceShort) || !ShortEventDescriptor)
+ {
+ delete ShortEventDescriptor;
+ ShortEventDescriptor = sed;
+ d = NULL; // so that it is not deleted
+ }
+ }
+ break;
#if APIVERSNUM > 10711
- case SI::ContentDescriptorTag:
- {
- SI::ContentDescriptor *cd = (SI::ContentDescriptor *) d;
- SI::ContentDescriptor::Nibble Nibble;
- int NumContents = 0;
- uchar Contents[MaxEventContents] =
- { 0 };
- for (SI::Loop::Iterator it3; cd->nibbleLoop.getNext(Nibble, it3);)
- {
- if (NumContents < MaxEventContents)
- {
- Contents[NumContents] = ((Nibble.getContentNibbleLevel1()
- & 0xF) << 4) | (Nibble.getContentNibbleLevel2() & 0xF);
- NumContents++;
- }
- if (DishEventDescriptor && NumContents == 1)
- {
- DishEventDescriptor->setContent(Nibble);
- }
- // LogD(2, prep("EEPGDEBUG:Nibble:%x-%x-%x-%x)"), Nibble.getContentNibbleLevel1(),Nibble.getContentNibbleLevel2()
- // , Nibble.getUserNibble1(), Nibble.getUserNibble2());
-
- }
- pEvent->SetContents(Contents);
- }
- break;
+ case SI::ContentDescriptorTag:
+ {
+ SI::ContentDescriptor *cd = (SI::ContentDescriptor *) d;
+ SI::ContentDescriptor::Nibble Nibble;
+ int NumContents = 0;
+ uchar Contents[MaxEventContents] =
+ { 0 };
+ for (SI::Loop::Iterator it3; cd->nibbleLoop.getNext(Nibble, it3);)
+ {
+ if (NumContents < MaxEventContents)
+ {
+ Contents[NumContents] = ((Nibble.getContentNibbleLevel1()
+ & 0xF) << 4) | (Nibble.getContentNibbleLevel2() & 0xF);
+ NumContents++;
+ }
+ if (DishEventDescriptor && NumContents == 1)
+ {
+ DishEventDescriptor->setContent(Nibble);
+ }
+ // LogD(2, prep("EEPGDEBUG:Nibble:%x-%x-%x-%x)"), Nibble.getContentNibbleLevel1(),Nibble.getContentNibbleLevel2()
+ // , Nibble.getUserNibble1(), Nibble.getUserNibble2());
+
+ }
+ pEvent->SetContents(Contents);
+ }
+ break;
#endif
- case SI::ParentalRatingDescriptorTag:
- {
- int LanguagePreferenceRating = -1;
- SI::ParentalRatingDescriptor *prd =
- (SI::ParentalRatingDescriptor *) d;
- SI::ParentalRatingDescriptor::Rating Rating;
- for (SI::Loop::Iterator it3; prd->ratingLoop.getNext(Rating, it3);)
- {
- if (I18nIsPreferredLanguage(Setup.EPGLanguages,
- Rating.languageCode, LanguagePreferenceRating))
- {
- int ParentalRating = (Rating.getRating() & 0xFF);
- switch (ParentalRating)
- {
- // values defined by the DVB standard (minimum age = rating + 3 years):
- case 0x01 ... 0x0F:
- ParentalRating += 3;
- break;
- // values defined by broadcaster CSAT (now why didn't they just use 0x07, 0x09 and 0x0D?):
- case 0x11:
- ParentalRating = 10;
- break;
- case 0x12:
- ParentalRating = 12;
- break;
- case 0x13:
- ParentalRating = 16;
- break;
- default:
- ParentalRating = 0;
- }
- pEvent->SetParentalRating(ParentalRating);
- }
- }
- }
- break;
- case SI::PDCDescriptorTag:
- {
- SI::PDCDescriptor * pd = (SI::PDCDescriptor *) d;
- time_t now = time(NULL);
- struct tm tm_r;
- struct tm t = *localtime_r(&now, &tm_r); // this initializes the time zone in 't'
- t.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
- int month = t.tm_mon;
- t.tm_mon = pd->getMonth() - 1;
- t.tm_mday = pd->getDay();
- t.tm_hour = pd->getHour();
- t.tm_min = pd->getMinute();
- t.tm_sec = 0;
- if (month == 11 && t.tm_mon == 0) // current month is dec, but event is in jan
- t.tm_year++;
- else if (month == 0 && t.tm_mon == 11) // current month is jan, but event is in dec
- t.tm_year--;
- time_t vps = mktime(&t);
- pEvent->SetVps(vps);
- }
- break;
- case SI::TimeShiftedEventDescriptorTag:
- {
- if (Schedules) {
- SI::TimeShiftedEventDescriptor * tsed =
- (SI::TimeShiftedEventDescriptor *) d;
- cSchedule *rSchedule = (cSchedule *) Schedules->GetSchedule(
- tChannelID(Source, channel->Nid(), channel->Tid(),
- tsed->getReferenceServiceId()));
- if (!rSchedule)
- break;
- rEvent = (cEvent *) rSchedule->GetEvent(
- tsed->getReferenceEventId());
- if (!rEvent)
- break;
- pEvent->SetTitle(rEvent->Title());
- pEvent->SetShortText(rEvent->ShortText());
- pEvent->SetDescription(rEvent->Description());
- }
- }
- break;
- case SI::LinkageDescriptorTag:
+ case SI::ParentalRatingDescriptorTag:
+ {
+ int LanguagePreferenceRating = -1;
+ SI::ParentalRatingDescriptor *prd =
+ (SI::ParentalRatingDescriptor *) d;
+ SI::ParentalRatingDescriptor::Rating Rating;
+ for (SI::Loop::Iterator it3; prd->ratingLoop.getNext(Rating, it3);)
+ {
+ if (I18nIsPreferredLanguage(Setup.EPGLanguages,
+ Rating.languageCode, LanguagePreferenceRating))
+ {
+ int ParentalRating = (Rating.getRating() & 0xFF);
+ switch (ParentalRating)
{
- SI::LinkageDescriptor * ld = (SI::LinkageDescriptor *) d;
- tChannelID linkID(Source, ld->getOriginalNetworkId(),
- ld->getTransportStreamId(), ld->getServiceId());
- if (ld->getLinkageType() == 0xB0)
- { // Premiere World
- time_t now = time(NULL);
- bool hit = SiEitEvent->getStartTime() <= now
- && now
- < SiEitEvent->getStartTime() + SiEitEvent->getDuration();
- if (hit)
- {
- char linkName[ld->privateData.getLength() + 1];
- strn0cpy(linkName, (const char *) ld->privateData.getData(),
- sizeof(linkName));
- // TODO is there a standard way to determine the character set of this string?
- cChannel *link = Channels.GetByChannelID(linkID);
- if (link != channel)
- { // only link to other channels, not the same one
- //fprintf(stderr, "Linkage %s %4d %4d %5d %5d %5d %5d %02X '%s'\n", hit ? "*" : "", channel->Number(), link ? link->Number() : -1, SiEitEvent.getEventId(), ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId(), ld->getLinkageType(), linkName);//XXX
- if (link)
- {
- if (Setup.UpdateChannels == 1
- || Setup.UpdateChannels >= 3)
- link->SetName(linkName, "", "");
- }
- else if (Setup.UpdateChannels >= 4)
- {
- cChannel *transponder = channel;
- if (channel->Tid() != ld->getTransportStreamId())
- transponder = Channels.GetByTransponderID(linkID);
- link = Channels.NewChannel(transponder, linkName,
- "", "", ld->getOriginalNetworkId(),
- ld->getTransportStreamId(), ld->getServiceId());
- }
- if (link)
- {
- if (!LinkChannels)
- LinkChannels = new cLinkChannels;
- LinkChannels->Add(new cLinkChannel(link));
- }
- }
- else
- channel->SetPortalName(linkName);
- }
- }
- }
+ // values defined by the DVB standard (minimum age = rating + 3 years):
+ case 0x01 ... 0x0F:
+ ParentalRating += 3;
break;
- case SI::ComponentDescriptorTag:
- {
- SI::ComponentDescriptor * cd = (SI::ComponentDescriptor *) d;
- uchar Stream = cd->getStreamContent();
- uchar Type = cd->getComponentType();
- //if (1 <= Stream && Stream <= 3 && Type != 0) { // 1=video, 2=audio, 3=subtitles
- if (1 <= Stream && Stream <= 6 && Type != 0)
- { // 1=MPEG2-video, 2=MPEG1-audio, 3=subtitles, 4=AC3-audio, 5=H.264-video, 6=HEAAC-audio
- if (!Components)
- Components = new cComponents;
- char buffer[Utf8BufSize (256)];
- Components->SetComponent(Components->NumComponents(), Stream,
- Type, I18nNormalizeLanguageCode(cd->languageCode),
- cd->description.getText(buffer, sizeof(buffer)));
- }
+ // values defined by broadcaster CSAT (now why didn't they just use 0x07, 0x09 and 0x0D?):
+ case 0x11:
+ ParentalRating = 10;
+ break;
+ case 0x12:
+ ParentalRating = 12;
+ break;
+ case 0x13:
+ ParentalRating = 16;
+ break;
+ default:
+ ParentalRating = 0;
}
+ pEvent->SetParentalRating(ParentalRating);
+ }
+ }
+ }
+ break;
+ case SI::PDCDescriptorTag:
+ {
+ SI::PDCDescriptor * pd = (SI::PDCDescriptor *) d;
+ time_t now = time(NULL);
+ struct tm tm_r;
+ struct tm t = *localtime_r(&now, &tm_r); // this initializes the time zone in 't'
+ t.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
+ int month = t.tm_mon;
+ t.tm_mon = pd->getMonth() - 1;
+ t.tm_mday = pd->getDay();
+ t.tm_hour = pd->getHour();
+ t.tm_min = pd->getMinute();
+ t.tm_sec = 0;
+ if (month == 11 && t.tm_mon == 0) // current month is dec, but event is in jan
+ t.tm_year++;
+ else if (month == 0 && t.tm_mon == 11) // current month is jan, but event is in dec
+ t.tm_year--;
+ time_t vps = mktime(&t);
+ pEvent->SetVps(vps);
+ }
+ break;
+ case SI::TimeShiftedEventDescriptorTag:
+ {
+ if (Schedules) {
+ SI::TimeShiftedEventDescriptor * tsed =
+ (SI::TimeShiftedEventDescriptor *) d;
+ cSchedule *rSchedule = (cSchedule *) Schedules->GetSchedule(
+ tChannelID(Source, channel->Nid(), channel->Tid(),
+ tsed->getReferenceServiceId()));
+ if (!rSchedule)
break;
- case SI::DishExtendedEventDescriptorTag:
- {
- SI::UnimplementedDescriptor *deed =
- (SI::UnimplementedDescriptor *) d;
- if (!DishEventDescriptor)
- {
- DishEventDescriptor = new SI::DishDescriptor();
- }
- DishEventDescriptor->setExtendedtData(Tid + 1, deed->getData());
- // HasExternalData = true;
- }
+ rEvent = (cEvent *) rSchedule->GetEvent(
+ tsed->getReferenceEventId());
+ if (!rEvent)
break;
- case SI::DishShortEventDescriptorTag:
+ pEvent->SetTitle(rEvent->Title());
+ pEvent->SetShortText(rEvent->ShortText());
+ pEvent->SetDescription(rEvent->Description());
+ }
+ }
+ break;
+ case SI::LinkageDescriptorTag:
+ {
+ SI::LinkageDescriptor * ld = (SI::LinkageDescriptor *) d;
+ tChannelID linkID(Source, ld->getOriginalNetworkId(),
+ ld->getTransportStreamId(), ld->getServiceId());
+ if (ld->getLinkageType() == 0xB0)
+ { // Premiere World
+ time_t now = time(NULL);
+ bool hit = SiEitEvent->getStartTime() <= now
+ && now
+ < SiEitEvent->getStartTime() + SiEitEvent->getDuration();
+ if (hit)
+ {
+ char linkName[ld->privateData.getLength() + 1];
+ strn0cpy(linkName, (const char *) ld->privateData.getData(),
+ sizeof(linkName));
+ // TODO is there a standard way to determine the character set of this string?
+ cChannel *link = Channels.GetByChannelID(linkID);
+ if (link != channel)
+ { // only link to other channels, not the same one
+ //fprintf(stderr, "Linkage %s %4d %4d %5d %5d %5d %5d %02X '%s'\n", hit ? "*" : "", channel->Number(), link ? link->Number() : -1, SiEitEvent.getEventId(), ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId(), ld->getLinkageType(), linkName);//XXX
+ if (link)
{
- SI::UnimplementedDescriptor *dsed =
- (SI::UnimplementedDescriptor *) d;
- if (!DishEventDescriptor)
- {
- DishEventDescriptor = new SI::DishDescriptor();
- }
- DishEventDescriptor->setShortData(Tid + 1, dsed->getData());
- // HasExternalData = true;
+ if (Setup.UpdateChannels == 1
+ || Setup.UpdateChannels >= 3)
+ link->SetName(linkName, "", "");
}
- break;
- case SI::DishRatingDescriptorTag:
+ else if (Setup.UpdateChannels >= 4)
{
- if (d->getLength() == 4)
- {
- if (!DishEventDescriptor)
- {
- DishEventDescriptor = new SI::DishDescriptor();
- }
- uint16_t rating = d->getData().TwoBytes(2);
- DishEventDescriptor->setRating(rating);
- }
+ cChannel *transponder = channel;
+ if (channel->Tid() != ld->getTransportStreamId())
+ transponder = Channels.GetByTransponderID(linkID);
+ link = Channels.NewChannel(transponder, linkName,
+ "", "", ld->getOriginalNetworkId(),
+ ld->getTransportStreamId(), ld->getServiceId());
}
- break;
- case SI::DishSeriesDescriptorTag:
+ if (link)
{
- if (d->getLength() == 10)
- {
- //LogD(2, prep("DishSeriesDescriptorTag: %s)"), (const char*) d->getData().getData());
- if (!DishEventDescriptor)
- {
- DishEventDescriptor = new SI::DishDescriptor();
- }
- DishEventDescriptor->setEpisodeInfo(d->getData());
- }
- // else {
- // LogD(2, prep("DishSeriesDescriptorTag length: %d)"), d->getLength());
- // }
+ if (!LinkChannels)
+ LinkChannels = new cLinkChannels;
+ LinkChannels->Add(new cLinkChannel(link));
}
- break;
- default:
- break;
- }
- delete d;
+ }
+ else
+ channel->SetPortalName(linkName);
}
- if (!rEvent) {
- if (ShortEventDescriptor) {
+ }
+ }
+ break;
+ case SI::ComponentDescriptorTag:
+ {
+ SI::ComponentDescriptor * cd = (SI::ComponentDescriptor *) d;
+ uchar Stream = cd->getStreamContent();
+ uchar Type = cd->getComponentType();
+ //if (1 <= Stream && Stream <= 3 && Type != 0) { // 1=video, 2=audio, 3=subtitles
+ if (1 <= Stream && Stream <= 6 && Type != 0)
+ { // 1=MPEG2-video, 2=MPEG1-audio, 3=subtitles, 4=AC3-audio, 5=H.264-video, 6=HEAAC-audio
+ if (!Components)
+ Components = new cComponents;
char buffer[Utf8BufSize (256)];
- unsigned char *f;
- int l = ShortEventDescriptor->name.getLength();
- f = (unsigned char *) ShortEventDescriptor->name.getData().getData();
- decodeText2 (f, l, buffer, sizeof (buffer));
- //ShortEventDescriptor->name.getText(buffer, sizeof(buffer));
- LogD(2, prep("Title: %s Decoded: %s"), f, buffer);
- pEvent->SetTitle (buffer);
- LogD(3, prep("channelID: %s Title: %s"), *channel->GetChannelID().ToString(), pEvent->Title());
- l = ShortEventDescriptor->text.getLength();
- if (l > 0) { //Set the Short Text only if there is data so that we do not overwrite valid data
- f = (unsigned char *) ShortEventDescriptor->text.getData().getData();
- decodeText2 (f, l, buffer, sizeof (buffer));
- //ShortEventDescriptor->text.getText(buffer, sizeof(buffer));
- pEvent->SetShortText (buffer);
- }
- LogD(3, prep("ShortText: %s"), pEvent->ShortText());
- LogD(2, prep("ShortText: %s Decoded: %s"), f, buffer);
- } else if (/*!HasExternalData*/!DishEventDescriptor) {
- pEvent->SetTitle (NULL);
- pEvent->SetShortText (NULL);
- LogD(3, prep("SetTitle (NULL)"));
+ Components->SetComponent(Components->NumComponents(), Stream,
+ Type, I18nNormalizeLanguageCode(cd->languageCode),
+ cd->description.getText(buffer, sizeof(buffer)));
}
- if (ExtendedEventDescriptors) {
- char buffer[Utf8BufSize (ExtendedEventDescriptors->getMaximumTextLength (": ")) + 1];
- pEvent->SetDescription (ExtendedEventDescriptors->getText (buffer, sizeof (buffer), ": "));
- LogD(3, prep("Description: %s"), pEvent->Description());
- } else if (!/*HasExternalData*/DishEventDescriptor)
- pEvent->SetDescription (NULL);
-
- if (DishEventDescriptor) {
- if (DishEventDescriptor->getName())
- pEvent->SetTitle(DishEventDescriptor->getName());
- //LogD(2, prep("channelID: %s DishTitle: %s"), *channel->GetChannelID().ToString(), DishEventDescriptor->getName());
- pEvent->SetShortText(DishEventDescriptor->getShortText());
- char *tmp;
- string fmt;
-
- const char * description = DishEventDescriptor->getDescription();
- //BEV sets the description previously with ExtendedEventDescriptor
- if (0 == strcmp(DishEventDescriptor->getDescription(),"") && pEvent->Description())
- description = pEvent->Description();
-
-
- fmt = "%s";
- if (DishEventDescriptor->hasTheme()) {
- fmt += "\nTheme: ";
- }
- fmt += "%s";
- if (DishEventDescriptor->hasCategory()) {
- fmt += "\nCategory: ";
- }
- fmt += "%s";
-
- if ((0 != strcmp(DishEventDescriptor->getRating(),"")
- || 0 != strcmp(DishEventDescriptor->getStarRating(),""))) {
- fmt += "\n\nRating: ";
- }
- fmt += "%s %s";
- if (0 != strcmp(DishEventDescriptor->getProgramId(),"")) {
- fmt += "\n\nProgram ID: ";
+ }
+ break;
+ case SI::DishExtendedEventDescriptorTag:
+ {
+ SI::UnimplementedDescriptor *deed =
+ (SI::UnimplementedDescriptor *) d;
+ if (!DishEventDescriptor)
+ {
+ DishEventDescriptor = new SI::DishDescriptor();
+ }
+ DishEventDescriptor->setExtendedtData(Tid + 1, deed->getData());
+ // HasExternalData = true;
+ }
+ break;
+ case SI::DishShortEventDescriptorTag:
+ {
+ SI::UnimplementedDescriptor *dsed =
+ (SI::UnimplementedDescriptor *) d;
+ if (!DishEventDescriptor)
+ {
+ DishEventDescriptor = new SI::DishDescriptor();
+ }
+ DishEventDescriptor->setShortData(Tid + 1, dsed->getData());
+ // HasExternalData = true;
+ }
+ break;
+ case SI::DishRatingDescriptorTag:
+ {
+ if (d->getLength() == 4)
+ {
+ if (!DishEventDescriptor)
+ {
+ DishEventDescriptor = new SI::DishDescriptor();
}
- fmt += "%s %s%s";
- time_t orgAirDate = DishEventDescriptor->getOriginalAirDate();
- char datestr [80];
- bool dateok = false;
- if (orgAirDate == 0) {
- dateok = strftime (datestr,80," Original Air Date: %a %b %d %Y",gmtime(&orgAirDate)) > 0;
+ uint16_t rating = d->getData().TwoBytes(2);
+ DishEventDescriptor->setRating(rating);
+ }
+ }
+ break;
+ case SI::DishSeriesDescriptorTag:
+ {
+ if (d->getLength() == 10)
+ {
+ //LogD(2, prep("DishSeriesDescriptorTag: %s)"), (const char*) d->getData().getData());
+ if (!DishEventDescriptor)
+ {
+ DishEventDescriptor = new SI::DishDescriptor();
}
+ DishEventDescriptor->setEpisodeInfo(d->getData());
+ }
+ // else {
+ // LogD(2, prep("DishSeriesDescriptorTag length: %d)"), d->getLength());
+ // }
+ }
+ break;
+ default:
+ break;
+ }
+ delete d;
+ }
+ if (!rEvent) {
+ if (ShortEventDescriptor) {
+ char buffer[Utf8BufSize (256)];
+ unsigned char *f;
+ int l = ShortEventDescriptor->name.getLength();
+ f = (unsigned char *) ShortEventDescriptor->name.getData().getData();
+ decodeText2 (f, l, buffer, sizeof (buffer));
+ //ShortEventDescriptor->name.getText(buffer, sizeof(buffer));
+ LogD(2, prep("Title: %s Decoded: %s"), f, buffer);
+ pEvent->SetTitle (buffer);
+ LogD(3, prep("channelID: %s Title: %s"), *channel->GetChannelID().ToString(), pEvent->Title());
+ l = ShortEventDescriptor->text.getLength();
+ if (l > 0) { //Set the Short Text only if there is data so that we do not overwrite valid data
+ f = (unsigned char *) ShortEventDescriptor->text.getData().getData();
+ decodeText2 (f, l, buffer, sizeof (buffer));
+ //ShortEventDescriptor->text.getText(buffer, sizeof(buffer));
+ pEvent->SetShortText (buffer);
+ }
+ LogD(3, prep("ShortText: %s"), pEvent->ShortText());
+ LogD(2, prep("ShortText: %s Decoded: %s"), f, buffer);
+ } else if (/*!HasExternalData*/!DishEventDescriptor) {
+ pEvent->SetTitle (NULL);
+ pEvent->SetShortText (NULL);
+ LogD(3, prep("SetTitle (NULL)"));
+ }
+ if (ExtendedEventDescriptors) {
+ char buffer[Utf8BufSize (ExtendedEventDescriptors->getMaximumTextLength (": ")) + 1];
+ pEvent->SetDescription (ExtendedEventDescriptors->getText (buffer, sizeof (buffer), ": "));
+ LogD(3, prep("Description: %s"), pEvent->Description());
+ } else if (!/*HasExternalData*/DishEventDescriptor)
+ pEvent->SetDescription (NULL);
+
+ if (DishEventDescriptor) {
+ if (DishEventDescriptor->getName())
+ pEvent->SetTitle(DishEventDescriptor->getName());
+ //LogD(2, prep("channelID: %s DishTitle: %s"), *channel->GetChannelID().ToString(), DishEventDescriptor->getName());
+ pEvent->SetShortText(DishEventDescriptor->getShortText());
+ char *tmp;
+ string fmt;
+
+ const char * description = DishEventDescriptor->getDescription();
+ //BEV sets the description previously with ExtendedEventDescriptor
+ if (0 == strcmp(DishEventDescriptor->getDescription(),"") && pEvent->Description())
+ description = pEvent->Description();
+
+
+ fmt = "%s";
+ if (DishEventDescriptor->hasTheme()) {
+ fmt += "\nTheme: ";
+ }
+ fmt += "%s";
+ if (DishEventDescriptor->hasCategory()) {
+ fmt += "\nCategory: ";
+ }
+ fmt += "%s";
- Asprintf (&tmp, fmt.c_str(), description
- , DishEventDescriptor->getTheme(), DishEventDescriptor->getCategory()
- , DishEventDescriptor->getRating(), DishEventDescriptor->getStarRating()
- , DishEventDescriptor->getProgramId(), DishEventDescriptor->getSeriesId()
- , orgAirDate == 0 || !dateok ? "" : datestr);
- pEvent->SetDescription(tmp);
- free(tmp);
+ if ((0 != strcmp(DishEventDescriptor->getRating(),"")
+ || 0 != strcmp(DishEventDescriptor->getStarRating(),""))) {
+ fmt += "\n\nRating: ";
+ }
+ fmt += "%s %s";
+ if (0 != strcmp(DishEventDescriptor->getProgramId(),"")) {
+ fmt += "\n\nProgram ID: ";
+ }
+ fmt += "%s %s%s";
+ time_t orgAirDate = DishEventDescriptor->getOriginalAirDate();
+ char datestr [80];
+ bool dateok = false;
+ if (orgAirDate == 0) {
+ dateok = strftime (datestr,80," Original Air Date: %a %b %d %Y",gmtime(&orgAirDate)) > 0;
+ }
+ Asprintf (&tmp, fmt.c_str(), description
+ , DishEventDescriptor->getTheme(), DishEventDescriptor->getCategory()
+ , DishEventDescriptor->getRating(), DishEventDescriptor->getStarRating()
+ , DishEventDescriptor->getProgramId(), DishEventDescriptor->getSeriesId()
+ , orgAirDate == 0 || !dateok ? "" : datestr);
+ pEvent->SetDescription(tmp);
+ free(tmp);
- //LogD(2, prep("DishDescription: %s"), DishEventDescriptor->getDescription());
- //LogD(2, prep("DishShortText: %s"), DishEventDescriptor->getShortText());
- }
+ //LogD(2, prep("DishDescription: %s"), DishEventDescriptor->getDescription());
+ //LogD(2, prep("DishShortText: %s"), DishEventDescriptor->getShortText());
}
- delete ExtendedEventDescriptors;
- delete ShortEventDescriptor;
- delete DishEventDescriptor;
- pEvent->SetComponents (Components);
+ }
+ delete ExtendedEventDescriptors;
+ delete ShortEventDescriptor;
+ delete DishEventDescriptor;
-// LogD(2, prep("channelID: %s Title: %s"), *channel->GetChannelID().ToString(), pEvent->Title());
+ pEvent->SetComponents (Components);
-// if (pEvent->ChannelID() == tChannelID::FromString("S119.0W-4100-6-110-110")) {
-// LogD(2, prep("ID: %d Title: %s Time: %d Tid: 0x%x"), pEvent->EventID(), pEvent->Title(), pEvent->StartTime(), pEvent->TableID());
-// }
+ // LogD(2, prep("channelID: %s Title: %s"), *channel->GetChannelID().ToString(), pEvent->Title());
-// if (!HasExternalData)
- pEvent->FixEpgBugs ();
- if (LinkChannels)
- channel->SetLinkChannels (LinkChannels);
- }
+ // if (pEvent->ChannelID() == tChannelID::FromString("S119.0W-4100-6-110-110")) {
+ // LogD(2, prep("ID: %d Title: %s Time: %d Tid: 0x%x"), pEvent->EventID(), pEvent->Title(), pEvent->StartTime(), pEvent->TableID());
+ // }
+
+ // if (!HasExternalData)
+ pEvent->FixEpgBugs ();
+ if (LinkChannels)
+ channel->SetLinkChannels (LinkChannels);
+}
cEIT2::cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool isEITPid, bool OnlyRunningStatus)
: SI::EIT (Data, false)
, OnlyRunningStatus(OnlyRunningStatus)
, Schedules(Schedules)
{
- //LogD(2, prep("cEIT2::cEIT2"));
- if (Tid > 0 && (Format == DISH_BEV || (SetupPE->ProcessEIT && isEITPid))) Tid--;
- if (!CheckCRCAndParse ()) {
- LogD(2, prep("!CheckCRCAndParse ()"));
- return;
- }
+ //LogD(2, prep("cEIT2::cEIT2"));
+ if (Tid > 0 && (Format == DISH_BEV || (cSetupEEPG::getInstance()->ProcessEIT && isEITPid))) Tid--;
- bool searchOtherSatPositions = Format == DISH_BEV;
+ if (!CheckCRCAndParse ()) {
+ LogD(2, prep("!CheckCRCAndParse ()"));
+ return;
+ }
- tChannelID channelID (Source, getOriginalNetworkId (), getTransportStreamId (), getServiceId ());
- channel = GetChannelByID (channelID, searchOtherSatPositions);
- if (!channel) {
- LogD(3, prep("!channel channelID: %s"), *channelID.ToString());
- return; // only collect data for known channels
- }
+ bool searchOtherSatPositions = Format == DISH_BEV;
- //LogD(5, prep("channelID: %s format:%d"), *channel->GetChannelID().ToString(), Format);
-
- cSchedule *pSchedule = (cSchedule *) Schedules->GetSchedule (channel, true);
-
- Empty = true;
- Modified = false;
-// bool HasExternalData = false;
- SegmentStart = 0;
- SegmentEnd = 0;
-
- SI::EIT::Event SiEitEvent;
- for (SI::Loop::Iterator it; eventLoop.getNext (SiEitEvent, it);) {
- int versionNumber = getVersionNumber();
-// bool ExternalData = false;
-// // Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number.
-// if (SiEitEvent.getStartTime () == 0 || (SiEitEvent.getStartTime () > 0 && SiEitEvent.getDuration () == 0))
-// continue;
-// Empty = false;
-// if (!SegmentStart)
-// SegmentStart = SiEitEvent.getStartTime ();
-// SegmentEnd = SiEitEvent.getStartTime () + SiEitEvent.getDuration ();
-// int versionNumber = getVersionNumber();
-//
-// cEvent *newEvent = NULL;
-// cEvent *pEvent = (cEvent *) pSchedule->GetEvent (SiEitEvent.getEventId (), SiEitEvent.getStartTime ());
-// if (!pEvent) {
-// if (OnlyRunningStatus)
-// continue;
-// // If we don't have that event yet, we create a new one.
-// // Otherwise we copy the information into the existing event anyway, because the data might have changed.
-// pEvent = newEvent = new cEvent (SiEitEvent.getEventId ());
-// if (!pEvent)
-// continue;
-// } else {
-// //LogD(3, prep("existing event channelID: %s Title: %s TableID 0x%02X new TID 0x%02X Version %i, new version %i"), *channel->GetChannelID().ToString(), pEvent->Title(), pEvent->TableID(), Tid, pEvent->Version(), versionNumber);
-// // We have found an existing event, either through its event ID or its start time.
-// pEvent->SetSeen ();
-//
-// // If the existing event has a zero table ID it was defined externally and shall
-// // not be overwritten.
-// if (pEvent->TableID () == 0x00) {
-// if (pEvent->Version () == versionNumber)
-// continue;
-// /*HasExternalData = */ExternalData = true;
-// }
-// // If the new event has a higher table ID, let's skip it.
-// // The lower the table ID, the more "current" the information.
-// else if (Tid > pEvent->TableID())
-// continue;
-// // If the new event comes from the same table and has the same version number
-// // as the existing one, let's skip it to avoid unnecessary work.
-// // Unfortunately some stations (like, e.g. "Premiere") broadcast their EPG data on several transponders (like
-// // the actual Premiere transponder and the Sat.1/Pro7 transponder), but use different version numbers on
-// // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned
-// // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers.
-// else if (Tid == pEvent->TableID() && pEvent->Version() == versionNumber)
-// continue;
-// }
-// if (!ExternalData) {
-// pEvent->SetEventID (SiEitEvent.getEventId ()); // unfortunately some stations use different event ids for the same event in different tables :-(
-// pEvent->SetTableID (Tid);
-// pEvent->SetStartTime (SiEitEvent.getStartTime ());
-// pEvent->SetDuration (SiEitEvent.getDuration ());
-// }
-// if (newEvent)
-// pSchedule->AddEvent (newEvent);
-// if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
-// if (SiEitEvent.getRunningStatus () >= SI::RunningStatusNotRunning)
-// pSchedule->SetRunningStatus (pEvent, SiEitEvent.getRunningStatus (), channel);
-// }
-// if (OnlyRunningStatus)
-// continue; // do this before setting the version, so that the full update can be done later
-// pEvent->SetVersion (versionNumber);
-//
-// ProcessEventDescriptors(ExternalData, Source, Tid, SiEitEvent,
-// pEvent, Schedules, channel);
-//
-// Modified = true;
- cEvent *pEvent = ProcessEitEvent(pSchedule, &SiEitEvent,
- Tid, versionNumber);
- if (pEvent)
- EquivHandler->updateEquivalent(Schedules, channel->GetChannelID(), pEvent);
- }
+ tChannelID channelID (Source, getOriginalNetworkId (), getTransportStreamId (), getServiceId ());
+ channel = GetChannelByID (channelID, searchOtherSatPositions);
+ if (!channel) {
+ LogD(3, prep("!channel channelID: %s"), *channelID.ToString());
+ return; // only collect data for known channels
+ }
- ////
+ //LogD(5, prep("channelID: %s format:%d"), *channel->GetChannelID().ToString(), Format);
+
+ cSchedule *pSchedule = (cSchedule *) Schedules->GetSchedule (channel, true);
+
+ Empty = true;
+ Modified = false;
+ // bool HasExternalData = false;
+ SegmentStart = 0;
+ SegmentEnd = 0;
+
+ SI::EIT::Event SiEitEvent;
+ for (SI::Loop::Iterator it; eventLoop.getNext (SiEitEvent, it);) {
+ int versionNumber = getVersionNumber();
+ // bool ExternalData = false;
+ // // Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number.
+ // if (SiEitEvent.getStartTime () == 0 || (SiEitEvent.getStartTime () > 0 && SiEitEvent.getDuration () == 0))
+ // continue;
+ // Empty = false;
+ // if (!SegmentStart)
+ // SegmentStart = SiEitEvent.getStartTime ();
+ // SegmentEnd = SiEitEvent.getStartTime () + SiEitEvent.getDuration ();
+ // int versionNumber = getVersionNumber();
+ //
+ // cEvent *newEvent = NULL;
+ // cEvent *pEvent = (cEvent *) pSchedule->GetEvent (SiEitEvent.getEventId (), SiEitEvent.getStartTime ());
+ // if (!pEvent) {
+ // if (OnlyRunningStatus)
+ // continue;
+ // // If we don't have that event yet, we create a new one.
+ // // Otherwise we copy the information into the existing event anyway, because the data might have changed.
+ // pEvent = newEvent = new cEvent (SiEitEvent.getEventId ());
+ // if (!pEvent)
+ // continue;
+ // } else {
+ // //LogD(3, prep("existing event channelID: %s Title: %s TableID 0x%02X new TID 0x%02X Version %i, new version %i"), *channel->GetChannelID().ToString(), pEvent->Title(), pEvent->TableID(), Tid, pEvent->Version(), versionNumber);
+ // // We have found an existing event, either through its event ID or its start time.
+ // pEvent->SetSeen ();
+ //
+ // // If the existing event has a zero table ID it was defined externally and shall
+ // // not be overwritten.
+ // if (pEvent->TableID () == 0x00) {
+ // if (pEvent->Version () == versionNumber)
+ // continue;
+ // /*HasExternalData = */ExternalData = true;
+ // }
+ // // If the new event has a higher table ID, let's skip it.
+ // // The lower the table ID, the more "current" the information.
+ // else if (Tid > pEvent->TableID())
+ // continue;
+ // // If the new event comes from the same table and has the same version number
+ // // as the existing one, let's skip it to avoid unnecessary work.
+ // // Unfortunately some stations (like, e.g. "Premiere") broadcast their EPG data on several transponders (like
+ // // the actual Premiere transponder and the Sat.1/Pro7 transponder), but use different version numbers on
+ // // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned
+ // // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers.
+ // else if (Tid == pEvent->TableID() && pEvent->Version() == versionNumber)
+ // continue;
+ // }
+ // if (!ExternalData) {
+ // pEvent->SetEventID (SiEitEvent.getEventId ()); // unfortunately some stations use different event ids for the same event in different tables :-(
+ // pEvent->SetTableID (Tid);
+ // pEvent->SetStartTime (SiEitEvent.getStartTime ());
+ // pEvent->SetDuration (SiEitEvent.getDuration ());
+ // }
+ // if (newEvent)
+ // pSchedule->AddEvent (newEvent);
+ // if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
+ // if (SiEitEvent.getRunningStatus () >= SI::RunningStatusNotRunning)
+ // pSchedule->SetRunningStatus (pEvent, SiEitEvent.getRunningStatus (), channel);
+ // }
+ // if (OnlyRunningStatus)
+ // continue; // do this before setting the version, so that the full update can be done later
+ // pEvent->SetVersion (versionNumber);
+ //
+ // ProcessEventDescriptors(ExternalData, Source, Tid, SiEitEvent,
+ // pEvent, Schedules, channel);
+ //
+ // Modified = true;
+ cEvent *pEvent = ProcessEitEvent(pSchedule, &SiEitEvent,
+ Tid, versionNumber);
+ if (pEvent)
+ EquivHandler->updateEquivalent(Schedules, channel->GetChannelID(), pEvent);
+ }
- if (Empty && Tid == 0x4E && getSectionNumber () == 0)
- // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running
- pSchedule->ClrRunningStatus (channel);
- if (Tid == 0x4E)
- pSchedule->SetPresentSeen ();
- if (OnlyRunningStatus) {
- LogD(4, prep("OnlyRunningStatus"));
- return;
- }
- if (Modified) {
-// if (!HasExternalData)
- pSchedule->DropOutdated (SegmentStart, SegmentEnd, Tid, getVersionNumber ());
- sortSchedules(Schedules, channel->GetChannelID());
- }
- LogD(4, prep("end of cEIT2"));
+ ////
+ if (Empty && Tid == 0x4E && getSectionNumber () == 0)
+ // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running
+ pSchedule->ClrRunningStatus (channel);
+ if (Tid == 0x4E)
+ pSchedule->SetPresentSeen ();
+ if (OnlyRunningStatus) {
+ LogD(4, prep("OnlyRunningStatus"));
+ return;
+ }
+ if (Modified) {
+ // if (!HasExternalData)
+ pSchedule->DropOutdated (SegmentStart, SegmentEnd, Tid, getVersionNumber ());
+ sortSchedules(Schedules, channel->GetChannelID());
}
- //end of cEIT2
+ LogD(4, prep("end of cEIT2"));
+
+}
+//end of cEIT2
cEIT2::cEIT2 (cSchedule * Schedule)
-: OnlyRunningStatus(false)
-, Empty(true)
+: Empty(true)
, Modified(false)
+, OnlyRunningStatus(false)
, SegmentStart(0)
, SegmentEnd(0)
, Schedules(NULL)
{
- //LogD(2, prep("cEIT2::cEIT2"));
-// if (Tid > 0 && (Format == DISH_BEV || (SetupPE->ProcessEIT && isEITPid))) Tid--;
+ //LogD(2, prep("cEIT2::cEIT2"));
+ // if (Tid > 0 && (Format == DISH_BEV || (SetupPE->ProcessEIT && isEITPid))) Tid--;
- bool searchOtherSatPositions = Format == DISH_BEV;
+ bool searchOtherSatPositions = Format == DISH_BEV;
- tChannelID channelID (Schedule->channelID.Source(), getOriginalNetworkId (), getTransportStreamId (), getServiceId ());
- channel = GetChannelByID (channelID, searchOtherSatPositions);
- if (!channel) {
- LogD(3, prep("!channel channelID: %s"), *channelID.ToString());
- return; // only collect data for known channels
- }
+ tChannelID channelID (Schedule->ChannelID().Source(), getOriginalNetworkId (), getTransportStreamId (), getServiceId ());
+ channel = GetChannelByID (channelID, searchOtherSatPositions);
+ if (!channel) {
+ LogD(3, prep("!channel channelID: %s"), *channelID.ToString());
+ return; // only collect data for known channels
+ }
}
} //end namespace SI
diff --git a/eit2.h b/eit2.h
index e052b2d..7686672 100644
--- a/eit2.h
+++ b/eit2.h
@@ -7,12 +7,12 @@
namespace SI
{
- enum DescriptorTagExt {
- DishRatingDescriptorTag = 0x89,
- DishShortEventDescriptorTag = 0x91,
- DishExtendedEventDescriptorTag = 0x92,
- DishSeriesDescriptorTag = 0x96,
- };
+enum DescriptorTagExt {
+ DishRatingDescriptorTag = 0x89,
+ DishShortEventDescriptorTag = 0x91,
+ DishExtendedEventDescriptorTag = 0x92,
+ DishSeriesDescriptorTag = 0x96,
+};
// typedef InheritEnum< DescriptorTagExt, SI::DescriptorTag > ExtendedDescriptorTag;
@@ -22,28 +22,29 @@ extern bool SystemCharacterTableIsSingleByte;*/
class cEIT2:public SI::EIT
{
public:
- cEIT2 (cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool isEITPid = false, bool OnlyRunningStatus = false);
+ cEIT2(cSchedules * Schedules, int Source, u_char Tid, const u_char * Data, bool isEITPid = false,
+ bool OnlyRunningStatus = false);
cEIT2 (cSchedule * Schedule);
-//protected:
-// void updateEquivalent(cSchedules * Schedules, tChannelID channelID, cEvent *pEvent);
+ //protected:
+ // void updateEquivalent(cSchedules * Schedules, tChannelID channelID, cEvent *pEvent);
cEvent* ProcessEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version);
private:
- void ProcessEventDescriptors(bool ExternalData,
- int Source, u_char Tid, const SI::EIT::Event* SiEitEvent, cEvent* pEvent,
- cSchedules* Schedules, cChannel* channel);
+ void ProcessEventDescriptors(bool ExternalData, int Source, u_char Tid,
+ const SI::EIT::Event* SiEitEvent, cEvent* pEvent,
+ cSchedules* Schedules, cChannel* channel);
private:
- bool Empty;
- bool Modified;
-// bool HasExternalData = false;
- time_t SegmentStart;
- time_t SegmentEnd;
- cSchedules* Schedules;
- cChannel* channel;
+ bool Empty;
+ bool Modified;
+ // bool HasExternalData = false;
+ bool OnlyRunningStatus;
+ time_t SegmentStart;
+ time_t SegmentEnd;
+ cSchedules* Schedules;
+ cChannel* channel;
- bool OnlyRunningStatus;
- };
+};
} //end namespace SI
#endif /* CEIT2_H_ */
diff --git a/log.h b/log.h
index 35942d3..b743763 100644
--- a/log.h
+++ b/log.h
@@ -9,7 +9,8 @@
#define LOG_H_
#include <string>
-#include <stdarg.h>
+#include <vdr/tools.h>
+#include <vdr/thread.h>
#include "setupeepg.h"
#define VERBOSE 1
diff --git a/util.c b/util.c
index c1cc69d..2683131 100644
--- a/util.c
+++ b/util.c
@@ -5,6 +5,8 @@
* Author: d.petrovski
*/
#include "util.h"
+#include "log.h"
+#include "equivhandler.h"
#include <vdr/channels.h>
#include <vdr/thread.h>
#include <vdr/epg.h>
@@ -19,6 +21,12 @@ int Yesterday;
int YesterdayEpoch;
int YesterdayEpochUTC;
+struct hufftab *tables[2][128];
+int table_size[2][128];
+
+EFormat Format;
+cEquivHandler* EquivHandler;
+
cChannel *GetChannelByID(tChannelID & channelID, bool searchOtherPos)
{
cChannel *VC = Channels.GetByChannelID(channelID, true);
@@ -322,5 +330,20 @@ void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize
//LogE(5, prep("decodeText2 buffer %s - buffsize %d"), buffer, buffsize);
}
+void sortSchedules(cSchedules * Schedules, tChannelID channelID){
+
+ LogD(3, prep("Start sortEquivalent %s"), *channelID.ToString());
+
+ cChannel *pChannel = GetChannelByID (channelID, false);
+ cSchedule *pSchedule;
+ if (pChannel) {
+ pSchedule = (cSchedule *) (Schedules->GetSchedule(pChannel, true));
+ pSchedule->Sort();
+ Schedules->SetModified(pSchedule);
+ }
+ if (EquivHandler->getEquiChanMap().count(*channelID.ToString()) > 0)
+ EquivHandler->sortEquivalents(channelID, Schedules);
+}
+
}
diff --git a/util.h b/util.h
index 88e6c62..69c0717 100644
--- a/util.h
+++ b/util.h
@@ -11,9 +11,18 @@
class cChannel;
struct tChannelID;
class cEvent;
+class cEquivHandler;
+class cSchedules;
+
+#define START '\0'
+#define STOP '\0'
+#define ESCAPE '\1'
+
+#define Asprintf(a, b, c...) void( asprintf(a, b, c) < 0 ? esyslog("memory allocation error - %s", b) : void() )
namespace util
{
+
extern int AvailableSources[32];
extern int NumberOfAvailableSources;
@@ -21,41 +30,62 @@ extern int Yesterday;
extern int YesterdayEpoch;
extern int YesterdayEpochUTC;
+extern enum EFormat
+{
+//First all batchmode, load ONCE protocols:
+ MHW1 = 0,
+ MHW2,
+ SKY_IT,
+ SKY_UK,
+ NAGRA,
+//Than all CONTinuous protocols, so they will be processed LAST:
+ PREMIERE,
+ FREEVIEW,
+ DISH_BEV,
+ EIT,
+//the highest number of EPG-formats that is supported by this plugin
+ HIGHEST_FORMAT = EIT
+} Format;
+
+extern cEquivHandler* EquivHandler;
+
void AddEvent(cEvent *event, tChannelID ChannelID);
cChannel *GetChannelByID(tChannelID & channelID, bool searchOtherPos);
-time_t LocalTime2UTC (time_t t);
-time_t UTC2LocalTime (time_t t);
-void GetLocalTimeOffset (void);
-void CleanString (unsigned char *String);
-void decodeText2 (const unsigned char *from, int len, char *buffer, int buffsize);
-char *freesat_huffman_decode (const unsigned char *src, size_t size);
-
-struct sNode
-{
- char *Value;
- struct sNode *P0;
- struct sNode *P1;
-};
+time_t LocalTime2UTC(time_t t);
+time_t UTC2LocalTime(time_t t);
+void GetLocalTimeOffset(void);
+void CleanString(unsigned char *String);
+void decodeText2(const unsigned char *from, int len, char *buffer, int buffsize);
+char *freesat_huffman_decode(const unsigned char *src, size_t size);
+void sortSchedules(cSchedules * Schedules, tChannelID channelID);
-typedef struct sNode sNodeH;
+//struct sNode
+//{
+// char *Value;
+// struct sNode *P0;
+// struct sNode *P1;
+//};
+//
+//typedef struct sNode sNodeH;
-struct hufftab {
+template<class T> T REALLOC(T Var, size_t Size)
+{
+ T p = (T) realloc(Var, Size);
+ if (!p) free(Var);
+ return p;
+}
+
+struct hufftab
+{
unsigned int value;
short bits;
char next;
};
-#define START '\0'
-#define STOP '\0'
-#define ESCAPE '\1'
-
-static struct hufftab *tables[2][128];
-static int table_size[2][128];
-static sNodeH* sky_tables[2];
-
-
-#define Asprintf(a, b, c...) void( asprintf(a, b, c) < 0 ? esyslog("memory allocation error - %s", b) : void() )
+extern struct hufftab *tables[2][128];
+extern int table_size[2][128];
+//static sNodeH* sky_tables[2];
}
#endif /* UTIL_H_ */