From 371bf0665eda455c67926999f52b4850cd8529e4 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 18 Aug 2001 18:00:00 +0200 Subject: Version 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). --- CONTRIBUTORS | 3 + HISTORY | 14 + MANUAL | 18 + Makefile | 19 +- config.c | 5 +- config.h | 5 +- dvbapi.c | 24 +- eit.c | 669 ++++++--------------- eit.h | 15 +- i18n.c | 11 +- libdtv/COPYING | 339 +++++++++++ libdtv/Makefile | 73 +++ libdtv/README | 27 + libdtv/liblx/COPYING | 339 +++++++++++ libdtv/liblx/Makefile | 62 ++ libdtv/liblx/liblx.h | 448 ++++++++++++++ libdtv/liblx/xListFuncs.c | 187 ++++++ libdtv/liblx/xMemMgt.c | 621 ++++++++++++++++++++ libdtv/libsi/COPYING | 339 +++++++++++ libdtv/libsi/Makefile | 83 +++ libdtv/libsi/README | 2 + libdtv/libsi/include/libsi.h | 816 ++++++++++++++++++++++++++ libdtv/libsi/include/si_tables.h | 1205 ++++++++++++++++++++++++++++++++++++++ libdtv/libsi/si_debug_services.c | 487 +++++++++++++++ libdtv/libsi/si_debug_services.h | 217 +++++++ libdtv/libsi/si_parser.c | 881 ++++++++++++++++++++++++++++ libdtv/libvdr/COPYING | 339 +++++++++++ libdtv/libvdr/Makefile | 62 ++ libdtv/libvdr/libvdr.c | 169 ++++++ libdtv/libvdr/libvdr.h | 111 ++++ menu.c | 38 +- menu.h | 4 +- remux.c | 21 +- tools.c | 28 +- tools.h | 4 +- 35 files changed, 7179 insertions(+), 506 deletions(-) create mode 100644 libdtv/COPYING create mode 100644 libdtv/Makefile create mode 100644 libdtv/README create mode 100644 libdtv/liblx/COPYING create mode 100644 libdtv/liblx/Makefile create mode 100644 libdtv/liblx/liblx.h create mode 100644 libdtv/liblx/xListFuncs.c create mode 100644 libdtv/liblx/xMemMgt.c create mode 100644 libdtv/libsi/COPYING create mode 100644 libdtv/libsi/Makefile create mode 100644 libdtv/libsi/README create mode 100644 libdtv/libsi/include/libsi.h create mode 100644 libdtv/libsi/include/si_tables.h create mode 100644 libdtv/libsi/si_debug_services.c create mode 100644 libdtv/libsi/si_debug_services.h create mode 100644 libdtv/libsi/si_parser.c create mode 100644 libdtv/libvdr/COPYING create mode 100644 libdtv/libvdr/Makefile create mode 100644 libdtv/libvdr/libvdr.c create mode 100644 libdtv/libvdr/libvdr.h diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 241c861..c055c17 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -129,3 +129,6 @@ Artur Skawina Werner Fink for making I/O more robust by handling EINTR + +Rolf Hakenes + for providing 'libdtv' and adapting the EIT mechanisms to it diff --git a/HISTORY b/HISTORY index 715b668..b76067b 100644 --- a/HISTORY +++ b/HISTORY @@ -649,3 +649,17 @@ Video Disk Recorder Revision History - If there is no free DVB device to record, the log message will now be given only once. - Made I/O more robust by handling EINTR (thanks to Werner Fink). + +2001-08-18: Version 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). diff --git a/MANUAL b/MANUAL index 17f0248..9d77481 100644 --- a/MANUAL +++ b/MANUAL @@ -351,6 +351,24 @@ Video Disk Recorder User's Manual A value of '0' completely turns off scanning on both single and multiple card systems. + EPGBugfixLevel = 2 Some tv stations transmit weirdly formatted EPG data. + VDR attempts to fix these bugs up to the given level: + 0 = no EPG fixing + 1 = basic fixing of text location (Title, Subtitle and + Extended Description) + 2 = removal of excess whitespace and hyphens + 3 = fixing the date in timestamps between 00:00 and 06:00 + (use with care - hopefully one day Pro7 and Kabel1 + will learn how to read the clock/calender) + Default is '2', which will do all textual fixes, but + leaves out the timestamp fixes, since these might cause + recordings to fail. Use '3' at your own risk. + Note that after changing the setting of this parameter + any EPG data that has already been received will remain + in its existing format - only newly received data will + be fixed accordingly. Restart VDR if you want to make sure + all data is fixed. + SVDRPTimeout = 300 The time (in seconds) of inactivity on an open SVDRP connection after which the connection is automatically closed. Default is 300, a value of 0 means no timeout. diff --git a/Makefile b/Makefile index 7fcc62a..067f34a 100644 --- a/Makefile +++ b/Makefile @@ -4,16 +4,19 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.25 2001/08/10 16:46:45 kls Exp $ +# $Id: Makefile 1.26 2001/08/15 13:56:11 kls Exp $ .DELETE_ON_ERROR: DVBDIR = ../DVB DVDDIR = ../DVD AC3DIR = ./ac3dec +DTVDIR = ./libdtv INCLUDES = -I$(DVBDIR)/ost/include +DTVLIB = $(DTVDIR)/libdtv.a + ifdef DVD INCLUDES += -I$(DVDDIR)/libdvdread LIBDIRS += -L$(DVDDIR)/libdvdread/dvdread/.libs @@ -57,10 +60,10 @@ font: genfontfile fontfix.c fontosd.c # Dependencies: config.o : config.c config.h dvbapi.h dvbosd.h dvd.h eit.h font.h i18n.h interface.h remote.h svdrp.h thread.h tools.h -dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h dvd.h eit.h font.h recording.h remux.h ringbuffer.h thread.h tools.h videodir.h +dvbapi.o : dvbapi.c $(AC3DIR)/ac3.h config.h dvbapi.h dvbosd.h dvd.h eit.h font.h recording.h remux.h ringbuffer.h thread.h tools.h videodir.h dvbosd.o : dvbosd.c dvbosd.h font.h tools.h dvd.o : dvd.c dvd.h -eit.o : eit.c config.h dvbapi.h dvbosd.h dvd.h eit.h font.h thread.h tools.h videodir.h +eit.o : eit.c config.h dvbapi.h dvbosd.h dvd.h eit.h font.h $(DTVDIR)/libdtv.h thread.h tools.h videodir.h font.o : font.c font.h fontfix.c fontosd.c tools.h i18n.o : i18n.c config.h dvbapi.h dvbosd.h dvd.h eit.h font.h i18n.h thread.h tools.h interface.o : interface.c config.h dvbapi.h dvbosd.h dvd.h eit.h font.h i18n.h interface.h remote.h svdrp.h thread.h tools.h @@ -78,8 +81,8 @@ videodir.o : videodir.c tools.h videodir.h # The main program: -vdr: $(OBJS) $(AC3LIB) - g++ -g -O2 $(OBJS) -lncurses -ljpeg -lpthread $(LIBDIRS) $(DVDLIB) $(AC3LIB) -o vdr +vdr: $(OBJS) $(AC3LIB) $(DTVLIB) + g++ -g -O2 $(OBJS) -lncurses -ljpeg -lpthread $(LIBDIRS) $(DVDLIB) $(AC3LIB) $(DTVLIB) -o vdr # The font files: @@ -98,10 +101,16 @@ genfontfile: genfontfile.c $(AC3LIB): make -C $(AC3DIR) all +# The libdtv library: + +$(DTVLIB) $(DTVDIR)/libdtv.h: + make -C $(DTVDIR) all + # Housekeeping: clean: make -C $(AC3DIR) clean + make -C $(DTVDIR) clean -rm -f $(OBJS) vdr genfontfile genfontfile.o core *~ fontclean: -rm -f fontfix.c fontosd.c diff --git a/config.c b/config.c index 27cd62e..aed3254 100644 --- a/config.c +++ b/config.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.54 2001/08/11 15:34:42 kls Exp $ + * $Id: config.c 1.55 2001/08/17 13:02:01 kls Exp $ */ #include "config.h" @@ -774,6 +774,7 @@ cSetup::cSetup(void) MarginStart = 2; MarginStop = 10; EPGScanTimeout = 5; + EPGBugfixLevel = 2; SVDRPTimeout = 300; PrimaryLimit = 0; DefaultPriority = 50; @@ -804,6 +805,7 @@ bool cSetup::Parse(char *s) else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value); else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value); else if (!strcasecmp(Name, "EPGScanTimeout")) EPGScanTimeout = atoi(Value); + else if (!strcasecmp(Name, "EPGBugfixLevel")) EPGBugfixLevel = atoi(Value); else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value); else if (!strcasecmp(Name, "PrimaryLimit")) PrimaryLimit = atoi(Value); else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value); @@ -869,6 +871,7 @@ bool cSetup::Save(const char *FileName) fprintf(f, "MarginStart = %d\n", MarginStart); fprintf(f, "MarginStop = %d\n", MarginStop); fprintf(f, "EPGScanTimeout = %d\n", EPGScanTimeout); + fprintf(f, "EPGBugfixLevel = %d\n", EPGBugfixLevel); fprintf(f, "SVDRPTimeout = %d\n", SVDRPTimeout); fprintf(f, "PrimaryLimit = %d\n", PrimaryLimit); fprintf(f, "DefaultPriority = %d\n", DefaultPriority); diff --git a/config.h b/config.h index c9faf6c..ce77598 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.59 2001/08/11 15:28:21 kls Exp $ + * $Id: config.h 1.61 2001/08/17 13:00:48 kls Exp $ */ #ifndef __CONFIG_H @@ -19,7 +19,7 @@ #include "eit.h" #include "tools.h" -#define VDRVERSION "0.91" +#define VDRVERSION "0.92" #define MaxBuffer 10000 @@ -280,6 +280,7 @@ public: int SetSystemTime; int MarginStart, MarginStop; int EPGScanTimeout; + int EPGBugfixLevel; int SVDRPTimeout; int PrimaryLimit; int DefaultPriority, DefaultLifetime; diff --git a/dvbapi.c b/dvbapi.c index 4c38610..6ff39b3 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -7,7 +7,7 @@ * DVD support initially written by Andreas Schultz * based on dvdplayer-0.5 by Matjaz Thaler * - * $Id: dvbapi.c 1.106 2001/08/12 15:09:42 kls Exp $ + * $Id: dvbapi.c 1.109 2001/08/19 15:09:48 kls Exp $ */ //#define DVDDEBUG 1 @@ -545,9 +545,13 @@ void cRecordBuffer::Input(void) } else if (r < 0) { if (FATALERRNO) { - LOG_ERROR; - if (errno != EBUFFEROVERFLOW) + if (errno == EBUFFEROVERFLOW) { // this error code is not defined in the library + esyslog(LOG_ERR, "ERROR (%s,%d): DVB driver buffer overflow", __FILE__, __LINE__); + } + else { + LOG_ERROR; break; + } } } if (time(NULL) - t > MAXBROKENTIMEOUT) { @@ -752,7 +756,7 @@ void cPlayBuffer::Pause(void) Empty(true); fastForward = fastRewind = false; CHECK(ioctl(videoDev, paused ? VIDEO_FREEZE : VIDEO_CONTINUE)); - CHECK(ioctl(audioDev, AUDIO_SET_MUTE, paused)); + //CHECK(ioctl(audioDev, AUDIO_SET_MUTE, paused)); //XXX this caused chirping sound when playing a DVD still = false; if (empty) Empty(false); @@ -767,7 +771,7 @@ void cPlayBuffer::Play(void) still = false; CHECK(ioctl(videoDev, paused ? VIDEO_CONTINUE : VIDEO_PLAY)); CHECK(ioctl(audioDev, AUDIO_SET_AV_SYNC, true)); - CHECK(ioctl(audioDev, AUDIO_SET_MUTE, false)); + //CHECK(ioctl(audioDev, AUDIO_SET_MUTE, false)); //XXX this caused chirping sound when playing a DVD if (empty) Empty(false); fastForward = fastRewind = paused = false; @@ -2075,9 +2079,13 @@ void cTransferBuffer::Input(void) } else if (r < 0) { if (FATALERRNO) { - LOG_ERROR; - if (errno != EBUFFEROVERFLOW) + if (errno == EBUFFEROVERFLOW) { // this error code is not defined in the library + esyslog(LOG_ERR, "ERROR (%s,%d): DVB driver buffer overflow", __FILE__, __LINE__); + } + else { + LOG_ERROR; break; + } } } } @@ -3160,7 +3168,7 @@ bool cDvbApi::SetChannel(int ChannelNumber, int FrequencyMHz, char Polarization, } if (!ChannelSynced) { - esyslog(LOG_ERR, "ERROR: channel %d not sync'ed!", ChannelNumber); + esyslog(LOG_ERR, "ERROR: channel %d not sync'ed on DVB card %d!", ChannelNumber, CardIndex() + 1); if (this == PrimaryDvbApi) cThread::RaisePanic(); return false; 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 + ***************************************************************************/ /*************************************************************************** @@ -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 #include #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 diff --git a/eit.h b/eit.h index d4ba69f..8ca5f1e 100644 --- a/eit.h +++ b/eit.h @@ -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 + ***************************************************************************/ /*************************************************************************** @@ -13,7 +16,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.h 1.8 2001/08/11 09:06:17 kls Exp $ + * $Id: eit.h 1.10 2001/08/15 15:47:31 kls Exp $ ***************************************************************************/ #ifndef __EIT_H @@ -35,19 +38,17 @@ private: unsigned short uEventID; // Event ID of this event long lDuration; // duration of event in seconds time_t tTime; // Start time - u_char cExtendedDescriptorNumber; // current extended descriptor number that has to be inserted int nChannelNumber; // the actual channel number from VDR's channel list (used in cMenuSchedule for sorting by channel number) protected: void SetFollowing(bool foll); void SetPresent(bool pres); - bool SetTitle(char *string); + bool SetTitle(const char *string); void SetServiceID(unsigned short servid); void SetEventID(unsigned short evid); void SetDuration(long l); void SetTime(time_t t); - bool AddExtendedDescription(char *string); - bool SetSubtitle(char *string); - void IncreaseExtendedDescriptorNumber(void); + bool AddExtendedDescription(const char *string); + bool SetSubtitle(const char *string); cEventInfo(unsigned short serviceid, unsigned short eventid); public: ~cEventInfo(); @@ -62,11 +63,11 @@ public: unsigned short GetEventID(void) const; long GetDuration(void) const; time_t GetTime(void) const; - u_char GetExtendedDescriptorNumber(void) const; unsigned short GetServiceID(void) const; int GetChannelNumber(void) const { return nChannelNumber; } void SetChannelNumber(int ChannelNumber) const { ((cEventInfo *)this)->nChannelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const' void Dump(FILE *f, const char *Prefix = "") const; + void FixEpgBugs(void); }; class cSchedule : public cListObject { diff --git a/i18n.c b/i18n.c index 3d75c24..9878228 100644 --- a/i18n.c +++ b/i18n.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.31 2001/08/11 13:22:24 kls Exp $ + * $Id: i18n.c 1.32 2001/08/17 13:03:15 kls Exp $ * * Slovenian translations provided by Miha Setina * Italian translations provided by Alberto Carraro @@ -776,6 +776,15 @@ const tPhrase Phrases[] = { "Temps maxi EPG", "Ledig tid før EPG-søk", }, + { "EPGBugfixLevel", + "EPG Fehlerbereinigung", + "", // TODO + "", // TODO + "", // TODO + "", // TODO + "", // TODO + "", // TODO + }, { "SVDRPTimeout", "SVDRP Timeout", "", // TODO diff --git a/libdtv/COPYING b/libdtv/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/libdtv/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libdtv/Makefile b/libdtv/Makefile new file mode 100644 index 0000000..50a1400 --- /dev/null +++ b/libdtv/Makefile @@ -0,0 +1,73 @@ +############################################################## +### ### +### Makefile: global makefile for libdtv ### +### ### +############################################################## + +## $Revision: 1.1 $ +## $Date: 2001/06/25 12:53:00 $ +## $Author: kls $ +## +## (C) 2001 Rolf Hakenes , under the GNU GPL. +## +## libdtv is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2, or (at your option) +## any later version. +## +## libdtv is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You may have received a copy of the GNU General Public License +## along with libdtv; see the file COPYING. If not, write to the +## Free Software Foundation, Inc., 59 Temple Place - Suite 330, +## Boston, MA 02111-1307, USA. +# +# +# + +# +# adapt this to your GNU make executable +# +MAKE = make + +AR = ar +ARFLAGS = ru +RANLIB = ranlib + +SUBDIRS = liblx libsi libvdr + +all: newdist + +new: clean newdist + +clean: + @echo "making all clean..." + @for i in $(SUBDIRS);\ + do \ + ( echo $$i; cd $$i ;\ + $(MAKE) clean ) ;\ + done + @rm -rf lib include libdtv.* + +newdist: + @mkdir -p include lib + @echo "making all distributions..." + @for i in $(SUBDIRS) ;\ + do \ + ( cd $$i ;\ + $(MAKE) new dist ) ;\ + done + @echo "making libdtv.a/libdtv.h..." + @cat include/* > libdtv.h + @mkdir -p tmp + @for i in $(SUBDIRS) ;\ + do \ + ( cd tmp;\ + $(AR) x ../lib/$$i.a;\ + $(AR) $(ARFLAGS) ../libdtv.a *;\ + rm -f *) ;\ + done + @rm -rf lib include tmp diff --git a/libdtv/README b/libdtv/README new file mode 100644 index 0000000..88ee049 --- /dev/null +++ b/libdtv/README @@ -0,0 +1,27 @@ +DTV System Information Library +============================== + +This is intended to support the VDR application of Klaus Schmidinger with +extended EIT support, mainly on NVOD channels. +Bug reports and suggestions are very appreciated and should be sent to +hakenes@hippomi.de + +Have fun, + + (C) 2001 Rolf Hakenes , under the GNU GPL. + +libdtv is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +libdtv is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You may have received a copy of the GNU General Public License +along with libdtv; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. + diff --git a/libdtv/liblx/COPYING b/libdtv/liblx/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/libdtv/liblx/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libdtv/liblx/Makefile b/libdtv/liblx/Makefile new file mode 100644 index 0000000..a8034de --- /dev/null +++ b/libdtv/liblx/Makefile @@ -0,0 +1,62 @@ +############################################################## +### ### +### Makefile: local makefile for liblx ### +### ### +############################################################## + +## $Revision: 1.1 $ +## $Date: 2001/06/26 07:18:42 $ +## $Author: kls $ +## +## (C) 2001 Rolf Hakenes , under the GNU GPL. +## +## dtv_scan is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2, or (at your option) +## any later version. +## +## dtv_scan is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You may have received a copy of the GNU General Public License +## along with dtv_scan; see the file COPYING. If not, write to the +## Free Software Foundation, Inc., 59 Temple Place - Suite 330, +## Boston, MA 02111-1307, USA. +# +# +# +CC = gcc +CFLAGS = -O2 -g -pedantic -Wmissing-prototypes -Wstrict-prototypes \ + -Wimplicit -D__USE_FIXED_PROTOTYPES__ # -DDEBUG + + +AR = ar +ARFLAGS = r +RANLIB = ranlib +RM = rm -f +CP = cp + +LXINCLUDE = liblx.h +LXLIB = liblx.a +LXOBJS = xMemMgt.o xListFuncs.o + +all : $(LXLIB) + +clean : + @echo "cleaning workspace..." + @$(RM) $(LXOBJS) $(LXLIB) + +new : clean all + +$(LXLIB) : $(LXOBJS) + @echo "updating library..." + @$(AR) $(ARFLAGS) $(LXLIB) $(LXOBJS) + @$(RANLIB) $(LXLIB) + +dist: all + @echo "distributing liblx.a and liblx.h..." + @$(CP) $(LXLIB) ../lib + @$(CP) $(LXINCLUDE) ../include + diff --git a/libdtv/liblx/liblx.h b/libdtv/liblx/liblx.h new file mode 100644 index 0000000..f2527e7 --- /dev/null +++ b/libdtv/liblx/liblx.h @@ -0,0 +1,448 @@ +////////////////////////////////////////////////////////////// +/// /// +/// liblx.h: definitions necessary for the liblx package /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/06/26 07:18:42 $ +// $Author: kls $ +// +// (C) 1992-2001 Rolf Hakenes , under the GNU GPL. +// +// liblx is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// liblx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with liblx; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#ifndef LIBLX_H +#define LIBLX_H + +#ifndef NULL +#define NULL 0 +#endif + + +/* + * + * list support structures + * + */ +struct NODE +{ + struct NODE *Succ; + struct NODE *Pred; + char *Name; + unsigned short HashKey; +}; + +struct LIST +{ + struct NODE *Head; + struct NODE *Tail; + char *Name; + unsigned long Size; +}; + + +/* + * + * memory managment structures + * + */ +struct MEM_ENTRY +{ + struct MEM_ENTRY *Succ; + struct MEM_ENTRY *Pred; + unsigned long Size; +}; + +struct MEM_CHUNK +{ + struct MEM_CHUNK *Succ; + struct MEM_CHUNK *Pred; + unsigned long Size; + struct MEM_ENTRY *FirstFreeMemEntry; + struct MEM_ENTRY *FirstUsedMemEntry; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * + * list functions (package xList) + * + */ + unsigned short xHashKey (char *); + struct LIST *xNewList (char *); + struct NODE *xNewNode (char *, unsigned long); + struct NODE *xFindName (struct LIST *, char *); +/* + * + * memory management + * + */ + void xMemAllo (unsigned long, unsigned char **); + void xMemFre (unsigned char *); + void xMemFreeAll (struct MEM_CHUNK **); + void xMemMerge (struct MEM_CHUNK **); + struct MEM_CHUNK **xGetRemember (void); + void xSetRemember (struct MEM_CHUNK **); + void xPrintMemList (struct MEM_CHUNK **); + unsigned long xGetMemSize (struct MEM_CHUNK **); +extern unsigned long xAllocatedMemory; + char *xSetText (char *); + +#ifdef __cplusplus +} +#endif + + +#define MEM_CHUNK_SIZE 65536 + +#define xMemAlloc(size, ptr) \ + xMemAllo (((unsigned long)((size))), ((unsigned char **)((ptr)))) +#define xMemFree(ptr) xMemFre (((unsigned char *)((ptr)))) +/* + * + * list support macros + * + */ +/*---------------------------------------------------------------------* + | | + | xCreateNode (NodeStruct,Name) allocates a correctly sized and | + | typed node struct. | + | | + *---------------------------------------------------------------------*/ +#define xCreateNode(NodeStruct,Name) \ + (NodeStruct) = (void *) xNewNode(Name, sizeof(*(NodeStruct))) + + +/*---------------------------------------------------------------------* + | | + | xSize (List) scans for the ->Size field of a list struct | + | | + *---------------------------------------------------------------------*/ +#define xSize(List) ((List) ? ((struct LIST *)(List))->Size : 0) + + +/*---------------------------------------------------------------------* + | | + | xName (NodeStruct) scans for the ->Node.Name of a node struct | + | | + *---------------------------------------------------------------------*/ +#define xName(NodeStruct) (((struct NODE *)(NodeStruct))->Name) + + +/*---------------------------------------------------------------------* + | | + | xSucc (NodeStruct) scans for the ->Node.Succ of a node struct | + | | + *---------------------------------------------------------------------*/ +#define xSucc(NodeStruct) (((struct NODE *)(NodeStruct))->Succ) + + +/*---------------------------------------------------------------------* + | | + | xPred (NodeStruct) scans for the ->Node.Pred of a node struct | + | | + *---------------------------------------------------------------------*/ +#define xPred(NodeStruct) (((struct NODE *)(NodeStruct))->Pred) + + +/*---------------------------------------------------------------------* + | | + | xForeach(List,NodeStruct) builds a loop to process each list | + | element. | + | | + *---------------------------------------------------------------------*/ +#define xForeach(List,NodeStruct) \ + if (List) for ((NodeStruct) = (void *) ((struct LIST *)(List))->Head; \ + (NodeStruct); (NodeStruct) = (void *) xSucc (NodeStruct)) + + +/*---------------------------------------------------------------------* + | | + | xForeachReverse(List,NodeStruct) builds a loop to process each | + | element in reverse order. | + | | + *---------------------------------------------------------------------*/ +#define xForeachReverse(List,NodeStruct) \ + if (List) for ((NodeStruct) = (void *) ((struct LIST *)(List))->Tail; \ + NodeStruct; (NodeStruct) = (void *) xPred (NodeStruct)) + + +/*---------------------------------------------------------------------* + | | + | xRemove(List,NodeStruct) unchains a node struct out of a list. | + | | + *---------------------------------------------------------------------*/ +#define xRemove(List,NodeStruct) \ + do \ + { \ + struct NODE *TmpNode; \ + struct LIST *TmpList; \ + \ + TmpNode = ((struct NODE *)(NodeStruct)); \ + TmpList = ((struct LIST *)(List)); \ + \ + if (TmpNode->Pred) \ + (TmpNode->Pred)->Succ = TmpNode->Succ; \ + else TmpList->Head = TmpNode->Succ; \ + if (TmpNode->Succ) \ + (TmpNode->Succ)->Pred = TmpNode->Pred; \ + else TmpList->Tail = TmpNode->Pred; \ + TmpList->Size --; \ + } while (0) + + +/************************************************************************* + * * + * function : xAddHead * + * * + * arguments : List - pointer to a LIST structure * + * * + * Node - pointer to a NODE structure * + * * + *-----------------------------------------------------------------------* + * * + * xAddHead() inserts 'Node' at the head of 'List'. * + * * + *************************************************************************/ +#define xAddHead(List, NodeStruct) \ + do { \ + struct NODE *TmpNode; \ + struct LIST *TmpList; \ + \ + TmpNode = ((struct NODE *)(NodeStruct)); \ + TmpList = ((struct LIST *)(List)); \ + \ + if (TmpList->Head) { \ + TmpNode->Pred = NULL; \ + TmpNode->Succ = TmpList->Head; \ + (TmpList->Head)->Pred = TmpNode; \ + TmpList->Head = TmpNode; } \ + else { \ + TmpList->Head = TmpNode; \ + TmpList->Tail = TmpNode; \ + TmpNode->Pred = NULL; \ + TmpNode->Succ = NULL; } \ + TmpList->Size++; \ + } while (0) + + +/************************************************************************* + * * + * function : xAddTail * + * * + * arguments : List - pointer to a LIST structure * + * * + * Node - pointer to a NODE structure * + * * + *-----------------------------------------------------------------------* + * * + * xAddTail() inserts 'Node' at the tail of 'List'. * + * * + *************************************************************************/ +#define xAddTail(List, NodeStruct) \ + do { \ + struct NODE *TmpNode; \ + struct LIST *TmpList; \ + \ + TmpNode = ((struct NODE *)(NodeStruct)); \ + TmpList = ((struct LIST *)(List)); \ + \ + if (TmpList->Head) { \ + TmpNode->Succ = NULL; \ + TmpNode->Pred = TmpList->Tail; \ + (TmpList->Tail)->Succ = TmpNode; \ + TmpList->Tail = TmpNode; } \ + else { \ + TmpList->Head = TmpNode; \ + TmpList->Tail = TmpNode; \ + TmpNode->Pred = NULL; \ + TmpNode->Succ = NULL; } \ + TmpList->Size++; \ + } while (0) + + +/************************************************************************* + * * + * function : xRemHead * + * * + * arguments : List - pointer to a LIST structure * + * * + *-----------------------------------------------------------------------* + * * + * xRemHead() removes a Node from head of 'List'. * + * * + *************************************************************************/ +#define xRemHead(List) \ + do { \ + struct LIST *TmpList; \ + \ + TmpList = ((struct LIST *)(List)); \ + \ + if (TmpList->Head) \ + { \ + TmpList->Head = (TmpList->Head)->Succ; \ + if (TmpList->Head) (TmpList->Head)->Pred = NULL; \ + else TmpList->Tail = NULL; \ + TmpList->Size--; \ + } \ + } while (0) + + +/************************************************************************* + * * + * function : xRemTail * + * * + * arguments : List - pointer to a LIST structure * + * * + *-----------------------------------------------------------------------* + * * + * xRemTail() removes a Node from the tail of 'List'. * + * * + *************************************************************************/ +#define xRemTail(List) \ + do { \ + struct LIST *TmpList; \ + \ + TmpList = ((struct LIST *)(List)); \ + \ + if (TmpList->Tail) \ + { \ + TmpList->Tail = (TmpList->Tail)->Pred; \ + if (TmpList->Tail) (TmpList->Tail)->Succ = NULL; \ + else TmpList->Head = NULL; \ + TmpList->Size--; \ + } \ + } while (0) + + +/************************************************************************* + * * + * function : xConCat * + * * + * arguments : DestinationList - pointer to the destination * + * LIST structure * + * * + * SourceList - pointer to the source LIST structure * + * * + *-----------------------------------------------------------------------* + * * + * xConCat() concats 'SourceList' with 'DestinationList' and clears * + * 'SourceList'. * + * * + *************************************************************************/ +#define xConCat(DestinationList, SourceList) \ + do { \ + struct LIST *SrcList; \ + struct LIST *DstList; \ + \ + SrcList = ((struct LIST *)(SourceList)); \ + DstList = ((struct LIST *)(DestinationList)); \ + \ + if (DstList && SrcList) \ + { \ + if (DstList->Head) { \ + if (SrcList->Head) { \ + (DstList->Tail)->Succ = SrcList->Head; \ + (SrcList->Head)->Pred = DstList->Tail; \ + DstList->Tail = SrcList->Tail; \ + DstList->Size += SrcList->Size; \ + SrcList->Size = 0; \ + SrcList->Head = NULL; \ + SrcList->Tail = NULL; } } \ + else { \ + DstList->Head = SrcList->Head; \ + DstList->Tail = SrcList->Tail; \ + DstList->Size += SrcList->Size; \ + SrcList->Size = 0; \ + SrcList->Head = NULL; \ + SrcList->Tail = NULL; } \ + } \ + else if (SrcList) ((struct LIST *)(DestinationList)) = SrcList; \ + } while (0) + + + +#define xJoinList(SourceList, DestinationList, NodeStruct) \ + do { \ + struct NODE *KeyNode; \ + struct NODE *TmpNode; \ + struct LIST *SrcList; \ + struct LIST *DstList; \ + \ + KeyNode = ((struct NODE *)(NodeStruct)); \ + SrcList = ((struct LIST *)(SourceList)); \ + DstList = ((struct LIST *)(DestinationList)); \ + \ + if (SrcList->Head) \ + { \ + TmpNode = KeyNode->Succ; \ + KeyNode->Succ = SrcList->Head; \ + SrcList->Tail->Succ = TmpNode; \ + SrcList->Head->Pred = KeyNode; \ + if (!TmpNode) DstList->Tail = SrcList->Tail; \ + else TmpNode->Pred = SrcList->Tail; \ + DstList->Size += SrcList->Size; \ + SrcList->Size = 0; \ + SrcList->Head = NULL; \ + SrcList->Tail = NULL; \ + } \ + } while (0) + +#define xJoin(SourceNode, DestinationList, NodeStruct) \ + do { \ + struct NODE *KeyNode; \ + struct NODE *TmpNode; \ + struct NODE *SrcNode; \ + struct LIST *DstList; \ + \ + KeyNode = ((struct NODE *)(NodeStruct)); \ + SrcNode = ((struct NODE *)(SourceNode)); \ + DstList = ((struct LIST *)(DestinationList)); \ + \ + if (SrcNode) \ + { \ + TmpNode = KeyNode->Succ; \ + KeyNode->Succ = SrcNode; \ + SrcNode->Succ = TmpNode; \ + SrcNode->Pred = KeyNode; \ + if (!TmpNode) DstList->Tail = SrcNode; \ + else TmpNode->Pred = SrcNode; \ + DstList->Size += 1; \ + } \ + } while (0) + +#define xClearList(SrcList) \ + do { \ + (SrcList)->Size = 0; \ + (SrcList)->Head = NULL; \ + (SrcList)->Tail = NULL; \ + } while (0) + +#define xSetName(nodestruct, name) \ + do { \ + struct NODE *TmpNode; \ + \ + TmpNode = (struct NODE *) (nodestruct); \ + \ + TmpNode->Name = xSetText (name); \ + TmpNode->HashKey = xHashKey (name); \ + } while (0) + +#endif diff --git a/libdtv/liblx/xListFuncs.c b/libdtv/liblx/xListFuncs.c new file mode 100644 index 0000000..34df7a8 --- /dev/null +++ b/libdtv/liblx/xListFuncs.c @@ -0,0 +1,187 @@ +////////////////////////////////////////////////////////////// +/// /// +/// xListFuncs.c: list handling functions of liblx /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/06/25 12:29:47 $ +// $Author: kls $ +// +// (C) 1992-2001 Rolf Hakenes , under the GNU GPL. +// +// liblx is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// liblx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with liblx; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#include "liblx.h" + + +/************************************************************************* + * * + * function : xHashKey * + * * + * arguments : Name - character pointer * + * * + * return : 16 Bit CRC checksum as hashkey * + * * + *************************************************************************/ +unsigned short xHashKey (Name) + +char *Name; +{ + unsigned short Key = 0; + unsigned long Value; + char *Ptr; + + if (!Name) return (0); + + for (Ptr = Name; *Ptr; Ptr++) { + Value = ((Key >> 8) ^ (*Ptr)) & 0xFF; + Value = Value ^ (Value >> 4); + Key = 0xFFFF & ((Key << 8) ^ Value ^ (Value << 5) ^ (Value << 12)); + } + return (Key); +} + + +/************************************************************************* + * * + * function : xNewNode * + * * + * arguments : Name - character pointer to the node's name * + * * + * Size - size of the surrounding structure in bytes * + * * + * return : pointer to a correct initialized NODE structure * + * * + *-----------------------------------------------------------------------* + * * + * xNewNode() allocates memory for a NODE structure and initializes * + * it properly. If argument Name points to a string, it copies that * + * into a new allocated memory area and assigns Node->Name to it. * + * Because NODE's are often part of bigger structures, the size of * + * the surrounding structure could be specified to allocate it. * + * * + *************************************************************************/ + +struct NODE *xNewNode (Name, Size) + +char *Name; +unsigned long Size; +{ + struct NODE *Node; + + if (Size < sizeof(struct NODE)) Size = sizeof(struct NODE); + + xMemAlloc (Size, &Node); + + Node->Succ = NULL; + Node->Pred = NULL; + + if (Name == NULL) + { + Node->Name = NULL; + Node->HashKey = 0; + } + else + { + xMemAlloc (strlen (Name) + 1, &(Node->Name)); + strcpy (Node->Name, Name); + Node->HashKey = xHashKey (Name); + } + + return (Node); +} + + +/************************************************************************* + * * + * function : xNewList * + * * + * arguments : Name - character pointer to the list's name * + * * + * return : pointer to a correct initialized LIST structure * + * * + *-----------------------------------------------------------------------* + * * + * xNewList() allocates memory for a LIST structure and initializes * + * it properly. If argument Name points to a string, it copies that * + * into a new allocated memory area and assigns List->Name to it. * + * * + *************************************************************************/ + +struct LIST *xNewList (Name) + +char *Name; +{ + struct LIST *List; + + xMemAlloc (sizeof(struct LIST), &List); + + List->Head = NULL; + List->Tail = NULL; + List->Size = 0; + + if (Name == NULL) + { + List->Name = NULL; + } + else + { + xMemAlloc (strlen (Name) + 1, &(List->Name)); + strcpy (List->Name, Name); + } + + return (List); +} + + + +/************************************************************************* + * * + * function : xFindName * + * * + * arguments : List - pointer to a LIST structure * + * * + * Name - pointer to a name string * + * * + * return : pointer to a NODE structure * + * * + *-----------------------------------------------------------------------* + * * + * xFindName() looks for element with name 'Name' in list 'List' and * + * returns its NODE structure. * + * * + *************************************************************************/ + +struct NODE *xFindName (List, Name) + +struct LIST *List; +char *Name; +{ + struct NODE *Node; + unsigned short HashKey; + + if (!Name || !List) return (NULL); + + HashKey = xHashKey (Name); + + for (Node = List->Head; Node; Node = Node->Succ) + if (HashKey == Node->HashKey) + if (Node->Name) + if (strcmp (Node->Name, Name) == 0) return (Node); + + return (NULL); +} diff --git a/libdtv/liblx/xMemMgt.c b/libdtv/liblx/xMemMgt.c new file mode 100644 index 0000000..363ee4a --- /dev/null +++ b/libdtv/liblx/xMemMgt.c @@ -0,0 +1,621 @@ +////////////////////////////////////////////////////////////// +/// /// +/// xMemMgt.c: memory management functions of liblx /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/06/25 12:29:47 $ +// $Author: kls $ +// +// (C) 1992-2001 Rolf Hakenes , under the GNU GPL. +// +// liblx is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// liblx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with liblx; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#include +#include + +#include "liblx.h" + +#ifdef DEBUG +void logPrintf(int, char *, ...); +#endif + +static struct MEM_CHUNK *xRememberKey = NULL; + +static struct MEM_CHUNK **xRememberPtr = &xRememberKey; + +unsigned long xAllocatedMemory = 0; + +/************************************************************************* + * * + * function : xMemAlloc * + * * + * parameter : Size - size of the requested memory area * + * * + * DataPointer - pointer to data pointer * + * * + * return : none * + * * + *-----------------------------------------------------------------------* + * * + * xMemAlloc() is a clustered, remembering memory management routine. * + * It uses its own tables for free and used memory blocks on private * + * memory area. With xMemFree(), you can free this memory likewise * + * the C free() routine, with xMemFreeAll() all memory at once. * + * By changing the current remember key with xSetRemember() you can * + * define a local memory area, which can be freed by only one call of * + * xMemFreeAll() (see xSetRemember() / xGetRemember()). * + * * + *************************************************************************/ + +void xMemAllo (Size, DataPointer) + +unsigned long Size; +unsigned char **DataPointer; +{ + struct MEM_CHUNK *MemChunk, *MemChunkPred; + struct MEM_ENTRY *MemEntry, *MemEntryPred; + long int NewSize; + unsigned short FoundFlag; +#ifdef DEBUG + unsigned char *ptr; +#endif + + while (Size % 4) Size++; + + if (Size > (MEM_CHUNK_SIZE - sizeof(struct MEM_CHUNK) - + sizeof(struct MEM_ENTRY))) + { + NewSize = Size + sizeof(struct MEM_CHUNK) + sizeof(struct MEM_ENTRY); + + if (MemChunk = (*xRememberPtr)) + { + do + { + MemChunkPred = MemChunk; + } while (MemChunk = MemChunk->Succ); + } + else MemChunkPred = (struct MEM_CHUNK *) &(*xRememberPtr); + + MemChunk = MemChunkPred->Succ = (struct MEM_CHUNK *) malloc (NewSize); + xAllocatedMemory += NewSize; + +#ifdef DEBUG + for (ptr = (unsigned char *) MemChunk; ptr < (unsigned char *) + (MemChunk) + NewSize; ptr++) + *ptr = (((unsigned long)ptr)&1) ? 0x55 : 0xAA; +#endif + + if (!MemChunk) + { +#ifdef DEBUG + logPrintf (0, "Not enough memory...\r\n"); +#endif + exit (1); + } + + MemChunk->Size = NewSize; + MemChunk->Pred = MemChunkPred; + MemChunk->Succ = NULL; + MemChunk->FirstFreeMemEntry = NULL; + MemChunk->FirstUsedMemEntry = + MemEntry = (struct MEM_ENTRY *) ((unsigned char *)MemChunk + + sizeof(struct MEM_CHUNK)); + + MemEntry->Size = Size; + MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstUsedMemEntry; + MemEntry->Succ = NULL; + + *DataPointer = (unsigned char *) ((unsigned char *)MemEntry + + sizeof(struct MEM_ENTRY)); +#ifdef DEBUG_CALLS + logPrintf (0, "xMemAlloc: %x, %d bytes\r\n", *DataPointer, Size); +#endif + return; + } + + MemEntry = NULL; + FoundFlag = 0; + + if (MemChunk = (*xRememberPtr)) + { + do + { + if (MemEntry = MemChunk->FirstFreeMemEntry) + do + { + if (Size <= MemEntry->Size) FoundFlag = 1; + } while ((FoundFlag == 0) && (MemEntry = MemEntry->Succ)); + MemChunkPred = MemChunk; + } while ((FoundFlag == 0) && (MemChunk = MemChunk->Succ)); + } + else MemChunkPred = (struct MEM_CHUNK *) &(*xRememberPtr); + + if (!MemEntry) + { + MemChunk = MemChunkPred->Succ = + (struct MEM_CHUNK *) malloc (MEM_CHUNK_SIZE); + xAllocatedMemory += MEM_CHUNK_SIZE; + +#ifdef DEBUG + for (ptr = (unsigned char *) MemChunk; ptr < (unsigned char *) + (MemChunk) + MEM_CHUNK_SIZE; ptr++) + *ptr = (((unsigned long)ptr)&1) ? 0x55 : 0xAA; +#endif + + if (!MemChunk) + { +#ifdef DEBUG + logPrintf (0, "Not enough memory...\r\n"); +#endif + exit (1); + } + + MemChunk->Size = MEM_CHUNK_SIZE; + MemChunk->Pred = MemChunkPred; + MemChunk->Succ = NULL; + MemChunk->FirstUsedMemEntry = NULL; + MemChunk->FirstFreeMemEntry = + MemEntry = (struct MEM_ENTRY *) + ((unsigned char *)MemChunk + sizeof(struct MEM_CHUNK)); + + MemEntry->Size = MEM_CHUNK_SIZE - sizeof(struct MEM_CHUNK) - + sizeof(struct MEM_ENTRY); + MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstFreeMemEntry; + MemEntry->Succ = NULL; + } + + NewSize = MemEntry->Size - sizeof(struct MEM_ENTRY) - Size; + + MemEntry->Size = Size; + *DataPointer = (unsigned char *) + ((unsigned char *)MemEntry + sizeof(struct MEM_ENTRY)); + +#ifdef DEBUG + for (ptr = *DataPointer; ptr < (unsigned char *) + (*DataPointer) + Size; ptr++) + { + if (((unsigned long )ptr)&1) + { if (*ptr != 0x55) + logPrintf (0, "freed memory was used\r\n"); } + else { if (*ptr != 0xAA) + logPrintf (0, "freed memory was used\r\n"); } + } +#endif + + if (MemEntry->Succ) + ((struct MEM_ENTRY *)MemEntry->Succ)->Pred = MemEntry->Pred; + ((struct MEM_ENTRY *)MemEntry->Pred)->Succ = MemEntry->Succ; + + if (MemChunk->FirstUsedMemEntry) + MemChunk->FirstUsedMemEntry->Pred = MemEntry; + MemEntry->Succ = MemChunk->FirstUsedMemEntry; + MemChunk->FirstUsedMemEntry = MemEntry; + MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstUsedMemEntry; + + if (NewSize > 0) + { + MemEntry = (struct MEM_ENTRY *) + ((unsigned char *)MemEntry + sizeof(struct MEM_ENTRY) + Size); + MemEntry->Size = NewSize; + + if (MemChunk->FirstFreeMemEntry) + MemChunk->FirstFreeMemEntry->Pred = MemEntry; + MemEntry->Succ = MemChunk->FirstFreeMemEntry; + MemChunk->FirstFreeMemEntry = MemEntry; + MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstFreeMemEntry; + } +#ifdef DEBUG_CALLS + logPrintf (0, "xMemAlloc: %x, %d bytes\r\n", *DataPointer, Size); +#endif + return; +} + + + +/************************************************************************* + * * + * function : xMemFree * + * * + * parameter : DataPointer - data pointer * + * * + * return : none * + * * + *-----------------------------------------------------------------------* + * * + * xMemFree() frees with xMemAlloc() allocated memory. * + * * + *************************************************************************/ + +void xMemFre (DataPointer) + +unsigned char *DataPointer; +{ + struct MEM_CHUNK *MemChunk, *MemChunkPred; + struct MEM_ENTRY *MemEntry, *TempEntry, *PredEntry, *SuccEntry; + unsigned short FoundFlag; +#ifdef DEBUG + unsigned char *ptr; +#endif + + if (!DataPointer) + { + return; + } + else + { + MemEntry = NULL; + FoundFlag = 0; + + if (MemChunk = (*xRememberPtr)) + do + { + if (MemEntry = MemChunk->FirstUsedMemEntry) + do + { + if (DataPointer == (unsigned char *) ((unsigned char *) MemEntry + + sizeof(struct MEM_ENTRY))) FoundFlag = 1; + } while ((FoundFlag == 0) && (MemEntry = MemEntry->Succ)); + } while ((FoundFlag == 0) && (MemChunk = MemChunk->Succ)); + + if (FoundFlag == 1) + { +#ifdef DEBUG_CALLS + logPrintf (0, "xMemFree: %x, %d bytes\r\n", DataPointer, MemEntry->Size); +#endif + if (MemEntry->Succ) + ((struct MEM_ENTRY *)MemEntry->Succ)->Pred = MemEntry->Pred; + ((struct MEM_ENTRY *)MemEntry->Pred)->Succ = MemEntry->Succ; + + if (!MemChunk->FirstUsedMemEntry) + { + if (MemChunk->Succ) + ((struct MEM_CHUNK *)MemChunk->Succ)->Pred = MemChunk->Pred; + ((struct MEM_CHUNK *)MemChunk->Pred)->Succ = MemChunk->Succ; + if (xAllocatedMemory > 0) xAllocatedMemory -= MemChunk->Size; + free (MemChunk); + return; + } + + FoundFlag = 0; + PredEntry = NULL; + SuccEntry = NULL; + if (TempEntry = MemChunk->FirstFreeMemEntry) + do + { + if ((struct MEM_ENTRY *)((unsigned char *)TempEntry + + TempEntry->Size + sizeof(struct MEM_ENTRY)) == MemEntry) + { + FoundFlag ++; + PredEntry = TempEntry; + } + if ((struct MEM_ENTRY *)((unsigned char *)MemEntry + + MemEntry->Size + sizeof(struct MEM_ENTRY)) == TempEntry) + { + FoundFlag ++; + SuccEntry = TempEntry; + } + } while ((FoundFlag != 2) && (TempEntry = TempEntry->Succ)); + + if (PredEntry) + { + if (SuccEntry) + { + /* Vorgdnger + Nachfolger */ + + if (SuccEntry->Succ) + ((struct MEM_ENTRY *)SuccEntry->Succ)->Pred = SuccEntry->Pred; + ((struct MEM_ENTRY *)SuccEntry->Pred)->Succ = SuccEntry->Succ; + + PredEntry->Size += MemEntry->Size + sizeof(struct MEM_ENTRY) + + SuccEntry->Size + sizeof(struct MEM_ENTRY); + } + else + { + /* nur Vorgaenger */ + + PredEntry->Size += MemEntry->Size + sizeof(struct MEM_ENTRY); + } +#ifdef DEBUG + for (ptr = (unsigned char *) (PredEntry) + sizeof(struct MEM_ENTRY); + ptr < (unsigned char *) (PredEntry) + sizeof(struct MEM_ENTRY) + + PredEntry->Size; ptr++) + *ptr = (((unsigned long)ptr)&1) ? 0x55 : 0xAA; +#endif + } + else + { + if (SuccEntry) + { + /* nur Nachfolger */ + + if (SuccEntry->Succ) + ((struct MEM_ENTRY *)SuccEntry->Succ)->Pred = SuccEntry->Pred; + ((struct MEM_ENTRY *)SuccEntry->Pred)->Succ = SuccEntry->Succ; + + MemEntry->Size += SuccEntry->Size + sizeof(struct MEM_ENTRY); + } + + if (MemChunk->FirstFreeMemEntry) + MemChunk->FirstFreeMemEntry->Pred = MemEntry; + MemEntry->Succ = MemChunk->FirstFreeMemEntry; + MemChunk->FirstFreeMemEntry = MemEntry; + MemEntry->Pred = (struct MEM_ENTRY *) &MemChunk->FirstFreeMemEntry; +#ifdef DEBUG + for (ptr = (unsigned char *) (MemEntry) + sizeof(struct MEM_ENTRY); + ptr < (unsigned char *) (MemEntry) + sizeof(struct MEM_ENTRY) + + MemEntry->Size; ptr++) + *ptr = (((unsigned long)ptr)&1) ? 0x55 : 0xAA; +#endif + } + } +#ifdef DEBUG_CALLS + else + logPrintf (0, "xMemFree: tried to free unallocated data %x\r\n", DataPointer); +#endif + } + return; +} + + + +/************************************************************************* + * * + * function : xMemFreeAll * + * * + * parameter : RememberPtr * + * * + * return : none * + * * + *-----------------------------------------------------------------------* + * * + * xMemFreeAll() frees all with xMemAlloc() allocated memory. If Re- * + * memberPtr is not NULL, the MEM_CHUNK structure from the specified * + * Address is freed, otherwise the natural MEM_CHUNK will be done. * + * * + *************************************************************************/ + + +void xMemFreeAll (RememberPtr) + +struct MEM_CHUNK **RememberPtr; +{ + struct MEM_CHUNK *MemChunk, *MemChunkPred; + + if (RememberPtr) + { + if (MemChunkPred = (*RememberPtr)) + do + { + MemChunk = MemChunkPred->Succ; + if (xAllocatedMemory > 0) xAllocatedMemory -= MemChunkPred->Size; + free (MemChunkPred); + } while (MemChunkPred = MemChunk); + *RememberPtr = NULL; + } + else + { + if (MemChunkPred = (*xRememberPtr)) + do + { + MemChunk = MemChunkPred->Succ; + if (xAllocatedMemory > 0) xAllocatedMemory -= MemChunkPred->Size; + free (MemChunkPred); + } while (MemChunkPred = MemChunk); + *xRememberPtr = NULL; + } +} + + +/************************************************************************* + * * + * function : xMemMerge * + * * + * parameter : RememberPtr * + * * + * return : none * + * * + *-----------------------------------------------------------------------* + * * + * xMemMerge() merges the memory area pointed to by RememberKey with * + * the currently used in xRememberPtr. * + * * + *************************************************************************/ + +void xMemMerge (RememberPtr) + +struct MEM_CHUNK **RememberPtr; +{ + struct MEM_CHUNK *MemChunk, *MemChunkPred; + + if (RememberPtr) + { + if (MemChunk = (*xRememberPtr)) + { + while (MemChunk->Succ) MemChunk = MemChunk->Succ; + MemChunk->Succ = (*RememberPtr); + *RememberPtr = NULL; + } + else (*xRememberPtr = *RememberPtr); + } + return; +} + +/************************************************************************* + * * + * function : xGetRemember * + * * + * parameter : none * + * * + * return : pointer to a MEM_CHUNK tree * + * * + *-----------------------------------------------------------------------* + * * + * xGetRemember() returns the currently used MEM_CHUNK tree. * + * * + *************************************************************************/ + + +struct MEM_CHUNK **xGetRemember () +{ + return (xRememberPtr); +} + + +/************************************************************************* + * * + * function : xSetRemember * + * * + * parameter : pointer to a MEM_CHUNK tree * + * * + * return : none * + * * + *-----------------------------------------------------------------------* + * * + * xSetRemember() redefines the currently used MEM_CHUNK pointer. If * + * RememberPtr is NULL, the natural MEM_CHUNK is reloaded. * + * * + *************************************************************************/ + + +void xSetRemember (RememberPtr) + +struct MEM_CHUNK **RememberPtr; +{ + if (RememberPtr) + xRememberPtr = RememberPtr; + else + xRememberPtr = &xRememberKey; +} + +/************************************************************************* + * * + * function : xPrintMemList * + * * + * parameter : pointer to a MEM_CHUNK tree * + * * + * return : none * + * * + *-----------------------------------------------------------------------* + * * + * xPrintMemList() prints the currently allocated memory blocks of * + * the specified RememberPtr. * + * * + *************************************************************************/ + + +void xPrintMemList (Remember) + +struct MEM_CHUNK **Remember; +{ + struct MEM_CHUNK *MemChunk; + struct MEM_ENTRY *MemEntry; + + fprintf (stderr, "MemChunkPtr = %x\n", (int) Remember); + + if (MemChunk = *Remember) + do + { + fprintf (stderr, "\tMemChunk at %x with Size %d\n", (int) MemChunk, + (int) MemChunk->Size); + + if (MemEntry = MemChunk->FirstFreeMemEntry) + do + { + fprintf (stderr, "\t\tFree MemEntry at %x (%x) with Size %d\n", + (int) MemEntry, (int)((unsigned char *)MemEntry + + sizeof(struct MEM_ENTRY)), (int) MemEntry->Size); + + } while (MemEntry = MemEntry->Succ); + + if (MemEntry = MemChunk->FirstUsedMemEntry) + do + { + fprintf (stderr, "\t\tUsed MemEntry at %x (%x) with Size %d\n", + (int) MemEntry, (int)((unsigned char *)MemEntry + + sizeof(struct MEM_ENTRY)), (int) MemEntry->Size); + + } while (MemEntry = MemEntry->Succ); + + } while (MemChunk = MemChunk->Succ); + else fprintf (stderr, "\tNo current MemChunk\n"); +} + + +/************************************************************************* + * * + * function : xGetMemSize * + * * + * parameter : pointer to a MEM_CHUNK tree * + * * + * return : none * + * * + *-----------------------------------------------------------------------* + * * + * xGetMemSize() gets the size of the currently allocated memory * + * blocks of the specified (or natural if NULL) RememberPtr * + * * + *************************************************************************/ + + +unsigned long xGetMemSize (RememberPtr) + +struct MEM_CHUNK **RememberPtr; +{ + struct MEM_CHUNK *MemChunk; + struct MEM_ENTRY *MemEntry; + unsigned long Result = 0; + + if (RememberPtr) MemChunk = *RememberPtr; + else MemChunk = xRememberKey; + + if (MemChunk) + do { Result += (unsigned long) MemChunk->Size; } + while (MemChunk = MemChunk->Succ); + + return (Result); +} + + +/************************************************************************* + * * + * function : xSetText * + * * + * arguments : xText - pointer to a string * + * * + * return : pointer to an new allocated string * + * * + *-----------------------------------------------------------------------* + * * + * xSetText() allocates memory for the string pointed to by 'xText' * + * and duplicates it. * + * * + *************************************************************************/ + +char *xSetText (xText) + +char *xText; +{ + char *NewText; + + if (!xText) return (NULL); + + xMemAlloc (strlen(xText) + 1, &NewText); + strcpy (NewText, xText); + + return (NewText); +} diff --git a/libdtv/libsi/COPYING b/libdtv/libsi/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/libdtv/libsi/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libdtv/libsi/Makefile b/libdtv/libsi/Makefile new file mode 100644 index 0000000..4b939b9 --- /dev/null +++ b/libdtv/libsi/Makefile @@ -0,0 +1,83 @@ +############################################################## +### ### +### Makefile: local makefile for libsi ### +### ### +############################################################## + +## $Revision: 1.1 $ +## $Date: 2001/08/15 14:47:22 $ +## $Author: kls $ +## +## (C) 2001 Rolf Hakenes , under the GNU GPL. +## +## dtv_scan is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2, or (at your option) +## any later version. +## +## dtv_scan is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You may have received a copy of the GNU General Public License +## along with dtv_scan; see the file COPYING. If not, write to the +## Free Software Foundation, Inc., 59 Temple Place - Suite 330, +## Boston, MA 02111-1307, USA. +# +# +# + +.DELETE_ON_ERROR: + +CC = gcc +CFLAGS = -O2 -g -Wmissing-prototypes -Wstrict-prototypes \ + -DNAPI -Wimplicit -D__USE_FIXED_PROTOTYPES__ # -ansi -pedantic + +INCDIRS = -Iinclude -I../include +DISTDIR = ../lib +DISTINCDIR = ../include +INCLUDES = include/libsi.h include/si_tables.h +MAKEDEPEND = gcc -M + +LIBDIRS = -L. -L../lib +LIBS = -lsi -llx + +AR = ar +ARFLAGS = ru +RANLIB = ranlib + +SILIB = libsi.a +OBJS = si_parser.o si_debug_services.o + +all : $(SILIB) + +clean : + @echo cleaning workspace... + @rm -f $(OBJS) $(SILIB) *~ + @rm -f Makefile.dep + +depend : Makefile.dep +Makefile.dep : + @echo "updating dependencies..." + @$(MAKEDEPEND) $(INCDIRS) $(OBJS:%.o=%.c) $(SITEST_OBJS:%.o=%.c) \ + $(SISCAN_OBJS:%.o=%.c) > Makefile.dep + +new : clean depend all + +dist: all + @echo "distributing $(SILIB) to $(DISTDIR)..." + @cp $(SILIB) $(DISTDIR) + @cp $(INCLUDES) $(DISTINCDIR) + @$(RANLIB) $(DISTDIR)/$(SILIB) + +$(SILIB) : $(OBJS) + @echo updating library... + @$(AR) $(ARFLAGS) $(SILIB) $(OBJS) + @$(RANLIB) $(SILIB) + +.c.o : + @echo compiling $<... + @$(CC) $(DEFINES) $(CFLAGS) $(INCDIRS) -c $< + +include Makefile.dep diff --git a/libdtv/libsi/README b/libdtv/libsi/README new file mode 100644 index 0000000..4f1be1a --- /dev/null +++ b/libdtv/libsi/README @@ -0,0 +1,2 @@ +DVB - System Information Library +================================ diff --git a/libdtv/libsi/include/libsi.h b/libdtv/libsi/include/libsi.h new file mode 100644 index 0000000..3790ae1 --- /dev/null +++ b/libdtv/libsi/include/libsi.h @@ -0,0 +1,816 @@ +////////////////////////////////////////////////////////////// +/// /// +/// libsi.h: definitions for data structures of libsi /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/06/26 07:18:43 $ +// $Author: kls $ +// +// (C) 2001 Rolf Hakenes , under the GNU GPL. +// +// libsi is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// libsi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with libsi; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#ifndef LIBSI_H +#define LIBSI_H + +#include +#include +#include + + + /* Program Identifier */ + +#define PID_PAT 0x00 /* Program Association Table */ +#define PID_BAT 0x01 /* Bouquet Association Table */ +#define PID_CAT 0x01 /* Conditional Access Table */ +#define PID_NIT 0x10 /* Network Information Table */ +#define PID_SDT 0x11 /* Service Description Table */ +#define PID_EIT 0x12 /* Event Information Table */ +#define PID_RST 0x13 /* Running Status Table */ +#define PID_TDT 0x14 /* Time Date Table */ +#define PID_TOT 0x14 /* Time Offset Table */ +#define PID_ST 0x14 /* Stuffing Table */ + /* 0x15 - 0x1F */ /* Reserved for future use */ + + /* Table Identifier */ + +#define TID_PAT 0x00 /* Program Association Section */ +#define TID_CAT 0x01 /* Conditional Access Section */ +#define TID_PMT 0x02 /* Conditional Access Section */ + /* 0x03 - 0x3F */ /* Reserved for future use */ +#define TID_NIT_ACT 0x40 /* Network Information Section - + actual */ +#define TID_NIT_OTH 0x41 /* Network Information Section - + other */ +#define TID_SDT_ACT 0x42 /* Service Description Section - + actual */ +#define TID_SDT_OTH 0x46 /* Service Description Section - + other */ +#define TID_EIT_ACT 0x4E /* Event Information Section - + actual */ +#define TID_EIT_OTH 0x4F /* Event Information Section - + other */ +#define TID_EIT_ACT_SCH 0x50 /* Event Information Section - + actual, schedule */ +#define TID_EIT_OTH_SCH 0x60 /* Event Information Section - + other, schedule */ +#define TID_TDT 0x70 /* Time Date Section */ +#define TID_TOT 0x73 /* Time Offset Section */ +#define TID_CA_ECM_0 0x80 +#define TID_CA_ECM_1 0x81 + +#define TID_BAT 0x01 /* Bouquet Association Section */ + +#define TID_EIT 0x12 /* Event Information Section */ +#define TID_RST 0x13 /* Running Status Section */ +#define TID_ST 0x14 /* Stuffung Section */ + /* 0xFF */ /* Reserved for future use */ + + /* Descriptor Identifier */ + + /* defined by ISO/IEC 13818-1 */ + +#define DESCR_VIDEO_STREAM 0x02 +#define DESCR_AUDIO_STREAM 0x03 +#define DESCR_HIERARCHY 0x04 +#define DESCR_REGISTRATION 0x05 +#define DESCR_DATA_STREAM_ALIGN 0x06 +#define DESCR_TARGET_BACKGRID 0x07 +#define DESCR_VIDEO_WINDOW 0x08 +#define DESCR_CA 0x09 +#define DESCR_ISO_639_LANGUAGE 0x0A +#define DESCR_SYSTEM_CLOCK 0x0B +#define DESCR_MULTIPLEX_BUFFER_UTIL 0x0C +#define DESCR_COPYRIGHT 0x0D +#define DESCR_MAXIMUM_BITRATE 0x0E +#define DESCR_PRIVATE_DATA_IND 0x0F +#define DESCR_SMOOTHING_BUFFER 0x10 +#define DESCR_STD 0x11 +#define DESCR_IBP 0x12 + /* 0x13 - 0x3F */ /* Reserved */ + + /* defined by ETSI */ + +#define DESCR_NW_NAME 0x40 +#define DESCR_SERVICE_LIST 0x41 +#define DESCR_STUFFING 0x42 +#define DESCR_SAT_DEL_SYS 0x43 +#define DESCR_CABLE_DEL_SYS 0x44 +#define DESCR_VBI_DATA 0x45 +#define DESCR_VBI_TELETEXT 0x46 +#define DESCR_BOUQUET_NAME 0x47 +#define DESCR_SERVICE 0x48 +#define DESCR_COUNTRY_AVAIL 0x49 +#define DESCR_LINKAGE 0x4A +#define DESCR_NVOD_REF 0x4B +#define DESCR_TIME_SHIFTED_SERVICE 0x4C +#define DESCR_SHORT_EVENT 0x4D +#define DESCR_EXTENDED_EVENT 0x4E +#define DESCR_TIME_SHIFTED_EVENT 0x4F +#define DESCR_COMPONENT 0x50 +#define DESCR_MOSAIC 0x51 +#define DESCR_STREAM_ID 0x52 +#define DESCR_CA_IDENT 0x53 +#define DESCR_CONTENT 0x54 +#define DESCR_PARENTAL_RATING 0x55 +#define DESCR_TELETEXT 0x56 +#define DESCR_TELEPHONE 0x57 +#define DESCR_LOCAL_TIME_OFF 0x58 +#define DESCR_SUBTITLING 0x59 +#define DESCR_TERR_DEL_SYS 0x5A +#define DESCR_ML_NW_NAME 0x5B +#define DESCR_ML_BQ_NAME 0x5C +#define DESCR_ML_SERVICE_NAME 0x5D +#define DESCR_ML_COMPONENT 0x5E +#define DESCR_PRIV_DATA_SPEC 0x5F +#define DESCR_SERVICE_MOVE 0x60 +#define DESCR_SHORT_SMOOTH_BUF 0x61 +#define DESCR_FREQUENCY_LIST 0x62 +#define DESCR_PARTIAL_TP_STREAM 0x63 +#define DESCR_DATA_BROADCAST 0x64 +#define DESCR_CA_SYSTEM 0x65 +#define DESCR_DATA_BROADCAST_ID 0x66 +#define DESCR_TRANSPORT_STREAM 0x67 +#define DESCR_DSNG 0x68 +#define DESCR_PDC 0x69 +#define DESCR_AC3 0x6A +#define DESCR_ANCILLARY_DATA 0x6B +#define DESCR_CELL_LIST 0x6C +#define DESCR_CELL_FREQ_LINK 0x6D +#define DESCR_ANNOUNCEMENT_SUPPORT 0x6E + + +#define MAX_SECTION_BUFFER 4096 + + +/* Strukturen zur Aufnahme der SDT und EIT Informationen */ + +struct Service { + struct NODE Node; + int ServiceID; + int TransportStreamID; + int OriginalNetworkID; + int SdtVersion; + unsigned short Status; + struct LIST *Descriptors; + struct LIST *Events; +}; + +#define EIT_SCHEDULE_FLAG 0x0001 +#define GetScheduleFlag(x) ((x)&EIT_SCHEDULE_FLAG) +#define SetScheduleFlag(x) ((x)|=EIT_SCHEDULE_FLAG) +#define EIT_PRESENT_FOLLOWING_FLAG 0x0002 +#define GetPresentFollowing(x) ((x)&EIT_PRESENT_FOLLOWING_FLAG) +#define SetPresentFollowing(x) ((x)|=EIT_PRESENT_FOLLOWING_FLAG) +#define RUNNING_STATUS_NOT_RUNNING 0x0000 +#define RUNNING_STATUS_AWAITING 0x0004 +#define RUNNING_STATUS_PAUSING 0x0008 +#define RUNNING_STATUS_RUNNING 0x000C +#define GetRunningStatus(x) ((x)&RUNNING_STATUS_RUNNING) +#define SetRunningStatus(x,s) ((x)|=((s)&RUNNING_STATUS_RUNNING)) +#define FREE_TO_AIR 0x0000 +#define CONDITIONAL_ACCESS 0x0010 +#define GetConditionalAccess(x) ((x)&CONDITIONAL_ACCESS) +#define SetConditionalAccess(x) ((x)|=CONDITIONAL_ACCESS) + +#define CreateService(service, svid, tsid, onid, vers, sta) \ + do \ + { \ + xCreateNode (service, NULL); \ + service->ServiceID = svid; \ + service->TransportStreamID = tsid; \ + service->OriginalNetworkID = onid; \ + service->SdtVersion = vers; \ + service->Status = sta; \ + service->Descriptors = xNewList (NULL); \ + service->Events = xNewList (NULL); \ + } while (0) + + +struct Event { + struct NODE Node; + int EventID; + int ServiceID; + int EitVersion; + int TransportStreamID; + int OriginalNetworkID; + time_t StartTime; + time_t Duration; + unsigned short Status; + struct LIST *Descriptors; +}; + +#define CreateEvent(event, evid, svid, tsid, onid, vers, sta) \ + do \ + { \ + xCreateNode (event, NULL); \ + event->EventID = evid; \ + event->ServiceID = svid; \ + event->TransportStreamID = tsid; \ + event->OriginalNetworkID = onid; \ + event->EitVersion = vers; \ + event->Status = sta; \ + event->Descriptors = xNewList (NULL); \ + } while (0) + + +/* Strukturen zur Aufnahme der PAT und PMT Informationen */ + +struct Program { + struct NODE Node; + int ProgramID; + int TransportStreamID; + int NetworkPID; + int PatVersion; + struct LIST *Pids; +}; + +#define CreateProgram(program, pgid, tsid, npid, vers) \ + do \ + { \ + xCreateNode (program, NULL); \ + program->ProgramID = pgid; \ + program->TransportStreamID = tsid; \ + program->NetworkPID = npid; \ + program->PatVersion = vers; \ + program->Pids = xNewList (NULL); \ + } while (0) + +struct Pid { + struct NODE Node; + int ProgramID; + int PcrPID; + int PmtVersion; + struct LIST *Descriptors; + struct LIST *InfoList; +}; + +#define CreatePid(pid, pgid, pcid, vers) \ + do \ + { \ + xCreateNode (pid, NULL); \ + pid->ProgramID = pgid; \ + pid->PcrPID = pcid; \ + pid->PmtVersion = vers; \ + pid->Descriptors = xNewList (NULL); \ + pid->InfoList = xNewList (NULL); \ + } while (0) + +struct PidInfo { + struct NODE Node; + int StreamType; + int ElementaryPid; + struct LIST *Descriptors; +}; + +#define CreatePidInfo(pidinfo, styp, epid) \ + do \ + { \ + xCreateNode (pidinfo, NULL); \ + pidinfo->StreamType = styp; \ + pidinfo->ElementaryPid = epid; \ + pidinfo->Descriptors = xNewList (NULL); \ + } while (0) + + +#define STREAMTYPE_ISO_VIDEO 1 +#define STREAMTYPE_13818_VIDEO 2 +#define STREAMTYPE_11172_AUDIO 3 +#define STREAMTYPE_13818_AUDIO 4 +#define STREAMTYPE_VIDEOTEXT 6 +#define STREAMTYPE_13522_MPEG 7 +#define STREAMTYPE_ITU_222 8 +#define STREAMTYPE_13818_A 9 +#define STREAMTYPE_13818_B 10 +#define STREAMTYPE_13818_C 11 +#define STREAMTYPE_13818_D 12 +#define STREAMTYPE_13818_AUX 13 + +/* Descriptors */ + +#define DescriptorTag(x) ((struct Descriptor *)(x))->Tag + +struct Descriptor { + struct NODE Node; + unsigned short Tag; +}; + + +/* Iso639LanguageDescriptor */ + +struct Iso639LanguageDescriptor { + struct NODE Node; + unsigned short Tag; + char LanguageCode[4]; +}; + +#define CreateIso639LanguageDescriptor(descr, lc1, lc2, lc3) \ + do \ + { \ + xCreateNode (((struct Iso639LanguageDescriptor *)descr), NULL); \ + ((struct Iso639LanguageDescriptor *)descr)->Tag = DESCR_ISO_639_LANGUAGE; \ + ((struct Iso639LanguageDescriptor *)descr)->LanguageCode[0] = lc1; \ + ((struct Iso639LanguageDescriptor *)descr)->LanguageCode[1] = lc2; \ + ((struct Iso639LanguageDescriptor *)descr)->LanguageCode[2] = lc3; \ + ((struct Iso639LanguageDescriptor *)descr)->LanguageCode[3] = '\0'; \ + } while (0) + + +/* AncillaryDataDescriptor */ + +struct AncillaryDataDescriptor { + struct NODE Node; + unsigned short Tag; + unsigned short Identifier; +}; + +#define ANCILLARY_DATA_DVD_VIDEO 0x0001 +#define ANCILLARY_DATA_EXTENDED 0x0002 +#define ANCILLARY_DATA_SWITCHING 0x0004 +#define ANCILLARY_DATA_DAB 0x0008 +#define ANCILLARY_DATA_SCALE_FACTOR 0x0010 + +#define CreateAncillaryDataDescriptor(descr, id) \ + do \ + { \ + xCreateNode (((struct AncillaryDataDescriptor *)descr), NULL); \ + ((struct AncillaryDataDescriptor *)descr)->Tag = DESCR_ANCILLARY_DATA; \ + ((struct AncillaryDataDescriptor *)descr)->Identifier = id; \ + } while (0) + + +/* BouquetNameDescriptor */ + +struct BouquetNameDescriptor { + struct NODE Node; /* Node enthält Namen */ + unsigned short Tag; +}; + +#define CreateBouquetNameDescriptor(descr, text) \ + do \ + { \ + xCreateNode (((struct BouquetNameDescriptor *)descr), text); \ + ((struct BouquetNameDescriptor *)descr)->Tag = DESCR_BOUQUET_NAME; \ + } while (0) + + +/* CountryAvailabilityDescriptor */ + +struct CountryAvailabilityDescriptor { + struct NODE Node; + unsigned short Tag; + unsigned short AvailibilityFlag; + unsigned short Amount; /* CountryCodes */ + char *CountryCodes; +}; + +#define COUNTRIES_ARE_AVAILABLE 0x0001 +#define COUNTRIES_ARE_UNAVAILABLE 0x0000 + +#define CreateCountryAvailabilityDescriptor(descr, ava) \ + do \ + { \ + xCreateNode (((struct CountryAvailabilityDescriptor *)descr), NULL); \ + ((struct CountryAvailabilityDescriptor *)descr)->Tag = DESCR_COUNTRY_AVAIL; \ + ((struct CountryAvailabilityDescriptor *)descr)->AvailibilityFlag = ava; \ + ((struct CountryAvailabilityDescriptor *)descr)->Amount = 0; \ + ((struct CountryAvailabilityDescriptor *)descr)->CountryCodes = NULL; \ + } while (0) + +#define AddCountryAvailabilityCode(descr, lc1, lc2, lc3) \ + do \ + { \ + char tmpbuf[4], *tmpptr, *ttptr; \ + \ + tmpbuf[0] = lc1; tmpbuf[1] = lc2; \ + tmpbuf[2] = lc3; tmpbuf[3] = '\0'; \ + xMemAlloc (((struct CountryAvailabilityDescriptor *)descr)->Amount*4 + 8, &tmpptr); \ + ttptr = tmpptr; \ + if (((struct CountryAvailabilityDescriptor *)descr)->CountryCodes) { \ + memcpy (ttptr, ((struct CountryAvailabilityDescriptor *)descr)->CountryCodes, \ + ((struct CountryAvailabilityDescriptor *)descr)->Amount*4); \ + ttptr += ((struct CountryAvailabilityDescriptor *)descr)->Amount*4; \ + } \ + memcpy (ttptr, tmpbuf, 4); \ + ((struct CountryAvailabilityDescriptor *)descr)->CountryCodes = tmpptr; \ + } while (0) + + +/* CaIdentifierDescriptor */ + +struct CaIdentifierDescriptor { + struct NODE Node; + unsigned short Tag; + unsigned short Amount; /* SystemIDs */ + unsigned short *SystemID; +}; + +#define CreateCaIdentifierDescriptor(descr, amo) \ + do \ + { \ + xCreateNode (((struct CaIdentifierDescriptor *)descr), NULL); \ + ((struct CaIdentifierDescriptor *)descr)->Tag = DESCR_CA_IDENT; \ + ((struct CaIdentifierDescriptor *)descr)->Amount = amo; \ + xMemAlloc (amo*2+2, &((struct CaIdentifierDescriptor *)descr)->SystemID); \ + } while (0) + +#define SetCaIdentifierID(descr, num, id) \ + ((struct CaIdentifierDescriptor *)descr)->SystemID[num] = id +#define GetCaIdentifierID(descr, num) (((struct CaIdentifierDescriptor *)descr)->SystemID[num]) + + +/* StreamIdentifierDescriptor */ + +struct StreamIdentifierDescriptor { + struct NODE Node; + unsigned short Tag; + unsigned short ComponentTag; +}; + +#define CreateStreamIdentifierDescriptor(descr, ctag) \ + do \ + { \ + xCreateNode (((struct StreamIdentifierDescriptor *)descr), NULL); \ + ((struct StreamIdentifierDescriptor *)descr)->Tag = DESCR_STREAM_ID; \ + ((struct StreamIdentifierDescriptor *)descr)->ComponentTag = (ctag); \ + } while (0) + + +/* DataBroadcastDescriptor */ + +struct DataBroadcastDescriptor { + struct NODE Node; /* Node enthält DescriptorText */ + unsigned short Tag; + unsigned short DataBroadcastID; + unsigned short ComponentTag; + unsigned short SelectorLength; + unsigned char *SelectorBytes; + char LanguageCode[4]; +}; + +struct MosaicDescriptor { + struct NODE Node; + unsigned short Tag; + /* to be defined */ +}; + +struct MultiLingualServiceDescriptor { + struct NODE Node; + unsigned short Tag; + /* to be defined */ +}; + + +/* NvodReferenceDescriptor */ + +struct NvodReferenceDescriptor { + struct NODE Node; + unsigned short Tag; + struct LIST *Items; +}; + +#define CreateNvodReferenceDescriptor(descr) \ + do \ + { \ + xCreateNode (((struct NvodReferenceDescriptor *)descr), NULL); \ + ((struct NvodReferenceDescriptor *)descr)->Tag = DESCR_NVOD_REF; \ + ((struct NvodReferenceDescriptor *)descr)->Items = xNewList (NULL); \ + } while (0) + +struct NvodReferenceItem { + struct NODE Node; + int TransportStreamID; + int OriginalNetworkID; + int ServiceID; +}; + +#define CreateNvodReferenceItem(itm, tpid, onid, svid) \ + do \ + { \ + xCreateNode (itm, NULL); \ + itm->TransportStreamID = tpid; \ + itm->OriginalNetworkID = onid; \ + itm->ServiceID = svid; \ + } while (0) + +#define AddNvodReferenceItem(desc, tpid, onid, svid) \ + do \ + { \ + struct NvodReferenceItem *item; \ + \ + CreateNvodReferenceItem(item, tpid, onid, svid); \ + xAddTail (((struct NvodReferenceDescriptor *)desc)->Items, item); \ + } while (0) + + +/* LinkageDescriptor */ + +struct LinkageDescriptor { + struct NODE Node; + unsigned short Tag; + int TransportStreamID; + int OriginalNetworkID; + int ServiceID; + int LinkageType; + int PrivateDataLength; + unsigned char *PrivateData; +}; + +#define CreateLinkageDescriptor(descr, tpid, onid, svid, ltyp, pdl, pdp) \ + do \ + { \ + xCreateNode (((struct LinkageDescriptor *)descr), NULL); \ + ((struct LinkageDescriptor *)descr)->Tag = DESCR_LINKAGE; \ + ((struct LinkageDescriptor *)descr)->TransportStreamID = tpid; \ + ((struct LinkageDescriptor *)descr)->OriginalNetworkID = onid; \ + ((struct LinkageDescriptor *)descr)->ServiceID = svid; \ + ((struct LinkageDescriptor *)descr)->LinkageType = ltyp; \ + ((struct LinkageDescriptor *)descr)->PrivateDataLength = pdl; \ + xMemAlloc ((pdl)+1, &(((struct LinkageDescriptor *) \ + descr)->PrivateData)); \ + memcpy ((((struct LinkageDescriptor *)descr)->PrivateData),(pdp),(pdl));\ + } while (0) + + +/* ServiceDescriptor */ + +struct ServiceDescriptor { + struct NODE Node; /* Node enthält ServiceName */ + unsigned short Tag; + unsigned short ServiceType; + char *ServiceProvider; +}; + +#define CreateServiceDescriptor(descr, styp, prov, name) \ + do \ + { \ + xCreateNode (((struct ServiceDescriptor *)descr), name); \ + ((struct ServiceDescriptor *)descr)->Tag = DESCR_SERVICE; \ + ((struct ServiceDescriptor *)descr)->ServiceType = styp; \ + ((struct ServiceDescriptor *)descr)->ServiceProvider = prov; \ + } while (0) + + + +struct TelephoneDescriptor { + struct NODE Node; + unsigned short Tag; + /* to be defined */ +}; + + +/* TimeShiftedServiceDescriptor */ + +struct TimeShiftedServiceDescriptor { + struct NODE Node; + unsigned short Tag; + int ReferenceServiceID; +}; + +#define CreateTimeShiftedServiceDescriptor(descr, svid) \ + do \ + { \ + xCreateNode (((struct TimeShiftedServiceDescriptor *)descr), NULL); \ + ((struct TimeShiftedServiceDescriptor *)descr)->Tag = DESCR_TIME_SHIFTED_SERVICE; \ + ((struct TimeShiftedServiceDescriptor *)descr)->ReferenceServiceID = svid; \ + } while (0) + + +/* TimeShiftedEventDescriptor */ + +struct TimeShiftedEventDescriptor { + struct NODE Node; + unsigned short Tag; + int ReferenceServiceID; + int ReferenceEventID; +}; + +#define CreateTimeShiftedEventDescriptor(descr, svid, evid) \ + do \ + { \ + xCreateNode (((struct TimeShiftedEventDescriptor *)descr), NULL); \ + ((struct TimeShiftedEventDescriptor *)descr)->Tag = DESCR_TIME_SHIFTED_EVENT; \ + ((struct TimeShiftedEventDescriptor *)descr)->ReferenceServiceID = svid; \ + ((struct TimeShiftedEventDescriptor *)descr)->ReferenceEventID = evid; \ + } while (0) + + +/* ComponentDescriptor */ + +struct ComponentDescriptor { + struct NODE Node; /* Node enthält ComponentText */ + unsigned short Tag; + unsigned short StreamContent; + unsigned short ComponentType; + unsigned short ComponentTag; + char LanguageCode[4]; +}; + +#define CreateComponentDescriptor(descr, scnt, ctyp, tag, lc1, lc2, lc3, txt) \ + do \ + { \ + xCreateNode (((struct ComponentDescriptor *)descr), txt); \ + ((struct ComponentDescriptor *)descr)->Tag = DESCR_COMPONENT; \ + ((struct ComponentDescriptor *)descr)->StreamContent = scnt; \ + ((struct ComponentDescriptor *)descr)->ComponentType = ctyp; \ + ((struct ComponentDescriptor *)descr)->ComponentTag = tag; \ + ((struct ComponentDescriptor *)descr)->LanguageCode[0] = lc1; \ + ((struct ComponentDescriptor *)descr)->LanguageCode[1] = lc2; \ + ((struct ComponentDescriptor *)descr)->LanguageCode[2] = lc3; \ + ((struct ComponentDescriptor *)descr)->LanguageCode[3] = '\0'; \ + } while (0) + + +/* ContentDescriptor */ + +struct ContentDescriptor { + struct NODE Node; + unsigned short Tag; + unsigned short Amount; /* ContentIDs */ + unsigned short *ContentID; +}; + +#define CreateContentDescriptor(descr, amo) \ + do \ + { \ + xCreateNode (((struct ContentDescriptor *)descr), NULL); \ + ((struct ContentDescriptor *)descr)->Tag = DESCR_CONTENT; \ + ((struct ContentDescriptor *)descr)->Amount = amo; \ + xMemAlloc (amo*2+2, &((struct ContentDescriptor *)descr)->ContentID); \ + } while (0) + +#define SetContentID(descr, num, cnib1, cnib2, unib1, unib2) \ + do \ + { \ + ((struct ContentDescriptor *)descr)->ContentID[num] = \ + ((cnib1&0xF) << 12) | ((cnib2&0xF) << 8) | \ + ((unib1&0xF) << 4) | (unib2&0xF); \ + } while (0) +#define GetContentContentNibble1(descr, num) ((((struct ContentDescriptor *)descr)->ContentID[num]&0xF000) >> 12) +#define GetContentContentNibble2(descr, num) ((((struct ContentDescriptor *)descr)->ContentID[num]&0x0F00) >> 8) +#define GetContentUserNibble1(descr, num) ((((struct ContentDescriptor *)descr)->ContentID[num]&0x00F0) >> 4) +#define GetContentUserNibble2(descr, num) (((struct ContentDescriptor *)descr)->ContentID[num]&0x000F) + + +/* ExtendedEventDescriptor */ + +struct ExtendedEventDescriptor { + struct NODE Node; /* Node enthält EventText */ + unsigned short Tag; + unsigned short DescriptorNumber; + unsigned short LastDescriptorNumber; + char LanguageCode[4]; + struct LIST *Items; +}; + +#define CreateExtendedEventDescriptor(descr, dnum, ldnb, lc1, lc2, lc3, text) \ + do \ + { \ + xCreateNode (((struct ExtendedEventDescriptor *)descr), text); \ + ((struct ExtendedEventDescriptor *)descr)->Tag = DESCR_EXTENDED_EVENT; \ + ((struct ExtendedEventDescriptor *)descr)->DescriptorNumber = dnum; \ + ((struct ExtendedEventDescriptor *)descr)->LastDescriptorNumber = ldnb; \ + ((struct ExtendedEventDescriptor *)descr)->LanguageCode[0] = lc1; \ + ((struct ExtendedEventDescriptor *)descr)->LanguageCode[1] = lc2; \ + ((struct ExtendedEventDescriptor *)descr)->LanguageCode[2] = lc3; \ + ((struct ExtendedEventDescriptor *)descr)->LanguageCode[3] = '\0'; \ + ((struct ExtendedEventDescriptor *)descr)->Items = xNewList (NULL); \ + } while (0) + +struct ExtendedEventItem { + struct NODE Node; /* Node enthält ItemDescription Text */ + char *Text; +}; + +#define CreateExtendedEventItem(itm, dtxt, text) \ + do \ + { \ + xCreateNode (itm, dtxt); \ + itm->Text = text; \ + } while (0) + +#define AddExtendedEventItem(desc, dtxt, text) \ + do \ + { \ + struct ExtendedEventItem *item; \ + \ + CreateExtendedEventItem(item, dtxt, text); \ + xAddTail (((struct ExtendedEventDescriptor *)desc)->Items, item); \ + } while (0) + + +/* ParentalRatingDescriptor */ + +struct ParentalRatingDescriptor { + struct NODE Node; + unsigned short Tag; + struct LIST *Ratings; +}; + +#define CreateParentalRatingDescriptor(descr) \ + do \ + { \ + xCreateNode (((struct ParentalRatingDescriptor *)descr), NULL); \ + ((struct ParentalRatingDescriptor *)descr)->Tag = DESCR_PARENTAL_RATING; \ + ((struct ParentalRatingDescriptor *)descr)->Ratings = xNewList (NULL); \ + } while (0) + +struct ParentalRating { + struct NODE Node; /* Node enthält ItemDescription Text */ + char LanguageCode[4]; + char Rating; +}; + +#define CreateParentalRating(rat, lc1, lc2, lc3, val) \ + do \ + { \ + xCreateNode (rat, NULL); \ + rat->LanguageCode[0] = lc1; \ + rat->LanguageCode[1] = lc2; \ + rat->LanguageCode[2] = lc3; \ + rat->LanguageCode[3] = '\0'; \ + rat->Rating = val; \ + } while (0) + +#define AddParentalRating(desc, lc1, lc2, lc3, val) \ + do \ + { \ + struct ParentalRating *item; \ + \ + CreateParentalRating(item, lc1, lc2, lc3, val); \ + xAddTail (((struct ParentalRatingDescriptor *)desc)->Ratings, item); \ + } while (0) + +/* ShortEventDescriptor */ + +struct ShortEventDescriptor { + struct NODE Node; /* Node enthält EventName */ + unsigned short Tag; + char LanguageCode[4]; + char *Text; +}; + +#define CreateShortEventDescriptor(descr, name, lc1, lc2, lc3, text) \ + do \ + { \ + xCreateNode (((struct ShortEventDescriptor *)descr), name); \ + ((struct ShortEventDescriptor *)descr)->Tag = DESCR_SHORT_EVENT; \ + ((struct ShortEventDescriptor *)descr)->LanguageCode[0] = lc1; \ + ((struct ShortEventDescriptor *)descr)->LanguageCode[1] = lc2; \ + ((struct ShortEventDescriptor *)descr)->LanguageCode[2] = lc3; \ + ((struct ShortEventDescriptor *)descr)->LanguageCode[3] = '\0'; \ + ((struct ShortEventDescriptor *)descr)->Text = text; \ + } while (0) + + + +/* Prototypes */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* si_parser.c */ + +struct LIST *siParsePAT (u_char *); +struct Pid *siParsePMT (u_char *); +struct LIST *siParseSDT (u_char *); +struct LIST *siParseEIT (u_char *); +time_t siParseTDT (u_char *); +void siParseDescriptors (struct LIST *, u_char *, u_int, u_char); +void siParseDescriptor (struct LIST *, u_char *); +char *siGetDescriptorText (u_char *, u_int); +u_long crc32 (char *data, int len); + +/* si_debug_services.c */ + +void siDebugServices (struct LIST *); +void siDebugService (struct Service *); +void siDebugEvents (char *, struct LIST *); +void siDebugPrograms (char *, struct LIST *); +void siDebugProgram (struct Program *); +void siDebugPids (char *, struct LIST *); +void siDebugDescriptors (char *, struct LIST *); +void siDebugEitServices (struct LIST *); +void siDebugEitEvents (char *, struct LIST *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libdtv/libsi/include/si_tables.h b/libdtv/libsi/include/si_tables.h new file mode 100644 index 0000000..517838a --- /dev/null +++ b/libdtv/libsi/include/si_tables.h @@ -0,0 +1,1205 @@ +////////////////////////////////////////////////////////////// +/// /// +/// si_tables.h: definitions for data structures of the /// +/// incoming SI data stream /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/06/25 12:41:20 $ +// $Author: kls $ +// +// (C) 2001 Rolf Hakenes , under the GNU GPL. +// +// libsi is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// libsi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with libsi; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#ifndef SI_TABLES_H +#define SI_TABLES_H + +#define HILO(x) (x##_hi << 8 | x##_lo) + +#define MjdToEpochTime(x) (((x##_hi << 8 | x##_lo)-40587)*86400) +#define BcdTimeToSeconds(x) ((3600 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \ + (60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \ + ((10*((x##_s & 0xF0)>>4)) + (x##_s & 0xF))) + +#define TableHasMoreSections(x) (((pat_t *)(x))->last_section_number > ((pat_t *)(x))->section_number) +#define GetTableId(x) ((pat_t *)(x))->table_id +#define GetSectionNumber(x) ((pat_t *)(x))->section_number +#define GetLastSectionNumber(x) ((pat_t *)(x))->last_section_number +#define GetServiceId(x) (((eit_t *)(x))->service_id_hi << 8) | ((eit_t *)(x))->service_id_lo + +/* + * + * ETSI ISO/IEC 13818-1 specifies SI which is referred to as PSI. The PSI + * data provides information to enable automatic configuration of the + * receiver to demultiplex and decode the various streams of programs + * within the multiplex. The PSI data is structured as four types of table. + * The tables are transmitted in sections. + * + * 1) Program Association Table (PAT): + * + * - for each service in the multiplex, the PAT indicates the location + * (the Packet Identifier (PID) values of the Transport Stream (TS) + * packets) of the corresponding Program Map Table (PMT). + * It also gives the location of the Network Information Table (NIT). + * + */ + +#define PAT_LEN 8 + +typedef struct { + u_char table_id :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char section_syntax_indicator :1; + u_char dummy :1; // has to be 0 + u_char :2; + u_char section_length_hi :4; +#else + u_char section_length_hi :4; + u_char :2; + u_char dummy :1; // has to be 0 + u_char section_syntax_indicator :1; +#endif + u_char section_length_lo :8; + u_char transport_stream_id_hi :8; + u_char transport_stream_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; +} pat_t; + +#define PAT_PROG_LEN 4 + +typedef struct { + u_char program_number_hi :8; + u_char program_number_lo :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char :3; + u_char network_pid_hi :5; +#else + u_char network_pid_hi :5; + u_char :3; +#endif + u_char network_pid_lo :8; + /* or program_map_pid (if prog_num=0)*/ +} pat_prog_t; + +/* + * + * 2) Conditional Access Table (CAT): + * + * - the CAT provides information on the CA systems used in the + * multiplex; the information is private and dependent on the CA + * system, but includes the location of the EMM stream, when + * applicable. + * + */ + /* TO BE DONE */ +/* + * + * 3) Program Map Table (PMT): + * + * - the PMT identifies and indicates the locations of the streams that + * make up each service, and the location of the Program Clock + * Reference fields for a service. + * + */ + +#define PMT_LEN 12 + +typedef struct { + u_char table_id :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char section_syntax_indicator :1; + u_char dummy :1; // has to be 0 + u_char :2; + u_char section_length_hi :4; +#else + u_char section_length_hi :4; + u_char :2; + u_char dummy :1; // has to be 0 + u_char section_syntax_indicator :1; +#endif + u_char section_length_lo :8; + u_char program_number_hi :8; + u_char program_number_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; +#if BYTE_ORDER == BIG_ENDIAN + u_char :3; + u_char PCR_PID_hi :5; +#else + u_char PCR_PID_hi :5; + u_char :3; +#endif + u_char PCR_PID_lo :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char :4; + u_char program_info_length_hi :4; +#else + u_char program_info_length_hi :4; + u_char :4; +#endif + u_char program_info_length_lo :8; + //descriptors +} pmt_t; + +#define PMT_INFO_LEN 5 + +typedef struct { + u_char stream_type :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char :3; + u_char elementary_PID_hi :5; +#else + u_char elementary_PID_hi :5; + u_char :3; +#endif + u_char elementary_PID_lo :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char :4; + u_char ES_info_length_hi :4; +#else + u_char ES_info_length_hi :4; + u_char :4; +#endif + u_char ES_info_length_lo :8; + // descriptors +} pmt_info_t; + +/* + * + * 4) Network Information Table (NIT): + * + * - the NIT is intended to provide information about the physical + * network. The syntax and semantics of the NIT are defined in + * ETSI EN 300 468. + * + */ + +#define NIT_LEN 10 + +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 network_id_hi :8; + u_char network_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; +#if BYTE_ORDER == BIG_ENDIAN + u_char :4; + u_char network_descriptor_length_hi :4; +#else + u_char network_descriptor_length_hi :4; + u_char :4; +#endif + u_char network_descriptor_length_lo :8; + /* descriptors */ +} nit_t; + +#define SIZE_NIT_MID 2 + +typedef struct { // after descriptors +#if BYTE_ORDER == BIG_ENDIAN + u_char :4; + u_char transport_stream_loop_length_hi :4; +#else + u_char transport_stream_loop_length_hi :4; + u_char :4; +#endif + u_char transport_stream_loop_length_lo :8; +} nit_mid_t; + +#define SIZE_NIT_END 4 + +struct nit_end_struct { + long CRC; +}; + +#define NIT_TS_LEN 6 + +typedef struct { + 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; +#if BYTE_ORDER == BIG_ENDIAN + u_char :4; + u_char transport_descriptors_length_hi :4; +#else + u_char transport_descriptors_length_hi :4; + u_char :4; +#endif + u_char transport_descriptors_length_lo :8; + /* descriptors */ +} nit_ts_t; + +/* + * + * In addition to the PSI, data is needed to provide identification of + * services and events for the user. In contrast with the PAT, CAT, and + * PMT of the PSI, which give information only for the multiplex in which + * they are contained (the actual multiplex), the additional information + * defined within the present document can also provide information on + * services and events carried by different multiplexes, and even on other + * networks. This data is structured as nine tables: + * + * 1) Bouquet Association Table (BAT): + * + * - the BAT provides information regarding bouquets. As well as giving + * the name of the bouquet, it provides a list of services for each + * bouquet. + * + */ + /* TO BE DONE */ +/* + * + * 2) Service Description Table (SDT): + * + * - the SDT contains data describing the services in the system e.g. + * names of services, the service provider, etc. + * + */ + +#define SDT_LEN 11 + +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 transport_stream_id_hi :8; + u_char transport_stream_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 original_network_id_hi :8; + u_char original_network_id_lo :8; + u_char :8; +} sdt_t; + +#define SDT_DESCR_LEN 5 + +typedef struct { + u_char service_id_hi :8; + u_char service_id_lo :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char :6; + u_char eit_schedule_flag :1; + u_char eit_present_following_flag :1; + u_char running_status :3; + u_char free_ca_mode :1; + u_char descriptors_loop_length_hi :4; +#else + u_char eit_present_following_flag :1; + u_char eit_schedule_flag :1; + u_char :6; + 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; +} sdt_descr_t; + +/* + * + * 3) Event Information Table (EIT): + * + * - the EIT contains data concerning events or programmes such as event + * name, start time, duration, etc.; - the use of different descriptors + * allows the transmission of different kinds of event information e.g. + * for different service types. + * + */ + +#define EIT_LEN 14 + +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 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; + +#define EIT_EVENT_LEN 12 + +typedef struct { + u_char event_id_hi :8; + u_char event_id_lo :8; + u_char mjd_hi :8; + u_char mjd_lo :8; + u_char start_time_h :8; + u_char start_time_m :8; + u_char start_time_s :8; + u_char duration_h :8; + u_char duration_m :8; + u_char duration_s :8; +#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_event_t; + +/* + * + * 4) Running Status Table (RST): + * + * - the RST gives the status of an event (running/not running). The RST + * updates this information and allows timely automatic switching to + * events. + * + */ + /* TO BE DONE */ +/* + * + * 5) Time and Date Table (TDT): + * + * - the TDT gives information relating to the present time and date. + * This information is given in a separate table due to the frequent + * updating of this information. + * + */ + +#define TDT_LEN 8 + +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_mjd_hi :8; + u_char utc_mjd_lo :8; + u_char utc_time_h :8; + u_char utc_time_m :8; + u_char utc_time_s :8; +} tdt_t; + +/* + * + * 6) Time Offset Table (TOT): + * + * - the TOT gives information relating to the present time and date and + * local time offset. This information is given in a separate table due + * to the frequent updating of the time information. + * + */ + /* TO BE DONE */ +/* + * + * 7) Stuffing Table (ST): + * + * - the ST is used to invalidate existing sections, for example at + * delivery system boundaries. + * + */ + /* TO BE DONE */ +/* + * + * 8) Selection Information Table (SIT): + * + * - the SIT is used only in "partial" (i.e. recorded) bitstreams. It + * carries a summary of the SI information required to describe the + * streams in the partial bitstream. + * + */ + /* TO BE DONE */ +/* + * + * 9) Discontinuity Information Table (DIT): + * + * - the DIT is used only in "partial" (i.e. recorded) bitstreams. + * It is inserted where the SI information in the partial bitstream may + * be discontinuous. Where applicable the use of descriptors allows a + * flexible approach to the organization of the tables and allows for + * future compatible extensions. + * + */ + /* TO BE DONE */ +/* + * + * The following describes the different descriptors that can be used within + * the SI. + * + * The following semantics apply to all the descriptors defined in this + * subclause: + * + * descriptor_tag: The descriptor tag is an 8-bit field which identifies + * each descriptor. Those values with MPEG-2 normative + * meaning are described in ISO/IEC 13818-1. The values of + * descriptor_tag are defined in 'libsi.h' + * descriptor_length: The descriptor length is an 8-bit field specifying the + * total number of bytes of the data portion of the + * descriptor following the byte defining the value of + * this field. + * + */ + +#define DESCR_GEN_LEN 2 +typedef struct descr_gen_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; +} descr_gen_t; +#define CastGenericDescriptor(x) ((descr_gen_t *)(x)) + +#define GetDescriptorTag(x) (((descr_gen_t *) x)->descriptor_tag) +#define GetDescriptorLength(x) (((descr_gen_t *) x)->descriptor_length+DESCR_GEN_LEN) + + +/* 0x0A iso_639_language_descriptor */ + +#define DESCR_ISO_639_LANGUAGE_LEN 5 +typedef struct descr_iso_639_language_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char lang_code1 :8; + u_char lang_code2 :8; + u_char lang_code3 :8; +} descr_iso_639_language_t; +#define CastIso639LanguageDescriptor(x) ((descr_iso_639_language_t *)(x)) + + +/* 0x40 network_name_descriptor */ + +#define DESCR_NETWORK_NAME_LEN XX +typedef struct descr_network_name_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_network_name_t; +#define CastNetworkNameDescriptor(x) ((descr_network_name_t *)(x)) + + +/* 0x41 service_list_descriptor */ + +#define DESCR_SERVICE_LIST_LEN XX +typedef struct descr_service_list_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_service_list_t; +#define CastServiceListDescriptor(x) ((descr_service_list_t *)(x)) + + +/* 0x42 stuffing_descriptor */ + +#define DESCR_STUFFING_LEN XX +typedef struct descr_stuffing_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_stuffing_t; +#define CastStuffingDescriptor(x) ((descr_stuffing_t *)(x)) + + +/* 0x43 satellite_delivery_system_descriptor */ + +#define DESCR_SATELLITE_DELIVERY_SYSTEM_LEN 13 +typedef struct descr_satellite_delivery_system_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char frequency1 :8; + u_char frequency2 :8; + u_char frequency3 :8; + u_char frequency4 :8; + u_char orbital_position1 :8; + u_char orbital_position2 :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char modulation :5; + u_char polarization :2; + u_char west_east_flag :1; +#else + u_char west_east_flag :1; + u_char polarization :2; + u_char modulation :5; +#endif + u_char symbol_rate1 :8; + u_char symbol_rate2 :8; + u_char symbol_rate3 :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char symbol_rate4 :4; + u_char fec_inner :4; +#else + u_char fec_inner :4; + u_char symbol_rate4 :4; +#endif +} descr_satellite_delivery_system_t; +#define CastSatelliteDeliverySystemDescriptor(x) ((descr_satellite_delivery_system_t *)(x)) + + +/* 0x44 cable_delivery_system_descriptor */ + +#define DESCR_CABLE_DELIVERY_SYSTEM_LEN 13 +typedef struct descr_cable_delivery_system_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char frequency1 :8; + u_char frequency2 :8; + u_char frequency3 :8; + u_char frequency4 :8; + u_char reserved1 :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char reserved2 :4; + u_char fec_outer :4; +#else + u_char fec_outer :4; + u_char reserved2 :4; +#endif + u_char modulation :8; + u_char symbol_rate1 :8; + u_char symbol_rate2 :8; + u_char symbol_rate3 :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char symbol_rate4 :4; + u_char fec_inner :4; +#else + u_char fec_inner :4; + u_char symbol_rate4 :4; +#endif +} descr_cable_delivery_system_t; +#define CastCableDeliverySystemDescriptor(x) ((descr_cable_delivery_system_t *)(x)) + + +/* 0x45 vbi_data_descriptor */ + +#define DESCR_VBI_DATA_LEN XX +typedef struct descr_vbi_data_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_vbi_data_t; +#define CastVbiDataDescriptor(x) ((descr_vbi_data_t *)(x)) + + +/* 0x46 vbi_teletext_descriptor */ + +#define DESCR_VBI_TELETEXT_LEN XX +typedef struct descr_vbi_teletext_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_vbi_teletext_t; +#define CastVbiDescriptor(x) ((descr_vbi_teletext_t *)(x)) + + +/* 0x47 bouquet_name_descriptor */ + +#define DESCR_BOUQUET_NAME_LEN 2 +typedef struct descr_bouquet_name_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; +} descr_bouquet_name_t; +#define CastBouquetNameDescriptor(x) ((descr_bouquet_name_t *)(x)) + + +/* 0x48 service_descriptor */ + +#define DESCR_SERVICE_LEN 4 +typedef struct descr_service_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char service_type :8; + u_char provider_name_length :8; +} descr_service_t; +#define CastServiceDescriptor(x) ((descr_service_t *)(x)) + + +/* 0x49 country_availability_descriptor */ + +#define DESCR_COUNTRY_AVAILABILITY_LEN 3 +typedef struct descr_country_availability_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char country_availability_flag :1; + u_char reserved :7; +#else + u_char reserved :7; + u_char country_availability_flag :1; +#endif +} descr_country_availability_t; +#define CastCountryAvailabilityDescriptor(x) ((descr_country_availability_t *)(x)) + + +/* 0x4A linkage_descriptor */ + +#define DESCR_LINKAGE_LEN 9 +typedef struct descr_linkage_struct { + u_char descriptor_tag :8; + u_char descriptor_length :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 service_id_hi :8; + u_char service_id_lo :8; + u_char linkage_type :8; +} descr_linkage_t; +#define CastLinkageDescriptor(x) ((descr_linkage_t *)(x)) + + +/* 0x4B nvod_reference_descriptor */ + +#define DESCR_NVOD_REFERENCE_LEN 2 +typedef struct descr_nvod_reference_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; +} descr_nvod_reference_t; +#define CastNvodReferenceDescriptor(x) ((descr_nvod_reference_t *)(x)) + +#define ITEM_NVOD_REFERENCE_LEN 6 +typedef struct item_nvod_reference_struct { + 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 service_id_hi :8; + u_char service_id_lo :8; +} item_nvod_reference_t; +#define CastNvodReferenceItem(x) ((item_nvod_reference_t *)(x)) + + + +/* 0x4C time_shifted_service_descriptor */ + +#define DESCR_TIME_SHIFTED_SERVICE_LEN 4 +typedef struct descr_time_shifted_service_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char reference_service_id_hi :8; + u_char reference_service_id_lo :8; +} descr_time_shifted_service_t; +#define CastTimeShiftedServiceDescriptor(x) ((descr_time_shifted_service_t *)(x)) + + +/* 0x4D short_event_descriptor */ + +#define DESCR_SHORT_EVENT_LEN 6 +typedef struct descr_short_event_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char lang_code1 :8; + u_char lang_code2 :8; + u_char lang_code3 :8; + u_char event_name_length :8; +} descr_short_event_t; +#define CastShortEventDescriptor(x) ((descr_short_event_t *)(x)) + + +/* 0x4E extended_event_descriptor */ + +#define DESCR_EXTENDED_EVENT_LEN 7 +typedef struct descr_extended_event_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +#if BYTE_ORDER == BIG_ENDIAN + u_char descriptor_number :4; + u_char last_descriptor_number :4; +#else + u_char last_descriptor_number :4; + u_char descriptor_number :4; +#endif + u_char lang_code1 :8; + u_char lang_code2 :8; + u_char lang_code3 :8; + u_char length_of_items :8; +} descr_extended_event_t; +#define CastExtendedEventDescriptor(x) ((descr_extended_event_t *)(x)) + +#define ITEM_EXTENDED_EVENT_LEN 1 +typedef struct item_extended_event_struct { + u_char item_description_length :8; +} item_extended_event_t; +#define CastExtendedEventItem(x) ((item_extended_event_t *)(x)) + + +/* 0x4F time_shifted_event_descriptor */ + +#define DESCR_TIME_SHIFTED_EVENT_LEN 6 +typedef struct descr_time_shifted_event_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char reference_service_id_hi :8; + u_char reference_service_id_lo :8; + u_char reference_event_id_hi :8; + u_char reference_event_id_lo :8; +} descr_time_shifted_event_t; +#define CastTimeShiftedEventDescriptor(x) ((descr_time_shifted_event_t *)(x)) + + +/* 0x50 component_descriptor */ + +#define DESCR_COMPONENT_LEN 8 +typedef struct descr_component_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; +#if BYTE_ORDER == BIG_ENDIAN + u_char reserved :4; + u_char stream_content :4; +#else + u_char stream_content :4; + u_char reserved :4; +#endif + u_char component_type :8; + u_char component_tag :8; + u_char lang_code1 :8; + u_char lang_code2 :8; + u_char lang_code3 :8; +} descr_component_t; +#define CastComponentDescriptor(x) ((descr_component_t *)(x)) + + +/* 0x51 mosaic_descriptor */ + +#define DESCR_MOSAIC_LEN XX +typedef struct descr_mosaic_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_mosaic_t; +#define CastMosaicDescriptor(x) ((descr_mosaic_t *)(x)) + + +/* 0x52 stream_identifier_descriptor */ + +#define DESCR_STREAM_IDENTIFIER_LEN 3 +typedef struct descr_stream_identifier_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char component_tag :8; +} descr_stream_identifier_t; +#define CastStreamIdentifierDescriptor(x) ((descr_stream_identifier_t *)(x)) + + +/* 0x53 ca_identifier_descriptor */ + +#define DESCR_CA_IDENTIFIER_LEN 2 +typedef struct descr_ca_identifier_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; +} descr_ca_identifier_t; +#define CastCaIdentifierDescriptor(x) ((descr_ca_identifier_t *)(x)) + + +/* 0x54 content_descriptor */ + +#define DESCR_CONTENT_LEN 2 +typedef struct descr_content_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; +} descr_content_t; +#define CastContentDescriptor(x) ((descr_content_t *)(x)) + +typedef struct nibble_content_struct { +#if BYTE_ORDER == BIG_ENDIAN + u_char content_nibble_level_1 :4; + u_char content_nibble_level_2 :4; + u_char user_nibble_1 :4; + u_char user_nibble_2 :4; +#else + u_char user_nibble_2 :4; + u_char user_nibble_1 :4; + u_char content_nibble_level_2 :4; + u_char content_nibble_level_1 :4; +#endif +} nibble_content_t; +#define CastContentNibble(x) ((nibble_content_t *)(x)) + + +/* 0x55 parental_rating_descriptor */ + +#define DESCR_PARENTAL_RATING_LEN 2 +typedef struct descr_parental_rating_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; +} descr_parental_rating_t; +#define CastParentalRatingDescriptor(x) ((descr_parental_rating_t *)(x)) + +#define PARENTAL_RATING_LEN 4 +typedef struct parental_rating_struct { + u_char lang_code1 :8; + u_char lang_code2 :8; + u_char lang_code3 :8; + u_char rating :8; +} parental_rating_t; +#define CastParentalRating(x) ((parental_rating_t *)(x)) + + +/* 0x56 teletext_descriptor */ + +#define DESCR_TELETEXT_LEN XX +typedef struct descr_teletext_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_teletext_t; +#define CastTeletextDescriptor(x) ((descr_teletext_t *)(x)) + + +/* 0x57 telephone_descriptor */ + +#define DESCR_TELEPHONE_LEN XX +typedef struct descr_telephone_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_telephone_t; +#define CastTelephoneDescriptor(x) ((descr_telephone_t *)(x)) + + +/* 0x58 local_time_offset_descriptor */ + +#define DESCR_LOCAL_TIME_OFFSET_LEN XX +typedef struct descr_local_time_offset_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_local_time_offset_t; +#define CastLocalTimeOffsetDescriptor(x) ((descr_local_time_offset_t *)(x)) + + +/* 0x59 subtitling_descriptor */ + +#define DESCR_SUBTITLING_LEN XX +typedef struct descr_subtitling_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_subtitling_t; +#define CastSubtitlingDescriptor(x) ((descr_subtitling_t *)(x)) + + +/* 0x5A terrestrial_delivery_system_descriptor */ + +#define DESCR_TERRESTRIAL_DELIVERY_SYSTEM_LEN XX +typedef struct descr_terrestrial_delivery_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_terrestrial_delivery_system_t; +#define CastTerrestrialDeliverySystemDescriptor(x) ((descr_terrestrial_delivery_system_t *)(x)) + + +/* 0x5B multilingual_network_name_descriptor */ + +#define DESCR_MULTILINGUAL_NETWORK_NAME_LEN XX +typedef struct descr_multilingual_network_name_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_multilingual_network_name_t; +#define CastMultilingualNetworkNameDescriptor(x) ((descr_multilingual_network_name_t *)(x)) + + +/* 0x5C multilingual_bouquet_name_descriptor */ + +#define DESCR_MULTILINGUAL_BOUQUET_NAME_LEN XX +typedef struct descr_multilingual_bouquet_name_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_multilingual_bouquet_name_t; +#define CastMultilingualBouquetNameDescriptor(x) ((descr_multilingual_bouquet_name_t *)(x)) + + +/* 0x5D multilingual_service_name_descriptor */ + +#define DESCR_MULTILINGUAL_SERVICE_NAME_LEN XX +typedef struct descr_multilingual_service_name_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_multilingual_service_name_t; +#define CastMultilingualServiceNameDescriptor(x) ((descr_multilingual_service_name_t *)(x)) + + +/* 0x5E multilingual_component_descriptor */ + +#define DESCR_MULTILINGUAL_COMPONENT_LEN XX +typedef struct descr_multilingual_component_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_multilingual_component_t; +#define CastMultilingualComponentDescriptor(x) ((descr_multilingual_component_t *)(x)) + + +/* 0x5F private_data_specifier_descriptor */ + +#define DESCR_PRIVATE_DATA_SPECIFIER_LEN XX +typedef struct descr_private_data_specifier_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_private_data_specifier_t; +#define CastPrivateDataSpecifierDescriptor(x) ((descr_private_data_specifier_t *)(x)) + + +/* 0x60 service_move_descriptor */ + +#define DESCR_SERVICE_MOVE_LEN XX +typedef struct descr_service_move_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_service_move_t; +#define CastServiceMoveDescriptor(x) ((descr_service_move_t *)(x)) + + +/* 0x61 short_smoothing_buffer_descriptor */ + +#define DESCR_SHORT_SMOOTHING_BUFFER_LEN XX +typedef struct descr_short_smoothing_buffer_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_short_smoothing_buffer_t; +#define CastShortSmoothingBufferDescriptor(x) ((descr_short_smoothing_buffer_t *)(x)) + + +/* 0x62 frequency_list_descriptor */ + +#define DESCR_FREQUENCY_LIST_LEN XX +typedef struct descr_frequency_list_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_frequency_list_t; +#define CastFrequencyListDescriptor(x) ((descr_frequency_list_t *)(x)) + + +/* 0x63 partial_transport_stream_descriptor */ + +#define DESCR_PARTIAL_TRANSPORT_STREAM_LEN XX +typedef struct descr_partial_transport_stream_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_partial_transport_stream_t; +#define CastPartialDescriptor(x) ((descr_partial_transport_stream_t *)(x)) + + +/* 0x64 data_broadcast_descriptor */ + +#define DESCR_DATA_BROADCAST_LEN XX +typedef struct descr_data_broadcast_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_data_broadcast_t; +#define CastDataBroadcastDescriptor(x) ((descr_data_broadcast_t *)(x)) + + +/* 0x65 ca_system_descriptor */ + +#define DESCR_CA_SYSTEM_LEN XX +typedef struct descr_ca_system_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_ca_system_t; +#define CastCaSystemDescriptor(x) ((descr_ca_system_t *)(x)) + + +/* 0x66 data_broadcast_id_descriptor */ + +#define DESCR_DATA_BROADCAST_ID_LEN XX +typedef struct descr_data_broadcast_id_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_data_broadcast_id_t; +#define CastDataBroadcastIdDescriptor(x) ((descr_data_broadcast_id_t *)(x)) + + +/* 0x67 transport_stream_descriptor */ + +#define DESCR_TRANSPORT_STREAM_LEN XX +typedef struct descr_transport_stream_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_transport_stream_t; +#define CastTransportStreamDescriptor(x) ((descr_transport_stream_t *)(x)) + + +/* 0x68 dsng_descriptor */ + +#define DESCR_DSNG_LEN XX +typedef struct descr_dsng_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_dsng_t; +#define CastDsngDescriptor(x) ((descr_dsng_t *)(x)) + + +/* 0x69 pdc_descriptor */ + +#define DESCR_PDC_LEN XX +typedef struct descr_pdc_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_pdc_t; +#define CastPdcDescriptor(x) ((descr_pdc_t *)(x)) + + +/* 0x6A ac3_descriptor */ + +#define DESCR_AC3_LEN XX +typedef struct descr_ac3_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_ac3_t; +#define CastAc3Descriptor(x) ((descr_ac3_t *)(x)) + + +/* 0x6B ancillary_data_descriptor */ + +#define DESCR_ANCILLARY_DATA_LEN 3 +typedef struct descr_ancillary_data_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char ancillary_data_identifier :8; +} descr_ancillary_data_t; +#define CastAncillaryDataDescriptor(x) ((descr_ancillary_data_t *)(x)) + + +/* 0x6C cell_list_descriptor */ + +#define DESCR_CELL_LIST_LEN XX +typedef struct descr_cell_list_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_cell_list_t; +#define CastCellListDescriptor(x) ((descr_cell_list_t *)(x)) + + +/* 0x6D cell_frequency_link_descriptor */ + +#define DESCR_CELL_FREQUENCY_LINK_LEN XX +typedef struct descr_cell_frequency_link_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_cell_frequency_link_t; +#define CastCellFrequencyLinkDescriptor(x) ((descr_cell_frequency_link_t *)(x)) + + +/* 0x6E announcement_support_descriptor */ + +#define DESCR_ANNOUNCEMENT_SUPPORT_LEN XX +typedef struct descr_announcement_support_struct { + u_char descriptor_tag :8; + u_char descriptor_length :8; + /* TBD */ +} descr_announcement_support_t; +#define CastAnnouncementSupportDescriptor(x) ((descr_announcement_support_t *)(x)) + +#endif diff --git a/libdtv/libsi/si_debug_services.c b/libdtv/libsi/si_debug_services.c new file mode 100644 index 0000000..dd09cff --- /dev/null +++ b/libdtv/libsi/si_debug_services.c @@ -0,0 +1,487 @@ +////////////////////////////////////////////////////////////// +/// /// +/// si_debug_services.c: debugging functions for libsi /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/08/15 14:40:55 $ +// $Author: kls $ +// +// (C) 2001 Rolf Hakenes , under the GNU GPL. +// +// libsi is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// libsi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with libsi; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#include +#include +#include + +#include "../liblx/liblx.h" +#include "libsi.h" +#include "si_debug_services.h" + + + + +void siDebugServices (struct LIST *Services) +{ + struct Service *Service; + + if (!Services) return; + + xForeach (Services, Service) + { + printf ("Service\n=======\n"); + printf (" ServiceID: %d\n", Service->ServiceID); + printf (" TransportStreamID: %d\n", Service->TransportStreamID); + printf (" OriginalNetworkID: %d\n", Service->OriginalNetworkID); + printf (" SdtVersion: %d\n", Service->SdtVersion); + printf (" Status: "); + if (GetScheduleFlag (Service->Status)) + printf ("SCHEDULE_INFO "); + if (GetPresentFollowing(Service->Status)) + printf ("PRESENT_FOLLOWING "); + switch (GetRunningStatus (Service->Status)) + { + case RUNNING_STATUS_NOT_RUNNING: + printf ("RUNNING_STATUS_NOT_RUNNING\n"); + break; + + case RUNNING_STATUS_AWAITING: + printf ("RUNNING_STATUS_AWAITING\n"); + break; + + case RUNNING_STATUS_PAUSING: + printf ("RUNNING_STATUS_PAUSING\n"); + break; + + case RUNNING_STATUS_RUNNING: + printf ("RUNNING_STATUS_RUNNING\n"); + break; + } + siDebugDescriptors (" ", Service->Descriptors); + siDebugEvents (" ", Service->Events); + } + return; +} + +void siDebugService (struct Service *Service) +{ + if (!Service) return; + + printf ("Service\r\n=======\r\n"); + printf (" ServiceID: %d\r\n", Service->ServiceID); + printf (" TransportStreamID: %d\r\n", Service->TransportStreamID); + printf (" OriginalNetworkID: %d\r\n", Service->OriginalNetworkID); + printf (" SdtVersion: %d\r\n", Service->SdtVersion); + printf (" Status: "); + if (GetScheduleFlag (Service->Status)) + printf ("SCHEDULE_INFO "); + if (GetPresentFollowing(Service->Status)) + printf ("PRESENT_FOLLOWING "); + switch (GetRunningStatus (Service->Status)) + { + case RUNNING_STATUS_NOT_RUNNING: + printf ("RUNNING_STATUS_NOT_RUNNING\r\n"); + break; + + case RUNNING_STATUS_AWAITING: + printf ("RUNNING_STATUS_AWAITING\r\n"); + break; + + case RUNNING_STATUS_PAUSING: + printf ("RUNNING_STATUS_PAUSING\r\n"); + break; + + case RUNNING_STATUS_RUNNING: + printf ("RUNNING_STATUS_RUNNING\r\n"); + break; + } + siDebugDescriptors ("\r ", Service->Descriptors); + siDebugEvents ("\r ", Service->Events); + + return; +} + +void siDebugEvents (char *Prepend, struct LIST *EventList) +{ + struct Event *Event; + char NewPrepend[32]; + + if (!EventList) return; + + xForeach (EventList, Event) + { + printf ("%sEvent\n%s=====\n", Prepend, Prepend); + printf ("%s EventID: %d\n", Prepend, Event->EventID); + printf ("%s ServiceID: %d\n", Prepend, Event->ServiceID); + printf ("%s TransportStreamID: %d\n", Prepend, Event->TransportStreamID); + printf ("%s OriginalNetworkID: %d\n", Prepend, Event->OriginalNetworkID); + printf ("%s EitVersion: %d\n", Prepend, Event->EitVersion); + printf ("%s StartTime: %s", Prepend, ctime (&Event->StartTime)); + printf ("%s Duration: %d Minuten\n", Prepend, Event->Duration/60); + printf ("%s Status: "); + switch (GetRunningStatus (Event->Status)) + { + case RUNNING_STATUS_NOT_RUNNING: + printf ("RUNNING_STATUS_NOT_RUNNING\n"); + break; + + case RUNNING_STATUS_AWAITING: + printf ("RUNNING_STATUS_AWAITING\n"); + break; + + case RUNNING_STATUS_PAUSING: + printf ("RUNNING_STATUS_PAUSING\n"); + break; + + case RUNNING_STATUS_RUNNING: + printf ("RUNNING_STATUS_RUNNING\n"); + break; + } + sprintf (NewPrepend, "%s ", Prepend); + siDebugDescriptors (NewPrepend, Event->Descriptors); + } + return; +} + + +void siDebugPrograms (char *Prepend, struct LIST *ProgramList) +{ + struct Program *Program; + char NewPrepend[32]; + + if (!ProgramList) return; + + xForeach (ProgramList, Program) + { + printf ("%sProgram\n%s=======\n", Prepend, Prepend); + printf ("%s ProgramID: %d\n", Prepend, Program->ProgramID); + printf ("%s TransportStreamID: %d\n", Prepend, Program->TransportStreamID); + printf ("%s NetworkPID: %d\n", Prepend, Program->NetworkPID); + printf ("%s PatVersion: %d\n", Prepend, Program->PatVersion); + + sprintf (NewPrepend, "%s ", Prepend); + siDebugPids (NewPrepend, Program->Pids); + } + return; +} + +void siDebugProgram (struct Program *Program) +{ + if (!Program) return; + + printf ("Program\r\n=======\r\n"); + printf (" ProgramID: %d\r\n", Program->ProgramID); + printf (" TransportStreamID: %d\r\n", Program->TransportStreamID); + printf (" NetworkPID: %d\r\n", Program->NetworkPID); + printf (" PatVersion: %d\r\n", Program->PatVersion); + + siDebugPids ("\r ", Program->Pids); + + return; +} + +void siDebugPids (char *Prepend, struct LIST *PidList) +{ + struct Pid *Pid; + struct PidInfo *PidInfo; + char NewPrepend[32]; + int index; + + if (!PidList) return; + + xForeach (PidList, Pid) + { + printf ("%sPid\n%s===\n", Prepend, Prepend); + printf ("%s ProgramID: %d\n", Prepend, Pid->ProgramID); + printf ("%s PcrPid: %d\n", Prepend, Pid->PcrPID); + printf ("%s PmtVersion: %d\n", Prepend, Pid->PmtVersion); + + xForeach (Pid->InfoList, PidInfo) + { + printf ("%s PidInfo\n%s =======\n", Prepend, Prepend); + index = PidInfo->StreamType; + if (index > 0x0F && index <= 0x7F) index = 0x0E; + if (index >= 0x80) index = 0x0F; + printf ("%s StreamType: %s\n", Prepend, StreamTypes[index]); + printf ("%s ElementaryPid: %d\n", Prepend, PidInfo->ElementaryPid); + + sprintf (NewPrepend, "%s ", Prepend); + siDebugDescriptors (NewPrepend, PidInfo->Descriptors); + } + } + return; +} + + +void siDebugDescriptors (char *Prepend, struct LIST *Descriptors) +{ + struct Descriptor *Descriptor; + int i; + + xForeach (Descriptors, Descriptor) + { + switch (DescriptorTag (Descriptor)) + { + case DESCR_ANCILLARY_DATA: + printf ("%sDescriptor: Ancillary Data\n", Prepend); + printf ("%s Identifier: ", Prepend); + if (((struct AncillaryDataDescriptor *)Descriptor)-> + Identifier & ANCILLARY_DATA_DVD_VIDEO) + printf ("DVD-Video Ancillary Data "); + if (((struct AncillaryDataDescriptor *)Descriptor)-> + Identifier & ANCILLARY_DATA_EXTENDED) + printf ("Extended Ancillary Data "); + if (((struct AncillaryDataDescriptor *)Descriptor)-> + Identifier & ANCILLARY_DATA_SWITCHING) + printf ("Announcement Switching Data "); + if (((struct AncillaryDataDescriptor *)Descriptor)-> + Identifier & ANCILLARY_DATA_DAB) + printf ("DAB Ancillary Data "); + if (((struct AncillaryDataDescriptor *)Descriptor)-> + Identifier & ANCILLARY_DATA_SCALE_FACTOR) + printf ("Scale Factor Error Check (ScF-CRC) "); + printf ("\n"); + break; + + case DESCR_BOUQUET_NAME: + printf ("%sDescriptor: Bouquet Name\n", Prepend); + printf ("%s Name: %s\n", Prepend, xName (Descriptor)); + break; + + case DESCR_COMPONENT: + printf ("%sDescriptor: Component\n", Prepend); + printf ("%s Text: %s\n", Prepend, xName (Descriptor)); + printf ("%s Content/Type: ", Prepend); + for (i = 0; i < COMPONENT_TYPE_NUMBER; i++) + if ((((struct ComponentDescriptor *)Descriptor)-> + StreamContent == ComponentTypes[i].Content) && + (((struct ComponentDescriptor *)Descriptor)-> + ComponentType == ComponentTypes[i].Type)) + { printf ("%s\n", ComponentTypes[i].Description); break; } + if (i == COMPONENT_TYPE_NUMBER) { printf ("unbekannt\n"); } + printf ("%s ComponentTag: 0x%02x\n", Prepend, + ((struct ComponentDescriptor *)Descriptor)->ComponentTag); + printf ("%s LanguageCode: %s\n", Prepend, + ((struct ComponentDescriptor *)Descriptor)->LanguageCode); + break; + + case DESCR_SERVICE: + printf ("%sDescriptor: Service\n", Prepend); + printf ("%s Name: %s\n", Prepend, xName (Descriptor)); + printf ("%s ServiceType: ", Prepend); + for (i = 0; i < SERVICE_TYPE_NUMBER; i++) + if ((((struct ServiceDescriptor *)Descriptor)-> + ServiceType == ServiceTypes[i].Type)) + { printf ("%s\n", ServiceTypes[i].Description); break; } + if (i == SERVICE_TYPE_NUMBER) { printf ("unbekannt\n"); } + printf ("%s ServiceProvider: %s\n", Prepend, + ((struct ServiceDescriptor *)Descriptor)->ServiceProvider); + break; + + case DESCR_COUNTRY_AVAIL: + printf ("%sDescriptor: Country Availability\n", Prepend); + printf ("%s Type: %s\n", Prepend, (((struct CountryAvailabilityDescriptor *)Descriptor)-> + AvailibilityFlag == COUNTRIES_ARE_AVAILABLE) ? "countries are available" : + "countries are unavailable"); + { + char *cptr = ((struct CountryAvailabilityDescriptor *)Descriptor)->CountryCodes; int j; + for (j = 0; j < ((struct CountryAvailabilityDescriptor *)Descriptor)->Amount; j++) + { printf ("%s Country: %s\n", Prepend, cptr); cptr += 4; } + } + break; + + case DESCR_SHORT_EVENT: + printf ("%sDescriptor: Short Event\n", Prepend); + printf ("%s Name: %s\n", Prepend, xName (Descriptor)); + printf ("%s LanguageCode: %s\n", Prepend, + ((struct ShortEventDescriptor *)Descriptor)->LanguageCode); + printf ("%s Text: %s\n", Prepend, + ((struct ShortEventDescriptor *)Descriptor)->Text); + break; + + case DESCR_EXTENDED_EVENT: + { + struct ExtendedEventItem *Item; + + printf ("%sDescriptor: Extended Event\n", Prepend); + printf ("%s Text: %s\n", Prepend, xName (Descriptor)); + printf ("%s DescriptorNumber: %d\n", Prepend, + ((struct ExtendedEventDescriptor *)Descriptor)->DescriptorNumber); + printf ("%s LastDescriptorNumber: %d\n", Prepend, + ((struct ExtendedEventDescriptor *)Descriptor)->LastDescriptorNumber); + printf ("%s LanguageCode: %s\n", Prepend, + ((struct ExtendedEventDescriptor *)Descriptor)->LanguageCode); + xForeach (((struct ExtendedEventDescriptor *)Descriptor)->Items, Item) + { + printf ("%s Item:\n"); + printf ("%s Description: %s\n", xName(Item)); + printf ("%s Text: %s\n", Item->Text); + } + } + break; + + case DESCR_CA_IDENT: + printf ("%sDescriptor: Conditional Access Identity\n", Prepend); + { + int j; + for (j = 0; j < ((struct CaIdentifierDescriptor *)Descriptor)->Amount; j++) + printf ("%s SystemID: 0x%04x\n", Prepend, GetCaIdentifierID (Descriptor, j)); + } + break; + + case DESCR_CONTENT: + printf ("%sDescriptor: Content\n", Prepend); + { + int j; + for (j = 0; j < ((struct ContentDescriptor *)Descriptor)->Amount; j++) + { + printf ("%s Content: ", Prepend); + for (i = 0; i < CONTENT_TYPE_NUMBER; i++) + if ((GetContentContentNibble1(Descriptor, j) == ContentTypes[i].Nibble1) && + (GetContentContentNibble2(Descriptor, j) == ContentTypes[i].Nibble2)) + { printf ("%s\n", ContentTypes[i].Description); break; } + if (i == CONTENT_TYPE_NUMBER) { printf ("unbekannt\n"); } + printf ("%s User-Nibble 1: 0x%1x\n", Prepend, GetContentUserNibble1(Descriptor, j)); + printf ("%s User-Nibble 2: 0x%1x\n", Prepend, GetContentUserNibble2(Descriptor, j)); + } + } + break; + + case DESCR_PARENTAL_RATING: + { + struct ParentalRating *Rating; + + printf ("%sDescriptor: Parental Rating\n", Prepend); + xForeach (((struct ParentalRatingDescriptor *)Descriptor)->Ratings, Rating) + { + printf ("%s Rating:\n"); + printf ("%s LanguageCode: %s\n", Rating->LanguageCode); + printf ("%s Rating: "); + if (Rating->Rating == 0) printf ("(undefined)\n"); + else { if (Rating->Rating <= 0x10) printf ("minimum age is %d\n", Rating->Rating + 3); + else printf ("(rating is provider defined)\n"); } + } + } + break; + + case DESCR_NVOD_REF: + { + struct NvodReferenceItem *Item; + + printf ("%sDescriptor: NVOD Reference\n", Prepend); + xForeach (((struct NvodReferenceDescriptor *)Descriptor)->Items, Item) + { + printf ("%s Item:\n", Prepend); + printf ("%s ServiceID: %d\n", Prepend, Item->ServiceID); + printf ("%s TransportStreamID: %d\n", Prepend, Item->TransportStreamID); + printf ("%s OriginalNetworkID: %d\n", Prepend, Item->OriginalNetworkID); + } + } + break; + + case DESCR_TIME_SHIFTED_SERVICE: + printf ("%sDescriptor: Time Shifted Service\n", Prepend); + printf ("%s ReferenceServiceID: %d\n", Prepend, + ((struct TimeShiftedServiceDescriptor *) + Descriptor)->ReferenceServiceID); + break; + + case DESCR_TIME_SHIFTED_EVENT: + printf ("%sDescriptor: Time Shifted Event\n", Prepend); + printf ("%s ReferenceServiceID: %d\n", Prepend, + ((struct TimeShiftedEventDescriptor *) + Descriptor)->ReferenceServiceID); + printf ("%s ReferenceEventID: %d\n", Prepend, + ((struct TimeShiftedEventDescriptor *) + Descriptor)->ReferenceEventID); + break; + + case DESCR_ISO_639_LANGUAGE: + printf ("%sDescriptor: ISO 639 Language\n", Prepend); + printf ("%s LanguageCode: %s\n", Prepend, + ((struct Iso639LanguageDescriptor *)Descriptor)->LanguageCode); + break; + + case DESCR_STREAM_ID: + printf ("%sDescriptor: Stream Identifier\n", Prepend); + printf ("%s ComponentTag: %d\n", Prepend, + ((struct StreamIdentifierDescriptor *)Descriptor)->ComponentTag); + break; + + case DESCR_LINKAGE: + printf ("%sDescriptor: Linkage\n", Prepend); + printf ("%s TransportStreamID: %d\n", Prepend, + ((struct LinkageDescriptor *)Descriptor)->TransportStreamID); + printf ("%s OriginalNetworkID: %d\n", Prepend, + ((struct LinkageDescriptor *)Descriptor)->OriginalNetworkID); + printf ("%s ServiceID: %d\n", Prepend, + ((struct LinkageDescriptor *)Descriptor)->ServiceID); + printf ("%s LinkageType: %d\n", Prepend, + ((struct LinkageDescriptor *)Descriptor)->LinkageType); + if (((struct LinkageDescriptor *)Descriptor)->PrivateDataLength) + { + int j; + printf ("%s PrivateData: ", Prepend); + for (j = 0; j < ((struct LinkageDescriptor *) + Descriptor)->PrivateDataLength; j++) + printf ("0x%02X ", ((struct LinkageDescriptor *) + Descriptor)->PrivateData[j]); + printf ("\n"); + } + break; + + case DESCR_NW_NAME: + case DESCR_SERVICE_LIST: + case DESCR_STUFFING: + case DESCR_SAT_DEL_SYS: + case DESCR_CABLE_DEL_SYS: + case DESCR_VBI_DATA: + case DESCR_VBI_TELETEXT: + case DESCR_MOSAIC: + case DESCR_TELETEXT: + case DESCR_TELEPHONE: + case DESCR_LOCAL_TIME_OFF: + case DESCR_SUBTITLING: + case DESCR_TERR_DEL_SYS: + case DESCR_ML_NW_NAME: + case DESCR_ML_BQ_NAME: + case DESCR_ML_SERVICE_NAME: + case DESCR_ML_COMPONENT: + case DESCR_PRIV_DATA_SPEC: + case DESCR_SERVICE_MOVE: + case DESCR_SHORT_SMOOTH_BUF: + case DESCR_FREQUENCY_LIST: + case DESCR_PARTIAL_TP_STREAM: + case DESCR_DATA_BROADCAST: + case DESCR_CA_SYSTEM: + case DESCR_DATA_BROADCAST_ID: + case DESCR_TRANSPORT_STREAM: + case DESCR_DSNG: + case DESCR_PDC: + case DESCR_AC3: + case DESCR_CELL_LIST: + case DESCR_CELL_FREQ_LINK: + case DESCR_ANNOUNCEMENT_SUPPORT: + default: + printf ("%sDescriptor: (noch nicht unterstützt)\n", Prepend); + break; + } + } + return; +} + diff --git a/libdtv/libsi/si_debug_services.h b/libdtv/libsi/si_debug_services.h new file mode 100644 index 0000000..33528db --- /dev/null +++ b/libdtv/libsi/si_debug_services.h @@ -0,0 +1,217 @@ +////////////////////////////////////////////////////////////// +/// /// +/// si_debug_services.h: local debugging definitions /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/06/25 12:29:47 $ +// $Author: kls $ +// +// (C) 2001 Rolf Hakenes , under the GNU GPL. +// +// libsi is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// libsi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with libsi; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + + +struct component_type { + u_char Content; + u_char Type; + char *Description; +}; + +static struct component_type ComponentTypes[] = { + { 0x01, 0x01, "video, 4:3 aspect ratio, 25 Hz" }, + { 0x01, 0x02, "video, 16:9 aspect ratio with pan vectors, 25 Hz" }, + { 0x01, 0x03, "video, 16:9 aspect ratio without pan vectors, 25 Hz" }, + { 0x01, 0x04, "video, > 16:9 aspect ratio, 25 Hz" }, + { 0x01, 0x05, "video, 4:3 aspect ratio, 30 Hz" }, + { 0x01, 0x06, "video, 16:9 aspect ratio with pan vectors, 30 Hz" }, + { 0x01, 0x07, "video, 16:9 aspect ratio without pan vectors, 30 Hz" }, + { 0x01, 0x08, "video, > 16:9 aspect ratio, 30 Hz" }, + { 0x01, 0x09, "HD video, 4:3 aspect ratio, 25 Hz" }, + { 0x01, 0x0A, "HD video, 16:9 aspect ratio with pan vectors, 25 Hz" }, + { 0x01, 0x0B, "HD video, 16:9 aspect ratio without pan vectors, 25 Hz" }, + { 0x01, 0x0C, "HD video, > 16:9 aspect ratio, 25 Hz" }, + { 0x01, 0x0D, "HD video, 4:3 aspect ratio, 30 Hz" }, + { 0x01, 0x0E, "HD video, 16:9 aspect ratio with pan vectors, 30 Hz" }, + { 0x01, 0x0F, "HD video, 16:9 aspect ratio without pan vectors, 30 Hz" }, + { 0x01, 0x10, "HD video, > 16:9 aspect ratio, 30 Hz" }, + { 0x02, 0x01, "audio, single mono channel" }, + { 0x02, 0x02, "audio, dual mono channel" }, + { 0x02, 0x03, "audio, stereo (2 channel)" }, + { 0x02, 0x04, "audio, multi lingual, multi channel" }, + { 0x02, 0x05, "audio, surround sound" }, + { 0x02, 0x40, "audio description for the visually impaired" }, + { 0x02, 0x41, "audio for the hard of hearing" }, + { 0x03, 0x01, "EBU Teletext subtitles" }, + { 0x03, 0x02, "associated EBU Teletext" }, + { 0x03, 0x03, "VBI data" }, + { 0x03, 0x10, "DVB subtitles (normal), no aspect criticality" }, + { 0x03, 0x11, "DVB subtitles (normal), aspect 4:3 only" }, + { 0x03, 0x12, "DVB subtitles (normal), aspect 16:9 only" }, + { 0x03, 0x13, "DVB subtitles (normal), aspect 2.21:1 only" }, + { 0x03, 0x20, "DVB subtitles (hard of hearing), no aspect criticality" }, + { 0x03, 0x21, "DVB subtitles (hard of hearing), aspect 4:3 only" }, + { 0x03, 0x22, "DVB subtitles (hard of hearing), aspect 16:9 only" }, + { 0x03, 0x23, "DVB subtitles (hard of hearing), aspect 2.21:1 only" } +}; +#define COMPONENT_TYPE_NUMBER 35 + + +struct service_type { + u_char Type; + char *Description; +}; + +static struct service_type ServiceTypes[] = { + { 0x01, "digital television service" }, + { 0x02, "digital radio sound service" }, + { 0x03, "Teletext service" }, + { 0x04, "NVOD reference service" }, + { 0x05, "NVOD time-shifted service" }, + { 0x06, "mosaic service" }, + { 0x07, "PAL coded signal" }, + { 0x08, "SECAM coded signal" }, + { 0x09, "D/D2-MAC" }, + { 0x0A, "FM Radio" }, + { 0x0B, "NTSC coded signal" }, + { 0x0C, "data broadcast service" }, + { 0x0D, "common interface data" }, + { 0x0E, "RCS Map" }, + { 0x0F, "RCS FLS" }, + { 0x10, "DVB MHP service" } +}; +#define SERVICE_TYPE_NUMBER 16 + + +struct content_type { + u_char Nibble1; + u_char Nibble2; + char *Description; +}; + +static struct content_type ContentTypes[] = { + /* Movie/Drama: */ + { 0x01, 0x00, "movie/drama (general)" }, + { 0x01, 0x01, "detective/thriller" }, + { 0x01, 0x02, "adventure/western/war" }, + { 0x01, 0x03, "science fiction/fantasy/horror" }, + { 0x01, 0x04, "comedy" }, + { 0x01, 0x05, "soap/melodrama/folkloric" }, + { 0x01, 0x06, "romance" }, + { 0x01, 0x07, "serious/classical/religious/historical movie/drama" }, + { 0x01, 0x08, "adult movie/drama" }, + /* News/Current affairs: */ + { 0x02, 0x00, "news/current affairs (general)" }, + { 0x02, 0x01, "news/weather report" }, + { 0x02, 0x02, "news magazine" }, + { 0x02, 0x03, "documentary" }, + { 0x02, 0x04, "discussion/interview/debate" }, + /* Show/Game show: */ + { 0x03, 0x00, "show/game show (general)" }, + { 0x03, 0x01, "game show/quiz/contest" }, + { 0x03, 0x02, "variety show" }, + { 0x03, 0x03, "talk show" }, + /* Sports: */ + { 0x04, 0x00, "sports (general)" }, + { 0x04, 0x01, "special events (Olympic Games, World Cup etc.)" }, + { 0x04, 0x02, "sports magazines" }, + { 0x04, 0x03, "football/soccer" }, + { 0x04, 0x04, "tennis/squash" }, + { 0x04, 0x05, "team sports (excluding football)" }, + { 0x04, 0x06, "athletics" }, + { 0x04, 0x07, "motor sport" }, + { 0x04, 0x08, "water sport" }, + { 0x04, 0x09, "winter sports" }, + { 0x04, 0x0A, "equestrian" }, + { 0x04, 0x0B, "martial sports" }, + /* Children's/Youth programmes: */ + { 0x05, 0x00, "children's/youth programmes (general)" }, + { 0x05, 0x01, "pre-school children's programmes" }, + { 0x05, 0x02, "entertainment programmes for 6 to14" }, + { 0x05, 0x03, "entertainment programmes for 10 to 16" }, + { 0x05, 0x04, "informational/educational/school programmes" }, + { 0x05, 0x05, "cartoons/puppets" }, + /* Music/Ballet/Dance: */ + { 0x06, 0x00, "music/ballet/dance (general)" }, + { 0x06, 0x01, "rock/pop" }, + { 0x06, 0x02, "serious music/classical music" }, + { 0x06, 0x03, "folk/traditional music" }, + { 0x06, 0x04, "jazz" }, + { 0x06, 0x05, "musical/opera" }, + { 0x06, 0x06, "ballet" }, + /* Arts/Culture (without music): */ + { 0x07, 0x00, "arts/culture (without music, general)" }, + { 0x07, 0x01, "performing arts" }, + { 0x07, 0x02, "fine arts" }, + { 0x07, 0x03, "religion" }, + { 0x07, 0x04, "popular culture/traditional arts" }, + { 0x07, 0x05, "literature" }, + { 0x07, 0x06, "film/cinema" }, + { 0x07, 0x07, "experimental film/video" }, + { 0x07, 0x08, "broadcasting/press" }, + { 0x07, 0x09, "new media" }, + { 0x07, 0x0A, "arts/culture magazines" }, + { 0x07, 0x0B, "fashion" }, + /* Social/Political issues/Economics: */ + { 0x08, 0x00, "social/political issues/economics (general)" }, + { 0x08, 0x01, "magazines/reports/documentary" }, + { 0x08, 0x02, "economics/social advisory" }, + { 0x08, 0x03, "remarkable people" }, + /* Children's/Youth programmes: */ + /* Education/ Science/Factual topics: */ + { 0x09, 0x00, "education/science/factual topics (general)" }, + { 0x09, 0x01, "nature/animals/environment" }, + { 0x09, 0x02, "technology/natural sciences" }, + { 0x09, 0x03, "medicine/physiology/psychology" }, + { 0x09, 0x04, "foreign countries/expeditions" }, + { 0x09, 0x05, "social/spiritual sciences" }, + { 0x09, 0x06, "further education" }, + { 0x09, 0x07, "languages" }, + /* Leisure hobbies: */ + { 0x0A, 0x00, "leisure hobbies (general)" }, + { 0x0A, 0x01, "tourism/travel" }, + { 0x0A, 0x02, "handicraft" }, + { 0x0A, 0x03, "motoring" }, + { 0x0A, 0x04, "fitness & health" }, + { 0x0A, 0x05, "cooking" }, + { 0x0A, 0x06, "advertisement/shopping" }, + { 0x0A, 0x07, "gardening" }, + { 0x0B, 0x00, "original language" }, + { 0x0B, 0x01, "black & white" }, + { 0x0B, 0x02, "unpublished" }, + { 0x0B, 0x03, "live broadcast" } +}; +#define CONTENT_TYPE_NUMBER 79 + +static char StreamTypes[][70] = { + "ITU-T|ISO/IEC Reserved", + "ISO/IEC Video", + "13818-2 Video or 11172-2 constrained parameter video stream", + "ISO/IEC 11172 Audio", + "ISO/IEC 13818-3 Audio", + "private_sections", + "packets containing private data / Videotext", + "ISO/IEC 13522 MPEG", + "ITU-T Rec. H.222.1", + "ISO/IEC 13818-6 type A", + "ISO/IEC 13818-6 type B", + "ISO/IEC 13818-6 type C", + "ISO/IEC 13818-6 type D", + "ISO/IEC 13818-1 auxiliary", + "ITU-T Rec. H.222.0 | ISO 13818-1 Reserved", + "User private" +}; diff --git a/libdtv/libsi/si_parser.c b/libdtv/libsi/si_parser.c new file mode 100644 index 0000000..acafa7b --- /dev/null +++ b/libdtv/libsi/si_parser.c @@ -0,0 +1,881 @@ +////////////////////////////////////////////////////////////// +/// /// +/// si_parser.c: main parsing functions of libsi /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/08/15 14:41:45 $ +// $Author: kls $ +// +// (C) 2001 Rolf Hakenes , under the GNU GPL. +// +// libsi is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// libsi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with libsi; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#include +#include +#include + +#include "../liblx/liblx.h" +#include "libsi.h" +#include "si_tables.h" + + + +struct LIST *siParsePAT (u_char *Buffer) +{ + pat_t *Pat; + pat_prog_t *PatProgram; + u_char *Ptr; + u_int SectionLength; + int TransportStreamID; + int PatVersion; + struct Program *Program; + struct LIST *ProgramList = NULL; + + if (!Buffer) return NULL; + + Pat = (pat_t *) Buffer; Ptr = Buffer; + + if (Pat->table_id != TID_PAT) { +// fprintf (stderr, "PAT: wrong TID %d\n", Pat->table_id); + return NULL; + } + + SectionLength = HILO (Pat->section_length) + 3 - PAT_LEN - 4; + + if (crc32 (Ptr, HILO (Pat->section_length) + 3)) return (NULL); + + TransportStreamID = HILO (Pat->transport_stream_id); + PatVersion = Pat->version_number; + + Ptr += PAT_LEN; + + while (SectionLength > 0) + { + PatProgram = (pat_prog_t *) Ptr; + + CreateProgram (Program, HILO (PatProgram->program_number), + TransportStreamID, HILO (PatProgram->network_pid), PatVersion); + + if (!ProgramList) ProgramList = xNewList (NULL); + xAddTail (ProgramList, Program); + + SectionLength -= PAT_PROG_LEN; + Ptr += PAT_PROG_LEN; + } + + return (ProgramList); +} + + +struct Pid *siParsePMT (u_char *Buffer) +{ + pmt_t *Pmt; + pmt_info_t *PmtInfo; + u_char *Ptr; + u_int SectionLength, ProgramInfoLength, + StreamLength, LoopLength; + int ProgramID; + int PcrID; + int PmtVersion; + struct Pid *Pid; + struct PidInfo *PidInfo; + + if (!Buffer) return NULL; + + Pmt = (pmt_t *) Buffer; Ptr = Buffer; + + if (Pmt->table_id != TID_PMT) { +// fprintf (stderr, "PMT: wrong TID %d\n", Pmt->table_id); + return NULL; + } + + SectionLength = HILO (Pmt->section_length) + 3 - 4; + + if (crc32 (Ptr, HILO (Pmt->section_length) + 3)) return (NULL); + + ProgramInfoLength = HILO (Pmt->program_info_length); + StreamLength = SectionLength - ProgramInfoLength - PMT_LEN; + + ProgramID = HILO (Pmt->program_number); + PmtVersion = Pmt->version_number; + PcrID = HILO (Pmt->PCR_PID); + + Ptr += PMT_LEN; + + CreatePid (Pid, ProgramID, PcrID, PmtVersion); + + siParseDescriptors (Pid->Descriptors, Ptr, ProgramInfoLength, Pmt->table_id); + + Ptr += ProgramInfoLength; + + while (StreamLength > 0) + { + PmtInfo = (pmt_info_t *) Ptr; + + CreatePidInfo (PidInfo, PmtInfo->stream_type, + HILO (PmtInfo->elementary_PID)); + + LoopLength = HILO (PmtInfo->ES_info_length); + Ptr += PMT_INFO_LEN; + + siParseDescriptors (PidInfo->Descriptors, Ptr, LoopLength, Pmt->table_id); + + xAddTail (Pid->InfoList, PidInfo); + + StreamLength -= LoopLength + PMT_INFO_LEN; + Ptr += LoopLength; + } + + return (Pid); +} + + +struct LIST *siParseSDT (u_char *Buffer) +{ + sdt_t *Sdt; + sdt_descr_t *SdtDescriptor; + u_char *Ptr; + u_int SectionLength, LoopLength; + int TransportStreamID; + int SdtVersion; + int OriginalNetworkID; + struct Service *Service; + struct LIST *ServiceList = NULL; + + if (!Buffer) return NULL; + + Sdt = (sdt_t *) Buffer; Ptr = Buffer; + + if (Sdt->table_id != TID_SDT_ACT && Sdt->table_id != TID_SDT_OTH) { +// fprintf (stderr, "SDT: wrong TID %d\n", Sdt->table_id); + return NULL; + } + + SectionLength = HILO (Sdt->section_length) + 3 - SDT_LEN - 4; + + if (crc32 (Ptr, HILO (Sdt->section_length) + 3)) return (NULL); + + TransportStreamID = HILO (Sdt->transport_stream_id); + SdtVersion = Sdt->version_number; + OriginalNetworkID = HILO (Sdt->original_network_id); + + Ptr += SDT_LEN; + + while (SectionLength > 0) + { + SdtDescriptor = (sdt_descr_t *) Ptr; + + CreateService (Service, HILO (SdtDescriptor->service_id), + TransportStreamID, OriginalNetworkID, SdtVersion, + SdtDescriptor->free_ca_mode ? CONDITIONAL_ACCESS : FREE_TO_AIR); + + switch (SdtDescriptor->running_status) + { + case 0x01: + SetRunningStatus (Service->Status, RUNNING_STATUS_NOT_RUNNING); + break; + + case 0x02: + SetRunningStatus (Service->Status, RUNNING_STATUS_AWAITING); + break; + + case 0x03: + SetRunningStatus (Service->Status, RUNNING_STATUS_PAUSING); + break; + + case 0x04: + default: + SetRunningStatus (Service->Status, RUNNING_STATUS_RUNNING); + break; + } + if (SdtDescriptor->eit_schedule_flag) + SetScheduleFlag (Service->Status); + if (SdtDescriptor->eit_present_following_flag) + SetPresentFollowing (Service->Status); + + LoopLength = HILO (SdtDescriptor->descriptors_loop_length); + Ptr += SDT_DESCR_LEN; + + siParseDescriptors (Service->Descriptors, Ptr, LoopLength, Sdt->table_id); + + if (!ServiceList) ServiceList = xNewList (NULL); + xAddTail (ServiceList, Service); + + SectionLength -= LoopLength + SDT_DESCR_LEN; + Ptr += LoopLength; + } + + return (ServiceList); +} + + +struct LIST *siParseEIT (u_char *Buffer) +{ + eit_t *Eit; + eit_event_t *EitEvent; + u_char *Ptr; + u_int SectionLength, LoopLength; + int ServiceID; + int EitVersion; + int TransportStreamID; + int OriginalNetworkID; + struct Event *Event; + struct LIST *EventList = NULL; + + if (!Buffer) return NULL; + + Eit = (eit_t *) Buffer; Ptr = Buffer; + + if (Eit->table_id != TID_EIT_ACT && Eit->table_id != TID_EIT_OTH && + !(Eit->table_id >= TID_EIT_ACT_SCH && + Eit->table_id <= TID_EIT_ACT_SCH + 0x0F) && + !(Eit->table_id >= TID_EIT_OTH_SCH && + Eit->table_id <= TID_EIT_OTH_SCH + 0x0F)) { +// fprintf (stderr, "EIT: wrong TID %d\n", Eit->table_id); + return NULL; + } + + SectionLength = HILO (Eit->section_length) + 3 - EIT_LEN - 4; + + if (crc32 (Ptr, HILO (Eit->section_length) + 3)) return (NULL); + + ServiceID = HILO (Eit->service_id); + TransportStreamID = HILO (Eit->transport_stream_id); + EitVersion = Eit->version_number; + OriginalNetworkID = HILO (Eit->original_network_id); + + Ptr += EIT_LEN; + + while (SectionLength > 0) + { + struct tm thisTime; + int year, month, day; + double mjd; + + EitEvent = (eit_event_t *) Ptr; + + CreateEvent (Event, HILO (EitEvent->event_id), ServiceID, + TransportStreamID, OriginalNetworkID, EitVersion, + EitEvent->free_ca_mode ? CONDITIONAL_ACCESS : FREE_TO_AIR); + + switch (EitEvent->running_status) + { + case 0x01: + SetRunningStatus (Event->Status, RUNNING_STATUS_NOT_RUNNING); + break; + + case 0x02: + SetRunningStatus (Event->Status, RUNNING_STATUS_AWAITING); + break; + + case 0x03: + SetRunningStatus (Event->Status, RUNNING_STATUS_PAUSING); + break; + + case 0x04: + default: + SetRunningStatus (Event->Status, RUNNING_STATUS_RUNNING); + break; + } + Event->StartTime = MjdToEpochTime (EitEvent->mjd) + + BcdTimeToSeconds (EitEvent->start_time); + Event->Duration = BcdTimeToSeconds (EitEvent->duration); + + LoopLength = HILO (EitEvent->descriptors_loop_length); + Ptr += EIT_EVENT_LEN; + + siParseDescriptors (Event->Descriptors, Ptr, LoopLength, Eit->table_id); + + if (!EventList) EventList = xNewList (NULL); + xAddTail (EventList, Event); + + SectionLength -= LoopLength + EIT_EVENT_LEN; + Ptr += LoopLength; + } + + return (EventList); +} + + +time_t siParseTDT (u_char *Buffer) +{ + tdt_t *Tdt; + u_char *Ptr; + u_int SectionLength; + int TdtVersion; + time_t CurrentTime; + + if (!Buffer) return 0; + + Tdt = (tdt_t *) Buffer; Ptr = Buffer; + + if (Tdt->table_id != TID_TDT) { +// fprintf (stderr, "TDT: wrong TID %d\n", Tdt->table_id); + return 0; + } + + SectionLength = HILO (Tdt->section_length) + 3; /* no CRC ?! */ + + CurrentTime = MjdToEpochTime (Tdt->utc_mjd) + + BcdTimeToSeconds (Tdt->utc_time); + + return (CurrentTime); +} + + +void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, + u_int Length, u_char TableID) +{ + u_int DescriptorLength; + u_char *Ptr; + + DescriptorLength = 0; + Ptr = Buffer; + + while (DescriptorLength < Length) + { + switch (TableID) + { + case TID_NIT_ACT: case TID_NIT_OTH: + switch (GetDescriptorTag(Ptr)) + { + case DESCR_NW_NAME: + case DESCR_SERVICE_LIST: + case DESCR_STUFFING: + case DESCR_SAT_DEL_SYS: + case DESCR_CABLE_DEL_SYS: + case DESCR_LINKAGE: + case DESCR_TERR_DEL_SYS: + case DESCR_ML_NW_NAME: + case DESCR_PRIV_DATA_SPEC: + case DESCR_CELL_LIST: + case DESCR_CELL_FREQ_LINK: + case DESCR_ANNOUNCEMENT_SUPPORT: + siParseDescriptor (Descriptors, Ptr); + break; + + default: + /* fprintf (stderr, "forbidden descriptor 0x%x in NIT\n", + GetDescriptorTag(Ptr));*/ + break; + } + break; + + case TID_BAT: + switch (GetDescriptorTag(Ptr)) + { + case DESCR_SERVICE_LIST: + case DESCR_STUFFING: + case DESCR_BOUQUET_NAME: + case DESCR_SERVICE: + case DESCR_COUNTRY_AVAIL: + case DESCR_LINKAGE: + case DESCR_CA_IDENT: + case DESCR_ML_BQ_NAME: + case DESCR_PRIV_DATA_SPEC: + siParseDescriptor (Descriptors, Ptr); + break; + + default: + /*fprintf (stderr, "forbidden descriptor 0x%x in BAT\n", + GetDescriptorTag(Ptr));*/ + break; + } + break; + + case TID_SDT_ACT: case TID_SDT_OTH: + switch (GetDescriptorTag(Ptr)) + { + case DESCR_STUFFING: + case DESCR_BOUQUET_NAME: + case DESCR_SERVICE: + case DESCR_COUNTRY_AVAIL: + case DESCR_LINKAGE: + case DESCR_NVOD_REF: + case DESCR_TIME_SHIFTED_SERVICE: + case DESCR_MOSAIC: + case DESCR_CA_IDENT: + case DESCR_TELEPHONE: + case DESCR_ML_SERVICE_NAME: + case DESCR_PRIV_DATA_SPEC: + case DESCR_DATA_BROADCAST: + siParseDescriptor (Descriptors, Ptr); + break; + + default: + /* fprintf (stderr, "forbidden descriptor 0x%x in SDT\n", + GetDescriptorTag(Ptr)); */ + break; + } + break; + + case TID_EIT_ACT: case TID_EIT_OTH: + case TID_EIT_ACT_SCH: case TID_EIT_OTH_SCH: + case TID_EIT_ACT_SCH+1: case TID_EIT_OTH_SCH+1: + case TID_EIT_ACT_SCH+2: case TID_EIT_OTH_SCH+2: + case TID_EIT_ACT_SCH+3: case TID_EIT_OTH_SCH+3: + case TID_EIT_ACT_SCH+4: case TID_EIT_OTH_SCH+4: + case TID_EIT_ACT_SCH+5: case TID_EIT_OTH_SCH+5: + case TID_EIT_ACT_SCH+6: case TID_EIT_OTH_SCH+6: + case TID_EIT_ACT_SCH+7: case TID_EIT_OTH_SCH+7: + case TID_EIT_ACT_SCH+8: case TID_EIT_OTH_SCH+8: + case TID_EIT_ACT_SCH+9: case TID_EIT_OTH_SCH+9: + case TID_EIT_ACT_SCH+10: case TID_EIT_OTH_SCH+10: + case TID_EIT_ACT_SCH+11: case TID_EIT_OTH_SCH+11: + case TID_EIT_ACT_SCH+12: case TID_EIT_OTH_SCH+12: + case TID_EIT_ACT_SCH+13: case TID_EIT_OTH_SCH+13: + case TID_EIT_ACT_SCH+14: case TID_EIT_OTH_SCH+14: + case TID_EIT_ACT_SCH+15: case TID_EIT_OTH_SCH+15: + switch (GetDescriptorTag(Ptr)) + { + case DESCR_STUFFING: + case DESCR_LINKAGE: + case DESCR_SHORT_EVENT: + case DESCR_EXTENDED_EVENT: + case DESCR_TIME_SHIFTED_EVENT: + case DESCR_COMPONENT: + case DESCR_CA_IDENT: + case DESCR_CONTENT: + case DESCR_PARENTAL_RATING: + case DESCR_TELEPHONE: + case DESCR_ML_COMPONENT: + case DESCR_PRIV_DATA_SPEC: + case DESCR_SHORT_SMOOTH_BUF: + case DESCR_DATA_BROADCAST: + case DESCR_PDC: + siParseDescriptor (Descriptors, Ptr); + break; + + default: + /*fprintf (stderr, "forbidden descriptor 0x%x in EIT\n", + GetDescriptorTag(Ptr));*/ + break; + } + break; + + case TID_TOT: + switch (GetDescriptorTag(Ptr)) + { + case DESCR_LOCAL_TIME_OFF: + siParseDescriptor (Descriptors, Ptr); + break; + + default: + /*fprintf (stderr, "forbidden descriptor 0x%x in TOT\n", + GetDescriptorTag(Ptr));*/ + break; + } + break; + + case TID_PMT: + switch (GetDescriptorTag(Ptr)) + { + case DESCR_VBI_DATA: + case DESCR_VBI_TELETEXT: + case DESCR_MOSAIC: + case DESCR_STREAM_ID: + case DESCR_TELETEXT: + case DESCR_SUBTITLING: + case DESCR_PRIV_DATA_SPEC: + case DESCR_SERVICE_MOVE: + case DESCR_CA_SYSTEM: + case DESCR_DATA_BROADCAST_ID: + case DESCR_AC3: + case DESCR_ANCILLARY_DATA: + case DESCR_VIDEO_STREAM: + case DESCR_AUDIO_STREAM: + case DESCR_HIERARCHY: + case DESCR_REGISTRATION: + case DESCR_DATA_STREAM_ALIGN: + case DESCR_TARGET_BACKGRID: + case DESCR_VIDEO_WINDOW: + case DESCR_CA: + case DESCR_ISO_639_LANGUAGE: + case DESCR_SYSTEM_CLOCK: + case DESCR_MULTIPLEX_BUFFER_UTIL: + case DESCR_COPYRIGHT: + case DESCR_MAXIMUM_BITRATE: + siParseDescriptor (Descriptors, Ptr); + break; + + default: + /* fprintf (stderr, "forbidden descriptor 0x%x in PMT\n", + GetDescriptorTag(Ptr)); */ + break; + } + break; + + default: + fprintf (stderr, "descriptor 0x%x in unsupported table 0x%x\n", + GetDescriptorTag(Ptr), TableID); + break; + } + DescriptorLength += GetDescriptorLength (Ptr); + Ptr += GetDescriptorLength (Ptr); + } + return; +} + + +void siParseDescriptor (struct LIST *Descriptors, u_char *Buffer) +{ + struct NODE *Descriptor = NULL; + char *Text , *Text2; + u_char *Ptr; + int Length, i; + + if (!Descriptors || !Buffer) return; + + Ptr = Buffer; + + switch (GetDescriptorTag(Buffer)) + { + case DESCR_ANCILLARY_DATA: + CreateAncillaryDataDescriptor (Descriptor, + CastAncillaryDataDescriptor(Buffer)->ancillary_data_identifier); + break; + + case DESCR_BOUQUET_NAME: + Text = siGetDescriptorText (Buffer + DESCR_BOUQUET_NAME_LEN, + GetDescriptorLength (Buffer) - DESCR_BOUQUET_NAME_LEN); + CreateBouquetNameDescriptor (Descriptor, Text); +// xMemFree (Text); + break; + + case DESCR_COMPONENT: + Text = siGetDescriptorText (Buffer + DESCR_COMPONENT_LEN, + GetDescriptorLength (Buffer) - DESCR_COMPONENT_LEN); + CreateComponentDescriptor (Descriptor, + CastComponentDescriptor(Buffer)->stream_content, + CastComponentDescriptor(Buffer)->component_type, + CastComponentDescriptor(Buffer)->component_tag, + CastComponentDescriptor(Buffer)->lang_code1, + CastComponentDescriptor(Buffer)->lang_code2, + CastComponentDescriptor(Buffer)->lang_code3, Text); +// xMemFree (Text); + break; + + case DESCR_SERVICE: + Text = siGetDescriptorText (Buffer + DESCR_SERVICE_LEN, + CastServiceDescriptor(Buffer)->provider_name_length); + Text2 = siGetDescriptorText (Buffer + DESCR_SERVICE_LEN + + CastServiceDescriptor(Buffer)->provider_name_length + 1, + *((u_char *)(Buffer + DESCR_SERVICE_LEN + + CastServiceDescriptor(Buffer)->provider_name_length))); + CreateServiceDescriptor (Descriptor, + CastServiceDescriptor(Buffer)->service_type, Text, Text2); +// xMemFree (Text2); + break; + + case DESCR_COUNTRY_AVAIL: + CreateCountryAvailabilityDescriptor (Descriptor, + CastCountryAvailabilityDescriptor(Buffer)->country_availability_flag); + Length = GetDescriptorLength (Buffer) - DESCR_COUNTRY_AVAILABILITY_LEN; + Ptr += DESCR_COUNTRY_AVAILABILITY_LEN; + while (Length > 0) + { AddCountryAvailabilityCode(Descriptor, + Ptr[0], Ptr[1], Ptr[2]); Ptr += 3; Length -= 3; } + break; + + case DESCR_SHORT_EVENT: + Text = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN, + CastShortEventDescriptor(Buffer)->event_name_length); + Text2 = siGetDescriptorText (Buffer + DESCR_SHORT_EVENT_LEN + + CastShortEventDescriptor(Buffer)->event_name_length + 1, + *((u_char *)(Buffer + DESCR_SHORT_EVENT_LEN + + CastShortEventDescriptor(Buffer)->event_name_length))); + CreateShortEventDescriptor (Descriptor, Text, + CastShortEventDescriptor(Buffer)->lang_code1, + CastShortEventDescriptor(Buffer)->lang_code2, + CastShortEventDescriptor(Buffer)->lang_code3, Text2); +// xMemFree (Text); + break; + + case DESCR_EXTENDED_EVENT: + Text = siGetDescriptorText (Buffer + DESCR_EXTENDED_EVENT_LEN + + CastExtendedEventDescriptor(Buffer)->length_of_items + 1, + *((u_char *)(Buffer + DESCR_EXTENDED_EVENT_LEN + + CastExtendedEventDescriptor(Buffer)->length_of_items))); + CreateExtendedEventDescriptor (Descriptor, + CastExtendedEventDescriptor(Buffer)->descriptor_number, + CastExtendedEventDescriptor(Buffer)->last_descriptor_number, + CastExtendedEventDescriptor(Buffer)->lang_code1, + CastExtendedEventDescriptor(Buffer)->lang_code2, + CastExtendedEventDescriptor(Buffer)->lang_code3, Text); +// xMemFree (Text); + Length = CastExtendedEventDescriptor(Buffer)->length_of_items; + Ptr += DESCR_EXTENDED_EVENT_LEN; + while (Length > 0) + { + Text = siGetDescriptorText (Ptr + ITEM_EXTENDED_EVENT_LEN, + CastExtendedEventItem(Ptr)->item_description_length); + Text2 = siGetDescriptorText (Ptr + ITEM_EXTENDED_EVENT_LEN + + CastExtendedEventItem(Ptr)->item_description_length + 1, + *((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN + + CastExtendedEventItem(Ptr)->item_description_length))); + AddExtendedEventItem (Descriptor, Text2, Text); +// xMemFree (Text2); + Length -= ITEM_EXTENDED_EVENT_LEN + CastExtendedEventItem(Ptr)->item_description_length + + *((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN + + CastExtendedEventItem(Ptr)->item_description_length)) + 1; + Ptr += ITEM_EXTENDED_EVENT_LEN + CastExtendedEventItem(Ptr)->item_description_length + + *((u_char *)(Ptr + ITEM_EXTENDED_EVENT_LEN + + CastExtendedEventItem(Ptr)->item_description_length)) + 1; + } + break; + + case DESCR_CA_IDENT: + CreateCaIdentifierDescriptor (Descriptor, + (GetDescriptorLength(Buffer) - DESCR_CA_IDENTIFIER_LEN) / 2); + Length = GetDescriptorLength (Buffer) - DESCR_CA_IDENTIFIER_LEN; + Ptr += DESCR_CA_IDENTIFIER_LEN; i = 0; + while (Length > 0) + { SetCaIdentifierID(Descriptor, i, *((u_short *) Ptr)); + Length -= 2; Ptr += 2; i++; } + break; + + case DESCR_CONTENT: + CreateContentDescriptor (Descriptor, + (GetDescriptorLength(Buffer) - DESCR_CONTENT_LEN) / 2); + Length = GetDescriptorLength (Buffer) - DESCR_CONTENT_LEN; + Ptr += DESCR_CONTENT_LEN; i = 0; + while (Length > 0) + { SetContentID(Descriptor, i, CastContentNibble(Ptr)->content_nibble_level_1, + CastContentNibble(Ptr)->content_nibble_level_2, + CastContentNibble(Ptr)->user_nibble_1, + CastContentNibble(Ptr)->user_nibble_2); + Length -= 2; Ptr += 2; i++; } + break; + + case DESCR_STUFFING: + /* intentionally ignored */ + break; + + case DESCR_PARENTAL_RATING: + CreateParentalRatingDescriptor (Descriptor); + Length = GetDescriptorLength (Buffer) - DESCR_PARENTAL_RATING_LEN; + Ptr += DESCR_PARENTAL_RATING_LEN; i = 0; + while (Length > 0) + { AddParentalRating (Descriptor, CastParentalRating(Ptr)->lang_code1, + CastParentalRating(Ptr)->lang_code2, CastParentalRating(Ptr)->lang_code3, + CastParentalRating(Ptr)->rating); + Length -= PARENTAL_RATING_LEN; Ptr += PARENTAL_RATING_LEN; i++; } + break; + + case DESCR_NVOD_REF: + CreateNvodReferenceDescriptor (Descriptor); + Length = GetDescriptorLength (Buffer) - DESCR_NVOD_REFERENCE_LEN; + Ptr += DESCR_NVOD_REFERENCE_LEN; + while (Length > 0) + { + AddNvodReferenceItem (Descriptor, + HILO (CastNvodReferenceItem(Ptr)->transport_stream_id), + HILO (CastNvodReferenceItem(Ptr)->original_network_id), + HILO (CastNvodReferenceItem(Ptr)->service_id)); + Length -= ITEM_NVOD_REFERENCE_LEN; + Ptr += ITEM_NVOD_REFERENCE_LEN; + } + break; + + case DESCR_TIME_SHIFTED_SERVICE: + CreateTimeShiftedServiceDescriptor (Descriptor, + HILO (CastTimeShiftedServiceDescriptor(Ptr)->reference_service_id)); + break; + + case DESCR_TIME_SHIFTED_EVENT: + CreateTimeShiftedEventDescriptor (Descriptor, + HILO (CastTimeShiftedEventDescriptor(Ptr)->reference_service_id), + HILO (CastTimeShiftedEventDescriptor(Ptr)->reference_event_id)); + break; + + case DESCR_ISO_639_LANGUAGE: + CreateIso639LanguageDescriptor (Descriptor, + CastIso639LanguageDescriptor(Buffer)->lang_code1, + CastIso639LanguageDescriptor(Buffer)->lang_code2, + CastIso639LanguageDescriptor(Buffer)->lang_code3); + break; + + case DESCR_STREAM_ID: + CreateStreamIdentifierDescriptor (Descriptor, + CastStreamIdentifierDescriptor(Ptr)->component_tag); + break; + + case DESCR_LINKAGE: + CreateLinkageDescriptor (Descriptor, + HILO (CastLinkageDescriptor(Ptr)->transport_stream_id), + HILO (CastLinkageDescriptor(Ptr)->original_network_id), + HILO (CastLinkageDescriptor(Ptr)->service_id), + CastLinkageDescriptor(Ptr)->linkage_type, + GetDescriptorLength (Ptr) - DESCR_LINKAGE_LEN, + Ptr + DESCR_LINKAGE_LEN); + break; + + case DESCR_VIDEO_STREAM: + case DESCR_AUDIO_STREAM: + case DESCR_HIERARCHY: + case DESCR_REGISTRATION: + case DESCR_DATA_STREAM_ALIGN: + case DESCR_TARGET_BACKGRID: + case DESCR_VIDEO_WINDOW: + case DESCR_CA: + case DESCR_SYSTEM_CLOCK: + case DESCR_MULTIPLEX_BUFFER_UTIL: + case DESCR_COPYRIGHT: + case DESCR_MAXIMUM_BITRATE: + case DESCR_PRIVATE_DATA_IND: + case DESCR_SMOOTHING_BUFFER: + case DESCR_STD: + case DESCR_IBP: + case DESCR_NW_NAME: + case DESCR_SERVICE_LIST: + case DESCR_SAT_DEL_SYS: + case DESCR_CABLE_DEL_SYS: + case DESCR_VBI_DATA: + case DESCR_VBI_TELETEXT: + case DESCR_MOSAIC: + case DESCR_TELETEXT: + case DESCR_TELEPHONE: + case DESCR_LOCAL_TIME_OFF: + case DESCR_SUBTITLING: + case DESCR_TERR_DEL_SYS: + case DESCR_ML_NW_NAME: + case DESCR_ML_BQ_NAME: + case DESCR_ML_SERVICE_NAME: + case DESCR_ML_COMPONENT: + case DESCR_PRIV_DATA_SPEC: + case DESCR_SERVICE_MOVE: + case DESCR_SHORT_SMOOTH_BUF: + case DESCR_FREQUENCY_LIST: + case DESCR_PARTIAL_TP_STREAM: + case DESCR_DATA_BROADCAST: + case DESCR_CA_SYSTEM: + case DESCR_DATA_BROADCAST_ID: + case DESCR_TRANSPORT_STREAM: + case DESCR_DSNG: + case DESCR_PDC: + case DESCR_AC3: + case DESCR_CELL_LIST: + case DESCR_CELL_FREQ_LINK: + case DESCR_ANNOUNCEMENT_SUPPORT: + default: + /* fprintf (stderr, "unsupported descriptor 0x%x\n", + GetDescriptorTag(Buffer)); */ + break; + } + if (Descriptor) xAddTail (Descriptors, Descriptor); + return; +} + + +/* + * ToDo: ETSI conformal text definition + */ +char *siGetDescriptorText (u_char *Buffer, u_int Length) +{ + char *tmp, *result; + int i; + + if (*Buffer == 0x05 || (*Buffer >= 0x20 && *Buffer <= 0xff)) + { + xMemAlloc (Length+1, &result); + tmp = result; + for (i = 0; i < Length; i++) + { + if (*Buffer == 0) break; + + if ((*Buffer >= ' ' && *Buffer <= '~') || + (*Buffer >= 0xa0 && *Buffer <= 0xff)) *tmp++ = *Buffer++; + else Buffer++; + } + *tmp = '\0'; + } + else + { + switch (*Buffer) + { + case 0x01: result = xSetText ("Coding according to character table 1"); break; + case 0x02: result = xSetText ("Coding according to character table 2"); break; + case 0x03: result = xSetText ("Coding according to character table 3"); break; + case 0x04: result = xSetText ("Coding according to character table 4"); break; + case 0x10: result = xSetText ("Coding according to ISO/IEC 8859"); break; + case 0x11: result = xSetText ("Coding according to ISO/IEC 10646"); break; + case 0x12: result = xSetText ("Coding according to KSC 5601"); break; + default: result = xSetText ("Unknown coding"); break; + } + } + + return (result); +} + +// CRC32 lookup table for polynomial 0x04c11db7 + +static u_long crc_table[256] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, + 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, + 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, + 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, + 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, + 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, + 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, + 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, + 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, + 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, + 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, + 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, + 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, + 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, + 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, + 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, + 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4}; + +u_long crc32 (char *data, int len) +{ + register int i; + u_long crc = 0xffffffff; + + for (i=0; i> 24) ^ *data++) & 0xff]; + + return crc; +} diff --git a/libdtv/libvdr/COPYING b/libdtv/libvdr/COPYING new file mode 100644 index 0000000..a43ea21 --- /dev/null +++ b/libdtv/libvdr/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libdtv/libvdr/Makefile b/libdtv/libvdr/Makefile new file mode 100644 index 0000000..8aecffc --- /dev/null +++ b/libdtv/libvdr/Makefile @@ -0,0 +1,62 @@ +############################################################## +### ### +### Makefile: local makefile for libvdr ### +### ### +############################################################## + +## $Revision: 1.1 $ +## $Date: 2001/08/15 14:05:16 $ +## $Author: kls $ +## +## (C) 2001 Rolf Hakenes , under the GNU GPL. +## +## libdtv is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2, or (at your option) +## any later version. +## +## libdtv is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You may have received a copy of the GNU General Public License +## along with libdtv; see the file COPYING. If not, write to the +## Free Software Foundation, Inc., 59 Temple Place - Suite 330, +## Boston, MA 02111-1307, USA. +# +# +# +CC = gcc +CFLAGS = -O2 -g -Wmissing-prototypes -Wstrict-prototypes \ + -Wimplicit -D__USE_FIXED_PROTOTYPES__ -I../include # -DDEBUG + + +AR = ar +ARFLAGS = r +RANLIB = ranlib +RM = rm -f +CP = cp + +VDRINCLUDE = libvdr.h +VDRLIB = libvdr.a +VDROBJS = libvdr.o + +all : $(VDRLIB) + +clean : + @echo "cleaning workspace..." + @$(RM) $(VDROBJS) $(VDRLIB) + +new : clean all + +$(VDRLIB) : $(VDROBJS) + @echo "updating library..." + @$(AR) $(ARFLAGS) $(VDRLIB) $(VDROBJS) + @$(RANLIB) $(VDRLIB) + +dist: all + @echo "distributing libvdr.a and libvdr.h..." + @$(CP) $(VDRLIB) ../lib + @$(CP) $(VDRINCLUDE) ../include + diff --git a/libdtv/libvdr/libvdr.c b/libdtv/libvdr/libvdr.c new file mode 100644 index 0000000..5caa5d7 --- /dev/null +++ b/libdtv/libvdr/libvdr.c @@ -0,0 +1,169 @@ +////////////////////////////////////////////////////////////// +/// /// +/// libvdr.c: routines to parse the DVB-SI stream /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/08/15 14:05:24 $ +// $Author: kls $ +// +// (C) 2001 Rolf Hakenes , under the GNU GPL. +// +// libvdr is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// libvdr is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with libvdr; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "libvdr.h" + + + +struct LIST *createVdrProgramInfos (unsigned char *siBuffer) +{ + struct VdrProgramInfo *VdrProgramInfo; + struct LIST *Result, *EventList; + struct Event *Event; + struct Descriptor *Descriptor; + + if (!siBuffer) return (NULL); + + if (!(EventList = siParseEIT (siBuffer))) return (NULL); + + Result = xNewList (NULL); + + xForeach (EventList, Event) + { + VdrProgramInfo = NULL; + + xForeach (Event->Descriptors, Descriptor) + { + switch (Descriptor->Tag) + { + case DESCR_SHORT_EVENT: + { + if (!xName(Descriptor) || !xName(Descriptor)[0]) + break; + + if (!VdrProgramInfo) + { + CreateVdrProgramInfo(VdrProgramInfo, + Event->EventID, Event->TransportStreamID, + Event->ServiceID, Event->StartTime, + Event->Duration, Event->Status); + + VdrProgramInfo->ShortName = + xSetText (xName (Descriptor)); + VdrProgramInfo->ShortText = + xSetText (((struct ShortEventDescriptor + *)Descriptor)->Text); + memcpy (VdrProgramInfo->LanguageCode, ((struct + ShortEventDescriptor *)Descriptor)-> + LanguageCode, 4); + } + } + break; + + case DESCR_TIME_SHIFTED_EVENT: + { + struct tm *StartTime; + + if (!VdrProgramInfo) + { + CreateVdrProgramInfo(VdrProgramInfo, + Event->EventID, Event->TransportStreamID, + Event->ServiceID, Event->StartTime, + Event->Duration, Event->Status); + + VdrProgramInfo->ReferenceServiceID = + ((struct TimeShiftedEventDescriptor + *)Descriptor)->ReferenceServiceID; + VdrProgramInfo->ReferenceEventID = + ((struct TimeShiftedEventDescriptor + *)Descriptor)->ReferenceEventID; + } + } + break; + + case DESCR_EXTENDED_EVENT: + { + struct ExtendedEventItem *Item; + + if (VdrProgramInfo) + { + if (xName (Descriptor)) + AddToText (xName (Descriptor), + VdrProgramInfo->ExtendedName); + xForeach (((struct ExtendedEventDescriptor*) + Descriptor)->Items, Item) + { + AddItemToText (xName (Item), + VdrProgramInfo->ExtendedText); + AddItemToText (Item->Text, + VdrProgramInfo->ExtendedText); + } + } + } + break; + + case DESCR_CONTENT: + { + int i, j; + + if (VdrProgramInfo) + { + for (j = 0; j < ((struct ContentDescriptor*) + Descriptor)->Amount; j++) + { + VdrProgramInfo->ContentNibble1 = + GetContentContentNibble1(Descriptor, j); + VdrProgramInfo->ContentNibble2 = + GetContentContentNibble2(Descriptor, j); + } + } + } + break; + + case DESCR_PARENTAL_RATING: + { + struct ParentalRating *Rating; + + if (VdrProgramInfo) + { + xForeach (((struct ParentalRatingDescriptor *) + Descriptor)->Ratings, Rating) + if (!strncmp (VdrProgramInfo->LanguageCode, + Rating->LanguageCode, 3)) + VdrProgramInfo->Rating = Rating->Rating; + } + } + break; + } + } + if (VdrProgramInfo) xAddTail (Result, VdrProgramInfo); + } + + return (Result); +} diff --git a/libdtv/libvdr/libvdr.h b/libdtv/libvdr/libvdr.h new file mode 100644 index 0000000..6fde10b --- /dev/null +++ b/libdtv/libvdr/libvdr.h @@ -0,0 +1,111 @@ +////////////////////////////////////////////////////////////// +/// /// +/// libvdr.h: definitions necessary for the libvdr package /// +/// /// +////////////////////////////////////////////////////////////// + +// $Revision: 1.1 $ +// $Date: 2001/08/15 10:54:13 $ +// $Author: kls $ +// +// (C) 1992-2001 Rolf Hakenes , under the GNU GPL. +// +// libvdr is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// libvdr is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You may have received a copy of the GNU General Public License +// along with libvdr; see the file COPYING. If not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. + +#ifndef LIBVDR_H +#define LIBVDR_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct LIST *createVdrProgramInfos (unsigned char *); + +#ifdef __cplusplus +} +#endif + +struct VdrProgramInfo { + struct NODE Node; + int EventID; + int TransportStreamID; + int ServiceID; + time_t StartTime; + time_t Duration; + unsigned short Status; + char LanguageCode[4]; + unsigned short Rating; + unsigned short ContentNibble1; + unsigned short ContentNibble2; + char *ShortName; + char *ShortText; + char *ExtendedName; + char *ExtendedText; + int ReferenceServiceID; + int ReferenceEventID; +}; + + +#define CreateVdrProgramInfo(cinf, evid, tpid, svid, stst, dura, sta) \ + do \ + { \ + xCreateNode (cinf, NULL); \ + cinf->EventID = evid; \ + cinf->TransportStreamID = tpid; \ + cinf->ServiceID = svid; \ + cinf->StartTime = stst; \ + cinf->Duration = dura; \ + cinf->Status = sta; \ + cinf->LanguageCode[0] = 0; \ + cinf->Rating = 0; \ + cinf->ContentNibble1 = 0; \ + cinf->ContentNibble2 = 0; \ + cinf->ShortName = NULL; \ + cinf->ShortText = NULL; \ + cinf->ExtendedName = NULL; \ + cinf->ExtendedText = NULL; \ + cinf->ReferenceServiceID = 0; \ + cinf->ReferenceEventID = 0; \ + } while (0) + +#define AddToText(src, dest) \ + do { \ + if (dest) \ + { \ + char *tmbuf; \ + xMemAlloc (strlen (src) + strlen (dest) + 4, &tmbuf); \ + sprintf (tmbuf, "%s%s", (dest), (src)); \ + xMemFree (dest); (dest) = tmbuf; \ + } else { \ + (dest) = xSetText (src); \ + } \ + } while (0) + + +#define AddItemToText(src, dest) \ + do { \ + if (dest) \ + { \ + char *tmbuf; \ + xMemAlloc (strlen (src) + strlen (dest) + 4, &tmbuf); \ + sprintf (tmbuf, "%s|%s", (dest), (src)); \ + xMemFree (dest); (dest) = tmbuf; \ + } else { \ + (dest) = xSetText (src); \ + } \ + } while (0) + +#endif diff --git a/menu.c b/menu.c index 0f89fab..4cc43f0 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.103 2001/08/12 12:42:37 kls Exp $ + * $Id: menu.c 1.105 2001/08/19 14:45:31 kls Exp $ */ #include "menu.h" @@ -17,6 +17,7 @@ #include "i18n.h" #define MENUTIMEOUT 120 // seconds +#define MAXWAIT4EPGINFO 10 // seconds const char *FileNameChars = " aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789-.#^"; @@ -1701,6 +1702,7 @@ void cMenuSetup::Set(void) Add(new cMenuEditIntItem( tr("MarginStart"), &data.MarginStart)); Add(new cMenuEditIntItem( tr("MarginStop"), &data.MarginStop)); Add(new cMenuEditIntItem( tr("EPGScanTimeout"), &data.EPGScanTimeout)); + Add(new cMenuEditIntItem( tr("EPGBugfixLevel"), &data.EPGBugfixLevel, 0, 3)); Add(new cMenuEditIntItem( tr("SVDRPTimeout"), &data.SVDRPTimeout)); Add(new cMenuEditIntItem( tr("PrimaryLimit"), &data.PrimaryLimit, 0, MAXPRIORITY)); Add(new cMenuEditIntItem( tr("DefaultPriority"), &data.DefaultPriority, 0, MAXPRIORITY)); @@ -2062,6 +2064,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer) { + eventInfo = NULL; instantId = NULL; dvbApi = DvbApi; if (!dvbApi) dvbApi = cDvbApi::PrimaryDvbApi;//XXX @@ -2075,6 +2078,11 @@ cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer) timer->SetPending(true); timer->SetRecording(true); if (Channels.SwitchTo(timer->channel, dvbApi)) { + if (GetEventInfo()) { + //XXX this is in preparation for storing recordings in subdirectories and giving them the name of the Subtitle + dsyslog(LOG_INFO, "Title: '%s' Subtitle: '%s'", eventInfo->GetTitle(), eventInfo->GetSubtitle());//XXX + //XXX modify timer's name and summary, mark it as modified (revert later when stopping) + } cRecording Recording(timer); if (dvbApi->StartRecord(Recording.FileName(), Channels.GetByNumber(timer->channel)->ca, timer->priority)) Recording.WriteSummary(); @@ -2090,6 +2098,34 @@ cRecordControl::~cRecordControl() delete instantId; } +bool cRecordControl::GetEventInfo(void) +{ + cChannel *channel = Channels.GetByNumber(timer->channel); + time_t Time = timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2; + for (int seconds = 0; seconds <= MAXWAIT4EPGINFO; seconds++) { + { + cThreadLock ThreadLock; + const cSchedules *Schedules = dvbApi->Schedules(&ThreadLock); + if (Schedules) { + const cSchedule *Schedule = Schedules->GetSchedule(channel->pnr); + if (Schedule) { + eventInfo = Schedule->GetEvent(Time); + if (eventInfo) { + if (seconds > 0) + dsyslog(LOG_INFO, "got EPG info after %d seconds", seconds); + return true; + } + } + } + } + if (seconds == 0) + dsyslog(LOG_INFO, "waiting for EPG info..."); + sleep(1); + } + dsyslog(LOG_INFO, "no EPG info available"); + return false; +} + void cRecordControl::Stop(bool KeepInstant) { if (timer) { diff --git a/menu.h b/menu.h index f75ca86..d6db002 100644 --- a/menu.h +++ b/menu.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.23 2001/08/11 14:08:50 kls Exp $ + * $Id: menu.h 1.24 2001/08/18 10:22:43 kls Exp $ */ #ifndef _MENU_H @@ -72,7 +72,9 @@ class cRecordControl { private: cDvbApi *dvbApi; cTimer *timer; + const cEventInfo *eventInfo; char *instantId; + bool GetEventInfo(void); public: cRecordControl(cDvbApi *DvbApi, cTimer *Timer = NULL); virtual ~cRecordControl(); diff --git a/remux.c b/remux.c index 3c7ec6e..f89b897 100644 --- a/remux.c +++ b/remux.c @@ -8,7 +8,7 @@ * the Linux DVB driver's 'tuxplayer' example and were rewritten to suit * VDR's needs. * - * $Id: remux.c 1.5 2001/06/24 16:37:23 kls Exp $ + * $Id: remux.c 1.6 2001/08/19 11:52:05 kls Exp $ */ /* The calling interface of the 'cRemux::Process()' function is defined @@ -489,6 +489,8 @@ void cRemux::SetAudioPid(int APid) resultCount = resultDelivered = 0; } +#define TS_SYNC_BYTE 0x47 + const uchar *cRemux::Process(const uchar *Data, int &Count, int &Result, uchar *PictureType) { uchar dummyPictureType; @@ -511,12 +513,27 @@ XXX*/ resultDelivered = 0; } + int used = 0; + + // Make sure we are looking at a TS packet: + + while (Count > TS_SIZE) { + if (Data[0] == TS_SYNC_BYTE && Data[TS_SIZE] == TS_SYNC_BYTE) + break; + Data++; + Count--; + used++; + } + if (used) + esyslog(LOG_ERR, "ERROR: skipped %d byte to sync on TS packet", used); + // Convert incoming TS data into multiplexed PES: - int used = 0; for (int i = 0; i < Count; i += TS_SIZE) { if (Count - i < TS_SIZE) break; + if (Data[i] != TS_SYNC_BYTE) + break; int pid = GetPid(Data + i + 1); if (Data[i + 3] & 0x10) { // got payload if (pid == vPid) vTS2PES->ts_to_pes(Data + i); diff --git a/tools.c b/tools.c index e6aba17..30b675b 100644 --- a/tools.c +++ b/tools.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.39 2001/08/12 15:12:54 kls Exp $ + * $Id: tools.c 1.40 2001/08/17 12:45:42 kls Exp $ */ #define _GNU_SOURCE @@ -103,6 +103,32 @@ char *stripspace(char *s) return s; } +char *compactspace(char *s) +{ + if (s && *s) { + char *t = stripspace(skipspace(s)); + char *p = t; + while (p && *p) { + char *q = skipspace(p); + if (q - p > 1) + memmove(p + 1, q, strlen(q) + 1); + p++; + } + if (t != s) + memmove(s, t, strlen(t) + 1); + } + return s; +} + +bool startswith(const char *s, const char *p) +{ + while (*p) { + if (*p++ != *s++) + return false; + } + return true; +} + bool isempty(const char *s) { return !(s && *skipspace(s)); diff --git a/tools.h b/tools.h index bf2e46b..af7958f 100644 --- a/tools.h +++ b/tools.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.28 2001/08/12 15:13:02 kls Exp $ + * $Id: tools.h 1.29 2001/08/17 12:44:39 kls Exp $ */ #ifndef __TOOLS_H @@ -41,6 +41,8 @@ char *strn0cpy(char *dest, const char *src, size_t n); char *strreplace(char *s, char c1, char c2); char *skipspace(const char *s); char *stripspace(char *s); +char *compactspace(char *s); +bool startswith(const char *s, const char *p); bool isempty(const char *s); int time_ms(void); void delay_ms(int ms); -- cgit v1.2.3