summaryrefslogtreecommitdiff
path: root/eit.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2001-08-18 18:00:00 +0200
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2001-08-18 18:00:00 +0200
commit371bf0665eda455c67926999f52b4850cd8529e4 (patch)
tree383f39f92ef1f3846d89e4ae6ad7e39699334f01 /eit.c
parentefea0f64d08052b0189d962101e1a3634d4adfc8 (diff)
downloadvdr-patch-lnbsharing-371bf0665eda455c67926999f52b4850cd8529e4.tar.gz
vdr-patch-lnbsharing-371bf0665eda455c67926999f52b4850cd8529e4.tar.bz2
Version 0.92vdr-0.92
- The "channel not sync'ed" log message now also lists the card number. - Now using the EIT services from 'libdtv' (thanks to Rolf Hakenes), which provides EPG information for NVOD ("Near Video On Demand") channels. - Doing some bug fixing on the EPG data (some tv stations apparently have their own idea on how to fill in the data...). The level up to which EPG bugs are fixed can be controlled with the EPGBugfixLevel parameter in the "Setup" menu (see MANUAL for details, and cEventInfo::FixEpgBugs() in eit.c for the actual implementation). - Fixed broken recordings after a driver buffer overflow. - Fixed the chirping sound after Pause/Play of a DVD (thanks to Andreas Schultz).
Diffstat (limited to 'eit.c')
-rw-r--r--eit.c669
1 files changed, 193 insertions, 476 deletions
diff --git a/eit.c b/eit.c
index 14738f3..d2927cc 100644
--- a/eit.c
+++ b/eit.c
@@ -4,6 +4,9 @@
begin : Fri Aug 25 2000
copyright : (C) 2000 by Robert Schneider
email : Robert.Schneider@web.de
+
+ 2001-08-15: Adapted to 'libdtv' by Rolf Hakenes <hakenes@hippomi.de>
+
***************************************************************************/
/***************************************************************************
@@ -13,7 +16,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: eit.c 1.19 2001/08/12 15:04:37 kls Exp $
+ * $Id: eit.c 1.22 2001/08/19 14:44:32 kls Exp $
***************************************************************************/
#include "eit.h"
@@ -33,6 +36,7 @@
#include <time.h>
#include <unistd.h>
#include "config.h"
+#include "libdtv/libdtv.h"
#include "videodir.h"
// --- cMJD ------------------------------------------------------------------
@@ -144,32 +148,6 @@ time_t cMJD::GetTime_t()
// --- cTDT ------------------------------------------------------------------
-typedef struct {
- u_char table_id : 8;
-
-#if BYTE_ORDER == BIG_ENDIAN
- u_char section_syntax_indicator : 1;
- u_char : 3;
- u_char section_length_hi : 4;
-#else
- u_char section_length_hi : 4;
- u_char : 3;
- u_char section_syntax_indicator : 1;
-#endif
-
- u_char section_length_lo : 8;
-
-
- u_char utc_date_hi : 8;
- u_char utc_date_lo : 8;
- u_char utc_hour : 4;
- u_char utc_hour_ten : 4;
- u_char utc_min : 4;
- u_char utc_min_ten : 4;
- u_char utc_sec : 4;
- u_char utc_sec_ten : 4;
-} tdt_t;
-
class cTDT {
public:
cTDT(tdt_t *ptdt);
@@ -183,11 +161,11 @@ protected: // Protected attributes
cMJD mjd; // kls 2001-03-02: made this a member instead of a pointer (it wasn't deleted in the destructor!)
};
+#define BCD2DEC(b) (((b >> 4) & 0x0F) * 10 + (b & 0x0F))
+
cTDT::cTDT(tdt_t *ptdt)
:tdt(*ptdt)
-,mjd(tdt.utc_date_hi, tdt.utc_date_lo, tdt.utc_hour_ten * 10 + tdt.utc_hour,
- tdt.utc_min_ten * 10 + tdt.utc_min,
- tdt.utc_sec_ten * 10 + tdt.utc_sec)
+,mjd(tdt.utc_mjd_hi, tdt.utc_mjd_lo, BCD2DEC(tdt.utc_time_h), BCD2DEC(tdt.utc_time_m), BCD2DEC(tdt.utc_time_s))
{
}
@@ -212,7 +190,6 @@ cEventInfo::cEventInfo(unsigned short serviceid, unsigned short eventid)
tTime = 0;
uEventID = eventid;
uServiceID = serviceid;
- cExtendedDescriptorNumber = 0;
nChannelNumber = 0;
}
@@ -302,7 +279,7 @@ unsigned short cEventInfo::GetEventID() const
return uEventID;
}
/** */
-bool cEventInfo::SetTitle(char *string)
+bool cEventInfo::SetTitle(const char *string)
{
if (string == NULL)
return false;
@@ -314,7 +291,7 @@ bool cEventInfo::SetTitle(char *string)
return true;
}
/** */
-bool cEventInfo::SetSubtitle(char *string)
+bool cEventInfo::SetSubtitle(const char *string)
{
if (string == NULL)
return false;
@@ -326,7 +303,7 @@ bool cEventInfo::SetSubtitle(char *string)
return true;
}
/** */
-bool cEventInfo::AddExtendedDescription(char *string)
+bool cEventInfo::AddExtendedDescription(const char *string)
{
int size = 0;
bool first = true;
@@ -376,16 +353,6 @@ void cEventInfo::SetServiceID(unsigned short servid)
{
uServiceID = servid;
}
-/** */
-u_char cEventInfo::GetExtendedDescriptorNumber() const
-{
- return cExtendedDescriptorNumber;
-}
-/** */
-void cEventInfo::IncreaseExtendedDescriptorNumber()
-{
- cExtendedDescriptorNumber++;
-}
/** */
unsigned short cEventInfo::GetServiceID() const
@@ -408,6 +375,116 @@ void cEventInfo::Dump(FILE *f, const char *Prefix) const
}
}
+void cEventInfo::FixEpgBugs(void)
+{
+ if (Setup.EPGBugfixLevel == 0)
+ return;
+
+ // Some TV stations apparently have their own idea about how to fill in the
+ // EPG data. Let's fix their bugs as good as we can:
+ if (pTitle) {
+
+ // Pro7 preceeds the Subtitle with the Title:
+ //
+ // Title
+ // Title / Subtitle
+ //
+ if (pSubtitle && strstr(pSubtitle, pTitle) == pSubtitle) {
+ char *p = pSubtitle + strlen(pTitle);
+ const char *delim = " / ";
+ if (strstr(p, delim) == p) {
+ p += strlen(delim);
+ memmove(pSubtitle, p, strlen(p) + 1);
+ }
+ }
+
+ // VOX and VIVA put the Subtitle in quotes and use either the Subtitle
+ // or the Extended Description field, depending on how long the string is:
+ //
+ // Title
+ // "Subtitle". Extended Description
+ //
+ if ((pSubtitle == NULL) != (pExtendedDescription == NULL)) {
+ char *p = pSubtitle ? pSubtitle : pExtendedDescription;
+ if (*p == '"') {
+ const char *delim = "\".";
+ char *e = strstr(p + 1, delim);
+ if (e) {
+ *e = 0;
+ char *s = strdup(p + 1);
+ char *d = strdup(e + strlen(delim));
+ delete pSubtitle;
+ delete pExtendedDescription;
+ pSubtitle = s;
+ pExtendedDescription = d;
+ }
+ }
+ }
+
+ // VOX and VIVA put the Extended Description into the Subtitle (preceeded
+ // by a blank) if there is no actual Subtitle and the Extended Description
+ // is short enough:
+ //
+ // Title
+ // Extended Description
+ //
+ if (pSubtitle && !pExtendedDescription) {
+ if (*pSubtitle == ' ') {
+ memmove(pSubtitle, pSubtitle + 1, strlen(pSubtitle));
+ pExtendedDescription = pSubtitle;
+ pSubtitle = NULL;
+ }
+ }
+ }
+
+ // Pro7 sometimes repeats the Title in the Subtitle:
+ //
+ // Title
+ // Title
+ //
+ if (pSubtitle && strcmp(pTitle, pSubtitle) == 0) {
+ delete pSubtitle;
+ pSubtitle = NULL;
+ }
+
+ if (Setup.EPGBugfixLevel <= 1)
+ return;
+
+ // Some channels apparently try to do some formatting in the texts,
+ // which is a bad idea because they have no way of knowing the width
+ // of the window that will actually display the text.
+ // Remove excess whitespace:
+ pTitle = compactspace(pTitle);
+ pSubtitle = compactspace(pSubtitle);
+ pExtendedDescription = compactspace(pExtendedDescription);
+ // Remove superfluous hyphens:
+ if (pExtendedDescription) {
+ char *p = pExtendedDescription + 1;
+ while (*p) {
+ if (*p == '-' && *(p + 1) == ' ' && *(p + 2) && islower(*(p - 1)) && islower(*(p + 2))) {
+ if (!startswith(p + 2, "und ")) // special case in German, as in "Lach- und Sachgeschichten"
+ memmove(p, p + 2, strlen(p + 2) + 1);
+ }
+ p++;
+ }
+ }
+
+ if (Setup.EPGBugfixLevel <= 2)
+ return;
+
+ // Pro7 and Kabel1 apparently are unable to use a calendar/clock,
+ // because all events between 00:00 and 06:00 have the date of the
+ // day before (sometimes even this correction doesn't help).
+ // Channels are recognized by their ServiceID, which may only work
+ // correctly on the ASTRA satellite system.
+ if (uServiceID == 898 // Pro-7
+ || uServiceID == 899) { // Kabel 1
+ tm *t = localtime(&tTime);
+ if (t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec <= 6 * 3600)
+ tTime += 24 * 3600;
+ }
+}
+
// --- cSchedule -------------------------------------------------------------
cSchedule::cSchedule(unsigned short servid)
@@ -425,7 +502,7 @@ const cEventInfo * cSchedule::GetPresentEvent() const
{
// checking temporal sanity of present event (kls 2000-11-01)
time_t now = time(NULL);
- if (pPresent && !(pPresent->GetTime() <= now && now <= pPresent->GetTime() + pPresent->GetDuration()))
+//XXX if (pPresent && !(pPresent->GetTime() <= now && now <= pPresent->GetTime() + pPresent->GetDuration()))
{
cEventInfo *pe = Events.First();
while (pe != NULL)
@@ -435,6 +512,7 @@ const cEventInfo * cSchedule::GetPresentEvent() const
pe = Events.Next(pe);
}
}
+ return NULL;//XXX
return pPresent;
}
/** */
@@ -443,7 +521,7 @@ const cEventInfo * cSchedule::GetFollowingEvent() const
// checking temporal sanity of following event (kls 2000-11-01)
time_t now = time(NULL);
const cEventInfo *pr = GetPresentEvent(); // must have it verified!
- if (pFollowing && !(pr && pr->GetTime() + pr->GetDuration() <= pFollowing->GetTime()))
+if (pr)//XXX if (pFollowing && !(pr && pr->GetTime() + pr->GetDuration() <= pFollowing->GetTime()))
{
int minDt = INT_MAX;
cEventInfo *pe = Events.First(), *pf = NULL;
@@ -459,6 +537,7 @@ const cEventInfo * cSchedule::GetFollowingEvent() const
}
return pf;
}
+ return NULL;//XXX
return pFollowing;
}
/** */
@@ -491,7 +570,7 @@ const cEventInfo * cSchedule::GetEvent(time_t tTime) const
cEventInfo *pe = Events.First();
while (pe != NULL)
{
- if (pe->GetTime() == tTime)
+ if (pe->GetTime() <= tTime && tTime <= pe->GetTime() + pe->GetDuration())
return pe;
pe = Events.Next(pe);
@@ -536,7 +615,7 @@ void cSchedule::Cleanup(time_t tTime)
pEvent = Events.Get(a);
if (pEvent == NULL)
break;
- if (pEvent->GetTime() + pEvent->GetDuration() < tTime)
+ if (pEvent->GetTime() + pEvent->GetDuration() + 3600 < tTime) // adding one hour for safety
{
Events.Del(pEvent);
a--;
@@ -627,170 +706,28 @@ void cSchedules::Dump(FILE *f, const char *Prefix) const
// --- cEIT ------------------------------------------------------------------
-#define DEC(N) dec << setw(N) << setfill(int('0'))
-#define HEX(N) hex << setw(N) << setfill(int('0'))
-
-#define EIT_STUFFING_DESCRIPTOR 0x42
-#define EIT_LINKAGE_DESCRIPTOR 0x4a
-#define EIT_SHORT_EVENT_DESCRIPTOR 0x4d
-#define EIT_EXTENDED_EVENT_DESCRIPTOR 0x4e
-#define EIT_TIME_SHIFTED_EVENT_DESCRIPTOR 0x4f
-#define EIT_COMPONENT_DESCRIPTOR 0x50
-#define EIT_CA_IDENTIFIER_DESCRIPTOR 0x53
-#define EIT_CONTENT_DESCRIPTOR 0x54
-#define EIT_PARENTAL_RATING_DESCRIPTOR 0x55
-#define EIT_TELEPHONE_DESCRIPTOR 0x57
-#define EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR 0x5e
-#define EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR 0x5f
-#define EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR 0x61
-#define EIT_DATA_BROADCAST_DESCRIPTOR 0x64
-#define EIT_PDC_DESCRIPTOR 0x69
-
-typedef struct eit_struct {
- u_char table_id : 8;
-
-#if BYTE_ORDER == BIG_ENDIAN
- u_char section_syntax_indicator : 1;
- u_char : 3;
- u_char section_length_hi : 4;
-#else
- u_char section_length_hi : 4;
- u_char : 3;
- u_char section_syntax_indicator : 1;
-#endif
-
- u_char section_length_lo : 8;
-
- u_char service_id_hi : 8;
- u_char service_id_lo : 8;
-
-#if BYTE_ORDER == BIG_ENDIAN
- u_char : 2;
- u_char version_number : 5;
- u_char current_next_indicator : 1;
-#else
- u_char current_next_indicator : 1;
- u_char version_number : 5;
- u_char : 2;
-#endif
-
- u_char section_number : 8;
- u_char last_section_number : 8;
- u_char transport_stream_id_hi : 8;
- u_char transport_stream_id_lo : 8;
- u_char original_network_id_hi : 8;
- u_char original_network_id_lo : 8;
- u_char segment_last_section_number : 8;
- u_char segment_last_table_id : 8;
-} eit_t;
-
-typedef struct eit_loop_struct {
- u_char event_id_hi : 8;
- u_char event_id_lo : 8;
-
- u_char date_hi : 8;
- u_char date_lo : 8;
- u_char time_hour : 4;
- u_char time_hour_ten : 4;
- u_char time_minute : 4;
- u_char time_minute_ten : 4;
- u_char time_second : 4;
- u_char time_second_ten : 4;
-
- u_char dur_hour : 4;
- u_char dur_hour_ten : 4;
- u_char dur_minute : 4;
- u_char dur_minute_ten : 4;
- u_char dur_second : 4;
- u_char dur_second_ten : 4;
-
-#if BYTE_ORDER == BIG_ENDIAN
- u_char running_status : 3;
- u_char free_ca_mode : 1;
- u_char descriptors_loop_length_hi : 4;
-#else
- u_char descriptors_loop_length_hi : 4;
- u_char free_ca_mode : 1;
- u_char running_status : 3;
-#endif
-
- u_char descriptors_loop_length_lo : 8;
-} eit_loop_t;
-
-typedef struct eit_short_event_struct {
- u_char descriptor_tag : 8;
- u_char descriptor_length : 8;
-
- u_char language_code_1 : 8;
- u_char language_code_2 : 8;
- u_char language_code_3 : 8;
-
- u_char event_name_length : 8;
-} eit_short_event_t;
-
-typedef struct eit_extended_event_struct {
- u_char descriptor_tag : 8;
- u_char descriptor_length : 8;
-
- u_char last_descriptor_number : 4;
- u_char descriptor_number : 4;
-
- u_char language_code_1 : 8;
- u_char language_code_2 : 8;
- u_char language_code_3 : 8;
-
- u_char length_of_items : 8;
-} eit_extended_event_t;
-
-typedef struct eit_content_descriptor {
- u_char descriptor_tag : 8;
- u_char descriptor_length : 8;
-} eit_content_descriptor_t;
-
-typedef struct eit_content_loop {
- u_char content_nibble_level_2 : 4;
- u_char content_nibble_level_1 : 4;
- u_char user_nibble_2 : 4;
- u_char user_nibble_1 : 4;
-} eit_content_loop_t;
-
class cEIT {
private:
cSchedules *schedules;
public:
- cEIT(void *buf, int length, cSchedules *Schedules);
+ cEIT(unsigned char *buf, int length, cSchedules *Schedules);
~cEIT();
/** */
- int ProcessEIT();
+ int ProcessEIT(unsigned char *buffer);
protected: // Protected methods
- /** */
- int strdvbcpy(unsigned char *dst, unsigned char *src, int max);
/** returns true if this EIT covers a
present/following information, false if it's
schedule information */
bool IsPresentFollowing();
- /** */
- bool WriteShortEventDescriptor(unsigned short service, eit_loop_t *eitloop, u_char *buf);
- /** */
- bool WriteExtEventDescriptor(unsigned short service, eit_loop_t *eitloop, u_char *buf);
protected: // Protected attributes
- int buflen;
-protected: // Protected attributes
- /** */
- u_char buffer[4097];
/** Table ID of this EIT struct */
u_char tid;
- /** EITs service id (program number) */
- u_short pid;
};
-cEIT::cEIT(void * buf, int length, cSchedules *Schedules)
+cEIT::cEIT(unsigned char * buf, int length, cSchedules *Schedules)
{
- buflen = length < int(sizeof(buffer)) ? length : sizeof(buffer);
- memset(buffer, 0, sizeof(buffer));
- memcpy(buffer, buf, buflen);
- tid = buffer[0];
+ tid = buf[0];
schedules = Schedules;
}
@@ -799,162 +736,72 @@ cEIT::~cEIT()
}
/** */
-int cEIT::ProcessEIT()
-{
- int bufact = 0;
- eit_t *eit;
- eit_loop_t *eitloop;
- u_char tmp[256];
-
- if (bufact + (int)sizeof(eit_t) > buflen)
- return 0;
- eit = (eit_t *)buffer;
- bufact += sizeof(eit_t);
-
- unsigned int service = (eit->service_id_hi << 8) | eit->service_id_lo;
-
- while(bufact + (int)sizeof(eit_loop_t) <= buflen)
- {
- eitloop = (eit_loop_t *)&buffer[bufact];
- bufact += sizeof(eit_loop_t);
-
- int descdatalen = (eitloop->descriptors_loop_length_hi << 8) + eitloop->descriptors_loop_length_lo;
- int descdataact = 0;
-
- while (descdataact < descdatalen && bufact < buflen)
- {
- switch (buffer[bufact])
- {
- eit_content_descriptor_t *cont;
- eit_content_loop_t *contloop;
-
- case EIT_STUFFING_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_STUFFING_DESCRIPTOR");
- break;
-
- case EIT_LINKAGE_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_LINKAGE_DESCRIPTOR");
- break;
-
- case EIT_SHORT_EVENT_DESCRIPTOR:
- WriteShortEventDescriptor(service, eitloop, &buffer[bufact]);
- break;
-
- case EIT_EXTENDED_EVENT_DESCRIPTOR:
- WriteExtEventDescriptor(service, eitloop, &buffer[bufact]);
- break;
-
- case EIT_TIME_SHIFTED_EVENT_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_TIME_SHIFTED_EVENT_DESCRIPTOR");
- break;
-
- case EIT_COMPONENT_DESCRIPTOR :
- if (buffer[bufact + 1] > 6) // kls 2001-02-24: otherwise strncpy() causes a segfault in strdvbcpy()
- strdvbcpy(tmp, &buffer[bufact + 8], buffer[bufact + 1] - 6);
- //dsyslog(LOG_INFO, "Found EIT_COMPONENT_DESCRIPTOR %c%c%c 0x%02x/0x%02x/0x%02x '%s'\n", buffer[bufact + 5], buffer[bufact + 6], buffer[bufact + 7], buffer[2], buffer[3], buffer[4], tmp);
- break;
-
- case EIT_CA_IDENTIFIER_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_CA_IDENTIFIER_DESCRIPTOR");
- break;
-
- case EIT_CONTENT_DESCRIPTOR :
- cont = (eit_content_descriptor_t *)buffer;
- contloop = (eit_content_loop_t *)&buffer[sizeof(eit_content_descriptor_t)];
- //dsyslog(LOG_INFO, "Found EIT_CONTENT_DESCRIPTOR 0x%02x/0x%02x\n", contloop->content_nibble_level_1, contloop->content_nibble_level_2);
- break;
-
- case EIT_PARENTAL_RATING_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_PARENTAL_RATING_DESCRIPTOR");
- break;
-
- case EIT_TELEPHONE_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_TELEPHONE_DESCRIPTOR");
- break;
-
- case EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_MULTILINGUAL_COMPONENT_DESCRIPTOR");
- break;
-
- case EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_PRIVATE_DATE_SPECIFIER_DESCRIPTOR");
- break;
-
- case EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_SHORT_SMOOTHING_BUFFER_DESCRIPTOR");
- break;
-
- case EIT_DATA_BROADCAST_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_DATA_BROADCAST_DESCRIPTOR");
- break;
-
- case EIT_PDC_DESCRIPTOR :
- //dsyslog(LOG_INFO, "Found EIT_PDC_DESCRIPTOR");
- break;
-
- default:
- //dsyslog(LOG_INFO, "Found unhandled descriptor 0x%02x with length of %04d\n", (int)buffer[bufact], (int)buffer[bufact + 1]);
- break;
- }
- descdataact += (buffer[bufact + 1] + 2);
- bufact += (buffer[bufact + 1] + 2);
+int cEIT::ProcessEIT(unsigned char *buffer)
+{
+ cEventInfo *pEvent, *rEvent = NULL;
+ cSchedule *pSchedule, *rSchedule = NULL;
+ struct LIST *VdrProgramInfos;
+ struct VdrProgramInfo *VdrProgramInfo;
+
+ if (!buffer)
+ return -1;
+
+ VdrProgramInfos = createVdrProgramInfos(buffer);
+
+ if (VdrProgramInfos) {
+ for (VdrProgramInfo = (struct VdrProgramInfo *) VdrProgramInfos->Head; VdrProgramInfo; VdrProgramInfo = (struct VdrProgramInfo *) xSucc (VdrProgramInfo)) {
+ pSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ServiceID);
+ if (!pSchedule) {
+ schedules->Add(new cSchedule(VdrProgramInfo->ServiceID));
+ pSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ServiceID);
+ if (!pSchedule)
+ break;
+ }
+ if (VdrProgramInfo->ReferenceServiceID) {
+ rSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ReferenceServiceID);
+ if (!rSchedule)
+ break;
+ rEvent = (cEventInfo *)rSchedule->GetEvent((unsigned short)VdrProgramInfo->ReferenceEventID);
+ if (!rEvent)
+ break;
+ }
+ pEvent = (cEventInfo *)pSchedule->GetEvent((unsigned short)VdrProgramInfo->EventID);
+ if (!pEvent) {
+ pSchedule->Events.Add(new cEventInfo(VdrProgramInfo->ServiceID, VdrProgramInfo->EventID));
+ pEvent = (cEventInfo *)pSchedule->GetEvent((unsigned short)VdrProgramInfo->EventID);
+ if (!pEvent)
+ break;
+ if (rEvent) {
+ pEvent->SetTitle(rEvent->GetTitle());
+ pEvent->SetSubtitle(rEvent->GetSubtitle());
+ pEvent->SetTime(VdrProgramInfo->StartTime);
+ pEvent->SetDuration(VdrProgramInfo->Duration);
+ pEvent->AddExtendedDescription(rEvent->GetExtendedDescription());
+ pEvent->FixEpgBugs();
+ }
+ else {
+ pEvent->SetTitle(VdrProgramInfo->ShortName);
+ pEvent->SetSubtitle(VdrProgramInfo->ShortText);
+ pEvent->SetTime(VdrProgramInfo->StartTime);
+ pEvent->SetDuration(VdrProgramInfo->Duration);
+ pEvent->AddExtendedDescription(VdrProgramInfo->ExtendedName);
+ pEvent->AddExtendedDescription(VdrProgramInfo->ExtendedText);
+ pEvent->FixEpgBugs();
+ }
+ }
+ if (IsPresentFollowing()) {
+ if ((GetRunningStatus(VdrProgramInfo->Status) == RUNNING_STATUS_PAUSING) || (GetRunningStatus(VdrProgramInfo->Status) == RUNNING_STATUS_RUNNING))
+ pSchedule->SetPresentEvent(pEvent);
+ else if (GetRunningStatus(VdrProgramInfo->Status) == RUNNING_STATUS_AWAITING)
+ pSchedule->SetFollowingEvent(pEvent);
+ }
+ }
}
- }
+ xMemFreeAll(NULL);
return 0;
}
-/** */
-int cEIT::strdvbcpy(unsigned char *dst, unsigned char *src, int max)
-{
- int a = 0;
-
- // kls 2001-02-24: if we come in with negative values, the caller must
- // have done something wrong and the strncpy() below will cause a segfault
- if (max <= 0)
- {
- *dst = 0;
- return 0;
- }
-
- if (*src == 0x05 || (*src >= 0x20 && *src <= 0xff))
- {
- for (a = 0; a < max; a++)
- {
- if (*src == 0)
- break;
-
- if ((*src >= ' ' && *src <= '~') || (*src >= 0xa0 && *src <= 0xff))
- *dst++ = *src++;
- else
- {
- // if ((*src > '~' && *src < 0xa0) || *src == 0xff)
- // cerr << "found special character 0x" << HEX(2) << (int)*src << endl;
- src++;
- }
- }
- *dst = 0;
- }
- else
- {
- const char *ret;
-
- switch (*src)
- {
- case 0x01: ret = "Coding according to character table 1"; break;
- case 0x02: ret = "Coding according to character table 2"; break;
- case 0x03: ret = "Coding according to character table 3"; break;
- case 0x04: ret = "Coding according to character table 4"; break;
- case 0x10: ret = "Coding according to ISO/IEC 8859"; break;
- case 0x11: ret = "Coding according to ISO/IEC 10646"; break;
- case 0x12: ret = "Coding according to KSC 5601"; break;
- default: ret = "Unknown coding"; break;
- }
- strncpy((char *)dst, ret, max);
- }
- return a;
-}
-
/** returns true if this EIT covers a
present/following information, false if it's
schedule information */
@@ -966,136 +813,6 @@ bool cEIT::IsPresentFollowing()
return false;
}
-/** */
-bool cEIT::WriteShortEventDescriptor(unsigned short service, eit_loop_t *eitloop, u_char *buf)
-{
- u_char tmp[256];
- eit_short_event_t *evt = (eit_short_event_t *)buf;
- unsigned short eventid = (unsigned short)((eitloop->event_id_hi << 8) | eitloop->event_id_lo);
- cEventInfo *pEvent;
-
- //isyslog(LOG_INFO, "Found Short Event Descriptor");
-
- cSchedule *pSchedule = (cSchedule *)schedules->GetSchedule(service);
- if (pSchedule == NULL)
- {
- schedules->Add(new cSchedule(service));
- pSchedule = (cSchedule *)schedules->GetSchedule(service);
- if (pSchedule == NULL)
- return false;
- }
-
- /* cSchedule::GetPresentEvent() and cSchedule::GetFollowingEvent() verify
- the temporal sanity of these events, so calling them here appears to
- be a bad idea... (kls 2000-11-01)
- //
- // if we are working on a present/following info, let's see whether
- // we already have present/following info for this service and if yes
- // check whether it's the same eventid, if yes, just return, nothing
- // left to do.
- //
- if (IsPresentFollowing())
- {
- if (eitloop->running_status == 4 || eitloop->running_status == 3)
- pEvent = (cEventInfo *)pSchedule->GetPresentEvent();
- else
- pEvent = (cEventInfo *)pSchedule->GetFollowingEvent();
-
- if (pEvent != NULL)
- if (pEvent->GetEventID() == eventid)
- return true;
- }
- */
-
- //
- // let's see whether we have that eventid already
- // in case not, we have to create a new cEventInfo for it
- //
- pEvent = (cEventInfo *)pSchedule->GetEvent(eventid);
- if (pEvent == NULL)
- {
- pSchedule->Events.Add(new cEventInfo(service, eventid));
- pEvent = (cEventInfo *)pSchedule->GetEvent(eventid);
- if (pEvent == NULL)
- return false;
-
- strdvbcpy(tmp, &buf[sizeof(eit_short_event_t)], evt->event_name_length);
- pEvent->SetTitle((char *)tmp);
- strdvbcpy(tmp, &buf[sizeof(eit_short_event_t) + evt->event_name_length + 1],
- (int)buf[sizeof(eit_short_event_t) + evt->event_name_length]);
- pEvent->SetSubtitle((char *)tmp);
- cMJD mjd(eitloop->date_hi, eitloop->date_lo,
- eitloop->time_hour_ten * 10 + eitloop->time_hour,
- eitloop->time_minute_ten * 10 + eitloop->time_minute,
- eitloop->time_second_ten * 10 + eitloop->time_second);
- pEvent->SetTime(mjd.GetTime_t());
- pEvent->SetDuration((long)((long)((eitloop->dur_hour_ten * 10 + eitloop->dur_hour) * 60l * 60l) +
- (long)((eitloop->dur_minute_ten * 10 + eitloop->dur_minute) * 60l) +
- (long)(eitloop->dur_second_ten * 10 + eitloop->dur_second)));
- }
-
- if (IsPresentFollowing())
- {
- if (eitloop->running_status == 4 || eitloop->running_status == 3)
- pSchedule->SetPresentEvent(pEvent);
- else if (eitloop->running_status == 1 || eitloop->running_status == 2 || eitloop->running_status == 0)
- pSchedule->SetFollowingEvent(pEvent);
- }
-
- return true;
-}
-
-/** */
-bool cEIT::WriteExtEventDescriptor(unsigned short service, eit_loop_t *eitloop, u_char *buf)
-{
- u_char tmp[256];
- eit_extended_event_t *evt = (eit_extended_event_t *)buf;
- int bufact, buflen;
- unsigned short eventid = (unsigned short)((eitloop->event_id_hi << 8) | eitloop->event_id_lo);
- cEventInfo *pEvent;
-
- //isyslog(LOG_INFO, "Found Extended Event Descriptor");
-
- cSchedule *pSchedule = (cSchedule *)schedules->GetSchedule(service);
- if (pSchedule == NULL)
- {
- schedules->Add(new cSchedule(service));
- pSchedule = (cSchedule *)schedules->GetSchedule(service);
- if (pSchedule == NULL)
- return false;
- }
-
- pEvent = (cEventInfo *)pSchedule->GetEvent(eventid);
- if (pEvent == NULL)
- return false;
-
- if (evt->descriptor_number != pEvent->GetExtendedDescriptorNumber())
- return false;
-
- bufact = sizeof(eit_extended_event_t);
- buflen = buf[1] + 2;
-
- if (evt->length_of_items > 0)
- {
- while (bufact - sizeof(eit_extended_event_t) < evt->length_of_items)
- {
- strdvbcpy(tmp, &buf[bufact + 1], (int)buf[bufact]);
- // could use value in tmp now to do something,
- // haven't seen any items as of yet transmitted from satellite
- bufact += (buf[bufact] + 1);
- }
- }
-
- strdvbcpy(tmp, &buf[bufact + 1], (int)buf[bufact]);
- if (pEvent->AddExtendedDescription((char *)tmp))
- {
- pEvent->IncreaseExtendedDescriptorNumber();
- return true;
- }
-
- return false;
-}
-
// --- cSIProcessor ----------------------------------------------------------
#define MAX_FILTERS 20
@@ -1262,7 +979,7 @@ void cSIProcessor::Action()
schedulesMutex.Lock();
cEIT ceit(buf, seclen, schedules);
- ceit.ProcessEIT();
+ ceit.ProcessEIT(buf);
schedulesMutex.Unlock();
}
else