From 7ff59171e3f907a5584b72f0f8588ed65f22c0bd Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Mon, 22 Dec 2003 13:29:24 +0100 Subject: [PATCH] Changed section handling; replaced 'libdtv' with 'libsi' --- CONTRIBUTORS | 1 + HISTORY | 17 +- Makefile | 24 +- PLUGINS.html | 220 ++-- PLUGINS/src/hello/Makefile | 4 +- PLUGINS/src/osddemo/Makefile | 4 +- PLUGINS/src/sky/Makefile | 4 +- PLUGINS/src/status/Makefile | 4 +- device.c | 53 +- device.h | 26 +- dvbdevice.c | 57 +- dvbdevice.h | 13 +- eit.c | 1596 +++--------------------------- eit.h | 190 +--- epg.c | 669 +++++++++++++ epg.h | 130 +++ filter.c | 126 +++ filter.h | 74 ++ libdtv/COPYING | 339 ------- libdtv/Makefile | 73 -- libdtv/README | 27 - libdtv/liblx/COPYING | 339 ------- libdtv/liblx/Makefile | 62 -- libdtv/liblx/liblx.h | 449 --------- libdtv/liblx/xListFuncs.c | 189 ---- libdtv/liblx/xMemMgt.c | 624 ------------ libdtv/libsi/COPYING | 339 ------- libdtv/libsi/Makefile | 83 -- libdtv/libsi/README | 2 - libdtv/libsi/include/libsi.h | 1248 ----------------------- libdtv/libsi/include/si_tables.h | 1403 -------------------------- libdtv/libsi/si_debug_services.c | 674 ------------- libdtv/libsi/si_debug_services.h | 245 ----- libdtv/libsi/si_parser.c | 1335 ------------------------- libdtv/libvdr/COPYING | 339 ------- libdtv/libvdr/Makefile | 63 -- libdtv/libvdr/libvdr.c | 157 --- libdtv/libvdr/libvdr.h | 111 --- menu.c | 190 ++-- menu.h | 12 +- newplugin | 4 +- pat.c | 219 ++++ pat.h | 36 + sections.c | 180 ++++ sections.h | 45 + svdrp.c | 10 +- thread.c | 35 +- thread.h | 12 +- timers.c | 14 +- timers.h | 6 +- vdr.c | 27 +- 51 files changed, 2118 insertions(+), 9985 deletions(-) create mode 100644 epg.c create mode 100644 epg.h create mode 100644 filter.c create mode 100644 filter.h delete mode 100644 libdtv/COPYING delete mode 100644 libdtv/Makefile delete mode 100644 libdtv/README delete mode 100644 libdtv/liblx/COPYING delete mode 100644 libdtv/liblx/Makefile delete mode 100644 libdtv/liblx/liblx.h delete mode 100644 libdtv/liblx/xListFuncs.c delete mode 100644 libdtv/liblx/xMemMgt.c delete mode 100644 libdtv/libsi/COPYING delete mode 100644 libdtv/libsi/Makefile delete mode 100644 libdtv/libsi/README delete mode 100644 libdtv/libsi/include/libsi.h delete mode 100644 libdtv/libsi/include/si_tables.h delete mode 100644 libdtv/libsi/si_debug_services.c delete mode 100644 libdtv/libsi/si_debug_services.h delete mode 100644 libdtv/libsi/si_parser.c delete mode 100644 libdtv/libvdr/COPYING delete mode 100644 libdtv/libvdr/Makefile delete mode 100644 libdtv/libvdr/libvdr.c delete mode 100644 libdtv/libvdr/libvdr.h create mode 100644 pat.c create mode 100644 pat.h create mode 100644 sections.c create mode 100644 sections.h diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 99ff6d11..82f79031 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -642,6 +642,7 @@ Marcel Wiesweg for reporting a problem with cReceivers that want to receive from PIDs that are currently not transmitting for fixing volume display in case a plugin has its own OSD open + for providing 'libsi' and adapting the EIT mechanisms to it Torsten Herz for fixing a possible deadlock when using the "Blue" button in the "Schedules" menu diff --git a/HISTORY b/HISTORY index 406a1cd3..616d29f9 100644 --- a/HISTORY +++ b/HISTORY @@ -2393,7 +2393,7 @@ Video Disk Recorder Revision History not loaded (suggested by Alexander Wetzel). - Fixed checking for VIDEO_STREAM_S in cRemux::SetBrokenLink() (thanks to Oliver Endriss). -- Added 'repeat' function keys '7' and '9' ("jump to mark") in replay mode +- Added 'repeat' function to keys '7' and '9' ("jump to mark") in replay mode (suggested by Oliver Endriss). - Made cOsdMenu::Display() virtual, which allows plugins to do some additional processing after calling the base class function (suggested by Jan Rieger). @@ -2470,7 +2470,7 @@ Video Disk Recorder Revision History - Final release of version 1.2.6. -2003-10-24: Version 1.3.0 +2003-12-22: Version 1.3.0 - Changed thread handling to make it work with NPTL ("Native Posix Thread Library"). Thanks to Jon Burgess, Andreas Schultz, Werner Fink and Stefan Huelswitt. @@ -2489,3 +2489,16 @@ Video Disk Recorder Revision History provided by Alessio Sangalli). - Greek language texts now use iso8859-7 character set (thanks to Dimitrios Dimitrakos). +- Rearranged section data handling, so that the actual data handling can be done + separately, even from within plugins. +- The EPG data structures have been moved from eit.[hc] to epg.[hc] and have been + adapted to the general VDR coding style. Plugins that use these data structures + may need to change some function names (which should be obvious). + The name 'subtitle' has been changed to 'shortText' to avoid clashes with actual + subtitles that are part of a movie. The name 'extendedDescription' has been + shortened to 'description'. +- Replaced 'libdtv' with 'libsi' (thanks to Marcel Wiesweg), which is thread + safe and can be used by multiple section filters simultaneously. +- Added 'cRWlock' to 'thread.[hc]'. Note that all plugin Makefiles need to + define _GNU_SOURCE for this to work (see the example plugin Makefiles and + 'newplugin'). diff --git a/Makefile b/Makefile index 0eaf1405..5b3e743f 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 1.60 2003/10/24 13:13:02 kls Exp $ +# $Id: Makefile 1.61 2003/12/21 14:45:27 kls Exp $ .DELETE_ON_ERROR: @@ -15,7 +15,7 @@ CXX ?= g++ CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual DVBDIR = ../DVB -DTVDIR = ./libdtv +LSIDIR = ./libsi MANDIR = /usr/local/man BINDIR = /usr/local/bin @@ -31,12 +31,12 @@ DOXYFILE = Doxyfile INCLUDES = -I$(DVBDIR)/include -DTVLIB = $(DTVDIR)/libdtv.a +SILIB = $(LSIDIR)/libsi.a OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbosd.o\ - dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o interface.o keys.o\ - lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o\ - receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sources.o\ + dvbplayer.o dvbspu.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\ + lirc.o menu.o menuitems.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\ + receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sections.o sources.o\ spu.o status.o svdrp.o thread.o timers.o tools.o transfer.o vdr.o videodir.o FIXFONT_ISO8859_1 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1 @@ -89,8 +89,8 @@ $(DEPFILE): Makefile # The main program: -vdr: $(OBJS) $(DTVLIB) - $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) -ljpeg -lpthread -ldl $(LIBDIRS) $(DTVLIB) -o vdr +vdr: $(OBJS) $(SILIB) + $(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) -ljpeg -lpthread -ldl $(LIBDIRS) $(SILIB) -o vdr # The font files: @@ -112,10 +112,10 @@ fontsml_iso8859_1.c: genfontfile: genfontfile.c $(CC) $(CFLAGS) -o $@ -L/usr/X11R6/lib $< -lX11 -# The libdtv library: +# The libsi library: -$(DTVLIB) $(DTVDIR)/libdtv.h: - $(MAKE) -C $(DTVDIR) all +$(SILIB): + $(MAKE) -C $(LSIDIR) all # The 'include' directory (for plugins): @@ -154,7 +154,7 @@ srcdoc: # Housekeeping: clean: - $(MAKE) -C $(DTVDIR) clean + $(MAKE) -C $(LSIDIR) clean -rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core* *~ -rm -rf include -rm -rf srcdoc diff --git a/PLUGINS.html b/PLUGINS.html index 95ba5d79..67216e2a 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -6,7 +6,7 @@

The VDR Plugin System

-
Version 1.2.6
+
Version 1.3

Copyright © 2003 Klaus Schmidinger
@@ -14,9 +14,12 @@ Copyright © 2003 Klaus Schmidinger
www.cadsoft.de/vdr

-
  +
  Important modifications introduced in version 1.2.6 are marked like this. -
+
+
  +Important modifications introduced in version 1.3.0 are marked like this. +

VDR provides an easy to use plugin interface that allows additional functionality to be added to the program by implementing a dynamically loadable library file. @@ -64,6 +67,9 @@ structures and allows it to hook itself into specific areas to perform special a

  • Status monitor
  • Players
  • Receivers +
      +
  • Filters +
  • The On Screen Display
  • Devices
  • Dolby Digital @@ -112,7 +118,7 @@ No other characters should be used here.

    A plugin can access its name through the (non virtual) member function -


    +

     const char *Name(void);
     

    @@ -127,7 +133,7 @@ By default plugins are located in a directory named PLUGINS below the VDR source directory. Inside this directory the following subdirectory structure is used: -


    +

     VDR/PLUGINS/src
     VDR/PLUGINS/src/hello
     VDR/PLUGINS/lib
    @@ -172,7 +178,7 @@ To use the plugins and plugins-clean targets from the VDR 
     you need to unpack such an archive into the VDR/PLUGINS/src directory and
     create a symbolic link with the basic plugin name, as in
     
    -


    +

     ln -s hello-0.0.1 hello
     

    @@ -226,7 +232,7 @@ If your plugin shall not be accessible through VDR's main menu, simply remove

    At the end of the plugin's source file you will find a line that looks like this: -


    +

     VDRPLUGINCREATOR(cPluginHello);
     

    @@ -239,7 +245,7 @@ source directory and adjust the Makefile accordingly. Header files usually contain preprocessor statements that prevent the same file (or rather its contents, to be precise) from being included more than once, like -


    +

     #ifndef __I18N_H
     #define __I18N_H
     
    @@ -274,7 +280,7 @@ and two replacing the dot).
     
     The constructor and destructor of a plugin are defined as
     
    -


    +

     cPlugin(void);
     virtual ~cPlugin();
     

    @@ -304,7 +310,7 @@ Every plugin must have a version number of its own, which does not necessarily have to be in any way related to the VDR version number. VDR requests a plugin's version number through a call to the function -


    +

     virtual const char *Version(void) = 0;
     

    @@ -315,7 +321,7 @@ information, like for instance "0.0.1pre2" or the like. The string should only be as long as really necessary, and shall not contain the plugin's name itself. Here's an example: -


    +

     static const char *VERSION = "0.0.1";
     
     const char *cPluginHello::Version(void)
    @@ -347,13 +353,13 @@ would be acceptable.
     
     In order to tell the user what exactly a plugin does, it must implement the function
     
    -


    +

     virtual const char *Description(void) = 0;
     

    which returns a short, one line description of the plugin's purpose: -


    +

     static const char *DESCRIPTION = "A friendly greeting";
     
     virtual const char *Description(void)
    @@ -373,7 +379,7 @@ A VDR plugin can have command line arguments just like any normal program.
     If a plugin wants to react on command line arguments, it needs to implement
     the function
     
    -


    +

     virtual bool ProcessArgs(int argc, char *argv[]);
     

    @@ -390,7 +396,7 @@ these arguments. As with any normal C program, the strings pointed to by arg will survive the entire lifetime of the plugin, so it is safe to store pointers to these values inside the plugin. Here's an example: -


    +

     bool cPluginHello::ProcessArgs(int argc, char *argv[])
     {
       // Implement command line argument processing here if applicable.
    @@ -425,7 +431,7 @@ to exit.
     
     If a plugin accepts command line options, it should implement the function
     
    -


    +

     virtual const char *CommandLineHelp(void);
     

    @@ -433,7 +439,7 @@ which will be called if the user enters the -h option when start The returned string should contain the command line help for this plugin, formatted in the same way as done by VDR itself: -


    +

     const char *cPluginHello::CommandLineHelp(void)
     {
       // Return a string that describes all known command line options.
    @@ -456,7 +462,7 @@ If a plugin implements a function that runs in the background (presumably in a
     thread of its own), or wants to make use of internationalization,
     it needs to implement one of the functions
     
    -


    +

     virtual bool Initialize(void);
     virtual bool Start(void);
     

    @@ -493,7 +499,7 @@ texts, it doesn't need to implement either of these functions. If the plugin implements a feature that the user shall be able to access from VDR's main menu, it needs to implement the function -


    +

     virtual const char *MainMenuEntry(void);
     

    @@ -501,7 +507,7 @@ The default implementation returns a NULL pointer, which means that this plugin will not have an item in the main menu. Here's an example of a plugin that will have a main menu item: -


    +

     static const char *MAINMENUENTRY = "Hello";
     
     const char *cPluginHello::MainMenuEntry(void)
    @@ -520,7 +526,7 @@ in the call to VDR.
     
     If the user selects the main menu entry of a plugin, VDR calls the function
     
    -


    +

     virtual cOsdObject *MainMenuAction(void);
     

    @@ -554,7 +560,7 @@ the plugin should launch a separate thread to do this. From time to time a plugin may want to do some regular tasks, like cleaning up some files or other things. In order to do this it can implement the function -


    +

     virtual void Housekeeping(void);
     

    @@ -579,7 +585,7 @@ the plugin should launch a separate thread to do this. If a plugin requires its own setup parameters, it needs to implement the following functions to handle these parameters: -


    +

     virtual cMenuSetupPage *SetupMenu(void);
     virtual bool SetupParse(const char *Name, const char *Value);
     

    @@ -594,7 +600,7 @@ an error. If false is returned, an error message will be written to the log file (and program execution will continue). A possible implementation of SetupParse() could look like this: -


    +

     bool cPluginHello::SetupParse(const char *Name, const char *Value)
     {
       // Parse your own setup parameters and store their values.
    @@ -620,7 +626,7 @@ plugins need not worry about this.
     

    To store its values in the global setup, a plugin has to call the function -


    +

     void SetupStore(const char *Name, type Value);
     

    @@ -653,7 +659,7 @@ To implement a Setup menu, a plugin needs to derive a class from cMenuSetupPage and implement its constructor and the pure virtual Store() member function: -


    +

     int GreetingTime = 3;
     int UseAlternateGreeting = false;
     
    @@ -714,7 +720,7 @@ configuration file. While the plugin is free to store such files anywhere it
     sees fit, it might be a good idea to put them in a common place, preferably
     where other configuration data already exists. VDR provides the function
     
    -


    +

     const char *ConfigDirectory(const char *PluginName = NULL);
     

    @@ -737,7 +743,7 @@ these in a subdirectory of its own, named after the plugin. To easily get such a the ConfigDirectory() function can be given an additional string that will be appended to the returned directory name, as in -


    +

     const char *MyConfigDir = ConfigDirectory(Name());
     

    @@ -754,7 +760,7 @@ The ConfigDirectory() function is a static member function of the c class. This allows it to be called even from outside any member function of the derived plugin class, by writing -


    +

     const char *MyConfigDir = cPlugin::ConfigDirectory();
     

    @@ -765,7 +771,7 @@ const char *MyConfigDir = cPlugin::ConfigDirectory(); If a plugin displays texts to the user, it should implement internationalized versions of these texts and call the function -


    +

     void RegisterI18n(const tI18nPhrase * const Phrases);
     

    @@ -774,7 +780,7 @@ to register them with VDR's internationalization mechanism. The call to this function must be done in the Initialize() or Start() function of the plugin: -


    +

     const tI18nPhrase Phrases[] = {
       { "Hello world!",
         "Hallo Welt!",
    @@ -815,7 +821,7 @@ you may want to contact the maintainers of these languages (listed in the file
     The actual runtime selection of the texts corresponding to the selected language
     is done by wrapping each internationalized text with the tr() macro:
     
    -


    +

     const char *s = tr("Hello world!");
     

    @@ -833,20 +839,20 @@ core VDR code. Plugins are loaded into VDR using the command line option -P, as in -


    +

     vdr -Phello
     

    If the plugin accepts command line options, they are given as part of the argument to the -P option, which then has to be enclosed in quotes: -


    +

     vdr -P"hello -a abc -b"
     

    Any number of plugins can be loaded this way, each with its own -P option: -


    +

     vdr -P"hello -a abc -b" -Pdvd -Pmp3
     

    @@ -854,7 +860,7 @@ If you are not starting VDR from the VDR source directory (and thus your plugins cannot be found at their default location) you need to tell VDR the location of the plugins through the -L option: -


    +

     vdr -L/usr/lib/vdr -Phello
     

    @@ -879,14 +885,14 @@ provides the target dist, which does this for you.

    Simply change into your source directory and execute make dist: -


    +

     cd VDR/PLUGINS/src/hello
     make dist
     

    After this you should find a file named like -


    +

     vdr-hello-0.0.1.tgz
     

    @@ -902,7 +908,7 @@ plugin's name, and 0.0.1 will be your plugin's current version number. If a plugin wants to get informed on various events in VDR, it can derive a class from cStatus, as in -


    +

     #include <vdr/status.h>
     
     class cMyStatusMonitor : public cStatus {
    @@ -922,7 +928,7 @@ void cMyStatusMonitor::ChannelSwitch(const cDevice *Device, int ChannelNumber)
     An object of this class will be informed whenever the channel is switched on one of
     the DVB devices. It could be used in a plugin like this:
     
    -


    +

     #include <vdr/plugin.h>
     
     class cPluginStatus : public cPlugin {
    @@ -975,7 +981,7 @@ the functions you actually want to use.
     Implementing a player is a two step process.
     First you need the actual player class, which is derived from the abstract cPlayer:
     
    -


    +

     #include <vdr/player.h>
     
     class cMyPlayer : public cPlayer {
    @@ -991,7 +997,7 @@ What exactly you do in this class is entirely up to you. If you want to run a se
     thread which, e.g.,  reads data from a file, you can additionally derive your class from
     cThread and implement the necessary functionality:
     
    -


    +

     #include <vdr/player.h>
     
     class cMyPlayer : public cPlayer, cThread {
    @@ -1009,7 +1015,7 @@ its own player for the VDR recordings.
     

    To play the video data, the player needs to call its member function -


    +

     int PlayVideo(const uchar *Data, int Length);
     

    @@ -1020,7 +1026,7 @@ desired video data stream, and it must be delivered fast enough so that the DVB device doesn't run out of data. To avoid busy loops the player should call its member function -


    +

     bool DevicePoll(cPoller &Poller, int TimeoutMs = 0);
     

    @@ -1029,7 +1035,7 @@ to determine whether the device is ready for further data. If the player can provide more than a single audio track, it can implement the following functions to make them available: -


    +

     virtual int NumAudioTracks(void) const;
     virtual const char **GetAudioTracks(int *CurrentTrack = NULL);
     virtual void SetAudioTrack(int Index);
    @@ -1039,7 +1045,7 @@ virtual void SetAudioTrack(int Index);
     If there is an additional audio track that has to be replayed with external hardware,
     the player shall call its member function
     
    -


    +

     void PlayAudio(const uchar *Data, int Length);
     

    @@ -1048,7 +1054,7 @@ where Data points to a complete audio PES packet of Length byt The second part needed here is a control object that receives user input from the main program loop and reacts on this by telling the player what to do: -


    +

     #include <vdr/player.h>
     
     class cMyControl : public cControl {
    @@ -1066,7 +1072,7 @@ public:
     hand over a pointer to it to the cControl base class, so that it
     can be later attached to the primary DVB device:
     
    -


    +

     cMyControl::cMyControl(void)
     :cControl(player = new cMyPlayer)
     {
    @@ -1093,7 +1099,7 @@ Finally, to get things going, a plugin that implements a player (and the surroun
     infrastructure like displaying a list of playable stuff etc) simply has to call the
     static function cControl::Launch() with the player control object, as in
     
    -


    +

     cControl::Launch(new cMyControl);
     

    @@ -1104,7 +1110,7 @@ use the primary DVB device, or the user decides to start a different replay).

    The cPlayer class has a member function -


    +

     void DeviceStillPicture(const uchar *Data, int Length);
     

    @@ -1149,7 +1155,7 @@ ahead - it's your show... In order to receive any kind of data from a cDevice, a plugin must set up an object derived from the cReceiver class: -


    +

     #include <vdr/receiver.h>
     
     class cMyReceiver : public cReceiver, cThread {
    @@ -1187,7 +1193,7 @@ a cReceiver to be detached from its cDevice at any time.
     Once a cReceiver has been created, it needs to be attached to
     a cDevice:
     
    -


    +

     cMyReceiver *Receiver = new cMyReceiver(123);
     
     cDevice::ActualDevice()->AttachReceiver(Receiver);
    @@ -1201,6 +1207,49 @@ Mode).
     If the cReceiver isn't needed any more, it may simply be deleted
     and will automatically detach itself from the cDevice.
     
    +
      +

    Filters

    + +
    A Fistful of Datas

    + +If you want to receive section data you have to implement a derived cFilter +class which at least implements the Process() function and a constructor +that sets the (initial) filter parameters: + +

    +#include <vdr/filter.h>
    +
    +class cMyFilter : public cFilter {
    +protected:
    +  virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
    +public:
    +  cMyFilter(void);
    +  ...
    +  };
    +
    +cMyFilter::cMyFilter(void)
    +{
    +  Set(0x14, 0x70);        // TDT
    +}
    +
    +void cMyFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length)
    +{
    +  // do something with the data here
    +}
    +

    + +An instance of such a filter needs to be attached to the device from +which it shall receive data, as in + +

    +cMyFilter Filter;
    +
    +cDevice::ActualDevice()->AttachFilter(Filter);
    +

    + +See VDR/eit.c or VDR/pat.c to learn how to process filter data. +

    +

    The On Screen Display

    Express yourself

    @@ -1213,7 +1262,7 @@ windows and color depths. If a plugin needs to have total control over the OSD, it can call the static function -


    +

     #include <vdr/osd.h>
     
     cOsdBase *MyOsd = cOsd::OpenRaw(x, y);
    @@ -1223,7 +1272,7 @@ where x and y are the coordinates of the upper left corner
     of the OSD area on the screen. Such a "raw" OSD doesn't display anything
     yet, so you need to at least call the function
     
    -


    +

     MyOsd->Create(...);
     

    @@ -1247,7 +1296,7 @@ stream and displays it, for instance, on an existing graphics adapter.

    To implement an additional device, a plugin must derive a class from cDevice: -


    +

     #include <vdr/device.h>
     
     class cMyDevice : public cDevice {
    @@ -1266,7 +1315,7 @@ the cDvbDevice, which is used to access the DVB PCI cards.
     If the new device can receive, it most likely needs to provide a way of
     selecting which channel it shall tune to:
     
    -


    +

     virtual bool ProvidesSource(int Source) const;
     virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL);
     virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
    @@ -1281,7 +1330,7 @@ repectively.
     If the device can provide more than a single audio track, it can implement the
     following functions to make them available:
     
    -


    +

     virtual int NumAudioTracksDevice(void) const;
     virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
     virtual void SetAudioTrackDevice(int Index);
    @@ -1292,7 +1341,7 @@ virtual void SetAudioTrackDevice(int Index);
     

    A device that can be used for recording must implement the functions -


    +

     virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
     virtual bool OpenDvr(void);
     virtual void CloseDvr(void);
    @@ -1308,7 +1357,7 @@ must deliver exactly one such packet (if one is currently available).
     If this device allows receiving several different data streams, it can
     implement
     
    -


    +

     virtual bool CanBeReUsed(int Frequency, int Vpid);
     

    @@ -1318,13 +1367,13 @@ to indicate this to VDR.

    The functions to implement replaying capabilites are -


    +

     virtual bool HasDecoder(void) const;
     virtual bool CanReplay(void) const;
     virtual bool SetPlayMode(ePlayMode PlayMode);
    -
      +
      virtual int64_t GetSTC(void); -
    +
    virtual void TrickSpeed(int Speed); virtual void Clear(void); virtual void Play(void); @@ -1338,12 +1387,39 @@ virtual int PlayVideo(const uchar *Data, int Length); In addition, the following functions may be implemented to provide further functionality: -


    +

     virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int Si
     virtual void SetVideoFormat(bool VideoFormat16_9);
     virtual void SetVolumeDevice(int Volume);
     

    +
      +

    +Section Filtering +

    +If your device provides section filtering capabilities it can implement +the function + +

    +virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
    +

    + +which must open a file handle that delivers section data for the given +filter parameters. +

    +In order to actually start section handling, the +device also needs to call the function + +

    +StartSectionHandler();
    +

    + +from its constructor. +

    +See Filters on how to set up actual filters that can +handle section data. +

    +

    On Screen Display

    @@ -1351,7 +1427,7 @@ If your device provides On Screen Display (OSD) capabilities (which every device that is supposed to be used as a primary device should do), it can implement the function -


    +

     virtual cOsdBase *NewOsd(int x, int y);
     

    @@ -1391,7 +1467,7 @@ audio replay facility. To implement a new audio output facility, simply derive a class from cAudio, as in -


    +

     #include <vdr/audio.h>
     #include <vdr/thread.h>
     
    @@ -1435,7 +1511,7 @@ remote control, so a plugin can use the cRemote class to do that.
     The simplest method for a plugin to issue commands to VDR is to call the
     static function cRemote::Put(eKeys Key), as in
     
    -


    +

     cRemote::Put(kUp);
     

    @@ -1447,7 +1523,7 @@ In cases where the incoming codes are not known, or not all available keys may be supported by the actual remote control in use, you may want to derive your own remote control class from cRemote, as in -


    +

     #include <vdr/remote.h>
     #include <vdr/thread.h>
     
    @@ -1472,7 +1548,7 @@ when the program ends).
     

    The constructor of your remote control class should look like this -


    +

     cMyRemote::cMyRemote(const char *Name)
     :cRemote(Name)
     {
    @@ -1492,7 +1568,7 @@ member variables, you should do so before calling Start().
     If your remote control for some reason can't work (maybe because it was unable to
     open some file handle it requires) it can implement the virtual function
     
    -


    +

     virtual bool Ready(void);
     

    @@ -1513,7 +1589,7 @@ If your remote control class needs some setup data that shall be readily available next time VDR starts (without having to go through the initialization procedure again) it can use the cRemote member functions -


    +

     void PutSetup(const char *Setup);
     const char *GetSetup(void);
     

    @@ -1527,7 +1603,7 @@ The cRemote class assumes that any incoming remote control code can be expressed as a character string. So whatever data your remote control provides needs to be given to the base class by calling -


    +

     Put(const char *Code, bool Repeat = false, bool Release = false);
     

    @@ -1538,7 +1614,7 @@ Since a common case for remote control data is to be given as a numerical value, there is another Put() function available for your convenience, which takes a 64 bit unsigned integer value instead of a character string: -


    +

     Put(uint64 Code, bool Repeat = false, bool Release = false);
     

    diff --git a/PLUGINS/src/hello/Makefile b/PLUGINS/src/hello/Makefile index 068f6e9e..9f35d209 100644 --- a/PLUGINS/src/hello/Makefile +++ b/PLUGINS/src/hello/Makefile @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile 1.8 2002/12/13 14:54:14 kls Exp $ +# $Id: Makefile 1.9 2003/12/21 15:47:22 kls Exp $ # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -42,7 +42,7 @@ PACKAGE = vdr-$(ARCHIVE) INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' +DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): diff --git a/PLUGINS/src/osddemo/Makefile b/PLUGINS/src/osddemo/Makefile index db871613..8116d054 100644 --- a/PLUGINS/src/osddemo/Makefile +++ b/PLUGINS/src/osddemo/Makefile @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile 1.2 2002/12/13 14:54:29 kls Exp $ +# $Id: Makefile 1.3 2003/12/21 15:47:26 kls Exp $ # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -42,7 +42,7 @@ PACKAGE = vdr-$(ARCHIVE) INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' +DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): diff --git a/PLUGINS/src/sky/Makefile b/PLUGINS/src/sky/Makefile index 3df93c18..13d623ba 100644 --- a/PLUGINS/src/sky/Makefile +++ b/PLUGINS/src/sky/Makefile @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile 1.2 2002/12/13 14:54:24 kls Exp $ +# $Id: Makefile 1.3 2003/12/21 15:47:31 kls Exp $ # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -42,7 +42,7 @@ PACKAGE = vdr-$(ARCHIVE) INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' +DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): diff --git a/PLUGINS/src/status/Makefile b/PLUGINS/src/status/Makefile index 18d5eeed..4216e75d 100644 --- a/PLUGINS/src/status/Makefile +++ b/PLUGINS/src/status/Makefile @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile 1.6 2002/12/13 14:54:19 kls Exp $ +# $Id: Makefile 1.7 2003/12/21 15:47:41 kls Exp $ # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -42,7 +42,7 @@ PACKAGE = vdr-$(ARCHIVE) INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' +DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): diff --git a/device.c b/device.c index d1158a7a..20cbe5c5 100644 --- a/device.c +++ b/device.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 1.49 2003/11/07 14:15:10 kls Exp $ + * $Id: device.c 1.50 2003/12/22 10:53:45 kls Exp $ */ #include "device.h" @@ -13,7 +13,6 @@ #include #include "audio.h" #include "channels.h" -#include "eit.h" #include "i18n.h" #include "player.h" #include "receiver.h" @@ -45,6 +44,10 @@ cDevice::cDevice(void) mute = false; volume = Setup.CurrentVolume; + sectionHandler = NULL; + eitFilter = NULL; + patFilter = NULL; + ciHandler = NULL; player = NULL; @@ -65,6 +68,9 @@ cDevice::~cDevice() for (int i = 0; i < MAXRECEIVERS; i++) Detach(receiver[i]); delete ciHandler; + delete eitFilter; + delete patFilter; + delete sectionHandler; } void cDevice::SetUseDevice(int n) @@ -313,6 +319,31 @@ bool cDevice::SetPid(cPidHandle *Handle, int Type, bool On) return false; } +void cDevice::StartSectionHandler(void) +{ + if (!sectionHandler) { + sectionHandler = new cSectionHandler(this); + AttachFilter(eitFilter = new cEitFilter); + AttachFilter(patFilter = new cPatFilter); + sectionHandler->SetStatus(true); + } +} + +int cDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask) +{ + return -1; +} + +void cDevice::AttachFilter(cFilter *Filter) +{ + sectionHandler->Attach(Filter); +} + +void cDevice::Detach(cFilter *Filter) +{ + sectionHandler->Detach(Filter); +} + bool cDevice::ProvidesSource(int Source) const { return false; @@ -401,15 +432,25 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) } else { cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel - if (!SetChannelDevice(Channel, LiveView)) + // Stop section handling: + if (sectionHandler) { + sectionHandler->SetStatus(false); + sectionHandler->SetSource(0, 0); + } + if (SetChannelDevice(Channel, LiveView)) { + // Start section handling: + if (sectionHandler) { + sectionHandler->SetSource(Channel->Source(), Channel->Frequency()); + sectionHandler->SetStatus(true); + } + } + else Result = scrFailed; } if (Result == scrOk) { - if (LiveView && IsPrimaryDevice()) { - cSIProcessor::SetCurrentChannelID(Channel->GetChannelID()); + if (LiveView && IsPrimaryDevice()) currentChannel = Channel->Number(); - } cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull } diff --git a/device.h b/device.h index d73864f2..33b4ad80 100644 --- a/device.h +++ b/device.h @@ -4,13 +4,17 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 1.35 2003/11/07 13:15:45 kls Exp $ + * $Id: device.h 1.36 2003/12/22 10:52:39 kls Exp $ */ #ifndef __DEVICE_H #define __DEVICE_H #include "ci.h" +#include "eit.h" +#include "filter.h" +#include "pat.h" +#include "sections.h" #include "thread.h" #include "tools.h" @@ -222,6 +226,26 @@ protected: ///< Type indicates some special types of PIDs, which the device may ///< need to set in a specific way. +// Section filter facilities + +private: + cSectionHandler *sectionHandler; + cEitFilter *eitFilter; + cPatFilter *patFilter; +protected: + void StartSectionHandler(void); + ///< A derived device that provides section data must call + ///< this function to actually set up the section handler. +public: + virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask); + ///< Opens a file handle for the given filter data. + ///< A derived device that provides section data must + ///< implement this function. + void AttachFilter(cFilter *Filter); + ///< Attaches the given filter to this device. + void Detach(cFilter *Filter); + ///< Detaches the given filter from this device. + // Common Interface facilities: protected: diff --git a/dvbdevice.c b/dvbdevice.c index edebaa2d..e456a916 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 1.72 2003/11/09 11:19:00 kls Exp $ + * $Id: dvbdevice.c 1.73 2003/12/22 10:52:24 kls Exp $ */ #include "dvbdevice.h" @@ -274,7 +274,7 @@ void cDvbTuner::Action(void) if (tunerStatus != tsCam) {//XXX TODO update in case the CA descriptors have changed for (int Slot = 0; Slot < ciHandler->NumSlots(); Slot++) { uchar buffer[2048]; - int length = cSIProcessor::GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), ciHandler->GetCaSystemIds(Slot), sizeof(buffer), buffer); + int length = GetCaDescriptors(channel.Source(), channel.Frequency(), channel.Sid(), ciHandler->GetCaSystemIds(Slot), sizeof(buffer), buffer); if (length > 0) { cCiCaPmt CaPmt(channel.Sid()); CaPmt.AddCaDescriptor(length, buffer); @@ -312,13 +312,12 @@ cDvbDevice::cDvbDevice(int n) { dvbTuner = NULL; frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN - siProcessor = NULL; spuDecoder = NULL; playMode = pmNone; // Devices that are present on all card types: - int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK); + int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK); // Devices that are only present on cards with decoders: @@ -368,7 +367,6 @@ cDvbDevice::cDvbDevice(int n) if (fd_frontend >= 0) { dvb_frontend_info feinfo; - siProcessor = new cSIProcessor(DvbName(DEV_DVB_DEMUX, n)); if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) { frontendType = feinfo.type; ciHandler = cCiHandler::CreateCiHandler(DvbName(DEV_DVB_CA, n)); @@ -381,12 +379,13 @@ cDvbDevice::cDvbDevice(int n) esyslog("ERROR: can't open DVB device %d", n); aPid1 = aPid2 = 0; + + StartSectionHandler(); } cDvbDevice::~cDvbDevice() { delete spuDecoder; - delete siProcessor; delete dvbTuner; // We're not explicitly closing any device files here, since this sometimes // caused segfaults. Besides, the program is about to terminate anyway... @@ -617,6 +616,30 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On) return true; } +int cDvbDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask) +{ + const char *FileName = DvbName(DEV_DVB_DEMUX, CardIndex()); + int f = open(FileName, O_RDWR | O_NONBLOCK); + if (f >= 0) { + dmx_sct_filter_params sctFilterParams; + memset(&sctFilterParams, 0, sizeof(sctFilterParams)); + sctFilterParams.pid = Pid; + sctFilterParams.timeout = 0; + sctFilterParams.flags = DMX_IMMEDIATE_START; + sctFilterParams.filter.filter[0] = Tid; + sctFilterParams.filter.mask[0] = Mask; + if (ioctl(f, DMX_SET_FILTER, &sctFilterParams) >= 0) + return f; + else { + esyslog("ERROR: can't set filter (pid=%d, tid=%02X, mask=%02X)", Pid, Tid, Mask); + close(f); + } + } + else + esyslog("ERROR: can't open filter handle on '%s'", FileName); + return -1; +} + void cDvbDevice::TurnOffLiveMode(void) { // Avoid noise while switching: @@ -715,13 +738,6 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) TurnOnLivePIDs = false; } - // Stop SI filtering: - - if (siProcessor) { - siProcessor->SetCurrentTransponder(0, 0); - siProcessor->SetStatus(false); - } - // Turn off live PIDs if necessary: if (TurnOffLivePIDs) @@ -746,13 +762,6 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) else if (StartTransferMode) cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2())); - // Start SI filtering: - - if (siProcessor) { - siProcessor->SetCurrentTransponder(Channel->Source(), Channel->Frequency()); - siProcessor->SetStatus(true); - } - return true; } @@ -829,16 +838,12 @@ bool cDvbDevice::SetPlayMode(ePlayMode PlayMode) CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX)); CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false)); - if (siProcessor) - siProcessor->SetStatus(true); break; case pmAudioVideo: if (playMode == pmNone) TurnOffLiveMode(); // continue with next... case pmAudioOnlyBlack: - if (siProcessor) - siProcessor->SetStatus(false); CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true)); CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY)); CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, PlayMode == pmAudioVideo)); @@ -847,8 +852,6 @@ bool cDvbDevice::SetPlayMode(ePlayMode PlayMode) CHECK(ioctl(fd_video, VIDEO_PLAY)); break; case pmAudioOnly: - if (siProcessor) - siProcessor->SetStatus(false); CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true)); CHECK(ioctl(fd_audio, AUDIO_STOP, true)); CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER)); @@ -858,8 +861,6 @@ bool cDvbDevice::SetPlayMode(ePlayMode PlayMode) CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false)); break; case pmExtern_THIS_SHOULD_BE_AVOIDED: - if (siProcessor) - siProcessor->SetStatus(false); close(fd_video); close(fd_audio); fd_video = fd_audio = -1; diff --git a/dvbdevice.h b/dvbdevice.h index 56f1c2b1..f6f6f484 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.h 1.24 2003/11/07 13:17:13 kls Exp $ + * $Id: dvbdevice.h 1.25 2003/12/21 14:04:00 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -14,7 +14,6 @@ #include #include "device.h" #include "dvbspu.h" -#include "eit.h" #if DVB_API_VERSION != 3 #error VDR requires Linux DVB driver API version 3! @@ -71,6 +70,11 @@ protected: protected: virtual bool SetPid(cPidHandle *Handle, int Type, bool On); +// Section filter facilities + +protected: + virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask); + // Image Grab facilities private: @@ -95,11 +99,6 @@ protected: virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const; virtual void SetAudioTrackDevice(int Index); -// EIT facilities - -private: - cSIProcessor *siProcessor; - // Player facilities protected: diff --git a/eit.c b/eit.c index bb5b856a..3ac1d40d 100644 --- a/eit.c +++ b/eit.c @@ -1,1480 +1,182 @@ -/*************************************************************************** - eit.c - description - ------------------- - 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 - - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - * $Id: eit.c 1.81 2003/10/18 12:24:18 kls Exp $ - ***************************************************************************/ +/* + * eit.c: EIT section filter + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * Original version (as used in VDR before 1.3.0) written by + * Robert Schneider and Rolf Hakenes . + * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg . + * + * $Id: eit.c 1.82 2003/12/22 10:57:09 kls Exp $ + */ #include "eit.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "channels.h" -#include "config.h" -#include "libdtv/libdtv.h" -#include "videodir.h" +#include "epg.h" +#include "libsi/section.h" +#include "libsi/descriptor.h" -// --- cMJD ------------------------------------------------------------------ +// --- cEIT ------------------------------------------------------------------ -class cMJD { +class cEIT : public SI::EIT { public: - cMJD(); - cMJD(u_char date_hi, u_char date_lo); - cMJD(u_char date_hi, u_char date_lo, u_char timehr, u_char timemi, u_char timese); - ~cMJD(); - /** */ - void ConvertToTime(); - /** */ - bool SetSystemTime(); - /** */ - time_t GetTime_t(); -protected: // Protected attributes - /** */ - time_t mjdtime; -protected: // Protected attributes - /** */ - u_char time_second; -protected: // Protected attributes - /** */ - u_char time_minute; -protected: // Protected attributes - /** */ - u_char time_hour; -protected: // Protected attributes - /** */ - u_short mjd; -}; + cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data); + }; -cMJD::cMJD() +cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data) +:SI::EIT(Data, false) { -} + if (!CheckCRCAndParse()) + return; -cMJD::cMJD(u_char date_hi, u_char date_lo) -{ - mjd = date_hi << 8 | date_lo; - time_hour = time_minute = time_second = 0; - ConvertToTime(); -} + //XXX TODO use complete channel ID + cChannel *channel = Channels.GetByServiceID(Source, getServiceId()); + if (!channel) + return; // only collect data for known channels + tChannelID channelID = channel->GetChannelID(); + channelID.ClrRid(); -cMJD::cMJD(u_char date_hi, u_char date_lo, u_char timehr, u_char timemi, u_char timese) -{ - mjd = date_hi << 8 | date_lo; - time_hour = timehr; - time_minute = timemi; - time_second = timese; - ConvertToTime(); -} + cEvent *rEvent = NULL; -cMJD::~cMJD() -{ -} + cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channelID); + if (!pSchedule) { + pSchedule = new cSchedule(channelID); + Schedules->Add(pSchedule); + } -/** */ -void cMJD::ConvertToTime() -{ - struct tm t; + SI::EIT::Event SiEitEvent; + for (SI::Loop::Iterator it; eventLoop.hasNext(it); ) { + SiEitEvent = eventLoop.getNext(it); - t.tm_sec = time_second; - t.tm_min = time_minute; - t.tm_hour = time_hour; - int k; + cEvent *pEvent = (cEvent *)pSchedule->GetEvent(SiEitEvent.getEventId(), SiEitEvent.getStartTime()); + if (!pEvent) { + // If we don't have that event ID yet, we create a new one. + // Otherwise we copy the information into the existing event anyway, because the data might have changed. + pEvent = pSchedule->AddEvent(new cEvent(channelID, SiEitEvent.getEventId())); + if (!pEvent) + continue; + pEvent->SetTableID(Tid); + } + else { + // We have found an existing event, either through its event ID or its start time. + // If the existing event has a zero table ID it was defined externally and shall + // not be overwritten. + if (pEvent->TableID() == 0x00) + continue; + // If the new event comes from a table that belongs to an "other TS" and the existing + // one comes from an "actual TS" table, lets skip it. + if ((!isActualTS()) && (pEvent->TableID() == 0x4E || pEvent->TableID() == 0x50 || pEvent->TableID() == 0x51)) + continue; + } - t.tm_year = (int) ((mjd - 15078.2) / 365.25); - t.tm_mon = (int) ((mjd - 14956.1 - (int)(t.tm_year * 365.25)) / 30.6001); - t.tm_mday = (int) (mjd - 14956 - (int)(t.tm_year * 365.25) - (int)(t.tm_mon * 30.6001)); - k = (t.tm_mon == 14 || t.tm_mon == 15) ? 1 : 0; - t.tm_year = t.tm_year + k; - t.tm_mon = t.tm_mon - 1 - k * 12; - t.tm_mon--; + SI::Descriptor *d; + SI::ExtendedEventDescriptors exGroup; + char text[256]; + for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) { + switch (d->getDescriptorTag()) { + case SI::ExtendedEventDescriptorTag: + exGroup.Add((SI::ExtendedEventDescriptor *)d); + d = NULL; //so that it is not deleted + break; + case SI::ShortEventDescriptorTag: { + SI::ShortEventDescriptor *sed = (SI::ShortEventDescriptor *)d; + pEvent->SetTitle(sed->name.getText(text)); + pEvent->SetShortText(sed->text.getText(text)); + } + break; + case SI::ContentDescriptorTag: + break; + case SI::ParentalRatingDescriptorTag: + break; + case SI::TimeShiftedEventDescriptorTag: { + SI::TimeShiftedEventDescriptor *tsed = (SI::TimeShiftedEventDescriptor *)d; + cSchedule *rSchedule = (cSchedule *)Schedules->GetSchedule(tChannelID(Source, 0, 0, tsed->getReferenceServiceId())); + if (!rSchedule) + break; + rEvent = (cEvent *)rSchedule->GetEvent(tsed->getReferenceEventId()); + if (!rEvent) + break; + pEvent->SetTitle(rEvent->Title()); + pEvent->SetShortText(rEvent->ShortText()); + pEvent->SetDescription(rEvent->Description()); + } + break; + default: ; + } + delete d; + } - t.tm_isdst = -1; - t.tm_gmtoff = 0; + if (!rEvent) { + char buffer[exGroup.getMaximumTextLength()]; + pEvent->SetDescription(exGroup.getText(buffer)); + } - mjdtime = timegm(&t); + pEvent->SetStartTime(SiEitEvent.getStartTime()); + pEvent->SetDuration(SiEitEvent.getDuration()); + pEvent->FixEpgBugs(); - //isyslog("Time parsed = %s\n", ctime(&mjdtime)); -} - -/** */ -bool cMJD::SetSystemTime() -{ - struct tm *ptm; - time_t loctim; - - struct tm tm_r; - ptm = localtime_r(&mjdtime, &tm_r); - loctim = time(NULL); - - if (abs(mjdtime - loctim) > 2) - { - isyslog("System Time = %s (%ld)\n", ctime(&loctim), loctim); - isyslog("Local Time = %s (%ld)\n", ctime(&mjdtime), mjdtime); - if (stime(&mjdtime) < 0) - esyslog("ERROR while setting system time: %m"); - return true; - } - - return false; -} -/** */ -time_t cMJD::GetTime_t() -{ - return mjdtime; + if (isPresentFollowing()) { + if (SiEitEvent.getRunningStatus() == SI::RunningStatusPausing || SiEitEvent.getRunningStatus() == SI::RunningStatusRunning) + pSchedule->SetPresentEvent(pEvent); + else if (SiEitEvent.getRunningStatus() == SI::RunningStatusStartsInAFewSeconds) + pSchedule->SetFollowingEvent(pEvent); + } + } } // --- cTDT ------------------------------------------------------------------ -class cTDT { +class cTDT : public SI::TDT { +private: + static cMutex mutex; public: - cTDT(tdt_t *ptdt); - ~cTDT(); - /** */ - bool SetSystemTime(); -protected: // Protected attributes - /** */ - tdt_t tdt; - /** */ - 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_mjd_hi, tdt.utc_mjd_lo, BCD2DEC(tdt.utc_time_h), BCD2DEC(tdt.utc_time_m), BCD2DEC(tdt.utc_time_s)) -{ -} - -cTDT::~cTDT() -{ -} -/** */ -bool cTDT::SetSystemTime() -{ - return mjd.SetSystemTime(); -} - -// --- cEventInfo ------------------------------------------------------------ - -cEventInfo::cEventInfo(tChannelID channelid, unsigned short eventid) -{ - pTitle = NULL; - pSubtitle = NULL; - pExtendedDescription = NULL; - bIsPresent = bIsFollowing = false; - lDuration = 0; - tTime = 0; - uTableID = 0; - uEventID = eventid; - channelID = channelid; - nChannelNumber = 0; -} - -cEventInfo::~cEventInfo() -{ - free(pTitle); - free(pSubtitle); - free(pExtendedDescription); -} - -/** */ -const char * cEventInfo::GetTitle() const -{ - return pTitle; -} -/** */ -const char * cEventInfo::GetSubtitle() const -{ - return pSubtitle; -} -/** */ -const char * cEventInfo::GetExtendedDescription() const -{ - return pExtendedDescription; -} -/** */ -bool cEventInfo::IsPresent() const -{ - return bIsPresent; -} -/** */ -void cEventInfo::SetPresent(bool pres) -{ - bIsPresent = pres; -} -/** */ -bool cEventInfo::IsFollowing() const -{ - return bIsFollowing; -} - -void cEventInfo::SetTableID(unsigned char tableid) -{ - uTableID = tableid; -} - -/** */ -void cEventInfo::SetFollowing(bool foll) -{ - bIsFollowing = foll; -} -/** */ -const char * cEventInfo::GetDate() const -{ - static char szDate[25]; - - struct tm tm_r; - strftime(szDate, sizeof(szDate), "%d.%m.%Y", localtime_r(&tTime, &tm_r)); - - return szDate; -} - -const unsigned char cEventInfo::GetTableID(void) const -{ - return uTableID; -} - -/** */ -const char * cEventInfo::GetTimeString() const -{ - static char szTime[25]; - - struct tm tm_r; - strftime(szTime, sizeof(szTime), "%R", localtime_r(&tTime, &tm_r)); - - return szTime; -} -/** */ -const char * cEventInfo::GetEndTimeString() const -{ - static char szEndTime[25]; - time_t tEndTime = tTime + lDuration; - - struct tm tm_r; - strftime(szEndTime, sizeof(szEndTime), "%R", localtime_r(&tEndTime, &tm_r)); - - return szEndTime; -} -/** */ -time_t cEventInfo::GetTime() const -{ - return tTime; -} -/** */ -long cEventInfo::GetDuration() const -{ - return lDuration; -} -/** */ -unsigned short cEventInfo::GetEventID() const -{ - return uEventID; -} -/** */ -void cEventInfo::SetTitle(const char *string) -{ - pTitle = strcpyrealloc(pTitle, string); -} -/** */ -void cEventInfo::SetSubtitle(const char *string) -{ - pSubtitle = strcpyrealloc(pSubtitle, string); -} -/** */ -void cEventInfo::SetExtendedDescription(const char *string) -{ - pExtendedDescription = strcpyrealloc(pExtendedDescription, string); -} -/** */ -void cEventInfo::SetTime(time_t t) -{ - tTime = t; -} -/** */ -void cEventInfo::SetDuration(long l) -{ - lDuration = l; -} -/** */ -void cEventInfo::SetEventID(unsigned short evid) -{ - uEventID = evid; -} -/** */ -void cEventInfo::SetChannelID(tChannelID channelid) -{ - channelID = channelid; -} - -/** */ -tChannelID cEventInfo::GetChannelID() const -{ - return channelID; -} - -/** */ -void cEventInfo::Dump(FILE *f, const char *Prefix) const -{ - if (tTime + lDuration >= time(NULL)) { - fprintf(f, "%sE %u %ld %ld %X\n", Prefix, uEventID, tTime, lDuration, uTableID); - if (!isempty(pTitle)) - fprintf(f, "%sT %s\n", Prefix, pTitle); - if (!isempty(pSubtitle)) - fprintf(f, "%sS %s\n", Prefix, pSubtitle); - if (!isempty(pExtendedDescription)) - fprintf(f, "%sD %s\n", Prefix, pExtendedDescription); - fprintf(f, "%se\n", Prefix); - } -} - -bool cEventInfo::Read(FILE *f, cSchedule *Schedule) -{ - if (Schedule) { - cEventInfo *pEvent = NULL; - char *s; - while ((s = readline(f)) != NULL) { - char *t = skipspace(s + 1); - switch (*s) { - case 'E': if (!pEvent) { - unsigned int uEventID; - time_t tTime; - long lDuration; - unsigned int uTableID = 0; - int n = sscanf(t, "%u %ld %ld %X", &uEventID, &tTime, &lDuration, &uTableID); - if (n == 3 || n == 4) { - pEvent = (cEventInfo *)Schedule->GetEvent(uEventID, tTime); - if (!pEvent) - pEvent = Schedule->AddEvent(new cEventInfo(Schedule->GetChannelID(), uEventID)); - if (pEvent) { - pEvent->SetTableID(uTableID); - pEvent->SetTime(tTime); - pEvent->SetDuration(lDuration); - } - } - } - break; - case 'T': if (pEvent) - pEvent->SetTitle(t); - break; - case 'S': if (pEvent) - pEvent->SetSubtitle(t); - break; - case 'D': if (pEvent) - pEvent->SetExtendedDescription(t); - break; - case 'e': pEvent = NULL; - break; - case 'c': // to keep things simple we react on 'c' here - return true; - default: esyslog("ERROR: unexpected tag while reading EPG data: %s", s); - return false; - } - } - esyslog("ERROR: unexpected end of file while reading EPG data"); - } - return false; -} - -#define MAXEPGBUGFIXSTATS 7 -#define MAXEPGBUGFIXCHANS 100 -struct tEpgBugFixStats { - int hits; - int n; - tChannelID channelIDs[MAXEPGBUGFIXCHANS]; - tEpgBugFixStats(void) { hits = n = 0; } + cTDT(const u_char *Data); }; -tEpgBugFixStats EpgBugFixStats[MAXEPGBUGFIXSTATS]; +cMutex cTDT::mutex; -static void EpgBugFixStat(int Number, tChannelID ChannelID) +cTDT::cTDT(const u_char *Data) +:SI::TDT(Data, false) { - if (0 <= Number && Number < MAXEPGBUGFIXSTATS) { - tEpgBugFixStats *p = &EpgBugFixStats[Number]; - p->hits++; - int i = 0; - for (; i < p->n; i++) { - if (p->channelIDs[i] == ChannelID) - break; - } - if (i == p->n && p->n < MAXEPGBUGFIXCHANS) - p->channelIDs[p->n++] = ChannelID; + CheckParse(); + + time_t sattim = getTime(); + time_t loctim = time(NULL); + + if (abs(sattim - loctim) > 2) { + mutex.Lock(); + isyslog("System Time = %s (%ld)\n", ctime(&loctim), loctim); + isyslog("Local Time = %s (%ld)\n", ctime(&sattim), sattim); + if (stime(&sattim) < 0) + esyslog("ERROR while setting system time: %m"); + mutex.Unlock(); } } -static void ReportEpgBugFixStats(bool Reset = false) +// --- cEitFilter ------------------------------------------------------------ + +cEitFilter::cEitFilter(void) { - if (Setup.EPGBugfixLevel > 0) { - bool GotHits = false; - char buffer[1024]; - for (int i = 0; i < MAXEPGBUGFIXSTATS; i++) { - const char *delim = "\t"; - tEpgBugFixStats *p = &EpgBugFixStats[i]; - if (p->hits) { - bool PrintedStats = false; - char *q = buffer; - *buffer = 0; - for (int c = 0; c < p->n; c++) { - cChannel *channel = Channels.GetByChannelID(p->channelIDs[c], true); - if (channel) { - if (!GotHits) { - dsyslog("====================="); - dsyslog("EPG bugfix statistics"); - dsyslog("====================="); - dsyslog("IF SOMEBODY WHO IS IN CHARGE OF THE EPG DATA FOR ONE OF THE LISTED"); - dsyslog("CHANNELS READS THIS: PLEASE TAKE A LOOK AT THE FUNCTION cEventInfo::FixEpgBugs()"); - dsyslog("IN VDR/eit.c TO LEARN WHAT'S WRONG WITH YOUR DATA, AND FIX IT!"); - dsyslog("====================="); - dsyslog("Fix\tHits\tChannels"); - GotHits = true; - } - if (!PrintedStats) { - q += snprintf(q, sizeof(buffer) - (q - buffer), "%d\t%d", i, p->hits); - PrintedStats = true; - } - q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->Name()); - delim = ", "; - } - } - if (*buffer) - dsyslog("%s", buffer); - } - if (Reset) - p->hits = p->n = 0; + Set(0x12, 0x4E, 0xFE); // event info, actual(0x4E)/other(0x4F) TS, present/following + Set(0x12, 0x50, 0xFE); // event info, actual TS, schedule(0x50)/schedule for another 4 days(0x51) + Set(0x12, 0x60, 0xFE); // event info, other TS, schedule(0x60)/schedule for another 4 days(0x61) + Set(0x14, 0x70); // TDT +} + +void cEitFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) +{ + switch (Pid) { + case 0x12: { + cSchedulesLock SchedulesLock(true, 10); + cSchedules *Schedules = (cSchedules *)cSchedules::Schedules(SchedulesLock); + if (Schedules) + cEIT EIT(Schedules, Source(), Tid, Data); } - if (GotHits) - dsyslog("====================="); - } -} - -void cEventInfo::FixEpgBugs(void) -{ - // VDR can't usefully handle newline characters in the EPG data, so let's - // always convert them to blanks (independent of the setting of EPGBugfixLevel): - strreplace(pTitle, '\n', ' '); - strreplace(pSubtitle, '\n', ' '); - strreplace(pExtendedDescription, '\n', ' '); - - 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) { - - // VOX puts too much information into the Subtitle and leaves the Extended - // Description empty: - // - // Title - // (NAT, Year Min')[ ["Subtitle". ]Extended Description] - // - if (pSubtitle && !pExtendedDescription) { - if (*pSubtitle == '(') { - char *e = strchr(pSubtitle + 1, ')'); - if (e) { - if (*(e + 1)) { - if (*++e == ' ') - if (*(e + 1) == '"') - e++; - } - else - e = NULL; - char *s = e ? strdup(e) : NULL; - free(pSubtitle); - pSubtitle = s; - EpgBugFixStat(0, GetChannelID()); - // now the fixes #1 and #2 below will handle the rest - } - } - } - - // 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)); - free(pSubtitle); - free(pExtendedDescription); - pSubtitle = s; - pExtendedDescription = d; - EpgBugFixStat(1, GetChannelID()); - } - } - } - - // 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; - EpgBugFixStat(2, GetChannelID()); - } - } - - // Pro7 sometimes repeats the Title in the Subtitle: - // - // Title - // Title - // - if (pSubtitle && strcmp(pTitle, pSubtitle) == 0) { - free(pSubtitle); - pSubtitle = NULL; - EpgBugFixStat(3, GetChannelID()); - } - - // ZDF.info puts the Subtitle between double quotes, which is nothing - // but annoying (some even put a '.' after the closing '"'): - // - // Title - // "Subtitle"[.] - // - if (pSubtitle && *pSubtitle == '"') { - int l = strlen(pSubtitle); - if (l > 2 && (pSubtitle[l - 1] == '"' || (pSubtitle[l - 1] == '.' && pSubtitle[l - 2] == '"'))) { - memmove(pSubtitle, pSubtitle + 1, l); - char *p = strrchr(pSubtitle, '"'); - if (p) - *p = 0; - EpgBugFixStat(4, GetChannelID()); - } - } - - 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; - while (*p && *(p + 1) && *(p + 2)) { - 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); - EpgBugFixStat(5, GetChannelID()); - } - } - p++; - } - } - -#define MAX_USEFUL_SUBTITLE_LENGTH 40 - // Some channels put a whole lot of information in the Subtitle and leave - // the Extended Description totally empty. So if the Subtitle length exceeds - // MAX_USEFUL_SUBTITLE_LENGTH, let's put this into the Extended Description - // instead: - if (!isempty(pSubtitle) && isempty(pExtendedDescription)) { - if (strlen(pSubtitle) > MAX_USEFUL_SUBTITLE_LENGTH) { - free(pExtendedDescription); - pExtendedDescription = pSubtitle; - pSubtitle = NULL; - EpgBugFixStat(6, GetChannelID()); - } - } - - // Some channels use the ` ("backtick") character, where a ' (single quote) - // would be normally used. Actually, "backticks" in normal text don't make - // much sense, so let's replace them: - strreplace(pTitle, '`', '\''); - strreplace(pSubtitle, '`', '\''); - strreplace(pExtendedDescription, '`', '\''); - } -} - -// --- cSchedule ------------------------------------------------------------- - -cSchedule::cSchedule(tChannelID channelid) -{ - pPresent = pFollowing = NULL; - channelID = channelid; -} - - -cSchedule::~cSchedule() -{ -} - -cEventInfo *cSchedule::AddEvent(cEventInfo *EventInfo) -{ - Events.Add(EventInfo); - return EventInfo; -} - -const cEventInfo *cSchedule::GetPresentEvent(void) const -{ - return GetEventAround(time(NULL)); -} - -const cEventInfo *cSchedule::GetFollowingEvent(void) const -{ - const cEventInfo *pe = NULL; - time_t now = time(NULL); - time_t delta = INT_MAX; - for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) { - time_t dt = p->GetTime() - now; - if (dt > 0 && dt < delta) { - delta = dt; - pe = p; - } - } - return pe; -} - -void cSchedule::SetChannelID(tChannelID channelid) -{ - channelID = channelid; -} -/** */ -tChannelID cSchedule::GetChannelID() const -{ - return channelID; -} -/** */ -const cEventInfo * cSchedule::GetEvent(unsigned short uEventID, time_t tTime) const -{ - // Returns either the event info with the given uEventID or, if that one can't - // be found, the one with the given tTime (or NULL if neither can be found) - cEventInfo *pe = Events.First(); - cEventInfo *pt = NULL; - while (pe != NULL) - { - if (pe->GetEventID() == uEventID) - return pe; - if (tTime > 0 && pe->GetTime() == tTime) // 'tTime < 0' is apparently used with NVOD channels - pt = pe; - - pe = Events.Next(pe); - } - - return pt; -} - -const cEventInfo *cSchedule::GetEventAround(time_t Time) const -{ - const cEventInfo *pe = NULL; - time_t delta = INT_MAX; - for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) { - time_t dt = Time - p->GetTime(); - if (dt >= 0 && dt < delta && p->GetTime() + p->GetDuration() >= Time) { - delta = dt; - pe = p; - } - } - return pe; -} - -bool cSchedule::SetPresentEvent(cEventInfo *pEvent) -{ - if (pPresent != NULL) - pPresent->SetPresent(false); - pPresent = pEvent; - pPresent->SetPresent(true); - - return true; -} - -/** */ -bool cSchedule::SetFollowingEvent(cEventInfo *pEvent) -{ - if (pFollowing != NULL) - pFollowing->SetFollowing(false); - pFollowing = pEvent; - pFollowing->SetFollowing(true); - - return true; -} - -/** */ -void cSchedule::Cleanup() -{ - Cleanup(time(NULL)); -} - -/** */ -void cSchedule::Cleanup(time_t tTime) -{ - cEventInfo *pEvent; - for (int a = 0; true ; a++) - { - pEvent = Events.Get(a); - if (pEvent == NULL) break; - if (pEvent->GetTime() + pEvent->GetDuration() + 3600 < tTime) // adding one hour for safety - { - Events.Del(pEvent); - a--; - } - } -} - -/** */ -void cSchedule::Dump(FILE *f, const char *Prefix) const -{ - cChannel *channel = Channels.GetByChannelID(channelID, true); - if (channel) - { - fprintf(f, "%sC %s %s\n", Prefix, channel->GetChannelID().ToString(), channel->Name()); - for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) - p->Dump(f, Prefix); - fprintf(f, "%sc\n", Prefix); - } -} - -bool cSchedule::Read(FILE *f, cSchedules *Schedules) -{ - if (Schedules) { - char *s; - while ((s = readline(f)) != NULL) { - if (*s == 'C') { - s = skipspace(s + 1); - char *p = strchr(s, ' '); - if (p) - *p = 0; // strips optional channel name - if (*s) { - tChannelID channelID = tChannelID::FromString(s); - if (channelID.Valid()) { - cSchedule *p = (cSchedule *)Schedules->AddChannelID(channelID); - if (p) { - if (!cEventInfo::Read(f, p)) - return false; - } - } - else { - esyslog("ERROR: illegal channel ID: %s", s); - return false; - } - } - } - else { - esyslog("ERROR: unexpected tag while reading EPG data: %s", s); - return false; - } - } - return true; - } - return false; -} - -// --- cSchedules ------------------------------------------------------------ - -cSchedules::cSchedules() -{ - pCurrentSchedule = NULL; -} - -cSchedules::~cSchedules() -{ -} -/** */ -const cSchedule *cSchedules::AddChannelID(tChannelID channelid) -{ - channelid.ClrRid(); - const cSchedule *p = GetSchedule(channelid); - if (!p) { - Add(new cSchedule(channelid)); - p = GetSchedule(channelid); - } - return p; -} -/** */ -const cSchedule *cSchedules::SetCurrentChannelID(tChannelID channelid) -{ - channelid.ClrRid(); - pCurrentSchedule = AddChannelID(channelid); - if (pCurrentSchedule) - currentChannelID = channelid; - return pCurrentSchedule; -} -/** */ -const cSchedule * cSchedules::GetSchedule() const -{ - return pCurrentSchedule; -} -/** */ -const cSchedule * cSchedules::GetSchedule(tChannelID channelid) const -{ - cSchedule *p; - - channelid.ClrRid(); - p = First(); - while (p != NULL) - { - if (p->GetChannelID() == channelid) - return p; - p = Next(p); - } - - return NULL; -} - -/** */ -void cSchedules::Cleanup() -{ - cSchedule *p; - - p = First(); - while (p != NULL) - { - p->Cleanup(time(NULL)); - p = Next(p); - } -} - -/** */ -void cSchedules::Dump(FILE *f, const char *Prefix) const -{ - for (cSchedule *p = First(); p; p = Next(p)) - p->Dump(f, Prefix); -} - -/** */ -bool cSchedules::Read(FILE *f) -{ - cMutexLock MutexLock; - return cSchedule::Read(f, (cSchedules *)cSIProcessor::Schedules(MutexLock)); -} - -// --- cEIT ------------------------------------------------------------------ - -class cEIT { -private: - cSchedules *schedules; -public: - cEIT(unsigned char *buf, int length, cSchedules *Schedules); - ~cEIT(); - /** */ - int ProcessEIT(unsigned char *buffer, int CurrentSource); - -protected: // Protected methods - /** returns true if this EIT covers a -present/following information, false if it's -schedule information */ - bool IsPresentFollowing(); -protected: // Protected attributes - /** Table ID of this EIT struct */ - u_char tid; -}; - -cEIT::cEIT(unsigned char * buf, int length, cSchedules *Schedules) -{ - tid = buf[0]; - schedules = Schedules; -} - -cEIT::~cEIT() -{ -} - -/** */ -int cEIT::ProcessEIT(unsigned char *buffer, int CurrentSource) -{ - 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)) { - //XXX TODO use complete channel ID - cChannel *channel = Channels.GetByServiceID(CurrentSource, VdrProgramInfo->ServiceID); - tChannelID channelID = channel ? channel->GetChannelID() : tChannelID(CurrentSource, 0, 0, VdrProgramInfo->ServiceID); - channelID.ClrRid(); - //XXX - pSchedule = (cSchedule *)schedules->GetSchedule(channelID); - if (!pSchedule) { - schedules->Add(new cSchedule(channelID)); - pSchedule = (cSchedule *)schedules->GetSchedule(channelID); - if (!pSchedule) - break; - } - if (VdrProgramInfo->ReferenceServiceID) { - rSchedule = (cSchedule *)schedules->GetSchedule(tChannelID(CurrentSource, 0, 0, VdrProgramInfo->ReferenceServiceID)); - if (!rSchedule) - break; - rEvent = (cEventInfo *)rSchedule->GetEvent((unsigned short)VdrProgramInfo->ReferenceEventID); - if (!rEvent) - break; - } - pEvent = (cEventInfo *)pSchedule->GetEvent((unsigned short)VdrProgramInfo->EventID, VdrProgramInfo->StartTime); - if (!pEvent) { - // If we don't have that event ID yet, we create a new one. - // Otherwise we copy the information into the existing event anyway, because the data might have changed. - pEvent = pSchedule->AddEvent(new cEventInfo(channelID, VdrProgramInfo->EventID)); - if (!pEvent) - break; - pEvent->SetTableID(tid); - } - else { - // We have found an existing event, either through its event ID or its start time. - // If the existing event has a zero table ID it was defined externally and shall - // not be overwritten. - if (pEvent->GetTableID() == 0x00) - continue; - // If the new event comes from a table that belongs to an "other TS" and the existing - // one comes from an "actual TS" table, lets skip it. - if ((tid == 0x4F || tid == 0x60 || tid == 0x61) && (pEvent->GetTableID() == 0x4E || pEvent->GetTableID() == 0x50 || pEvent->GetTableID() == 0x51)) - continue; - } - if (rEvent) { - pEvent->SetTitle(rEvent->GetTitle()); - pEvent->SetSubtitle(rEvent->GetSubtitle()); - pEvent->SetExtendedDescription(rEvent->GetExtendedDescription()); - } - else { - pEvent->SetTableID(tid); - pEvent->SetTitle(VdrProgramInfo->ShortName); - pEvent->SetSubtitle(VdrProgramInfo->ShortText); - pEvent->SetExtendedDescription(VdrProgramInfo->ExtendedName); - //XXX kls 2001-09-22: - //XXX apparently this never occurred, so I have simpified ExtendedDescription handling - //XXX pEvent->AddExtendedDescription(VdrProgramInfo->ExtendedText); - } - pEvent->SetTime(VdrProgramInfo->StartTime); - pEvent->SetDuration(VdrProgramInfo->Duration); - 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; -} - -/** returns true if this EIT covers a -present/following information, false if it's -schedule information */ -bool cEIT::IsPresentFollowing() -{ - if (tid == 0x4e || tid == 0x4f) - return true; - - return false; -} - -// --- cCaDescriptor --------------------------------------------------------- - -class cCaDescriptor : public cListObject { - friend class cSIProcessor; -private: - int source; - int transponder; - int serviceId; - int caSystem; - unsigned int providerId; - int caPid; - int length; - uchar *data; -public: - cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, unsigned int ProviderId, int CaPid, int Length, uchar *Data); - virtual ~cCaDescriptor(); - int Length(void) const { return length; } - const uchar *Data(void) const { return data; } - }; - -cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, unsigned int ProviderId, int CaPid, int Length, uchar *Data) -{ - source = Source; - transponder = Transponder; - serviceId = ServiceId; - caSystem = CaSystem; - providerId = ProviderId; - caPid = CaPid; - length = Length + 6; - data = MALLOC(uchar, length); - data[0] = DESCR_CA; - data[1] = length - 2; - data[2] = (caSystem >> 8) & 0xFF; - data[3] = caSystem & 0xFF; - data[4] = ((CaPid >> 8) & 0x1F) | 0xE0; - data[5] = CaPid & 0xFF; - if (Length) - memcpy(&data[6], Data, Length); -//#define DEBUG_CA_DESCRIPTORS 1 -#ifdef DEBUG_CA_DESCRIPTORS - char buffer[1024]; - char *q = buffer; - q += sprintf(q, "CAM: %04X %5d %5d %04X %6X %04X -", source, transponder, serviceId, caSystem, providerId, caPid); - for (int i = 0; i < length; i++) - q += sprintf(q, " %02X", data[i]); - dsyslog(buffer); -#endif -} - -cCaDescriptor::~cCaDescriptor() -{ - free(data); -} - -// --- cSIProcessor ---------------------------------------------------------- - -#define MAX_FILTERS 20 -#define EPGDATAFILENAME "epg.data" - -int cSIProcessor::numSIProcessors = 0; -cSchedules *cSIProcessor::schedules = NULL; -cMutex cSIProcessor::schedulesMutex; -cList cSIProcessor::caDescriptors; -cMutex cSIProcessor::caDescriptorsMutex; -const char *cSIProcessor::epgDataFileName = EPGDATAFILENAME; -time_t cSIProcessor::lastDump = time(NULL); - -/** */ -cSIProcessor::cSIProcessor(const char *FileName) -:cThread("EIT processing") -{ - fileName = strdup(FileName); - masterSIProcessor = numSIProcessors == 0; // the first one becomes the 'master' - currentSource = 0; - currentTransponder = 0; - statusCount = 0; - pmtIndex = 0; - pmtPid = 0; - filters = NULL; - if (!numSIProcessors++) { // the first one creates them - schedules = new cSchedules; - } - filters = (SIP_FILTER *)calloc(MAX_FILTERS, sizeof(SIP_FILTER)); - SetStatus(true); - Start(); -} - -cSIProcessor::~cSIProcessor() -{ - if (masterSIProcessor) - ReportEpgBugFixStats(); - active = false; - Cancel(3); - ShutDownFilters(); - free(filters); - if (!--numSIProcessors) { // the last one deletes them - delete schedules; - } - free(fileName); -} - -const cSchedules *cSIProcessor::Schedules(cMutexLock &MutexLock) -{ - if (MutexLock.Lock(&schedulesMutex)) - return schedules; - return NULL; -} - -bool cSIProcessor::Read(FILE *f) -{ - bool OwnFile = f == NULL; - if (OwnFile) { - const char *FileName = GetEpgDataFileName(); - if (access(FileName, R_OK) == 0) { - dsyslog("reading EPG data from %s", FileName); - if ((f = fopen(FileName, "r")) == NULL) { - LOG_ERROR; - return false; - } - } - else - return false; - } - bool result = cSchedules::Read(f); - if (OwnFile) - fclose(f); - return result; -} - -void cSIProcessor::Clear(void) -{ - cMutexLock MutexLock(&schedulesMutex); - delete schedules; - schedules = new cSchedules; -} - -void cSIProcessor::SetEpgDataFileName(const char *FileName) -{ - epgDataFileName = NULL; - if (FileName) - epgDataFileName = strdup(DirectoryOk(FileName) ? AddDirectory(FileName, EPGDATAFILENAME) : FileName); -} - -const char *cSIProcessor::GetEpgDataFileName(void) -{ - if (epgDataFileName) - return *epgDataFileName == '/' ? epgDataFileName : AddDirectory(VideoDirectory, epgDataFileName); - return NULL; -} - -void cSIProcessor::SetStatus(bool On) -{ - LOCK_THREAD; - statusCount++; - ShutDownFilters(); - pmtIndex = 0; - pmtPid = 0; - if (On) - { - AddFilter(0x00, 0x00); // PAT - AddFilter(0x14, 0x70); // TDT - AddFilter(0x12, 0x4e, 0xfe); // event info, actual(0x4e)/other(0x4f) TS, present/following - AddFilter(0x12, 0x50, 0xfe); // event info, actual TS, schedule(0x50)/schedule for another 4 days(0x51) - AddFilter(0x12, 0x60, 0xfe); // event info, other TS, schedule(0x60)/schedule for another 4 days(0x61) - } -} - -#define PMT_SCAN_TIMEOUT 10 // seconds - -/** use the vbi device to parse all relevant SI -information and let the classes corresponding -to the tables write their information to the disk */ -void cSIProcessor::Action() -{ - time_t lastCleanup = time(NULL); - time_t lastPmtScan = time(NULL); - - int oldStatusCount = 0; - active = true; - - while(active) - { - if (masterSIProcessor) - { - time_t now = time(NULL); - struct tm tm_r; - struct tm *ptm = localtime_r(&now, &tm_r); - if (now - lastCleanup > 3600 && ptm->tm_hour == 5) - { - cMutexLock MutexLock(&schedulesMutex); - isyslog("cleaning up schedules data"); - schedules->Cleanup(); - lastCleanup = now; - ReportEpgBugFixStats(true); + case 0x14: { + if (Setup.SetSystemTime && Setup.TimeTransponder && ISTRANSPONDER(Transponder(), Setup.TimeTransponder)) + cTDT TDT(Data); } - if (epgDataFileName && now - lastDump > 600) - { - cMutexLock MutexLock(&schedulesMutex); - cSafeFile f(GetEpgDataFileName()); - if (f.Open()) { - schedules->Dump(f); - f.Close(); - } - else - LOG_ERROR; - lastDump = now; - } - } - - // set up pfd structures for all active filter - Lock(); - pollfd pfd[MAX_FILTERS]; - int NumUsedFilters = 0; - for (int a = 0; a < MAX_FILTERS ; a++) - { - if (filters[a].inuse) - { - pfd[NumUsedFilters].fd = filters[a].handle; - pfd[NumUsedFilters].events = POLLIN; - NumUsedFilters++; - } - } - oldStatusCount = statusCount; - Unlock(); - - // wait until data becomes ready from the bitfilter - if (poll(pfd, NumUsedFilters, 1000) != 0) - { - for (int aa = 0; aa < NumUsedFilters; aa++) - { - if (pfd[aa].revents & POLLIN) - { - int a; - for (a = 0; a < MAX_FILTERS; a++) { - if (pfd[aa].fd == filters[a].handle) - break; - } - if (a >= MAX_FILTERS || !filters[a].inuse) // filter no longer available - continue; - // read section - unsigned char buf[4096]; // max. allowed size for any EIT section - int r = safe_read(filters[a].handle, buf, sizeof(buf)); - if (r > 3) // minimum number of bytes necessary to get section length - { - int seclen = (((buf[1] & 0x0F) << 8) | (buf[2] & 0xFF)) + 3; - int pid = filters[a].pid; - if (seclen == r) - { - //dsyslog("Received pid 0x%04X with table ID 0x%02X and length of %4d\n", pid, buf[0], seclen); - cMutexLock MutexLock(&schedulesMutex); // since the xMem... stuff is not thread safe, we need to use a "global" mutex - LOCK_THREAD; - if (statusCount != oldStatusCount) - break; - switch (pid) - { - case 0x00: - if (buf[0] == 0x00) - { - if (pmtPid && time(NULL) - lastPmtScan > PMT_SCAN_TIMEOUT) { - DelFilter(pmtPid, 0x02); - pmtPid = 0; - pmtIndex++; - lastPmtScan = time(NULL); - } - if (!pmtPid) { - struct LIST *pat = siParsePAT(buf); - if (pat) { - int Index = 0; - for (struct Program *prg = (struct Program *)pat->Head; prg; prg = (struct Program *)xSucc(prg)) { - if (prg->ProgramID) { - if (Index++ == pmtIndex) { - pmtPid = prg->NetworkPID; - AddFilter(pmtPid, 0x02); - break; - } - } - } - if (!pmtPid) - pmtIndex = 0; - } - xMemFreeAll(NULL); - } - } - break; - case 0x14: - if (buf[0] == 0x70) - { - if (Setup.SetSystemTime && Setup.TimeTransponder && ISTRANSPONDER(currentTransponder, Setup.TimeTransponder)) - { - cTDT ctdt((tdt_t *)buf); - ctdt.SetSystemTime(); - } - } - break; - - case 0x12: - if (buf[0] != 0x72) - { - cEIT ceit(buf, seclen, schedules); - ceit.ProcessEIT(buf, currentSource); - } - /*else - dsyslog("Received stuffing section in EIT\n"); - */ - break; - - default: { - if (pid == pmtPid && buf[0] == 0x02 && currentSource && currentTransponder) { - struct Pid *pi = siParsePMT(buf); - if (pi) { - struct Descriptor *d; - for (d = (struct Descriptor *)pi->Descriptors->Head; d; d = (struct Descriptor *)xSucc(d)) - NewCaDescriptor(d, pi->ProgramID); - // Also scan the PidInfo list for descriptors - some broadcasts send them only here. - for (struct PidInfo *p = (struct PidInfo *)pi->InfoList->Head; p; p = (struct PidInfo *)xSucc(p)) { - for (d = (struct Descriptor *)p->Descriptors->Head; d; d = (struct Descriptor *)xSucc(d)) - NewCaDescriptor(d, pi->ProgramID); - } - } - xMemFreeAll(NULL); - lastPmtScan = 0; // this triggers the next scan - } - } - break; - } - } - /* - else - dsyslog("read incomplete section - seclen = %d, r = %d", seclen, r); - */ - } - } - } - } - } -} - -/** Add a filter with packet identifier pid and -table identifer tid */ -bool cSIProcessor::AddFilter(unsigned short pid, u_char tid, u_char mask) -{ - dmx_sct_filter_params sctFilterParams; - memset(&sctFilterParams, 0, sizeof(sctFilterParams)); - sctFilterParams.pid = pid; - sctFilterParams.timeout = 0; - sctFilterParams.flags = DMX_IMMEDIATE_START; - sctFilterParams.filter.filter[0] = tid; - sctFilterParams.filter.mask[0] = mask; - - for (int a = 0; a < MAX_FILTERS; a++) - { - if (!filters[a].inuse) - { - filters[a].pid = pid; - filters[a].tid = tid; - if ((filters[a].handle = open(fileName, O_RDWR | O_NONBLOCK)) >= 0) - { - if (ioctl(filters[a].handle, DMX_SET_FILTER, &sctFilterParams) >= 0) - filters[a].inuse = true; - else - { - esyslog("ERROR: can't set filter (pid=%d, tid=%02X)", pid, tid); - close(filters[a].handle); - return false; - } - // dsyslog("Registered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid); - } - else - { - esyslog("ERROR: can't open filter handle"); - return false; - } - return true; - } - } - esyslog("ERROR: too many filters"); - - return false; -} - -bool cSIProcessor::DelFilter(unsigned short pid, u_char tid) -{ - for (int a = 0; a < MAX_FILTERS; a++) - { - if (filters[a].inuse && filters[a].pid == pid && filters[a].tid == tid) - { - close(filters[a].handle); - // dsyslog("Deregistered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid); - filters[a].inuse = false; - return true; - } - } - return false; -} - -/** */ -bool cSIProcessor::ShutDownFilters(void) -{ - for (int a = 0; a < MAX_FILTERS; a++) - { - if (filters[a].inuse) - { - close(filters[a].handle); - // dsyslog("Deregistered filter handle %04x, pid = %02d, tid = %02d", filters[a].handle, filters[a].pid, filters[a].tid); - filters[a].inuse = false; - } - } - - return true; // there's no real 'boolean' to return here... -} - -/** */ -void cSIProcessor::SetCurrentTransponder(int CurrentSource, int CurrentTransponder) -{ - currentSource = CurrentSource; - currentTransponder = CurrentTransponder; -} - -/** */ -bool cSIProcessor::SetCurrentChannelID(tChannelID channelid) -{ - cMutexLock MutexLock(&schedulesMutex); - return schedules ? schedules->SetCurrentChannelID(channelid) : false; -} - -void cSIProcessor::TriggerDump(void) -{ - cMutexLock MutexLock(&schedulesMutex); - lastDump = 0; -} - -void cSIProcessor::NewCaDescriptor(struct Descriptor *d, int ServiceId) -{ - if (DescriptorTag(d) == DESCR_CA) { - struct CaDescriptor *cd = (struct CaDescriptor *)d; - cMutexLock MutexLock(&caDescriptorsMutex); - - for (cCaDescriptor *ca = caDescriptors.First(); ca; ca = caDescriptors.Next(ca)) { - if (ca->source == currentSource && ca->transponder == currentTransponder && ca->serviceId == ServiceId && ca->caSystem == cd->CA_type && ca->providerId == cd->ProviderID && ca->caPid == cd->CA_PID) - return; - } - caDescriptors.Add(new cCaDescriptor(currentSource, currentTransponder, ServiceId, cd->CA_type, cd->ProviderID, cd->CA_PID, cd->DataLength, cd->Data)); - //XXX update??? - } -} - -int cSIProcessor::GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data) -{ - if (!CaSystemIds || !*CaSystemIds) - return 0; - if (BufSize > 0 && Data) { - cMutexLock MutexLock(&caDescriptorsMutex); - int length = 0; - for (cCaDescriptor *d = caDescriptors.First(); d; d = caDescriptors.Next(d)) { - if (d->source == Source && d->transponder == Transponder && d->serviceId == ServiceId) { - const unsigned short *caids = CaSystemIds; - do { - if (d->caSystem == *caids) { - if (length + d->Length() <= BufSize) { - memcpy(Data + length, d->Data(), d->Length()); - length += d->Length(); - } - else - return -1; - } - } while (*++caids); - } - } - return length; - } - return -1; + break; + } } diff --git a/eit.h b/eit.h index 076e4f87..c57dd519 100644 --- a/eit.h +++ b/eit.h @@ -1,186 +1,22 @@ -/*************************************************************************** - eit.h - description - ------------------- - 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 - - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - * $Id: eit.h 1.29 2003/05/18 12:51:50 kls Exp $ - ***************************************************************************/ +/* + * eit.h: EIT section filter + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: eit.h 1.30 2003/12/21 14:51:50 kls Exp $ + */ #ifndef __EIT_H #define __EIT_H -#include "channels.h" -#include "thread.h" -#include "tools.h" +#include "filter.h" -#define MAXEPGBUGFIXLEVEL 2 - -class cEventInfo : public cListObject { - friend class cSchedule; - friend class cEIT; -private: - unsigned char uTableID; // Table ID this event came from - tChannelID channelID; // Channel ID of program for that event - bool bIsFollowing; // true if this is the next event on this channel - bool bIsPresent; // true if this is the present event running - char *pExtendedDescription; // Extended description of this event - char *pSubtitle; // Subtitle of event - char *pTitle; // Title of event - unsigned short uEventID; // Event ID of this event - long lDuration; // duration of event in seconds - time_t tTime; // Start time - int nChannelNumber; // the actual channel number from VDR's channel list (used in cMenuSchedule for sorting by channel number) +class cEitFilter : public cFilter { protected: - void SetTableID(unsigned char tableid); - void SetFollowing(bool foll); - void SetPresent(bool pres); - void SetTitle(const char *string); - void SetChannelID(tChannelID channelid); - void SetEventID(unsigned short evid); - void SetDuration(long l); - void SetTime(time_t t); - void SetExtendedDescription(const char *string); - void SetSubtitle(const char *string); - cEventInfo(tChannelID channelid, unsigned short eventid); + virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length); public: - ~cEventInfo(); - const unsigned char GetTableID(void) const; - const char *GetTimeString(void) const; - const char *GetEndTimeString(void) const; - const char *GetDate(void) const; - bool IsFollowing(void) const; - bool IsPresent(void) const; - const char *GetExtendedDescription(void) const; - const char *GetSubtitle(void) const; - const char *GetTitle(void) const; - unsigned short GetEventID(void) const; - long GetDuration(void) const; - time_t GetTime(void) const; - tChannelID GetChannelID(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; - static bool Read(FILE *f, cSchedule *Schedule); - void FixEpgBugs(void); + cEitFilter(void); }; -class cSchedule : public cListObject { - friend class cSchedules; - friend class cEIT; -private: - cEventInfo *pPresent; - cEventInfo *pFollowing; - tChannelID channelID; - cList Events; -protected: - void SetChannelID(tChannelID channelid); - bool SetFollowingEvent(cEventInfo *pEvent); - bool SetPresentEvent(cEventInfo *pEvent); - void Cleanup(time_t tTime); - void Cleanup(void); - cSchedule(tChannelID channelid = tChannelID::InvalidID); -public: - ~cSchedule(); - cEventInfo *AddEvent(cEventInfo *EventInfo); - const cEventInfo *GetPresentEvent(void) const; - const cEventInfo *GetFollowingEvent(void) const; - tChannelID GetChannelID(void) const; - const cEventInfo *GetEvent(unsigned short uEventID, time_t tTime = 0) const; - const cEventInfo *GetEventAround(time_t tTime) const; - const cEventInfo *GetEventNumber(int n) const { return Events.Get(n); } - int NumEvents(void) const { return Events.Count(); } - void Dump(FILE *f, const char *Prefix = "") const; - static bool Read(FILE *f, cSchedules *Schedules); - }; - -class cSchedules : public cList { - friend class cSchedule; - friend class cSIProcessor; -private: - const cSchedule *pCurrentSchedule; - tChannelID currentChannelID; -protected: - const cSchedule *AddChannelID(tChannelID channelid); - const cSchedule *SetCurrentChannelID(tChannelID channelid); - void Cleanup(); -public: - cSchedules(void); - ~cSchedules(); - const cSchedule *GetSchedule(tChannelID channelid) const; - const cSchedule *GetSchedule(void) const; - void Dump(FILE *f, const char *Prefix = "") const; - static bool Read(FILE *f); -}; - -typedef struct sip_filter { - - unsigned short pid; - u_char tid; - int handle; - bool inuse; - -}SIP_FILTER; - -class cCaDescriptor; - -class cSIProcessor : public cThread { -private: - static int numSIProcessors; - static cSchedules *schedules; - static cMutex schedulesMutex; - static cList caDescriptors; - static cMutex caDescriptorsMutex; - static const char *epgDataFileName; - static time_t lastDump; - bool masterSIProcessor; - int currentSource; - int currentTransponder; - int statusCount; - int pmtIndex; - int pmtPid; - SIP_FILTER *filters; - char *fileName; - bool active; - void Action(void); - bool AddFilter(unsigned short pid, u_char tid, u_char mask = 0xFF); - bool DelFilter(unsigned short pid, u_char tid); - bool ShutDownFilters(void); - void NewCaDescriptor(struct Descriptor *d, int ServiceId); -public: - cSIProcessor(const char *FileName); - ~cSIProcessor(); - static void SetEpgDataFileName(const char *FileName); - static const char *GetEpgDataFileName(void); - static const cSchedules *Schedules(cMutexLock &MutexLock); - // Caller must provide a cMutexLock which has to survive the entire - // time the returned cSchedules is accessed. Once the cSchedules is no - // longer used, the cMutexLock must be destroyed. - static int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data); - ///< Gets all CA descriptors for a given channel. - ///< Copies all available CA descriptors for the given Source, Transponder and ServiceId - ///< into the provided buffer at Data (at most BufSize bytes). Only those CA descriptors - ///< are copied that match one of the given CA system IDs. - ///< \return Returns the number of bytes copied into Data (0 if no CA descriptors are - ///< available), or -1 if BufSize was too small to hold all CA descriptors. - static bool Read(FILE *f = NULL); - static void Clear(void); - void SetStatus(bool On); - void SetCurrentTransponder(int CurrentSource, int CurrentTransponder); - static bool SetCurrentChannelID(tChannelID channelid); - static void TriggerDump(void); - }; - -#endif +#endif //__EIT_H diff --git a/epg.c b/epg.c new file mode 100644 index 00000000..eb7a53a2 --- /dev/null +++ b/epg.c @@ -0,0 +1,669 @@ +/* + * epg.c: Electronic Program Guide + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * Original version (as used in VDR before 1.3.0) written by + * Robert Schneider and Rolf Hakenes . + * + * $Id: epg.c 1.1 2003/12/22 13:07:32 kls Exp $ + */ + +#include "epg.h" +#include +#include + +// --- cEvent ---------------------------------------------------------------- + +cEvent::cEvent(tChannelID ChannelID, u_int16_t EventID) +{ + channelID = ChannelID; + eventID = EventID; + tableID = 0; + isPresent = isFollowing = false; + title = NULL; + shortText = NULL; + description = NULL; + startTime = 0; + duration = 0; + channelNumber = 0; +} + +cEvent::~cEvent() +{ + free(title); + free(shortText); + free(description); +} + +void cEvent::SetTableID(uchar TableID) +{ + tableID = TableID; +} + +void cEvent::SetIsPresent(bool IsPresent) +{ + isPresent = IsPresent; +} + +void cEvent::SetIsFollowing(bool IsFollowing) +{ + isFollowing = IsFollowing; +} + +void cEvent::SetTitle(const char *Title) +{ + title = strcpyrealloc(title, Title); +} + +void cEvent::SetShortText(const char *ShortText) +{ + shortText = strcpyrealloc(shortText, ShortText); +} + +void cEvent::SetDescription(const char *Description) +{ + description = strcpyrealloc(description, Description); +} + +void cEvent::SetStartTime(time_t StartTime) +{ + startTime = StartTime; +} + +void cEvent::SetDuration(int Duration) +{ + duration = Duration; +} + +const char *cEvent::GetDateString(void) const +{ + static char buf[25]; + struct tm tm_r; + strftime(buf, sizeof(buf), "%d.%m.%Y", localtime_r(&startTime, &tm_r)); + return buf; +} + +const char *cEvent::GetTimeString(void) const +{ + static char buf[25]; + struct tm tm_r; + strftime(buf, sizeof(buf), "%R", localtime_r(&startTime, &tm_r)); + return buf; +} + +const char *cEvent::GetEndTimeString(void) const +{ + static char buf[25]; + time_t EndTime = startTime + duration; + struct tm tm_r; + strftime(buf, sizeof(buf), "%R", localtime_r(&EndTime, &tm_r)); + return buf; +} + +void cEvent::Dump(FILE *f, const char *Prefix) const +{ + if (startTime + duration >= time(NULL)) { + fprintf(f, "%sE %u %ld %d %X\n", Prefix, eventID, startTime, duration, tableID); + if (!isempty(title)) + fprintf(f, "%sT %s\n", Prefix, title); + if (!isempty(shortText)) + fprintf(f, "%sS %s\n", Prefix, shortText); + if (!isempty(description)) + fprintf(f, "%sD %s\n", Prefix, description); + fprintf(f, "%se\n", Prefix); + } +} + +bool cEvent::Read(FILE *f, cSchedule *Schedule) +{ + if (Schedule) { + cEvent *Event = NULL; + char *s; + while ((s = readline(f)) != NULL) { + char *t = skipspace(s + 1); + switch (*s) { + case 'E': if (!Event) { + unsigned int EventID; + time_t StartTime; + int Duration; + unsigned int TableID = 0; + int n = sscanf(t, "%u %ld %d %X", &EventID, &StartTime, &Duration, &TableID); + if (n == 3 || n == 4) { + Event = (cEvent *)Schedule->GetEvent(EventID, StartTime); + if (!Event) + Event = Schedule->AddEvent(new cEvent(Schedule->ChannelID(), EventID)); + if (Event) { + Event->SetTableID(TableID); + Event->SetStartTime(StartTime); + Event->SetDuration(Duration); + } + } + } + break; + case 'T': if (Event) + Event->SetTitle(t); + break; + case 'S': if (Event) + Event->SetShortText(t); + break; + case 'D': if (Event) + Event->SetDescription(t); + break; + case 'e': Event = NULL; + break; + case 'c': // to keep things simple we react on 'c' here + return true; + default: esyslog("ERROR: unexpected tag while reading EPG data: %s", s); + return false; + } + } + esyslog("ERROR: unexpected end of file while reading EPG data"); + } + return false; +} + +#define MAXEPGBUGFIXSTATS 7 +#define MAXEPGBUGFIXCHANS 100 +struct tEpgBugFixStats { + int hits; + int n; + tChannelID channelIDs[MAXEPGBUGFIXCHANS]; + tEpgBugFixStats(void) { hits = n = 0; } + }; + +tEpgBugFixStats EpgBugFixStats[MAXEPGBUGFIXSTATS]; + +static void EpgBugFixStat(int Number, tChannelID ChannelID) +{ + if (0 <= Number && Number < MAXEPGBUGFIXSTATS) { + tEpgBugFixStats *p = &EpgBugFixStats[Number]; + p->hits++; + int i = 0; + for (; i < p->n; i++) { + if (p->channelIDs[i] == ChannelID) + break; + } + if (i == p->n && p->n < MAXEPGBUGFIXCHANS) + p->channelIDs[p->n++] = ChannelID; + } +} + +void ReportEpgBugFixStats(bool Reset) +{ + if (Setup.EPGBugfixLevel > 0) { + bool GotHits = false; + char buffer[1024]; + for (int i = 0; i < MAXEPGBUGFIXSTATS; i++) { + const char *delim = "\t"; + tEpgBugFixStats *p = &EpgBugFixStats[i]; + if (p->hits) { + bool PrintedStats = false; + char *q = buffer; + *buffer = 0; + for (int c = 0; c < p->n; c++) { + cChannel *channel = Channels.GetByChannelID(p->channelIDs[c], true); + if (channel) { + if (!GotHits) { + dsyslog("====================="); + dsyslog("EPG bugfix statistics"); + dsyslog("====================="); + dsyslog("IF SOMEBODY WHO IS IN CHARGE OF THE EPG DATA FOR ONE OF THE LISTED"); + dsyslog("CHANNELS READS THIS: PLEASE TAKE A LOOK AT THE FUNCTION cEvent::FixEpgBugs()"); + dsyslog("IN VDR/epg.c TO LEARN WHAT'S WRONG WITH YOUR DATA, AND FIX IT!"); + dsyslog("====================="); + dsyslog("Fix\tHits\tChannels"); + GotHits = true; + } + if (!PrintedStats) { + q += snprintf(q, sizeof(buffer) - (q - buffer), "%d\t%d", i, p->hits); + PrintedStats = true; + } + q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->Name()); + delim = ", "; + } + } + if (*buffer) + dsyslog("%s", buffer); + } + if (Reset) + p->hits = p->n = 0; + } + if (GotHits) + dsyslog("====================="); + } +} + +void cEvent::FixEpgBugs(void) +{ + // VDR can't usefully handle newline characters in the EPG data, so let's + // always convert them to blanks (independent of the setting of EPGBugfixLevel): + strreplace(title, '\n', ' '); + strreplace(shortText, '\n', ' '); + strreplace(description, '\n', ' '); + + 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 (title) { + + // VOX puts too much information into the ShortText and leaves the + // Description empty: + // + // Title + // (NAT, Year Min')[ ["ShortText". ]Description] + // + if (shortText && !description) { + if (*shortText == '(') { + char *e = strchr(shortText + 1, ')'); + if (e) { + if (*(e + 1)) { + if (*++e == ' ') + if (*(e + 1) == '"') + e++; + } + else + e = NULL; + char *s = e ? strdup(e) : NULL; + free(shortText); + shortText = s; + EpgBugFixStat(0, ChannelID()); + // now the fixes #1 and #2 below will handle the rest + } + } + } + + // VOX and VIVA put the ShortText in quotes and use either the ShortText + // or the Description field, depending on how long the string is: + // + // Title + // "ShortText". Description + // + if ((shortText == NULL) != (description == NULL)) { + char *p = shortText ? shortText : description; + 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)); + free(shortText); + free(description); + shortText = s; + description = d; + EpgBugFixStat(1, ChannelID()); + } + } + } + + // VOX and VIVA put the Description into the ShortText (preceeded + // by a blank) if there is no actual ShortText and the Description + // is short enough: + // + // Title + // Description + // + if (shortText && !description) { + if (*shortText == ' ') { + memmove(shortText, shortText + 1, strlen(shortText)); + description = shortText; + shortText = NULL; + EpgBugFixStat(2, ChannelID()); + } + } + + // Pro7 sometimes repeats the Title in the ShortText: + // + // Title + // Title + // + if (shortText && strcmp(title, shortText) == 0) { + free(shortText); + shortText = NULL; + EpgBugFixStat(3, ChannelID()); + } + + // ZDF.info puts the ShortText between double quotes, which is nothing + // but annoying (some even put a '.' after the closing '"'): + // + // Title + // "ShortText"[.] + // + if (shortText && *shortText == '"') { + int l = strlen(shortText); + if (l > 2 && (shortText[l - 1] == '"' || (shortText[l - 1] == '.' && shortText[l - 2] == '"'))) { + memmove(shortText, shortText + 1, l); + char *p = strrchr(shortText, '"'); + if (p) + *p = 0; + EpgBugFixStat(4, ChannelID()); + } + } + + 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: + title = compactspace(title); + shortText = compactspace(shortText); + description = compactspace(description); + // Remove superfluous hyphens: + if (description) { + char *p = description; + while (*p && *(p + 1) && *(p + 2)) { + 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); + EpgBugFixStat(5, ChannelID()); + } + } + p++; + } + } + +#define MAX_USEFUL_EPISODE_LENGTH 40 + // Some channels put a whole lot of information in the ShortText and leave + // the Description totally empty. So if the ShortText length exceeds + // MAX_USEFUL_EPISODE_LENGTH, let's put this into the Description + // instead: + if (!isempty(shortText) && isempty(description)) { + if (strlen(shortText) > MAX_USEFUL_EPISODE_LENGTH) { + free(description); + description = shortText; + shortText = NULL; + EpgBugFixStat(6, ChannelID()); + } + } + + // Some channels use the ` ("backtick") character, where a ' (single quote) + // would be normally used. Actually, "backticks" in normal text don't make + // much sense, so let's replace them: + strreplace(title, '`', '\''); + strreplace(shortText, '`', '\''); + strreplace(description, '`', '\''); + } +} + +// --- cSchedule ------------------------------------------------------------- + +cSchedule::cSchedule(tChannelID ChannelID) +{ + channelID = ChannelID; + present = following = NULL; +} + +cEvent *cSchedule::AddEvent(cEvent *Event) +{ + events.Add(Event); + return Event; +} + +const cEvent *cSchedule::GetPresentEvent(void) const +{ + return GetEventAround(time(NULL)); +} + +const cEvent *cSchedule::GetFollowingEvent(void) const +{ + const cEvent *pe = NULL; + time_t now = time(NULL); + time_t delta = INT_MAX; + for (cEvent *p = events.First(); p; p = events.Next(p)) { + time_t dt = p->StartTime() - now; + if (dt > 0 && dt < delta) { + delta = dt; + pe = p; + } + } + return pe; +} + +const cEvent *cSchedule::GetEvent(u_int16_t EventID, time_t StartTime) const +{ + // Returns either the event info with the given EventID or, if that one can't + // be found, the one with the given StartTime (or NULL if neither can be found) + cEvent *pt = NULL; + for (cEvent *pe = events.First(); pe; pe = events.Next(pe)) { + if (pe->EventID() == EventID) + return pe; + if (StartTime > 0 && pe->StartTime() == StartTime) // 'StartTime < 0' is apparently used with NVOD channels + pt = pe; + } + return pt; +} + +const cEvent *cSchedule::GetEventAround(time_t Time) const +{ + const cEvent *pe = NULL; + time_t delta = INT_MAX; + for (cEvent *p = events.First(); p; p = events.Next(p)) { + time_t dt = Time - p->StartTime(); + if (dt >= 0 && dt < delta && p->StartTime() + p->Duration() >= Time) { + delta = dt; + pe = p; + } + } + return pe; +} + +bool cSchedule::SetPresentEvent(cEvent *Event) +{ + if (present) + present->SetIsPresent(false); + present = Event; + present->SetIsPresent(true); + return true; +} + +bool cSchedule::SetFollowingEvent(cEvent *Event) +{ + if (following) + following->SetIsFollowing(false); + following = Event; + following->SetIsFollowing(true); + return true; +} + +void cSchedule::Cleanup(void) +{ + Cleanup(time(NULL)); +} + +void cSchedule::Cleanup(time_t Time) +{ + cEvent *Event; + for (int a = 0; true ; a++) { + Event = events.Get(a); + if (!Event) + break; + if (Event->StartTime() + Event->Duration() + 3600 < Time) { // adding one hour for safety + events.Del(Event); + a--; + } + } +} + +void cSchedule::Dump(FILE *f, const char *Prefix) const +{ + cChannel *channel = Channels.GetByChannelID(channelID, true); + if (channel) { + fprintf(f, "%sC %s %s\n", Prefix, channel->GetChannelID().ToString(), channel->Name()); + for (cEvent *p = events.First(); p; p = events.Next(p)) + p->Dump(f, Prefix); + fprintf(f, "%sc\n", Prefix); + } +} + +bool cSchedule::Read(FILE *f, cSchedules *Schedules) +{ + if (Schedules) { + char *s; + while ((s = readline(f)) != NULL) { + if (*s == 'C') { + s = skipspace(s + 1); + char *p = strchr(s, ' '); + if (p) + *p = 0; // strips optional channel name + if (*s) { + tChannelID channelID = tChannelID::FromString(s); + if (channelID.Valid()) { + cSchedule *p = Schedules->AddSchedule(channelID); + if (p) { + if (!cEvent::Read(f, p)) + return false; + } + } + else { + esyslog("ERROR: illegal channel ID: %s", s); + return false; + } + } + } + else { + esyslog("ERROR: unexpected tag while reading EPG data: %s", s); + return false; + } + } + return true; + } + return false; +} + +// --- cSchedulesLock -------------------------------------------------------- + +cSchedulesLock::cSchedulesLock(bool WriteLock, int TimeoutMs) +{ + locked = cSchedules::schedules.rwlock.Lock(WriteLock, TimeoutMs); +} + +cSchedulesLock::~cSchedulesLock() +{ + if (locked) + cSchedules::schedules.rwlock.Unlock(); +} + +// --- cSchedules ------------------------------------------------------------ + +cSchedules cSchedules::schedules; +const char *cSchedules::epgDataFileName = NULL; +time_t cSchedules::lastCleanup = time(NULL); +time_t cSchedules::lastDump = time(NULL); + +const cSchedules *cSchedules::Schedules(cSchedulesLock &SchedulesLock) +{ + return SchedulesLock.Locked() ? &schedules : NULL; +} + +void cSchedules::SetEpgDataFileName(const char *FileName) +{ + delete epgDataFileName; + if (FileName) + epgDataFileName = strdup(FileName); +} + +void cSchedules::Cleanup(bool Force) +{ + if (Force) + lastDump = 0; + time_t now = time(NULL); + struct tm tm_r; + struct tm *ptm = localtime_r(&now, &tm_r); + if (now - lastCleanup > 3600 && ptm->tm_hour == 5) { + isyslog("cleaning up schedules data"); + cSchedulesLock SchedulesLock(true, 1000); + cSchedules *s = (cSchedules *)Schedules(SchedulesLock); + if (s) { + for (cSchedule *p = s->First(); p; p = s->Next(p)) + p->Cleanup(now); + } + lastCleanup = now; + ReportEpgBugFixStats(true); + } + if (epgDataFileName && now - lastDump > 600) { + cSafeFile f(epgDataFileName); + if (f.Open()) { + Dump(f); + f.Close(); + } + else + LOG_ERROR; + lastDump = now; + } +} + +bool cSchedules::ClearAll(void) +{ + cSchedulesLock SchedulesLock(true, 1000); + cSchedules *s = (cSchedules *)Schedules(SchedulesLock); + if (s) { + s->Clear(); + return true; + } + return false; +} + +bool cSchedules::Dump(FILE *f, const char *Prefix) +{ + cSchedulesLock SchedulesLock; + cSchedules *s = (cSchedules *)Schedules(SchedulesLock); + if (s) { + for (cSchedule *p = s->First(); p; p = s->Next(p)) + p->Dump(f, Prefix); + return true; + } + return false; +} + +bool cSchedules::Read(FILE *f) +{ + cSchedulesLock SchedulesLock(true, 1000); + cSchedules *s = (cSchedules *)Schedules(SchedulesLock); + if (s) { + bool OwnFile = f == NULL; + if (OwnFile) { + if (epgDataFileName && access(epgDataFileName, R_OK) == 0) { + dsyslog("reading EPG data from %s", epgDataFileName); + if ((f = fopen(epgDataFileName, "r")) == NULL) { + LOG_ERROR; + return false; + } + } + else + return false; + } + bool result = cSchedule::Read(f, s); + if (OwnFile) + fclose(f); + return result; + } + return false; +} + +cSchedule *cSchedules::AddSchedule(tChannelID ChannelID) +{ + ChannelID.ClrRid(); + cSchedule *p = (cSchedule *)GetSchedule(ChannelID); + if (!p) { + p = new cSchedule(ChannelID); + Add(p); + } + return p; +} + +const cSchedule *cSchedules::GetSchedule(tChannelID ChannelID) const +{ + ChannelID.ClrRid(); + for (cSchedule *p = First(); p; p = Next(p)) { + if (p->ChannelID() == ChannelID) + return p; + } + return NULL; +} + diff --git a/epg.h b/epg.h new file mode 100644 index 00000000..4a999d12 --- /dev/null +++ b/epg.h @@ -0,0 +1,130 @@ +/* + * epg.h: Electronic Program Guide + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * Original version (as used in VDR before 1.3.0) written by + * Robert Schneider and Rolf Hakenes . + * + * $Id: epg.h 1.1 2003/12/22 13:03:10 kls Exp $ + */ + +#ifndef __EPG_H +#define __EPG_H + +#include "channels.h" +#include "thread.h" +#include "tools.h" + +#define MAXEPGBUGFIXLEVEL 2 + +class cSchedule; + +class cEvent : public cListObject { +private: + tChannelID channelID; // Channel ID of program for this event + u_int16_t eventID; // Event ID of this event + uchar tableID; // Table ID this event came from + //XXX present/following obsolete??? + bool isPresent; // true if this is the present event running + bool isFollowing; // true if this is the next event on this channel + char *title; // Title of this event + char *shortText; // Short description of this event (typically the episode name in case of a series) + char *description; // Description of this event + time_t startTime; // Start time of this event + int duration; // Duration of this event in seconds + //XXX find an other solution, avoiding channelNumber??? + int channelNumber; // the actual channel number from VDR's channel list (used in cMenuSchedule for sorting by channel number) +public: + cEvent(tChannelID ChannelID, u_int16_t EventID); + ~cEvent(); + tChannelID ChannelID(void) const { return channelID; } + u_int16_t EventID(void) const { return eventID; } + const uchar TableID(void) const { return tableID; } + bool IsPresent(void) const { return isPresent; } + bool IsFollowing(void) const { return isFollowing; } + const char *Title(void) const { return title; } + const char *ShortText(void) const { return shortText; } + const char *Description(void) const { return description; } + time_t StartTime(void) const { return startTime; } + int Duration(void) const { return duration; } + int ChannelNumber(void) const { return channelNumber; } + const char *GetDateString(void) const; + const char *GetTimeString(void) const; + const char *GetEndTimeString(void) const; + void SetTableID(uchar TableID); + void SetIsPresent(bool IsPresent); + void SetIsFollowing(bool IsFollowing); + void SetTitle(const char *Title); + void SetShortText(const char *ShortText); + void SetDescription(const char *Description); + void SetStartTime(time_t StartTime); + void SetDuration(int Duration); + void SetChannelNumber(int ChannelNumber) const { ((cEvent *)this)->channelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const' //XXX + void Dump(FILE *f, const char *Prefix = "") const; + static bool Read(FILE *f, cSchedule *Schedule); + void FixEpgBugs(void); + }; + +class cSchedules; + +class cSchedule : public cListObject { +private: + tChannelID channelID; + cList events; + cEvent *present; + cEvent *following; +public: + cSchedule(tChannelID ChannelID); + tChannelID ChannelID(void) const { return channelID; } + bool SetPresentEvent(cEvent *Event); + bool SetFollowingEvent(cEvent *Event); + void Cleanup(time_t Time); + void Cleanup(void); + cEvent *AddEvent(cEvent *Event); + const cEvent *GetPresentEvent(void) const; + const cEvent *GetFollowingEvent(void) const; + const cEvent *GetEvent(u_int16_t EventID, time_t StartTime = 0) const; + const cEvent *GetEventAround(time_t Time) const; + const cEvent *GetEventNumber(int n) const { return events.Get(n); } + int NumEvents(void) const { return events.Count(); } + void Dump(FILE *f, const char *Prefix = "") const; + static bool Read(FILE *f, cSchedules *Schedules); + }; + +class cSchedulesLock { +private: + bool locked; +public: + cSchedulesLock(bool WriteLock = false, int TimeoutMs = 0); + ~cSchedulesLock(); + bool Locked(void) { return locked; } + }; + +class cSchedules : public cList { + friend class cSchedule; + friend class cSchedulesLock; +private: + cRWlock rwlock; + static cSchedules schedules; + static const char *epgDataFileName; + static time_t lastCleanup; + static time_t lastDump; +public: + static void SetEpgDataFileName(const char *FileName); + static const cSchedules *Schedules(cSchedulesLock &SchedulesLock); + ///< Caller must provide a cSchedulesLock which has to survive the entire + ///< time the returned cSchedules is accessed. Once the cSchedules is no + ///< longer used, the cSchedulesLock must be destroyed. + static void Cleanup(bool Force = false); + static bool ClearAll(void); + static bool Dump(FILE *f, const char *Prefix = ""); + static bool Read(FILE *f = NULL); + cSchedule *AddSchedule(tChannelID ChannelID); + const cSchedule *GetSchedule(tChannelID ChannelID) const; + }; + +void ReportEpgBugFixStats(bool Reset = false); + +#endif //__EPG_H diff --git a/filter.c b/filter.c new file mode 100644 index 00000000..668b7d3a --- /dev/null +++ b/filter.c @@ -0,0 +1,126 @@ +/* + * filter.c: Section filter + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: filter.c 1.1 2003/12/21 15:26:16 kls Exp $ + */ + +#include "filter.h" +#include "sections.h" + +// --- cFilterData ----------------------------------------------------------- + +cFilterData::cFilterData(void) +{ + pid = 0; + tid = 0; + mask = 0; + sticky = false; +} + +cFilterData::cFilterData(u_short Pid, u_char Tid, u_char Mask, bool Sticky) +{ + pid = Pid; + tid = Tid; + mask = Mask; + sticky = Sticky; +} + +bool cFilterData::Is(u_short Pid, u_char Tid, u_char Mask) +{ + return pid == Pid && tid == Tid && mask == Mask; +} + +bool cFilterData::Matches(u_short Pid, u_char Tid) +{ + return pid == Pid && tid == (Tid & mask); +} + +// --- cFilter --------------------------------------------------------------- + +cFilter::cFilter(void) +{ + sectionHandler = NULL; + on = false; +} + +cFilter::cFilter(u_short Pid, u_char Tid, u_char Mask) +{ + sectionHandler = NULL; + on = false; + Set(Pid, Tid, Mask); +} + +cFilter::~cFilter() +{ + if (sectionHandler) + sectionHandler->Detach(this); +} + +int cFilter::Source(void) +{ + return sectionHandler ? sectionHandler->Source() : 0; +} + +int cFilter::Transponder(void) +{ + return sectionHandler ? sectionHandler->Transponder() : 0; +} + +void cFilter::SetStatus(bool On) +{ + if (sectionHandler && on != On) { + cFilterData *fd = data.First(); + while (fd) { + if (On) + sectionHandler->Add(fd); + else { + sectionHandler->Del(fd); + if (!fd->sticky) { + cFilterData *next = data.Next(fd); + data.Del(fd); + fd = next; + continue; + } + } + fd = data.Next(fd); + } + on = On; + } +} + +bool cFilter::Matches(u_short Pid, u_char Tid) +{ + for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) { + if (fd->Matches(Pid, Tid)) + return true; + } + return false; +} + +void cFilter::Set(u_short Pid, u_char Tid, u_char Mask) +{ + Add(Pid, Tid, Mask, true); +} + +void cFilter::Add(u_short Pid, u_char Tid, u_char Mask, bool Sticky) +{ + cFilterData *fd = new cFilterData(Pid, Tid, Mask, Sticky); + data.Add(fd); + if (sectionHandler && on) + sectionHandler->Add(fd); +} + +void cFilter::Del(u_short Pid, u_char Tid, u_char Mask) +{ + for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) { + if (fd->Is(Pid, Tid, Mask)) { + if (sectionHandler && on) + sectionHandler->Del(fd); + data.Del(fd); + return; + } + } +} diff --git a/filter.h b/filter.h new file mode 100644 index 00000000..09703e02 --- /dev/null +++ b/filter.h @@ -0,0 +1,74 @@ +/* + * filter.h: Section filter + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: filter.h 1.1 2003/12/22 11:41:40 kls Exp $ + */ + +#ifndef __FILTER_H +#define __FILTER_H + +#include +#include "tools.h" + +class cFilterData : public cListObject { +public: + u_short pid; + u_char tid; + u_char mask; + bool sticky; + cFilterData(void); + cFilterData(u_short Pid, u_char Tid, u_char Mask, bool Sticky); + bool Is(u_short Pid, u_char Tid, u_char Mask); + bool Matches(u_short Pid, u_char Tid); + }; + +class cSectionHandler; + +class cFilter : public cListObject { + friend class cSectionHandler; +private: + cSectionHandler *sectionHandler; + cList data; + bool on; +protected: + cFilter(void); + cFilter(u_short Pid, u_char Tid, u_char Mask = 0xFF); + virtual ~cFilter(); + virtual void SetStatus(bool On); + ///< Turns this filter on or off, depending on the value of On. + ///< If the filter is turned off, any filter data that has been + ///< added without the Sticky parameter set to 'true' will be + ///< automatically deleted. Those parameters that have been added + ///< with Sticky set to 'true' will be automatically reused when + ///< SetStatus(true) is called. + virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length) = 0; + ///< Processes the data delivered to this filter. + ///< Pid and Tid is one of the combinations added to this filter by + ///< a previous call to Add(), Data is a pointer to Length bytes of + ///< data. This function will be called from the section handler's + ///< thread, so it has to use proper locking mechanisms in case it + ///< accesses any global data. It is guaranteed that if several cFilters + ///< are attached to the same cSectionHandler, only _one_ of them has + ///< its Process() function called at any given time. It is allowed + ///< that more than one cFilter are set up to receive the same Pid/Tid. + ///< The Process() function must return as soon as possible. + int Source(void); + ///< Returns the source of the data delivered to this filter. + int Transponder(void); + ///< Returns the transponder of the data delivered to this filter. + bool Matches(u_short Pid, u_char Tid); + ///< Indicates whether this filter wants to receive data from the given Pid/Tid. + void Set(u_short Pid, u_char Tid, u_char Mask = 0xFF); + ///< Sets the given filter data by calling Add() with Sticky = true. + void Add(u_short Pid, u_char Tid, u_char Mask = 0xFF, bool Sticky = false); + ///< Adds the given filter data to this filter. + ///< If Sticky is true, this will survive a status change, otherwise + ///< it will be automatically deleted. + void Del(u_short Pid, u_char Tid, u_char Mask = 0xFF); + ///< Deletes the given filter data from this filter. + }; + +#endif //__FILTER_H diff --git a/libdtv/COPYING b/libdtv/COPYING deleted file mode 100644 index a43ea212..00000000 --- a/libdtv/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - 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 deleted file mode 100644 index 56cb5330..00000000 --- a/libdtv/Makefile +++ /dev/null @@ -1,73 +0,0 @@ -############################################################## -### ### -### Makefile: global makefile for libdtv ### -### ### -############################################################## - -## $Revision: 1.3 $ -## $Date: 2001/06/25 12:51:41 $ -## $Author: hakenes $ -## -## (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 deleted file mode 100644 index 88ee0490..00000000 --- a/libdtv/README +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index a43ea212..00000000 --- a/libdtv/liblx/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - 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 deleted file mode 100644 index d06ee091..00000000 --- a/libdtv/liblx/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -############################################################## -### ### -### Makefile: local makefile for liblx ### -### ### -############################################################## - -## $Revision: 1.2 $ -## $Date: 2001/06/25 19:39:00 $ -## $Author: hakenes $ -## -## (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 deleted file mode 100644 index 2e122956..00000000 --- a/libdtv/liblx/liblx.h +++ /dev/null @@ -1,449 +0,0 @@ -/* - * - * liblx.h: definitions necessary for the liblx package - * - * - * $Revision: 1.2 $ - * $Date: 2001/06/25 19:39:00 $ - * $Author: hakenes $ - * - * (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 deleted file mode 100644 index 348c7800..00000000 --- a/libdtv/liblx/xListFuncs.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * - * xListFuncs.c: list handling functions of liblx - * - * - * $Revision: 1.1 $ - * $Date: 2001/08/15 10:00:00 $ - * $Author: hakenes $ - * - * (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 "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 deleted file mode 100644 index 5f32ce2c..00000000 --- a/libdtv/liblx/xMemMgt.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * - * xMemMgt.c: memory management functions of liblx - * - * - * $Revision: 1.1 $ - * $Date: 2001/08/15 10:00:00 $ - * $Author: hakenes $ - * - * (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 -#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 deleted file mode 100644 index a43ea212..00000000 --- a/libdtv/libsi/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - 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 deleted file mode 100644 index 4f278a09..00000000 --- a/libdtv/libsi/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -############################################################## -### ### -### Makefile: local makefile for libsi ### -### ### -############################################################## - -## $Revision: 1.4 $ -## $Date: 2001/10/07 10:24:46 $ -## $Author: hakenes $ -## -## (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 deleted file mode 100644 index 4f1be1ab..00000000 --- a/libdtv/libsi/README +++ /dev/null @@ -1,2 +0,0 @@ -DVB - System Information Library -================================ diff --git a/libdtv/libsi/include/libsi.h b/libdtv/libsi/include/libsi.h deleted file mode 100644 index b4dad887..00000000 --- a/libdtv/libsi/include/libsi.h +++ /dev/null @@ -1,1248 +0,0 @@ -////////////////////////////////////////////////////////////// -/// /// -/// libsi.h: definitions for data structures of libsi /// -/// /// -////////////////////////////////////////////////////////////// - -// $Revision: 1.7 $ -// $Date: 2003/04/12 11:27:31 $ -// $Author: hakenes $ -// -// (C) 2001-03 Rolf Hakenes , under the -// GNU GPL with contribution of Oleg Assovski, -// www.satmania.com -// -// 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 - -#define dvb_pid_t int - - - /* Program Identifier */ - -#define PID_PAT 0x00 /* Program Association Table */ -#define PID_CAT 0x01 /* Conditional Access Table */ -#define PID_NIT 0x10 /* Network Information Table */ -#define PID_BAT 0x11 /* Bouquet Association 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_CA_EMM 0x82 - -#define TID_BAT 0x4A /* Bouquet Association Section */ - -#define TID_EIT 0x12 /* Event Information Section */ -#define TID_RST 0x71 /* Running Status Section */ -#define TID_ST 0x72 /* Stuffing 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 - - -/* NetworkInfo structure (used to store NIT/BAT information) */ - -struct NetworkInfo { - struct NODE Node; - unsigned short ID; // NetworkID / BouquetID - struct LIST *Descriptors; - struct LIST *TransportStreams; -}; - -#define CreateNetworkInfo(ni, id) \ - do { \ - xCreateNode (ni, NULL); \ - (ni)->ID = id; \ - (ni)->Descriptors = xNewList(NULL); \ - (ni)->TransportStreams = NULL; \ - } while(0) - -/* TransportStream structure (NIT/BAT TS loop member) */ - -struct TransportStream { - struct NODE Node; - int TransportStreamID; - unsigned short OriginalNetworkID; - struct LIST *Descriptors; -}; - -#define CreateTransportStream(ts, tsid, onid) \ - do { \ - xCreateNode (ts, NULL); \ - (ts)->TransportStreamID = tsid; \ - (ts)->OriginalNetworkID = onid; \ - (ts)->Descriptors = xNewList(NULL); \ - } while(0) - -/* 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; - dvb_pid_t ElementaryPid; - struct LIST *Descriptors; -}; - -#define CreatePidInfo(pidinfo, styp, epid) \ - do \ - { \ - xCreateNode (pidinfo, NULL); \ - pidinfo->StreamType = styp; \ - pidinfo->ElementaryPid = (dvb_pid_t) epid; \ - pidinfo->Descriptors = xNewList (NULL); \ - } while (0) - - -#define STREAMTYPE_11172_VIDEO 1 -#define STREAMTYPE_13818_VIDEO 2 -#define STREAMTYPE_11172_AUDIO 3 -#define STREAMTYPE_13818_AUDIO 4 -#define STREAMTYPE_13818_PRIVATE 5 -#define STREAMTYPE_13818_PES_PRIVATE 6 -#define STREAMTYPE_13522_MHPEG 7 -#define STREAMTYPE_13818_DSMCC 8 -#define STREAMTYPE_ITU_222_1 9 -#define STREAMTYPE_13818_A 10 -#define STREAMTYPE_13818_B 11 -#define STREAMTYPE_13818_C 12 -#define STREAMTYPE_13818_D 13 -#define STREAMTYPE_13818_AUX 14 - - -struct Tot { - time_t UTC; - time_t Bias; - struct LIST *Descriptors; -}; - -#define CreateTot(tot, utc) \ - do \ - { \ - xMemAlloc(sizeof(struct Tot), &tot); \ - tot->UTC = utc; \ - tot->Bias = ((utc - time(NULL) + 1800)/3600)*3600; \ - tot->Descriptors = xNewList(NULL); \ - } while (0) - - -/* 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) - - -/* Ac3Descriptor */ - -#define AC3_TYPE_FLAG 0x0001 -#define BS_ID_FLAG 0x0002 -#define MAIN_ID_FLAG 0x0004 -#define ASVC_FLAG 0x0008 - -struct Ac3Descriptor { - struct NODE Node; - unsigned short Tag; - unsigned short PresentFlags; - unsigned short Ac3Type; - unsigned short BsId; - unsigned short MainId; - unsigned short Asvc; - unsigned short Amount; /* AdditionalData */ - unsigned char *AdditionalData; -}; - -#define CreateAc3Descriptor(descr) \ - do \ - { \ - xCreateNode (((struct Ac3Descriptor *)descr), NULL); \ - ((struct Ac3Descriptor *)descr)->Tag = DESCR_AC3; \ - } while (0) - -#define AddAc3FlagAndValue(descr, flg, val) \ - do \ - { \ - if ((flg) & AC3_TYPE_FLAG) { \ - ((struct Ac3Descriptor *)descr)->PresentFlags |= AC3_TYPE_FLAG; \ - ((struct Ac3Descriptor *)descr)->Ac3Type = (val); } \ - else if ((flg) & BS_ID_FLAG) { \ - ((struct Ac3Descriptor *)descr)->PresentFlags |= BS_ID_FLAG; \ - ((struct Ac3Descriptor *)descr)->BsId = (val); } \ - else if ((flg) & MAIN_ID_FLAG) { \ - ((struct Ac3Descriptor *)descr)->PresentFlags |= MAIN_ID_FLAG; \ - ((struct Ac3Descriptor *)descr)->MainId = (val); } \ - else if ((flg) & ASVC_FLAG) { \ - ((struct Ac3Descriptor *)descr)->PresentFlags |= ASVC_FLAG; \ - ((struct Ac3Descriptor *)descr)->Asvc = (val); } \ - } while (0) - -#define AddAc3AdditionalData(descr, ptr, len) \ - do \ - { \ - xMemAlloc ((len)+1, &(((struct Ac3Descriptor *) \ - descr)->AdditionalData)); \ - memcpy ((((struct Ac3Descriptor *)descr)->AdditionalData),(ptr),(len)); \ - } 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 */ -/* - the same used instead of NetworkNameDescriptor because their structures - are identical. We pass 'tag' parameter to distinguish between them later -*/ - -struct BouquetNameDescriptor { - struct NODE Node; /* Node enthält Namen */ - unsigned short Tag; -}; - -#define CreateBouquetNameDescriptor(descr, text, tag) \ - do \ - { \ - xCreateNode (((struct BouquetNameDescriptor *)descr), NULL); \ - ((struct NODE *)descr)->Name = text; \ - ((struct NODE *)descr)->HashKey = xHashKey (text); \ - ((struct BouquetNameDescriptor *)descr)->Tag = tag; \ - } 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]) - -/* CaDescriptor */ - -struct CaDescriptor { - struct NODE Node; - unsigned short Tag; - unsigned short CA_type; - unsigned short CA_PID; - unsigned int ProviderID; - unsigned short DataLength; - unsigned char *Data; -}; - -#define CreateCaDescriptor(descr, typ, capid, len) \ - do \ - { \ - xCreateNode (((struct CaDescriptor *)descr), NULL); \ - ((struct CaDescriptor *)descr)->Tag = DESCR_CA; \ - ((struct CaDescriptor *)descr)->CA_type = typ; \ - ((struct CaDescriptor *)descr)->CA_PID = capid; \ - ((struct CaDescriptor *)descr)->ProviderID = 0; \ - ((struct CaDescriptor *)descr)->DataLength = len; \ - xMemAlloc (len+1, &((struct CaDescriptor *)descr)->Data); \ - } while (0) - -#define SetCaData(descr, num, id) \ - ((struct CaDescriptor *)descr)->Data[num] = id -#define GetCaData(descr, num) (((struct CaDescriptor *)descr)->Data[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), NULL); \ - ((struct NODE *)descr)->Name = name; \ - ((struct NODE *)descr)->HashKey = xHashKey (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), NULL); \ - ((struct NODE *)descr)->Name = txt; \ - ((struct NODE *)descr)->HashKey = xHashKey (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), NULL); \ - ((struct NODE *)descr)->Name = text; \ - ((struct NODE *)descr)->HashKey = xHashKey (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, NULL); \ - ((struct NODE *)itm)->Name = dtxt; \ - ((struct NODE *)itm)->HashKey = xHashKey (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), NULL); \ - ((struct NODE *)descr)->Name = name; \ - ((struct NODE *)descr)->HashKey = xHashKey (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) - - -/* TeletextDescriptor */ - -struct TeletextDescriptor { - struct NODE Node; - unsigned short Tag; - struct LIST *Items; -}; - -#define CreateTeletextDescriptor(descr) \ - do \ - { \ - xCreateNode (((struct TeletextDescriptor *)descr), NULL); \ - ((struct TeletextDescriptor *)descr)->Tag = DESCR_TELETEXT; \ - ((struct TeletextDescriptor *)descr)->Items = xNewList (NULL); \ - } while (0) - -#define TELETEXT_TYPE_INITIAL_PAGE 0x0001 -#define TELETEXT_TYPE_SUBTITLE_PAGE 0x0002 -#define TELETEXT_TYPE_ADDITIONAL_INFO 0x0003 -#define TELETEXT_TYPE_PROGRAM_SCHEDULE 0x0004 -#define TELETEXT_TYPE_HEARING_IMPAIRED 0x0005 - -struct TeletextItem { - struct NODE Node; - char LanguageCode[4]; - unsigned short Type; - unsigned short MagazineNumber; - unsigned short PageNumber; -}; - -#define CreateTeletextItem(itm, tp, mg, pg, lc1, lc2, lc3) \ - do \ - { \ - xCreateNode (itm, NULL); \ - ((struct TeletextItem *)itm)->Type = (tp); \ - ((struct TeletextItem *)itm)->MagazineNumber = (mg); \ - ((struct TeletextItem *)itm)->PageNumber = (mg); \ - ((struct TeletextItem *)itm)->LanguageCode[0] = (lc1); \ - ((struct TeletextItem *)itm)->LanguageCode[1] = (lc2); \ - ((struct TeletextItem *)itm)->LanguageCode[2] = (lc3); \ - ((struct TeletextItem *)itm)->LanguageCode[3] = '\0'; \ - } while (0) - -#define AddTeletextItem(desc, tp, mg, pg, lc1, lc2, lc3) \ - do \ - { \ - struct TeletextItem *item; \ - \ - CreateTeletextItem(item, tp, mg, pg, lc1, lc2, lc3); \ - xAddTail (((struct TeletextDescriptor *)desc)->Items, item); \ - } while (0) - - -/* SubtitlingDescriptor */ - -struct SubtitlingDescriptor { - struct NODE Node; - unsigned short Tag; - struct LIST *Items; -}; - -#define CreateSubtitlingDescriptor(descr) \ - do \ - { \ - xCreateNode (((struct SubtitlingDescriptor *)descr), NULL); \ - ((struct SubtitlingDescriptor *)descr)->Tag = DESCR_SUBTITLING; \ - ((struct SubtitlingDescriptor *)descr)->Items = xNewList (NULL); \ - } while (0) - -struct SubtitlingItem { - struct NODE Node; - char LanguageCode[4]; - unsigned char Type; - unsigned short CompositionPageId; - unsigned short AncillaryPageId; -}; - -#define CreateSubtitlingItem(itm, tp, cp, ap, lc1, lc2, lc3) \ - do \ - { \ - xCreateNode (itm, NULL); \ - ((struct SubtitlingItem *)itm)->Type = (tp); \ - ((struct SubtitlingItem *)itm)->CompositionPageId = (cp); \ - ((struct SubtitlingItem *)itm)->AncillaryPageId = (ap); \ - ((struct SubtitlingItem *)itm)->LanguageCode[0] = (lc1); \ - ((struct SubtitlingItem *)itm)->LanguageCode[1] = (lc2); \ - ((struct SubtitlingItem *)itm)->LanguageCode[2] = (lc3); \ - ((struct SubtitlingItem *)itm)->LanguageCode[3] = '\0'; \ - } while (0) - -#define AddSubtitlingItem(desc, tp, cp, ap, lc1, lc2, lc3) \ - do \ - { \ - struct SubtitlingItem *item; \ - \ - CreateSubtitlingItem(item, tp, cp, ap, lc1, lc2, lc3); \ - xAddTail (((struct SubtitlingDescriptor *)desc)->Items, item); \ - } while (0) - -/* SatelliteDeliverySystemDescriptor */ - -struct SatelliteDeliverySystemDescriptor { - struct NODE Node; - unsigned short Tag; - long Frequency; - short OrbitalPosition; - short Modulation; - char Polarization; - long SymbolRate; - char FEC; -}; - -#define CreateSatelliteDeliverySystemDescriptor(descr, freq, orb, mod, polar, sr, fec) \ - do \ - { \ - xCreateNode (((struct SatelliteDeliverySystemDescriptor *)descr), NULL); \ - ((struct SatelliteDeliverySystemDescriptor *)descr)->Tag = DESCR_SAT_DEL_SYS; \ - ((struct SatelliteDeliverySystemDescriptor *)descr)->Frequency = freq; \ - ((struct SatelliteDeliverySystemDescriptor *)descr)->OrbitalPosition = orb; \ - ((struct SatelliteDeliverySystemDescriptor *)descr)->Modulation = mod; \ - ((struct SatelliteDeliverySystemDescriptor *)descr)->Polarization = polar; \ - ((struct SatelliteDeliverySystemDescriptor *)descr)->SymbolRate = sr; \ - ((struct SatelliteDeliverySystemDescriptor *)descr)->FEC = fec; \ - } while (0) - -/* CableDeliverySystemDescriptor */ - -struct CableDeliverySystemDescriptor { - struct NODE Node; - unsigned short Tag; - long Frequency; - long SymbolRate; - char FECouter; - char FECinner; - char Modulation; -}; - -#define CreateCableDeliverySystemDescriptor(descr, freq, sr, fec_o, fec_i, mod) \ - do \ - { \ - xCreateNode (((struct CableDeliverySystemDescriptor *)descr), NULL); \ - ((struct CableDeliverySystemDescriptor *)descr)->Tag = DESCR_CABLE_DEL_SYS; \ - ((struct CableDeliverySystemDescriptor *)descr)->Frequency = freq; \ - ((struct CableDeliverySystemDescriptor *)descr)->SymbolRate = sr; \ - ((struct CableDeliverySystemDescriptor *)descr)->FECouter = fec_o; \ - ((struct CableDeliverySystemDescriptor *)descr)->FECinner = fec_i; \ - ((struct CableDeliverySystemDescriptor *)descr)->Modulation = mod; \ - } while (0) - -/* TerrestrialDeliverySystemDescriptor */ - -struct TerrestrialDeliverySystemDescriptor { - struct NODE Node; - unsigned short Tag; - long Frequency; - char Bandwidth; - char Constellation; - char Hierarchy; - char CodeRateHP; - char CodeRateLP; - char GuardInterval; - char TransmissionMode; - char OtherFrequencyFlag; -}; - -#define CreateTerrestrialDeliverySystemDescriptor(descr, freq, bw, cst, hr, crh, crl, gi, tm, ofm) \ - do \ - { \ - xCreateNode (((struct CableDeliverySystemDescriptor *)descr), NULL); \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->Tag = DESCR_TERR_DEL_SYS; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->Frequency = freq; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->Bandwidth = bw; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->Constellation = cst; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->Hierarchy = hr; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->CodeRateHP = crh; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->CodeRateLP = crl; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->GuardInterval = gi; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->TransmissionMode = tm; \ - ((struct TerrestrialDeliverySystemDescriptor *)descr)->OtherFrequencyFlag = ofm; \ - } while (0) - -/* ServiceListDescriptor */ - -struct ServiceListDescriptor { - struct NODE Node; - unsigned short Tag; - struct LIST *ServiceList; -}; - -#define CreateServiceListDescriptor(descr) \ - do \ - { \ - xCreateNode (((struct ServiceListDescriptor *)descr), NULL); \ - ((struct ServiceListDescriptor *)descr)->Tag = DESCR_SERVICE_LIST; \ - ((struct ServiceListDescriptor *)descr)->ServiceList = xNewList(NULL); \ - } while (0) - -struct ServiceListEntry { - struct NODE Node; - int ServiceID; - unsigned short ServiceType; -}; - -#define AddServiceListEntry(descr, id, typ) \ - do \ - { \ - struct ServiceListEntry *newent; \ - \ - xCreateNode (newent, NULL); \ - newent->ServiceID = id; \ - newent->ServiceType = typ; \ - xAddTail (((struct ServiceListDescriptor *)descr)->ServiceList, newent); \ - } while (0) - -/* LocalTimeOffsetDescriptor */ - -struct LocalTimeOffsetDescriptor { - struct NODE Node; - unsigned short Tag; - struct LIST *LocalTimeOffsets; -}; - -#define CreateLocalTimeOffsetDescriptor(descr) \ - do \ - { \ - xCreateNode (((struct LocalTimeOffsetDescriptor *)descr), NULL); \ - ((struct LocalTimeOffsetDescriptor *)descr)->Tag = DESCR_LOCAL_TIME_OFF; \ - ((struct LocalTimeOffsetDescriptor *)descr)->LocalTimeOffsets = xNewList(NULL); \ - } while (0) - -struct LocalTimeOffsetEntry { - struct NODE Node; - char CountryCode[4]; - char RegionID; - time_t CurrentOffset; - time_t ChangeTime; - time_t NextOffset; -}; - -#define CreateLocalTimeOffsetEntry(newent, code1, code2, code3, reg, co, ct, no) \ - do \ - { \ - xCreateNode (newent, NULL); \ - newent->CountryCode[0] = code1; \ - newent->CountryCode[1] = code2; \ - newent->CountryCode[2] = code3; \ - newent->CountryCode[3] = '\0'; \ - newent->RegionID = reg; \ - newent->CurrentOffset = co; \ - newent->ChangeTime = ct; \ - newent->NextOffset = no; \ - } while (0) - -#define AddLocalTimeOffsetEntry(descr, code1, code2, code3, reg, co, ct, no) \ - do \ - { \ - struct LocalTimeOffsetEntry *newent; \ - \ - xCreateNode (newent, NULL); \ - newent->CountryCode[0] = code1; \ - newent->CountryCode[1] = code2; \ - newent->CountryCode[2] = code3; \ - newent->CountryCode[3] = '\0'; \ - newent->RegionID = reg; \ - newent->CurrentOffset = co; \ - newent->ChangeTime = ct; \ - newent->NextOffset = no; \ - xAddTail (((struct LocalTimeOffsetDescriptor *)descr)->LocalTimeOffsets, newent); \ - } while (0) - -#define timezonecmp(ptoe,cod,reg) \ - (strncmp(ptoe->CountryCode, cod, 3) || (ptoe->RegionID != reg)) - - - -/* Prototypes */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* si_parser.c */ - -struct LIST *siParsePAT (u_char *); -struct LIST *siParseCAT (u_char *); -struct Pid *siParsePMT (u_char *); -struct LIST *siParseSDT (u_char *); -struct LIST *siParseNIT (u_char *); -struct LIST *siParseEIT (u_char *); -time_t siParseTDT (u_char *); -struct Tot *siParseTOT (u_char *); -void siParseDescriptors (struct LIST *, u_char *, int, u_char); -void siParseDescriptor (struct LIST *, u_char *); -char *siGetDescriptorText (u_char *, int); -char *siGetDescriptorName (u_char *, int); - -/* 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 *); -void siDumpDescriptor (void *); -void siDumpSection (void *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libdtv/libsi/include/si_tables.h b/libdtv/libsi/include/si_tables.h deleted file mode 100644 index f5e659ca..00000000 --- a/libdtv/libsi/include/si_tables.h +++ /dev/null @@ -1,1403 +0,0 @@ -////////////////////////////////////////////////////////////// -/// /// -/// si_tables.h: definitions for data structures of the /// -/// incoming SI data stream /// -/// /// -////////////////////////////////////////////////////////////// - -// $Revision: 1.4 $ -// $Date: 2003/04/12 11:27:31 $ -// $Author: hakenes $ -// -// (C) 2001-03 Rolf Hakenes , under the -// GNU GPL with contribution of Oleg Assovski, -// www.satmania.com -// -// 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. - -#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 BcdTimeToMinutes(x) ((60 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \ - (((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF)))) -#define BcdCharToInt(x) (10*((x & 0xF0)>>4) + (x & 0xF)) -#define CheckBcdChar(x) ((((x & 0xF0)>>4) <= 9) && \ - ((x & 0x0F) <= 9)) -#define CheckBcdSignedChar(x) ((((x & 0xF0)>>4) >= 0) && (((x & 0xF0)>>4) <= 9) && \ - ((x & 0x0F) >= 0) && ((x & 0x0F) <= 9)) - -#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 -#define GetSegmentLastSectionNumber(x) ((eit_t *)(x))->segment_last_section_number -#define GetLastTableId(x) ((eit_t *)(x))->segment_last_table_id -#define GetSectionLength(x) HILO(((pat_t *)(x))->section_length) - -/* - * - * 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. - * - */ -#define CAT_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 reserved_1 :8; - u_char reserved_2 :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; -} cat_t; - -/* - * - * 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. - * - */ -/* SEE NIT (It has the same structure but has different allowed descriptors) */ -/* - * - * 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 GetSDTTransportStreamId(x) (HILO(((sdt_t *) x)->transport_stream_id)) -#define GetSDTOriginalNetworkId(x) (HILO(((sdt_t *) x)->original_network_id)) - -#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. - * - */ -#define TOT_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 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; -#if BYTE_ORDER == BIG_ENDIAN - u_char :4; - u_char descriptors_loop_length_hi :4; -#else - u_char descriptors_loop_length_hi :4; - u_char :4; -#endif - u_char descriptors_loop_length_lo :8; -} tot_t; - - -/* - * - * 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) - - -/* 0x09 ca_descriptor */ - -#define DESCR_CA_LEN 6 -typedef struct descr_ca_struct { - u_char descriptor_tag :8; - u_char descriptor_length :8; - u_char CA_type_hi :8; - u_char CA_type_lo :8; -#if BYTE_ORDER == BIG_ENDIAN - u_char reserved :3; - u_char CA_PID_hi :5; -#else - u_char CA_PID_hi :5; - u_char reserved :3; -#endif - u_char CA_PID_lo :8; -} descr_ca_t; -#define CastCaDescriptor(x) ((descr_ca_t *)(x)) - -/* 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 2 -typedef struct descr_network_name_struct { - u_char descriptor_tag :8; - u_char descriptor_length :8; -} descr_network_name_t; -#define CastNetworkNameDescriptor(x) ((descr_network_name_t *)(x)) - - -/* 0x41 service_list_descriptor */ - -#define DESCR_SERVICE_LIST_LEN 2 -typedef struct descr_service_list_struct { - u_char descriptor_tag :8; - u_char descriptor_length :8; -} descr_service_list_t; -#define CastServiceListDescriptor(x) ((descr_service_list_t *)(x)) - -#define DESCR_SERVICE_LIST_LOOP_LEN 3 -typedef struct descr_service_list_loop_struct { - u_char service_id_hi :8; - u_char service_id_lo :8; - u_char service_type :8; -} descr_service_list_loop_t; -#define CastServiceListDescriptorLoop(x) ((descr_service_list_loop_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 west_east_flag :1; - u_char polarization :2; - u_char modulation :5; -#else - u_char modulation :5; - u_char polarization :2; - u_char west_east_flag :1; -#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 2 -typedef struct descr_teletext_struct { - u_char descriptor_tag :8; - u_char descriptor_length :8; -} descr_teletext_t; -#define CastTeletextDescriptor(x) ((descr_teletext_t *)(x)) - -#define ITEM_TELETEXT_LEN 5 -typedef struct item_teletext_struct { - u_char lang_code1 :8; - u_char lang_code2 :8; - u_char lang_code3 :8; -#if BYTE_ORDER == BIG_ENDIAN - u_char type :5; - u_char magazine_number :3; -#else - u_char magazine_number :3; - u_char type :5; -#endif - u_char page_number :8; -} item_teletext_t; -#define CastTeletextItem(x) ((item_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 2 -typedef struct descr_local_time_offset_struct { - u_char descriptor_tag :8; - u_char descriptor_length :8; -} descr_local_time_offset_t; -#define CastLocalTimeOffsetDescriptor(x) ((descr_local_time_offset_t *)(x)) - -#define LOCAL_TIME_OFFSET_ENTRY_LEN 15 -typedef struct local_time_offset_entry_struct { - u_char country_code1 :8; - u_char country_code2 :8; - u_char country_code3 :8; -#if BYTE_ORDER == BIG_ENDIAN - u_char country_region_id :6; - u_char :1; - u_char local_time_offset_polarity :1; -#else - u_char local_time_offset_polarity :1; - u_char :1; - u_char country_region_id :6; -#endif - u_char local_time_offset_h :8; - u_char local_time_offset_m :8; - u_char time_of_change_mjd_hi :8; - u_char time_of_change_mjd_lo :8; - u_char time_of_change_time_h :8; - u_char time_of_change_time_m :8; - u_char time_of_change_time_s :8; - u_char next_time_offset_h :8; - u_char next_time_offset_m :8; -} local_time_offset_entry_t ; -#define CastLocalTimeOffsetEntry(x) ((local_time_offset_entry_t *)(x)) - - -/* 0x59 subtitling_descriptor */ - -#define DESCR_SUBTITLING_LEN 2 -typedef struct descr_subtitling_struct { - u_char descriptor_tag :8; - u_char descriptor_length :8; -} descr_subtitling_t; -#define CastSubtitlingDescriptor(x) ((descr_subtitling_t *)(x)) - -#define ITEM_SUBTITLING_LEN 8 -typedef struct item_subtitling_struct { - u_char lang_code1 :8; - u_char lang_code2 :8; - u_char lang_code3 :8; - u_char subtitling_type :8; - u_char composition_page_id_hi :8; - u_char composition_page_id_lo :8; - u_char ancillary_page_id_hi :8; - u_char ancillary_page_id_lo :8; -} item_subtitling_t; -#define CastSubtitlingItem(x) ((item_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; - u_char frequency1 :8; - u_char frequency2 :8; - u_char frequency3 :8; - u_char frequency4 :8; -#if BYTE_ORDER == BIG_ENDIAN - u_char bandwidth :3; - u_char reserved1 :5; -#else - u_char reserved1 :5; - u_char bandwidth :3; -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_char constellation :2; - u_char hierarchy :3; - u_char code_rate_HP :3; -#else - u_char code_rate_HP :3; - u_char hierarchy :3; - u_char constellation :2; -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_char code_rate_LP :3; - u_char guard_interval :2; - u_char transmission_mode :2; - u_char other_frequency_flag :1; -#else - u_char other_frequency_flag :1; - u_char transmission_mode :2; - u_char guard_interval :2; - u_char code_rate_LP :3; -#endif - u_char reserver2 :8; - u_char reserver3 :8; - u_char reserver4 :8; - u_char reserver5 :8; -} 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 3 -typedef struct descr_ac3_struct { - u_char descriptor_tag :8; - u_char descriptor_length :8; -#if BYTE_ORDER == BIG_ENDIAN - u_char ac3_type_flag :1; - u_char bsid_flag :1; - u_char mainid_flag :1; - u_char asvc_flag :1; - u_char reserved :4; -#else - u_char reserved :4; - u_char asvc_flag :1; - u_char mainid_flag :1; - u_char bsid_flag :1; - u_char ac3_type_flag :1; -#endif - u_char ac3_type :8; - u_char bsid :8; - u_char mainid :8; - u_char asvc :8; -} 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)) - - diff --git a/libdtv/libsi/si_debug_services.c b/libdtv/libsi/si_debug_services.c deleted file mode 100644 index 1ff74000..00000000 --- a/libdtv/libsi/si_debug_services.c +++ /dev/null @@ -1,674 +0,0 @@ -////////////////////////////////////////////////////////////// -/// /// -/// si_debug_services.c: debugging functions for libsi /// -/// /// -////////////////////////////////////////////////////////////// - -// $Revision: 1.5 $ -// $Date: 2003/02/04 18:45:35 $ -// $Author: hakenes $ -// -// (C) 2001-03 Rolf Hakenes , under the -// GNU GPL with contribution of Oleg Assovski, -// www.satmania.com -// -// 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 - -#include "../liblx/liblx.h" -#include "libsi.h" -#include "si_tables.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); - sprintf (NewPrepend, "%s ", Prepend); - siDebugDescriptors (NewPrepend, Pid->Descriptors); - - 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_NW_NAME: - printf ("%sDescriptor: Network Name\n", Prepend); - printf ("%s Name: %s\n", Prepend, xName (Descriptor)); - 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", Prepend); - printf ("%s Description: %s\n", Prepend, xName(Item)); - printf ("%s Text: %s\n", Prepend, Item->Text); - } - } - break; - - case DESCR_CA_IDENT: - printf ("%sDescriptor: Conditional Access Identity\n", Prepend); - { - int j,k; - for (j = 0; j < ((struct CaIdentifierDescriptor *)Descriptor)->Amount; j++) - { - printf ("%s SystemID: 0x%04x", Prepend, GetCaIdentifierID (Descriptor, j)); - k = GetCaIdentifierID (Descriptor, j) >> 8; - if (k < 0 || k > MAX_CA_IDENT) printf (" (unknown)\n"); - else printf (" (%s)\n", CaIdents[k]); - } - } - break; - - case DESCR_CA: - { - int j,k; - - printf ("%sDescriptor: Conditional Access\n", Prepend); - printf ("%s CA type: 0x%04x", Prepend, (((struct CaDescriptor *)Descriptor)->CA_type)); - k = (((struct CaDescriptor *)Descriptor)->CA_type) >> 8; - if (k < 0 || k > MAX_CA_IDENT) printf (" (unknown)\n"); - else printf (" (%s)\n", CaIdents[k]); - printf ("%s CA PID: %d\n", Prepend, (((struct CaDescriptor *)Descriptor)->CA_PID)); - printf ("%s ProviderID: 0x%04X\n", Prepend, (((struct CaDescriptor *)Descriptor)->ProviderID)); - if (((struct CaDescriptor *)Descriptor)->DataLength > 0) - { - printf ("%s CA data:", Prepend); - for (j = 0; j < ((struct CaDescriptor *)Descriptor)->DataLength; j++) - printf (" 0x%02x", GetCaData (Descriptor, j)); - printf ("\n"); - } - } - 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_TELETEXT: - { - struct TeletextItem *Item; - - printf ("%sDescriptor: Teletext\n", Prepend); - xForeach (((struct TeletextDescriptor *)Descriptor)->Items, Item) - { - printf ("%s Item:\n"); - printf ("%s LanguageCode: %s\n", Prepend, Item->LanguageCode); - printf ("%s Type: ", Prepend); - switch (Item->Type) - { - case 0x01: printf ("initial Teletext page\n"); break; - case 0x02: printf ("Teletext subtitle page\n"); break; - case 0x03: printf ("additional information page\n"); break; - case 0x04: printf ("programme schedule page\n"); break; - case 0x05: printf ("Teletext subtitle page "); - printf ("for hearing impaired people\n"); break; - default: printf ("reserved for future use\n"); break; - } - printf ("%s MagazineNumber: %x\n", Prepend, Item->MagazineNumber); - printf ("%s PageNumber: %x\n", Prepend, Item->PageNumber); - } - } - break; - - case DESCR_SUBTITLING: - { - struct SubtitlingItem *Item; - - printf ("%sDescriptor: Subtitling\n", Prepend); - xForeach (((struct SubtitlingDescriptor *)Descriptor)->Items, Item) - { - printf ("%s Item:\n"); - printf ("%s LanguageCode: %s\n", Prepend, Item->LanguageCode); - printf ("%s Type: ", Prepend); - for (i = 0; i < COMPONENT_TYPE_NUMBER; i++) - if ((0x03 == ComponentTypes[i].Content) && - (Item->Type == ComponentTypes[i].Type)) - { printf ("%s\n", ComponentTypes[i].Description); break; } - printf ("%s CompositionPageId: %x\n", Prepend, Item->CompositionPageId); - printf ("%s AncillaryPageId: %x\n", Prepend, Item->AncillaryPageId); - } - } - break; - - case DESCR_SAT_DEL_SYS: - { - struct SatelliteDeliverySystemDescriptor *sds = - (struct SatelliteDeliverySystemDescriptor *)Descriptor; - - printf ("%sDescriptor: Satellite Delivery System\n", Prepend); - printf ("%s Frequency: %ld\n", Prepend, sds->Frequency); - printf ("%s OrbitalPosition: %d\n", Prepend, sds->OrbitalPosition); - printf ("%s Polarization: %c\n", Prepend, sds->Polarization); - printf ("%s Modulation: %c\n", Prepend, sds->Modulation); - printf ("%s SymbolRate: %ld\n", Prepend, sds->SymbolRate); - printf ("%s FEC: %c\n", Prepend, sds->FEC); - } - break; - - case DESCR_CABLE_DEL_SYS: - { - struct CableDeliverySystemDescriptor *cds = - (struct CableDeliverySystemDescriptor *)Descriptor; - - printf ("%sDescriptor: Cable Delivery System\n", Prepend); - printf ("%s Frequency: %ld\n", Prepend, cds->Frequency); - printf ("%s SymbolRate: %ld\n", Prepend, cds->SymbolRate); - printf ("%s FEC outer: %d\n", Prepend, cds->FECouter); - printf ("%s FEC inner: %d\n", Prepend, cds->FECinner); - printf ("%s Modulation: %d\n", Prepend, cds->Modulation); - } - break; - - case DESCR_TERR_DEL_SYS: - { - struct TerrestrialDeliverySystemDescriptor *tds = - (struct TerrestrialDeliverySystemDescriptor *)Descriptor; - - printf ("%sDescriptor: Terrestrial Delivery System\n", Prepend); - printf ("%s Frequency: %ld\n", Prepend, tds->Frequency); - printf ("%s Bandwidth: %d\n", Prepend, tds->Bandwidth); - printf ("%s Constellation: %d\n", Prepend, tds->Constellation); - printf ("%s Hierarchy: %d\n", Prepend, tds->Hierarchy); - printf ("%s CodeRateHP: %d\n", Prepend, tds->CodeRateHP); - printf ("%s CodeRateLP: %d\n", Prepend, tds->CodeRateLP); - printf ("%s GuardInterval: %d\n", Prepend, tds->GuardInterval); - printf ("%s TransmissionMode: %d\n", Prepend, tds->TransmissionMode); - printf ("%s OtherFrequencyFlag: %d\n", Prepend, tds->OtherFrequencyFlag); - } - break; - - case DESCR_SERVICE_LIST: - { - struct ServiceListEntry *Entry; - - printf ("%sDescriptor: Service List\n", Prepend); - xForeach (((struct ServiceListDescriptor *)Descriptor)->ServiceList, Entry) - { - printf ("%s Entry:\n"); - printf ("%s ServiceID: %d\n", Prepend, Entry->ServiceID); - printf ("%s ServiceType: %04x\n", Prepend, Entry->ServiceType); - } - } - break; - - case DESCR_LOCAL_TIME_OFF: - { - struct LocalTimeOffsetEntry *Offset; - - printf ("%sDescriptor: Local Time Offset\n", Prepend); - xForeach (((struct LocalTimeOffsetDescriptor *)Descriptor)->LocalTimeOffsets, Offset) - { - printf ("%s Offset:\n"); - printf ("%s CountryCode: %s\n", Offset->CountryCode); - printf ("%s RegionID: %c\n", Offset->RegionID); - printf ("%s CurrentOffset: %ld\n", Offset->CurrentOffset); - printf ("%s ChangeTime: %ld\n", Offset->ChangeTime); - printf ("%s NextOffset: %ld\n", Offset->NextOffset); - } - } - break; - - case DESCR_STUFFING: - case DESCR_VBI_DATA: - case DESCR_VBI_TELETEXT: - case DESCR_MOSAIC: - case DESCR_TELEPHONE: - 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: %02x (noch nicht unterstützt)\n", Prepend, DescriptorTag (Descriptor)); - break; - } - } - return; -} - -void siDumpDescriptor (void * Descriptor) -{ - int Length, i; - unsigned char *ptr; - - Length = GetDescriptorLength (Descriptor); - for (i = 0, ptr = (char*) Descriptor; i < Length; i++) { - if ((i % 8) == 0) - printf ("\n"); - printf ("0x%02X ", (unsigned int) ptr[i]); - } - printf ( "\n"); -} - -void siDumpSection (void *Section) -{ - int Length, i; - unsigned char *ptr; - char str[9]; - - Length = GetSectionLength (Section) + 3; - for (i = 0, ptr = (unsigned char*) Section, memset (str, 0, 9); i < Length; i++) { - if ((i % 8) == 0) - { - printf (" %s\n", str); - memset (str, 0, 8); - } - printf ("0x%02X ", (unsigned int) ptr[i]); - if (ptr[i] < 0x20 || (ptr[i] > 'z' && ptr[i] < ((unsigned char )'À')) ) - str[i % 8] = '.'; - else - str[i % 8] = ptr[i]; - } - printf (" %*s\n", (8 - ((abs(i - 1) % 8) ? (abs(i - 1) % 8) : 8)) * 5, str); -} - diff --git a/libdtv/libsi/si_debug_services.h b/libdtv/libsi/si_debug_services.h deleted file mode 100644 index 869c6d04..00000000 --- a/libdtv/libsi/si_debug_services.h +++ /dev/null @@ -1,245 +0,0 @@ -////////////////////////////////////////////////////////////// -/// /// -/// si_debug_services.h: local debugging definitions /// -/// /// -////////////////////////////////////////////////////////////// - -// $Revision: 1.2 $ -// $Date: 2003/04/12 11:27:31 $ -// $Author: hakenes $ -// -// (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[] = { - "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" -}; - -static char *CaIdents[] = { - "Standardized systems", - "Canal Plus", - "CCETT", - "Deutsche Telecom", - "Eurodec", - "France Telecom", - "Irdeto", - "Jerrold/GI", - "Matra Communication", - "News Datacom", - "Nokia", - "Norwegian Telekom", - "NTL", - "Philips", - "Scientific Atlanta", - "Sony", - "Tandberg Television", - "Thomson", - "TV/Com", - "HPT - Croatian Post and Telecommunications", - "HRT - Croatian Radio and Television", - "IBM", - "Nera", - "BetaTechnik" -}; -#define MAX_CA_IDENT 24 diff --git a/libdtv/libsi/si_parser.c b/libdtv/libsi/si_parser.c deleted file mode 100644 index 896c5ab9..00000000 --- a/libdtv/libsi/si_parser.c +++ /dev/null @@ -1,1335 +0,0 @@ -////////////////////////////////////////////////////////////// -/// /// -/// si_parser.c: main parsing functions of libsi /// -/// /// -////////////////////////////////////////////////////////////// - -// $Revision: 1.8 $ -// $Date: 2003/02/04 18:45:35 $ -// $Author: hakenes $ -// -// (C) 2001-03 Rolf Hakenes , under the -// GNU GPL with contribution of Oleg Assovski, -// www.satmania.com -// -// 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 - -#include "../liblx/liblx.h" -#include "libsi.h" -#include "si_tables.h" - -static u_long crc32 (char *data, int len); - -struct LIST *siParsePAT (u_char *Buffer) -{ - pat_t *Pat; - pat_prog_t *PatProgram; - u_char *Ptr; - 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 LIST *siParseCAT (u_char *Buffer) -{ - cat_t *Cat; - u_char *Ptr; - int SectionLength; - int TransportStreamID; - int CatVersion; - struct Descriptor *Descriptor; - struct LIST *DescriptorList = NULL; - - if (!Buffer) return NULL; - - Cat = (cat_t *) Buffer; Ptr = Buffer; - - if (Cat->table_id != TID_CAT) { - // fprintf (stderr, "CAT: wrong TID %d\n", Cat->table_id); - return NULL; - } - - SectionLength = HILO (Cat->section_length) + 3 - CAT_LEN - 4; - - if (crc32 (Ptr, HILO (Cat->section_length) + 3)) return (NULL); - - CatVersion = Cat->version_number; - - Ptr += CAT_LEN; - - if (SectionLength >= 0) - { - DescriptorList = xNewList (NULL); - siParseDescriptors (DescriptorList, Ptr, SectionLength, Cat->table_id); - } - - return (DescriptorList); -} - - -struct Pid *siParsePMT (u_char *Buffer) -{ - pmt_t *Pmt; - pmt_info_t *PmtInfo; - u_char *Ptr; - 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); - - if (StreamLength >= 0) 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 *siParseNIT (u_char *Buffer) -{ - nit_t *Nit; - nit_mid_t *NitMid; - nit_ts_t *TSDesc; - u_char *Ptr; - int SectionLength, LoopLength, Loop2Length; - int TransportStreamID; - int NitVersion; - int NetworkID; - struct TransportStream *TransportStream; - struct LIST *TSList = NULL; - struct LIST *Networks; - struct NetworkInfo *Network; - - if (!Buffer) return NULL; - - Nit = (nit_t *) Buffer; - Ptr = Buffer; - - if (Nit->table_id != TID_NIT_ACT && Nit->table_id != TID_NIT_OTH && Nit->table_id != TID_BAT) { - return NULL; - } - - SectionLength = HILO (Nit->section_length) + 3 - NIT_LEN - 4; - - if (crc32 (Ptr, HILO (Nit->section_length) + 3)) return (NULL); - - NitVersion = Nit->version_number; - NetworkID = HILO (Nit->network_id); - if (NetworkID == 65535) - NetworkID = 0; - CreateNetworkInfo (Network, NetworkID); - Networks = xNewList (NULL); - xAddTail (Networks, Network); - - Ptr += NIT_LEN; - - LoopLength = HILO (Nit->network_descriptor_length); -// fprintf (stderr, "table 0x%X, SectionLen = %d, LoopLen = %d\n", -// Nit->table_id, SectionLength, LoopLength); - if (LoopLength > SectionLength - SDT_DESCR_LEN) - return (Networks); - - if (LoopLength <= SectionLength) { - if (SectionLength >= 0) siParseDescriptors (Network->Descriptors, Ptr, LoopLength, Nit->table_id); - SectionLength -= LoopLength; - Ptr += LoopLength; - NitMid = (nit_mid_t *) Ptr; - LoopLength = HILO (NitMid->transport_stream_loop_length); -// fprintf (stderr, "table 0x%X, TS LoopLen = %d\n", -// Nit->table_id, LoopLength); - if ((SectionLength > 0) && (LoopLength <= SectionLength)) { - SectionLength -= SIZE_NIT_MID; - Ptr += SIZE_NIT_MID; - while (LoopLength > 0) { - TSDesc = (nit_ts_t *) Ptr; - CreateTransportStream (TransportStream, HILO(TSDesc->transport_stream_id), HILO(TSDesc->original_network_id)); - if (TransportStream->TransportStreamID == 65535) - TransportStream->TransportStreamID = 0; - if (TransportStream->OriginalNetworkID == 65535) - TransportStream->OriginalNetworkID = 0; - Loop2Length = HILO (TSDesc->transport_descriptors_length); -// fprintf (stderr, "table 0x%X, TSdesc LoopLen = %d\n", -// Nit->table_id, Loop2Length); - Ptr += NIT_TS_LEN; - if (Loop2Length <= LoopLength) { - if (LoopLength >= 0) siParseDescriptors (TransportStream->Descriptors, Ptr, Loop2Length, Nit->table_id); - } - if (!Network->TransportStreams) - Network->TransportStreams = xNewList (NULL); - xAddTail (Network->TransportStreams, TransportStream); - LoopLength -= Loop2Length + NIT_TS_LEN; - SectionLength -= Loop2Length + NIT_TS_LEN; - Ptr += Loop2Length; - } - } - } - - return (Networks); -} - - -struct LIST *siParseSDT (u_char *Buffer) -{ - sdt_t *Sdt; - sdt_descr_t *SdtDescriptor; - u_char *Ptr; - 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); - if (LoopLength > SectionLength - SDT_DESCR_LEN) - return (ServiceList); - 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; - 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); - if (LoopLength > SectionLength - EIT_EVENT_LEN) - return (EventList); - 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; - 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); -} - - -struct Tot *siParseTOT (u_char *Buffer) -{ - tot_t *Tot; - u_char *Ptr; - int SectionLength, LoopLength; - struct Tot *table; - time_t CurrentTime; - - if (!Buffer) return NULL; - - Tot = (tot_t *) Buffer; - Ptr = Buffer; - - if (Tot->table_id != TID_TOT) { - return NULL; - } - - if (crc32 (Ptr, HILO (Tot->section_length) + 3)) return (NULL); -// SectionLength = HILO (Tot->section_length) + 3 - TOT_LEN - 4; - - CurrentTime = MjdToEpochTime (Tot->utc_mjd) + - BcdTimeToSeconds (Tot->utc_time); - LoopLength = HILO (Tot->descriptors_loop_length); - if (!LoopLength) - return NULL; - - CreateTot (table, CurrentTime); - - Ptr += TOT_LEN; - - siParseDescriptors (table->Descriptors, Ptr, LoopLength, Tot->table_id); - - // fprintf (stderr, "TOT Bias: %d\n", table->Bias); - return (table); -} - -static u_char TempTableID = 0; - -void siParseDescriptors (struct LIST *Descriptors, u_char *Buffer, - int Length, u_char TableID) -{ - int DescriptorLength; - u_char *Ptr; - - DescriptorLength = 0; - Ptr = Buffer; - TempTableID = TableID; - - while (DescriptorLength < Length) - { - if ((GetDescriptorLength (Ptr) > Length - DescriptorLength) || - (GetDescriptorLength (Ptr) <= 0)) return; - switch (TableID) - { - case TID_NIT_ACT: case TID_NIT_OTH: - switch (GetDescriptorTag(Ptr)) - { - case DESCR_SAT_DEL_SYS: - case DESCR_CABLE_DEL_SYS: - case DESCR_SERVICE_LIST: - case DESCR_PRIV_DATA_SPEC: -// fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Ptr)); -// siDumpDescriptor (Ptr); - case DESCR_NW_NAME: - case DESCR_STUFFING: - case DESCR_LINKAGE: - case DESCR_TERR_DEL_SYS: - case DESCR_ML_NW_NAME: - 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: - // fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Ptr)); - 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; - - case TID_CAT: - switch (GetDescriptorTag(Ptr)) - { - case DESCR_CA_SYSTEM: - case DESCR_CA: - case DESCR_CA_IDENT: - siParseDescriptor (Descriptors, Ptr); - break; - - default: - // fprintf (stderr, "forbidden descriptor 0x%x in CAT\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; -// fprintf (stderr, "Got descriptor with tag = 0x%X\n", GetDescriptorTag(Buffer)); - - switch (GetDescriptorTag(Buffer)) - { - case DESCR_ANCILLARY_DATA: - CreateAncillaryDataDescriptor (Descriptor, - CastAncillaryDataDescriptor(Buffer)->ancillary_data_identifier); - break; - - case DESCR_NW_NAME: - case DESCR_BOUQUET_NAME: - Text = siGetDescriptorName (Buffer + DESCR_BOUQUET_NAME_LEN, - GetDescriptorLength (Buffer) - DESCR_BOUQUET_NAME_LEN); -// fprintf (stderr, "Got descriptor with tag = 0x%X, text = '%s'\n", GetDescriptorTag(Buffer), Text); - CreateBouquetNameDescriptor (Descriptor, Text, GetDescriptorTag(Buffer)); - 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); - break; - - case DESCR_SERVICE: - Text = siGetDescriptorName (Buffer + DESCR_SERVICE_LEN, - CastServiceDescriptor(Buffer)->provider_name_length); - Text2 = siGetDescriptorName (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); - 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 = siGetDescriptorName (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); - 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); - Length = CastExtendedEventDescriptor(Buffer)->length_of_items; - Ptr += DESCR_EXTENDED_EVENT_LEN; -// printf ("EEDesc #%d, %s\n", CastExtendedEventDescriptor(Buffer)->descriptor_number, Text); - while ((Length > 0) && (Length < GetDescriptorLength (Buffer))) - { - 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))); -// printf ("EEItem #%d, %s, %s\n", CastExtendedEventDescriptor(Buffer)->descriptor_number, Text, Text2); - AddExtendedEventItem (Descriptor, Text2, Text); - 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: - Length = GetDescriptorLength (Buffer) - DESCR_CA_IDENTIFIER_LEN; - CreateCaIdentifierDescriptor (Descriptor, Length / 2); - Ptr += DESCR_CA_IDENTIFIER_LEN; i = 0; - while (Length > 0) - { SetCaIdentifierID(Descriptor, i, ((*((u_char *) Ptr)<<8) + *((u_char *) (Ptr+1)))); - Length -= 2; Ptr += 2; i++; } - break; - - case DESCR_CA: - { - struct CaDescriptor *CD; - - Length = GetDescriptorLength (Buffer) - DESCR_CA_LEN; - CreateCaDescriptor (Descriptor, - HILO(CastCaDescriptor(Buffer)->CA_type), - HILO(CastCaDescriptor(Buffer)->CA_PID), Length); - Ptr += DESCR_CA_LEN; i = 0; - while (Length > 0) - { SetCaData(Descriptor, i, *Ptr); - Length --; Ptr ++; i++; } - - /* - * The following analyses are more or less directly copied from - * MultiDec 8.4b Sources. Thanx to Espresso for his great work !! - */ - CD = (struct CaDescriptor *) Descriptor; - - // fprintf (stderr, "TableID: %02x - CA - Type: 0x%04x, PID: %d\n", TempTableID, CD->CA_type, CD->CA_PID); - - if ((CD->CA_type >> 8) == 0x01) /* SECA */ - { - CD->ProviderID = (GetCaData (CD, 0) << 8) | GetCaData (CD, 1); - } - else if ((CD->CA_type >> 8) == 0x05) /* Viaccess ? (France Telecom) */ - { - i=0; - while (i < CD->DataLength) - { - if ((GetCaData (CD, i) == 0x14) && (GetCaData (CD, i+1) == 0x03)) - { - CD->ProviderID = (GetCaData (CD, i+2) << 16) | - (GetCaData (CD, i+3) << 8) | - (GetCaData (CD, i+4) & 0xf0); - i = CD->DataLength; - } - i++; - } - } - if (CD->CA_type==0x0100) /* SECA 1 */ - { - /* bptr=MyPtr+19; - - i=19; - while ( i+4 < ca_info->len ) { - if ( (*bptr&0xE0) == 0xE0 ) { - CA_ECM=(( *bptr&0x1f)<<8)+*(bptr+1); - Prov_Ident = ( *(bptr+2)<<8) | *(bptr+3); - j=0; - while ( j < ProgrammNeu[ProgrammNummer].CA_Anzahl ) { - if (( ProgrammNeu[ProgrammNummer].CA_System[j].CA_Typ == CA_Typ ) - && ( ProgrammNeu[ProgrammNummer].CA_System[j].ECM == CA_ECM )) break; - j++; - }; - - if ( j < MAX_CA_SYSTEMS ) { - if ( j >= ProgrammNeu[ProgrammNummer].CA_Anzahl ) - ProgrammNeu[ProgrammNummer].CA_Anzahl++; - ProgrammNeu[ProgrammNummer].CA_System[j].CA_Typ =CA_Typ; - ProgrammNeu[ProgrammNummer].CA_System[j].ECM =CA_ECM ; - ProgrammNeu[ProgrammNummer].CA_System[j].Provider_Id = Prov_Ident; - }; - } - i+=0x0f; - bptr+=0x0f; - }; */ - } - } - 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_TELETEXT: - CreateTeletextDescriptor (Descriptor); - Length = GetDescriptorLength (Buffer) - DESCR_TELETEXT_LEN; - Ptr += DESCR_TELETEXT_LEN; - while (Length > 0) - { - AddTeletextItem (Descriptor, - CastTeletextItem(Ptr)->type, - CastTeletextItem(Ptr)->magazine_number, - CastTeletextItem(Ptr)->page_number, - CastTeletextItem(Ptr)->lang_code1, - CastTeletextItem(Ptr)->lang_code2, - CastTeletextItem(Ptr)->lang_code3); - Length -= ITEM_TELETEXT_LEN; - Ptr += ITEM_TELETEXT_LEN; - } - break; - - case DESCR_AC3: - CreateAc3Descriptor (Descriptor); - Length = GetDescriptorLength (Buffer); - if (CastAc3Descriptor(Buffer)->ac3_type_flag) - { Length -= 1; Ptr += 1; AddAc3FlagAndValue (Descriptor, - AC3_TYPE_FLAG, CastAc3Descriptor(Buffer)->ac3_type); } - if (CastAc3Descriptor(Buffer)->bsid_flag) - { Length -= 1; Ptr += 1; AddAc3FlagAndValue (Descriptor, - BS_ID_FLAG, CastAc3Descriptor(Buffer)->bsid); } - if (CastAc3Descriptor(Buffer)->mainid_flag) - { Length -= 1; Ptr += 1; AddAc3FlagAndValue (Descriptor, - MAIN_ID_FLAG, CastAc3Descriptor(Buffer)->mainid); } - if (CastAc3Descriptor(Buffer)->asvc_flag) - { Length -= 1; Ptr += 1; AddAc3FlagAndValue (Descriptor, - ASVC_FLAG, CastAc3Descriptor(Buffer)->asvc); } - Length -= DESCR_AC3_LEN; - Ptr += DESCR_AC3_LEN; - if (Length > 0) AddAc3AdditionalData (Descriptor, Ptr, Length); - break; - - case DESCR_SUBTITLING: - CreateSubtitlingDescriptor (Descriptor); - Length = GetDescriptorLength (Buffer) - DESCR_SUBTITLING_LEN; - Ptr += DESCR_SUBTITLING_LEN; - while (Length > 0) - { - AddSubtitlingItem (Descriptor, - CastSubtitlingItem(Ptr)->subtitling_type, - HILO (CastSubtitlingItem(Ptr)->composition_page_id), - HILO (CastSubtitlingItem(Ptr)->ancillary_page_id), - CastSubtitlingItem(Ptr)->lang_code1, - CastSubtitlingItem(Ptr)->lang_code2, - CastSubtitlingItem(Ptr)->lang_code3); - Length -= ITEM_SUBTITLING_LEN; - Ptr += ITEM_SUBTITLING_LEN; - } - break; - - case DESCR_SAT_DEL_SYS: -// fprintf (stderr, "got descriptor 0x%x\n", GetDescriptorTag(Buffer)); - { - descr_satellite_delivery_system_t *sds; - sds = (descr_satellite_delivery_system_t *) Ptr; - if (CheckBcdChar (sds->frequency1) && CheckBcdChar (sds->frequency2) && - CheckBcdChar (sds->frequency3) && CheckBcdChar (sds->frequency4) && - CheckBcdChar (sds->orbital_position1) && - CheckBcdChar (sds->orbital_position2) && - CheckBcdChar (sds->symbol_rate1) && CheckBcdChar (sds->symbol_rate1) && - CheckBcdChar (sds->symbol_rate3) && (sds->fec_inner != 0) && (sds->modulation == 1)) - { - CreateSatelliteDeliverySystemDescriptor (Descriptor, - BcdCharToInt (sds->frequency1) * 10 * 1000 * 1000 + - BcdCharToInt (sds->frequency2) * 100 * 1000 + - BcdCharToInt (sds->frequency3) * 1000 + - BcdCharToInt (sds->frequency4) * 10, - (sds->west_east_flag ? 1 : -1) * - (BcdCharToInt (sds->orbital_position1) * 100 + - BcdCharToInt (sds->orbital_position2)), - sds->modulation, - sds->polarization, - BcdCharToInt (sds->symbol_rate1) * 10 * 1000 + - BcdCharToInt (sds->symbol_rate2) * 100 + - BcdCharToInt (sds->symbol_rate3), - sds->fec_inner); - } - /* else - { - fprintf (stderr, "Illegal sds descriptor\n"); - siDumpDescriptor (Buffer); - } */ - } - break; - - case DESCR_CABLE_DEL_SYS: -// fprintf (stderr, "got descriptor 0x%x\n", GetDescriptorTag(Buffer)); - { - descr_cable_delivery_system_t *cds; - cds = (descr_cable_delivery_system_t *) Ptr; - if (CheckBcdChar (cds->frequency1) && CheckBcdChar (cds->frequency2) && - CheckBcdChar (cds->frequency3) && CheckBcdChar (cds->frequency4) && - CheckBcdChar (cds->symbol_rate1) && CheckBcdChar (cds->symbol_rate1) && - CheckBcdChar (cds->symbol_rate3) && (cds->fec_inner != 0)) - { - CreateCableDeliverySystemDescriptor (Descriptor, - BcdCharToInt (cds->frequency1) * 100 * 1000 * 1000 + - BcdCharToInt (cds->frequency2) * 1000 * 1000 + - BcdCharToInt (cds->frequency3) * 10 * 1000 + - BcdCharToInt (cds->frequency4) * 100, - BcdCharToInt (cds->symbol_rate1) * 10 * 1000 + - BcdCharToInt (cds->symbol_rate2) * 100 + - BcdCharToInt (cds->symbol_rate3), - cds->fec_outer, - cds->fec_inner, - cds->modulation - ); - } - /* else - { - fprintf (stderr, "Illegal cds descriptor\n"); - siDumpDescriptor (Buffer); - } */ - } - break; - - case DESCR_TERR_DEL_SYS: -// fprintf (stderr, "got descriptor 0x%x\n", GetDescriptorTag(Buffer)); - { - descr_terrestrial_delivery_system_t *tds; - tds = (descr_terrestrial_delivery_system_t *) Ptr; - if (CheckBcdChar (tds->frequency1) && CheckBcdChar (tds->frequency2) && - CheckBcdChar (tds->frequency3) && CheckBcdChar (tds->frequency4)) - { - CreateTerrestrialDeliverySystemDescriptor (Descriptor, - BcdCharToInt (tds->frequency1) * 100 * 1000 * 1000 + - BcdCharToInt (tds->frequency2) * 1000 * 1000 + - BcdCharToInt (tds->frequency3) * 10 * 1000 + - BcdCharToInt (tds->frequency4) * 100, - tds->bandwidth, - tds->constellation, - tds->hierarchy, - tds->code_rate_HP, - tds->code_rate_LP, - tds->guard_interval, - tds->transmission_mode, - tds->other_frequency_flag - ); - } - /* else - { - fprintf (stderr, "Illegal cds descriptor\n"); - siDumpDescriptor (Buffer); - } */ - } - break; - - case DESCR_SERVICE_LIST: -// fprintf (stderr, "got descriptor 0x%x\n", GetDescriptorTag(Buffer)); - CreateServiceListDescriptor (Descriptor); - Length = GetDescriptorLength (Buffer) - DESCR_SERVICE_LIST_LEN; - Ptr += DESCR_SERVICE_LIST_LEN; - while (Length > 0) - { - AddServiceListEntry (Descriptor, - HILO (CastServiceListDescriptorLoop(Ptr)->service_id), - CastServiceListDescriptorLoop(Ptr)->service_type); - Length -= DESCR_SERVICE_LIST_LEN; - Ptr += DESCR_SERVICE_LIST_LEN; - } - break; - - case DESCR_LOCAL_TIME_OFF: - CreateLocalTimeOffsetDescriptor (Descriptor); - Length = GetDescriptorLength (Buffer) - DESCR_LOCAL_TIME_OFFSET_LEN; - Ptr += DESCR_LOCAL_TIME_OFFSET_LEN; - while (Length > 0) - { - time_t ct, co, no; - ct = MjdToEpochTime (CastLocalTimeOffsetEntry(Ptr)->time_of_change_mjd) + - BcdTimeToSeconds (CastLocalTimeOffsetEntry(Ptr)->time_of_change_time); - co = (BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->local_time_offset_h) * 3600 + - BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->local_time_offset_m) * 60) * - ((CastLocalTimeOffsetEntry(Ptr)->local_time_offset_polarity) ? -1 : 1); - no = (BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->next_time_offset_h) * 3600 + - BcdCharToInt(CastLocalTimeOffsetEntry(Ptr)->next_time_offset_m) * 60) * - ((CastLocalTimeOffsetEntry(Ptr)->local_time_offset_polarity) ? -1 : 1); - AddLocalTimeOffsetEntry (Descriptor, - CastLocalTimeOffsetEntry(Ptr)->country_code1, - CastLocalTimeOffsetEntry(Ptr)->country_code2, - CastLocalTimeOffsetEntry(Ptr)->country_code3, - CastLocalTimeOffsetEntry(Ptr)->country_region_id, co, ct, no); - Length -= LOCAL_TIME_OFFSET_ENTRY_LEN; - Ptr += LOCAL_TIME_OFFSET_ENTRY_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_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_VBI_DATA: - case DESCR_VBI_TELETEXT: - case DESCR_MOSAIC: - case DESCR_TELEPHONE: - 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_CELL_LIST: - case DESCR_CELL_FREQ_LINK: - case DESCR_ANNOUNCEMENT_SUPPORT: - default: -// fprintf (stderr, "Unsupported descriptor with tag = 0x%02X\n", GetDescriptorTag(Ptr)); -// siDumpDescriptor (Buffer); - /* fprintf (stderr, "unsupported descriptor 0x%x\n", - GetDescriptorTag(Buffer)); */ - break; - } - if (Descriptor) xAddTail (Descriptors, Descriptor); - return; -} - - -/* - * ToDo: ETSI conformal text definition - */ -#define GDT_TEXT_DESCRIPTOR 0 -#define GDT_NAME_DESCRIPTOR 1 -char *siGetDescriptorTextHandler (u_char *, int , int ); - -char *siGetDescriptorTextHandler (u_char *Buffer, int Length, int type) -{ - char *tmp, *result; - int i; - - if ((Length < 0) || (Length > 4095)) - return (xSetText ("text error")); -/* ASSENIZATION: removing coding detection - suppose they are all ANSI */ - // 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 == '\n') || - (*Buffer >= 0xa0)) *tmp++ = *Buffer; - if (*Buffer == 0x8A) *tmp++ = '\n'; - if ((*Buffer == 0x86 || *Buffer == 0x87) && !(GDT_NAME_DESCRIPTOR & type)) *tmp++ = ' '; - 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); -} - -char *siGetDescriptorText (u_char *Buffer, int Length) -{ - return siGetDescriptorTextHandler (Buffer, Length, GDT_TEXT_DESCRIPTOR); -} - -char *siGetDescriptorName (u_char *Buffer, int Length) -{ - return siGetDescriptorTextHandler (Buffer, Length, GDT_NAME_DESCRIPTOR); -} - - -// 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}; - -static 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 deleted file mode 100644 index a43ea212..00000000 --- a/libdtv/libvdr/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - 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 deleted file mode 100644 index 6eebedd4..00000000 --- a/libdtv/libvdr/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -############################################################## -### ### -### Makefile: local makefile for libvdr ### -### ### -############################################################## - -## $Revision: 1.3 $ -## $Date: 2001/10/06 15:33:46 $ -## $Author: hakenes $ -## -## (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__ # -DDEBUG - -CFLAGS += -I../include - -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 deleted file mode 100644 index 5f901258..00000000 --- a/libdtv/libvdr/libvdr.c +++ /dev/null @@ -1,157 +0,0 @@ -////////////////////////////////////////////////////////////// -/// /// -/// libvdr.c: routines to parse the DVB-SI stream /// -/// /// -////////////////////////////////////////////////////////////// - -// $Revision: 1.1 $ -// $Date: 2001/10/07 10:25:33 $ -// $Author: hakenes $ -// -// (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; - int GotVdrProgramInfo; - - if (!siBuffer) return (NULL); - - if (!(EventList = siParseEIT (siBuffer))) return (NULL); - - Result = xNewList (NULL); - - xForeach (EventList, Event) - { - VdrProgramInfo = NULL; - GotVdrProgramInfo = 0; - - xForeach (Event->Descriptors, Descriptor) - { - if (!VdrProgramInfo) - { - CreateVdrProgramInfo(VdrProgramInfo, - Event->EventID, Event->TransportStreamID, - Event->ServiceID, Event->StartTime, - Event->Duration, Event->Status); - } - - switch (Descriptor->Tag) - { - case DESCR_SHORT_EVENT: - { - if (!xName(Descriptor) || !xName(Descriptor)[0]) - break; - - VdrProgramInfo->ShortName = - xSetText (xName (Descriptor)); - VdrProgramInfo->ShortText = - xSetText (((struct ShortEventDescriptor - *)Descriptor)->Text); - memcpy (VdrProgramInfo->LanguageCode, ((struct - ShortEventDescriptor *)Descriptor)-> - LanguageCode, 4); - GotVdrProgramInfo = 1; - } - break; - - case DESCR_TIME_SHIFTED_EVENT: - { - struct tm *StartTime; - - VdrProgramInfo->ReferenceServiceID = - ((struct TimeShiftedEventDescriptor - *)Descriptor)->ReferenceServiceID; - VdrProgramInfo->ReferenceEventID = - ((struct TimeShiftedEventDescriptor - *)Descriptor)->ReferenceEventID; - GotVdrProgramInfo = 1; - } - break; - - case DESCR_EXTENDED_EVENT: - { - struct ExtendedEventItem *Item; - - 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; - - 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; - - xForeach (((struct ParentalRatingDescriptor *) - Descriptor)->Ratings, Rating) - if (!strncmp (VdrProgramInfo->LanguageCode, - Rating->LanguageCode, 3)) - VdrProgramInfo->Rating = Rating->Rating; - } - break; - } - } - if (GotVdrProgramInfo) xAddTail (Result, VdrProgramInfo); - else xMemFree (VdrProgramInfo); - } - - return (Result); -} diff --git a/libdtv/libvdr/libvdr.h b/libdtv/libvdr/libvdr.h deleted file mode 100644 index 421b2e71..00000000 --- a/libdtv/libvdr/libvdr.h +++ /dev/null @@ -1,111 +0,0 @@ -////////////////////////////////////////////////////////////// -/// /// -/// libvdr.h: definitions necessary for the libvdr package /// -/// /// -////////////////////////////////////////////////////////////// - -// $Revision: 1.4 $ -// $Date: 2001/10/06 15:33:46 $ -// $Author: hakenes $ -// -// (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 ee2b6936..16f2893a 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.274 2003/10/19 15:13:05 kls Exp $ + * $Id: menu.c 1.275 2003/12/22 10:05:14 kls Exp $ */ #include "menu.h" @@ -16,7 +16,6 @@ #include "channels.h" #include "config.h" #include "cutter.h" -#include "eit.h" #include "i18n.h" #include "menuitems.h" #include "plugin.h" @@ -69,7 +68,7 @@ eOSState cMenuEditChanItem::ProcessKey(eKeys Key) case kLeft|k_Repeat: case kLeft: delta = -1; case kRight|k_Repeat: - case kRight: + case kRight: { cChannel *channel = Channels.GetByNumber(*value + delta, delta); if (channel) { @@ -458,7 +457,7 @@ eOSState cMenuEditSrcItem::ProcessKey(eKeys Key) } } else if (NORMALKEY(Key) == kRight) { - if (source) { + if (source) { if (source->Next()) source = (cSource *)source->Next(); } @@ -904,7 +903,7 @@ eOSState cMenuEditTimer::ProcessKey(eKeys Key) if (state == osUnknown) { switch (Key) { - case kOk: { + case kOk: { cChannel *ch = Channels.GetByNumber(channel); if (ch) data.channel = ch; @@ -1128,29 +1127,29 @@ eOSState cMenuTimers::ProcessKey(eKeys Key) class cMenuEvent : public cOsdMenu { private: - const cEventInfo *eventInfo; + const cEvent *event; public: - cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch = false); + cMenuEvent(const cEvent *Event, bool CanSwitch = false); cMenuEvent(bool Now); virtual eOSState ProcessKey(eKeys Key); }; -cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch) +cMenuEvent::cMenuEvent(const cEvent *Event, bool CanSwitch) :cOsdMenu(tr("Event")) { - eventInfo = EventInfo; - if (eventInfo) { - cChannel *channel = Channels.GetByChannelID(eventInfo->GetChannelID(), true); + event = Event; + if (event) { + cChannel *channel = Channels.GetByChannelID(event->ChannelID(), true); if (channel) { char *buffer; - asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->Name(), 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString()); + asprintf(&buffer, "%-17.*s\t%.*s %s - %s", 17, channel->Name(), 5, event->GetDateString(), event->GetTimeString(), event->GetEndTimeString()); SetTitle(buffer, false); free(buffer); int Line = 2; cMenuTextItem *item; - const char *Title = eventInfo->GetTitle(); - const char *Subtitle = eventInfo->GetSubtitle(); - const char *ExtendedDescription = eventInfo->GetExtendedDescription(); + const char *Title = event->Title(); + const char *Subtitle = event->ShortText(); + const char *ExtendedDescription = event->Description(); if (!isempty(Title)) { Add(item = new cMenuTextItem(Title, 1, Line, Setup.OSDwidth - 2, -1, clrCyan)); Line += item->Height() + 1; @@ -1185,16 +1184,16 @@ eOSState cMenuEvent::ProcessKey(eKeys Key) class cMenuWhatsOnItem : public cOsdItem { public: - const cEventInfo *eventInfo; - cMenuWhatsOnItem(const cEventInfo *EventInfo); + const cEvent *event; + cMenuWhatsOnItem(const cEvent *Event); }; -cMenuWhatsOnItem::cMenuWhatsOnItem(const cEventInfo *EventInfo) +cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event) { - eventInfo = EventInfo; + event = Event; char *buffer = NULL; - cChannel *channel = Channels.GetByNumber(eventInfo->GetChannelNumber()); - asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", eventInfo->GetChannelNumber(), 6, channel ? channel->Name() : "???", 5, eventInfo->GetTimeString(), eventInfo->GetTitle()); + cChannel *channel = Channels.GetByNumber(event->ChannelNumber()); + asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", event->ChannelNumber(), 6, channel ? channel->Name() : "???", 5, event->GetTimeString(), event->Title()); SetText(buffer, false); } @@ -1205,36 +1204,36 @@ private: eOSState Record(void); eOSState Switch(void); static int currentChannel; - static const cEventInfo *scheduleEventInfo; + static const cEvent *scheduleEvent; public: cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr); static int CurrentChannel(void) { return currentChannel; } static void SetCurrentChannel(int ChannelNr) { currentChannel = ChannelNr; } - static const cEventInfo *ScheduleEventInfo(void); + static const cEvent *ScheduleEvent(void); virtual eOSState ProcessKey(eKeys Key); }; int cMenuWhatsOn::currentChannel = 0; -const cEventInfo *cMenuWhatsOn::scheduleEventInfo = NULL; +const cEvent *cMenuWhatsOn::scheduleEvent = NULL; static int CompareEventChannel(const void *p1, const void *p2) { - return (int)( (*(const cEventInfo **)p1)->GetChannelNumber() - (*(const cEventInfo **)p2)->GetChannelNumber()); + return (int)( (*(const cEvent **)p1)->ChannelNumber() - (*(const cEvent **)p2)->ChannelNumber()); } cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr) :cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6) { const cSchedule *Schedule = Schedules->First(); - const cEventInfo **pArray = NULL; + const cEvent **pArray = NULL; int num = 0; while (Schedule) { - pArray = (const cEventInfo **)realloc(pArray, (num + 1) * sizeof(cEventInfo *)); + pArray = (const cEvent **)realloc(pArray, (num + 1) * sizeof(cEvent *)); pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent(); if (pArray[num]) { - cChannel *channel = Channels.GetByChannelID(pArray[num]->GetChannelID(), true); + cChannel *channel = Channels.GetByChannelID(pArray[num]->ChannelID(), true); if (channel) { pArray[num]->SetChannelNumber(channel->Number()); num++; @@ -1243,20 +1242,20 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha Schedule = (const cSchedule *)Schedules->Next(Schedule); } - qsort(pArray, num, sizeof(cEventInfo *), CompareEventChannel); + qsort(pArray, num, sizeof(cEvent *), CompareEventChannel); for (int a = 0; a < num; a++) - Add(new cMenuWhatsOnItem(pArray[a]), pArray[a]->GetChannelNumber() == CurrentChannelNr); + Add(new cMenuWhatsOnItem(pArray[a]), pArray[a]->ChannelNumber() == CurrentChannelNr); currentChannel = CurrentChannelNr; free(pArray); SetHelp(Count() ? tr("Record") : NULL, Now ? tr("Next") : tr("Now"), tr("Button$Schedule"), tr("Switch")); } -const cEventInfo *cMenuWhatsOn::ScheduleEventInfo(void) +const cEvent *cMenuWhatsOn::ScheduleEvent(void) { - const cEventInfo *ei = scheduleEventInfo; - scheduleEventInfo = NULL; + const cEvent *ei = scheduleEvent; + scheduleEvent = NULL; return ei; } @@ -1264,7 +1263,7 @@ eOSState cMenuWhatsOn::Switch(void) { cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current()); if (item) { - cChannel *channel = Channels.GetByChannelID(item->eventInfo->GetChannelID(), true); + cChannel *channel = Channels.GetByChannelID(item->event->ChannelID(), true); if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true)) return osEnd; } @@ -1276,7 +1275,7 @@ eOSState cMenuWhatsOn::Record(void) { cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current()); if (item) { - cTimer *timer = new cTimer(item->eventInfo); + cTimer *timer = new cTimer(item->event); cTimer *t = Timers.GetTimer(timer); if (t) { delete timer; @@ -1300,14 +1299,14 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key) case kGreen: { cMenuWhatsOnItem *mi = (cMenuWhatsOnItem *)Get(Current()); if (mi) { - scheduleEventInfo = mi->eventInfo; - currentChannel = mi->eventInfo->GetChannelNumber(); + scheduleEvent = mi->event; + currentChannel = mi->event->ChannelNumber(); } } break; case kBlue: return Switch(); case kOk: if (Count()) - return AddSubMenu(new cMenuEvent(((cMenuWhatsOnItem *)Get(Current()))->eventInfo, true)); + return AddSubMenu(new cMenuEvent(((cMenuWhatsOnItem *)Get(Current()))->event, true)); break; default: break; } @@ -1319,15 +1318,15 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key) class cMenuScheduleItem : public cOsdItem { public: - const cEventInfo *eventInfo; - cMenuScheduleItem(const cEventInfo *EventInfo); + const cEvent *event; + cMenuScheduleItem(const cEvent *Event); }; -cMenuScheduleItem::cMenuScheduleItem(const cEventInfo *EventInfo) +cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event) { - eventInfo = EventInfo; + event = Event; char *buffer = NULL; - asprintf(&buffer, "%.*s\t%.*s\t%s", 5, eventInfo->GetDate(), 5, eventInfo->GetTimeString(), eventInfo->GetTitle()); + asprintf(&buffer, "%.*s\t%.*s\t%s", 5, event->GetDateString(), 5, event->GetTimeString(), event->Title()); SetText(buffer, false); } @@ -1335,7 +1334,7 @@ cMenuScheduleItem::cMenuScheduleItem(const cEventInfo *EventInfo) class cMenuSchedule : public cOsdMenu { private: - cMutexLock mutexLock; + cSchedulesLock schedulesLock; const cSchedules *schedules; bool now, next; int otherChannel; @@ -1356,7 +1355,7 @@ cMenuSchedule::cMenuSchedule(void) cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); if (channel) { cMenuWhatsOn::SetCurrentChannel(channel->Number()); - schedules = cSIProcessor::Schedules(mutexLock); + schedules = cSchedules::Schedules(schedulesLock); PrepareSchedule(channel); SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next")); } @@ -1364,12 +1363,12 @@ cMenuSchedule::cMenuSchedule(void) cMenuSchedule::~cMenuSchedule() { - cMenuWhatsOn::ScheduleEventInfo(); // makes sure any posted data is cleared + cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared } static int CompareEventTime(const void *p1, const void *p2) { - return (int)((*(cEventInfo **)p1)->GetTime() - (*(cEventInfo **)p2)->GetTime()); + return (int)((*(cEvent **)p1)->StartTime() - (*(cEvent **)p2)->StartTime()); } void cMenuSchedule::PrepareSchedule(cChannel *Channel) @@ -1382,17 +1381,17 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel) if (schedules) { const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID()); int num = Schedule->NumEvents(); - const cEventInfo **pArray = MALLOC(const cEventInfo *, num); + const cEvent **pArray = MALLOC(const cEvent *, num); if (pArray) { time_t now = time(NULL); int numreal = 0; for (int a = 0; a < num; a++) { - const cEventInfo *EventInfo = Schedule->GetEventNumber(a); - if (EventInfo->GetTime() + EventInfo->GetDuration() > now) - pArray[numreal++] = EventInfo; + const cEvent *Event = Schedule->GetEventNumber(a); + if (Event->StartTime() + Event->Duration() > now) + pArray[numreal++] = Event; } - qsort(pArray, numreal, sizeof(cEventInfo *), CompareEventTime); + qsort(pArray, numreal, sizeof(cEvent *), CompareEventTime); for (int a = 0; a < numreal; a++) Add(new cMenuScheduleItem(pArray[a])); @@ -1405,7 +1404,7 @@ eOSState cMenuSchedule::Record(void) { cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current()); if (item) { - cTimer *timer = new cTimer(item->eventInfo); + cTimer *timer = new cTimer(item->event); cTimer *t = Timers.GetTimer(timer); if (t) { delete timer; @@ -1438,7 +1437,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) if (!now && !next) { int ChannelNr = 0; if (Count()) { - cChannel *channel = Channels.GetByChannelID(((cMenuScheduleItem *)Get(Current()))->eventInfo->GetChannelID(), true); + cChannel *channel = Channels.GetByChannelID(((cMenuScheduleItem *)Get(Current()))->event->ChannelID(), true); if (channel) ChannelNr = channel->Number(); } @@ -1456,16 +1455,16 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) return Switch(); break; case kOk: if (Count()) - return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->eventInfo, otherChannel)); + return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->event, otherChannel)); break; default: break; } } else if (!HasSubMenu()) { now = next = false; - const cEventInfo *ei = cMenuWhatsOn::ScheduleEventInfo(); + const cEvent *ei = cMenuWhatsOn::ScheduleEvent(); if (ei) { - cChannel *channel = Channels.GetByChannelID(ei->GetChannelID(), true); + cChannel *channel = Channels.GetByChannelID(ei->ChannelID(), true); if (channel) { PrepareSchedule(channel); if (channel->Number() != cDevice::CurrentChannel()) { @@ -2633,10 +2632,10 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched) int EpgLines = withInfo ? 5 : 1; lines = 0; number = 0; - cChannel *channel = Channels.GetByNumber(Number); + channel = Channels.GetByNumber(Number); Interface->Open(Setup.OSDwidth, Setup.ChannelInfoPos ? EpgLines : -EpgLines); if (channel) { - DisplayChannel(channel); + DisplayChannel(); DisplayInfo(); } lastTime = time_ms(); @@ -2660,16 +2659,16 @@ cDisplayChannel::~cDisplayChannel() Interface->Close(); } -void cDisplayChannel::DisplayChannel(const cChannel *Channel) +void cDisplayChannel::DisplayChannel(void) { int BufSize = Width() + 1; char buffer[BufSize]; *buffer = 0; - if (Channel) { - if (Channel->GroupSep()) - snprintf(buffer, BufSize, "%s", Channel->Name()); + if (channel) { + if (channel->GroupSep()) + snprintf(buffer, BufSize, "%s", channel->Name()); else - snprintf(buffer, BufSize, "%d%s %s", Channel->Number(), number ? "-" : "", Channel->Name()); + snprintf(buffer, BufSize, "%d%s %s", channel->Number(), number ? "-" : "", channel->Name()); } else if (number) snprintf(buffer, BufSize, "%d-", number); @@ -2684,28 +2683,28 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel) void cDisplayChannel::DisplayInfo(void) { - if (withInfo) { - const cEventInfo *Present = NULL, *Following = NULL; - cMutexLock MutexLock; - const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock); + if (withInfo && channel) { + const cEvent *Present = NULL, *Following = NULL; + cSchedulesLock SchedulesLock; + const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - const cSchedule *Schedule = Schedules->GetSchedule(); + const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); if (Schedule) { const char *PresentTitle = NULL, *PresentSubtitle = NULL, *FollowingTitle = NULL, *FollowingSubtitle = NULL; int Lines = 0; if ((Present = Schedule->GetPresentEvent()) != NULL) { - PresentTitle = Present->GetTitle(); + PresentTitle = Present->Title(); if (!isempty(PresentTitle)) Lines++; - PresentSubtitle = Present->GetSubtitle(); + PresentSubtitle = Present->ShortText(); if (!isempty(PresentSubtitle)) Lines++; } if ((Following = Schedule->GetFollowingEvent()) != NULL) { - FollowingTitle = Following->GetTitle(); + FollowingTitle = Following->Title(); if (!isempty(FollowingTitle)) Lines++; - FollowingSubtitle = Following->GetSubtitle(); + FollowingSubtitle = Following->ShortText(); if (!isempty(FollowingSubtitle)) Lines++; } @@ -2733,7 +2732,7 @@ void cDisplayChannel::DisplayInfo(void) Interface->Flush(); lines = Lines; lastTime = time_ms(); - cStatus::MsgOsdProgramme(Present ? Present->GetTime() : 0, PresentTitle, PresentSubtitle, Following ? Following->GetTime() : 0, FollowingTitle, FollowingSubtitle); + cStatus::MsgOsdProgramme(Present ? Present->StartTime() : 0, PresentTitle, PresentSubtitle, Following ? Following->StartTime() : 0, FollowingTitle, FollowingSubtitle); } } } @@ -2743,7 +2742,8 @@ void cDisplayChannel::DisplayInfo(void) void cDisplayChannel::Refresh(void) { Interface->Clear(); - DisplayChannel(Channels.GetByNumber(cDevice::CurrentChannel())); + channel = Channels.GetByNumber(cDevice::CurrentChannel()); + DisplayChannel(); lastTime = time_ms(); lines = 0; } @@ -2761,20 +2761,21 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) if (number >= 0) { number = number * 10 + Key - k0; if (number > 0) { - cChannel *channel = Channels.GetByNumber(number); + channel = Channels.GetByNumber(number); Interface->Clear(); withInfo = false; - DisplayChannel(channel); + DisplayChannel(); lastTime = time_ms(); // Lets see if there can be any useful further input: int n = channel ? number * 10 : 0; - while (channel && (channel = Channels.Next(channel)) != NULL) { - if (!channel->GroupSep()) { - if (n <= channel->Number() && channel->Number() <= n + 9) { + cChannel *ch = channel; + while (ch && (ch = Channels.Next(ch)) != NULL) { + if (!ch->GroupSep()) { + if (n <= ch->Number() && ch->Number() <= n + 9) { n = 0; break; } - if (channel->Number() > n) + if (ch->Number() > n) n *= 10; } } @@ -2805,10 +2806,10 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) group = Channels.GetPrevGroup(group < 1 ? 1 : group); if (group < 0) group = SaveGroup; - cChannel *channel = Channels.Get(group); + channel = Channels.Get(group); if (channel) { Interface->Clear(); - DisplayChannel(channel); + DisplayChannel(); if (!channel->GroupSep()) group = -1; } @@ -2835,7 +2836,8 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) Channels.SwitchTo(number); else { number = 0; - DisplayChannel(NULL); + channel = NULL; + DisplayChannel(); lastTime = time_ms(); return osContinue; } @@ -2967,7 +2969,7 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key) cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) { - eventInfo = NULL; + event = NULL; instantId = NULL; fileName = NULL; recorder = NULL; @@ -2986,10 +2988,10 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) const char *Title = NULL; const char *Subtitle = NULL; const char *Summary = NULL; - if (GetEventInfo()) { - Title = eventInfo->GetTitle(); - Subtitle = eventInfo->GetSubtitle(); - Summary = eventInfo->GetExtendedDescription(); + if (GetEvent()) { + Title = event->Title(); + Subtitle = event->ShortText(); + Summary = event->Description(); dsyslog("Title: '%s' Subtitle: '%s'", Title, Subtitle); } cRecording Recording(timer, Title, Subtitle, Summary); @@ -3038,19 +3040,19 @@ cRecordControl::~cRecordControl() #define INSTANT_REC_EPG_LOOKAHEAD 300 // seconds to look into the EPG data for an instant recording -bool cRecordControl::GetEventInfo(void) +bool cRecordControl::GetEvent(void) { const cChannel *channel = timer->Channel(); time_t Time = timer->Active() == taActInst ? timer->StartTime() + INSTANT_REC_EPG_LOOKAHEAD : timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2; for (int seconds = 0; seconds <= MAXWAIT4EPGINFO; seconds++) { { - cMutexLock MutexLock; - const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock); + cSchedulesLock SchedulesLock; + const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID()); if (Schedule) { - eventInfo = Schedule->GetEventAround(Time); - if (eventInfo) { + event = Schedule->GetEventAround(Time); + if (event) { if (seconds > 0) dsyslog("got EPG info after %d seconds", seconds); return true; diff --git a/menu.h b/menu.h index e304ea31..ddab9863 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.57 2003/08/03 09:37:18 kls Exp $ + * $Id: menu.h 1.58 2003/12/21 15:27:07 kls Exp $ */ #ifndef __MENU_H @@ -12,6 +12,7 @@ #include "ci.h" #include "device.h" +#include "epg.h" #include "osd.h" #include "dvbplayer.h" #include "recorder.h" @@ -36,7 +37,8 @@ private: int lines; int lastTime; int number; - void DisplayChannel(const cChannel *Channel); + cChannel *channel; + void DisplayChannel(void); void DisplayInfo(void); void Refresh(void); public: @@ -113,10 +115,10 @@ private: cDevice *device; cTimer *timer; cRecorder *recorder; - const cEventInfo *eventInfo; + const cEvent *event; char *instantId; char *fileName; - bool GetEventInfo(void); + bool GetEvent(void); public: cRecordControl(cDevice *Device, cTimer *Timer = NULL, bool Pause = false); virtual ~cRecordControl(); @@ -151,7 +153,7 @@ private: bool visible, modeOnly, shown, displayFrames; int lastCurrent, lastTotal; time_t timeoutShow; - bool timeSearchActive, timeSearchHide; + bool timeSearchActive, timeSearchHide; int timeSearchTime, timeSearchPos; void TimeSearchDisplay(void); void TimeSearchProcess(eKeys Key); diff --git a/newplugin b/newplugin index e4742663..8adae35f 100755 --- a/newplugin +++ b/newplugin @@ -12,7 +12,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: newplugin 1.15 2003/05/09 14:59:28 kls Exp $ +# $Id: newplugin 1.16 2003/12/21 15:45:18 kls Exp $ $PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin \n"; @@ -97,7 +97,7 @@ PACKAGE = vdr-\$(ARCHIVE) INCLUDES += -I\$(VDRDIR)/include -I\$(DVBDIR)/include -DEFINES += -DPLUGIN_NAME_I18N='"\$(PLUGIN)"' +DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"\$(PLUGIN)"' ### The object files (add further files here): diff --git a/pat.c b/pat.c new file mode 100644 index 00000000..3809a7cf --- /dev/null +++ b/pat.c @@ -0,0 +1,219 @@ +/* + * pat.c: PAT section filter + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: pat.c 1.1 2003/12/21 15:28:28 kls Exp $ + */ + +#include "pat.h" +#include +#include "libsi/section.h" +#include "libsi/descriptor.h" + +#define PMT_SCAN_TIMEOUT 10 // seconds + +// --- cCaDescriptor --------------------------------------------------------- + +class cCaDescriptor : public cListObject { + friend class cCaDescriptors; +private: + int source; + int transponder; + int serviceId; + int caSystem; + int providerId; + int caPid; + int length; + uchar *data; +public: + cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int ProviderId, int CaPid, int Length, const uchar *Data); + virtual ~cCaDescriptor(); + int Length(void) const { return length; } + const uchar *Data(void) const { return data; } + }; + +cCaDescriptor::cCaDescriptor(int Source, int Transponder, int ServiceId, int CaSystem, int ProviderId, int CaPid, int Length, const uchar *Data) +{ + source = Source; + transponder = Transponder; + serviceId = ServiceId; + caSystem = CaSystem; + providerId = ProviderId; + caPid = CaPid; + length = Length + 6; + data = MALLOC(uchar, length); + data[0] = SI::CaDescriptorTag; + data[1] = length - 2; + data[2] = (caSystem >> 8) & 0xFF; + data[3] = caSystem & 0xFF; + data[4] = ((CaPid >> 8) & 0x1F) | 0xE0; + data[5] = CaPid & 0xFF; + if (Length) + memcpy(&data[6], Data, Length); +//#define DEBUG_CA_DESCRIPTORS 1 +#ifdef DEBUG_CA_DESCRIPTORS + char buffer[1024]; + char *q = buffer; + q += sprintf(q, "CAM: %04X %5d %5d %04X %6X %04X -", source, transponder, serviceId, caSystem, providerId, caPid); + for (int i = 0; i < length; i++) + q += sprintf(q, " %02X", data[i]); + dsyslog(buffer); +#endif +} + +cCaDescriptor::~cCaDescriptor() +{ + free(data); +} + +// --- cCaDescriptors -------------------------------------------------------- + +class cCaDescriptors : public cList { +private: + cMutex mutex; +public: + void NewCaDescriptor(int Source, int Transponder, int ServiceId, SI::CaDescriptor *d); + int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data); + }; + +void cCaDescriptors::NewCaDescriptor(int Source, int Transponder, int ServiceId, SI::CaDescriptor *d) +{ + // The code for determining the ProviderID was taken from 'libdtv' + // written by Rolf Hakenes . + + const uchar *Data = d->privateData.getData(); + int Length = d->privateData.getLength(); + int ProviderID = 0; + + switch (d->getCaType() >> 8) { + case 0x01: // SECA + ProviderID = (Data[0] << 8) | Data[1]; + break; + case 0x05: // Viaccess ? (France Telecom) + for (int i = 0; i < Length; i++) { + if (Data[i] == 0x14 && Data[i + 1] == 0x03) { + ProviderID = (Data[i + 2] << 16) | + (Data[i + 3] << 8) | + (Data[i + 4] & 0xf0); + break; + } + } + break; + } + + cMutexLock MutexLock(&mutex); + for (cCaDescriptor *ca = First(); ca; ca = Next(ca)) { + if (ca->source == Source && ca->transponder == Transponder && ca->serviceId == ServiceId && ca->caSystem == d->getCaType() && ca->providerId == ProviderID && ca->caPid == d->getCaPid()) + return; + } + Add(new cCaDescriptor(Source, Transponder, ServiceId, d->getCaType(), ProviderID, d->getCaPid(), Length, Data)); + //XXX update??? +} + +int cCaDescriptors::GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data) +{ + if (!CaSystemIds || !*CaSystemIds) + return 0; + if (BufSize > 0 && Data) { + cMutexLock MutexLock(&mutex); + int length = 0; + for (cCaDescriptor *d = First(); d; d = Next(d)) { + if (d->source == Source && d->transponder == Transponder && d->serviceId == ServiceId) { + const unsigned short *caids = CaSystemIds; + do { + if (d->caSystem == *caids) { + if (length + d->Length() <= BufSize) { + memcpy(Data + length, d->Data(), d->Length()); + length += d->Length(); + } + else + return -1; + } + } while (*++caids); + } + } + return length; + } + return -1; +} + +cCaDescriptors CaDescriptors; + +int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data) +{ + return CaDescriptors.GetCaDescriptors(Source, Transponder, ServiceId, CaSystemIds, BufSize, Data); +} + +// --- cPatFilter ------------------------------------------------------------ + +cPatFilter::cPatFilter(void) +{ + pmtIndex = 0; + pmtPid = 0; + lastPmtScan = 0; + Set(0x00, 0x00); // PAT +} + +void cPatFilter::SetStatus(bool On) +{ + cFilter::SetStatus(On); + pmtIndex = 0; + pmtPid = 0; + lastPmtScan = 0; +} + +void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) +{ + if (Pid == 0x00) { + if (Tid == 0x00) { + if (pmtPid && time(NULL) - lastPmtScan > PMT_SCAN_TIMEOUT) { + Del(pmtPid, 0x02); + pmtPid = 0; + pmtIndex++; + lastPmtScan = time(NULL); + } + if (!pmtPid) { + SI::PAT pat(Data, false); + if (!pat.CheckCRCAndParse()) + return; + SI::PAT::Association assoc; + int Index = 0; + for (SI::Loop::Iterator it; pat.associationLoop.hasNext(it); ) { + assoc = pat.associationLoop.getNext(it); + if (!assoc.isNITPid()) { + if (Index++ == pmtIndex) { + pmtPid = assoc.getPid(); + Add(pmtPid, 0x02); + break; + } + } + } + if (!pmtPid) + pmtIndex = 0; + } + } + } + else if (Pid == pmtPid && Tid == SI::TableIdPMT && Source() && Transponder()) { + SI::PMT pmt(Data, false); + if (!pmt.CheckCRCAndParse()) + return; + SI::CaDescriptor *d; + // Scan the common loop: + for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)pmt.commonDescriptors.getNext(it, SI::CaDescriptorTag)); ) { + CaDescriptors.NewCaDescriptor(Source(), Transponder(), pmt.getServiceId(), d); + delete d; + } + // Scan the stream-specific loop: + SI::PMT::Stream stream; + for (SI::Loop::Iterator it; pmt.streamLoop.hasNext(it); ) { + stream = pmt.streamLoop.getNext(it); + for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)stream.streamDescriptors.getNext(it, SI::CaDescriptorTag)); ) { + CaDescriptors.NewCaDescriptor(Source(), Transponder(), pmt.getServiceId(), d); + delete d; + } + } + lastPmtScan = 0; // this triggers the next scan + } +} diff --git a/pat.h b/pat.h new file mode 100644 index 00000000..aae7369c --- /dev/null +++ b/pat.h @@ -0,0 +1,36 @@ +/* + * pat.h: PAT section filter + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: pat.h 1.1 2003/12/21 14:56:03 kls Exp $ + */ + +#ifndef __PAT_H +#define __PAT_H + +#include "filter.h" +#include "thread.h" + +class cPatFilter : public cFilter { +private: + time_t lastPmtScan; + int pmtIndex; + int pmtPid; +protected: + virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length); +public: + cPatFilter(void); + virtual void SetStatus(bool On); + }; + +int GetCaDescriptors(int Source, int Transponder, int ServiceId, const unsigned short *CaSystemIds, int BufSize, uchar *Data); + ///< Gets all CA descriptors for a given channel. + ///< Copies all available CA descriptors for the given Source, Transponder and ServiceId + ///< into the provided buffer at Data (at most BufSize bytes). Only those CA descriptors + ///< are copied that match one of the given CA system IDs. + ///< \return Returns the number of bytes copied into Data (0 if no CA descriptors are + ///< available), or -1 if BufSize was too small to hold all CA descriptors. + +#endif //__PAT_H diff --git a/sections.c b/sections.c new file mode 100644 index 00000000..4a2f6d5f --- /dev/null +++ b/sections.c @@ -0,0 +1,180 @@ +/* + * sections.c: Section data handling + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: sections.c 1.1 2003/12/22 11:17:38 kls Exp $ + */ + +#include "sections.h" +#include +#include "device.h" + +// --- cFilterHandle---------------------------------------------------------- + +class cFilterHandle : public cListObject { +public: + cFilterData filterData; + int handle; + int used; + cFilterHandle(const cFilterData &FilterData); + }; + +cFilterHandle::cFilterHandle(const cFilterData &FilterData) +{ + filterData = FilterData; + handle = -1; + used = 0; +} + +// --- cSectionHandler ------------------------------------------------------- + +cSectionHandler::cSectionHandler(cDevice *Device) +:cThread("Section handler") +{ + device = Device; + active = false; + source = 0; + transponder = 0; + statusCount = 0; + on = false; + Start(); +} + +cSectionHandler::~cSectionHandler() +{ + active = false; + Cancel(3); + cFilter *fi; + while ((fi = filters.First()) != NULL) + Detach(fi); +} + +void cSectionHandler::Add(const cFilterData *FilterData) +{ + Lock(); + statusCount++; + cFilterHandle *fh; + for (fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) { + if (fh->filterData.Is(FilterData->pid, FilterData->tid, FilterData->mask)) + break; + } + if (!fh) { + fh = new cFilterHandle(*FilterData); + filterHandles.Add(fh); + fh->handle = device->OpenFilter(FilterData->pid, FilterData->tid, FilterData->mask); + } + fh->used++; + Unlock(); +} + +void cSectionHandler::Del(const cFilterData *FilterData) +{ + Lock(); + statusCount++; + cFilterHandle *fh; + for (fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) { + if (fh->filterData.Is(FilterData->pid, FilterData->tid, FilterData->mask)) { + if (--fh->used <= 0) { + close(fh->handle); + filterHandles.Del(fh); + break; + } + } + } + Unlock(); +} + +void cSectionHandler::Attach(cFilter *Filter) +{ + Lock(); + statusCount++; + filters.Add(Filter); + Filter->sectionHandler = this; + Filter->SetStatus(true); + Unlock(); +} + +void cSectionHandler::Detach(cFilter *Filter) +{ + Lock(); + statusCount++; + Filter->SetStatus(false); + Filter->sectionHandler = NULL; + filters.Del(Filter, false); + Unlock(); +} + +void cSectionHandler::SetSource(int Source, int Transponder) +{ + source = Source; + transponder = Transponder; +} + +void cSectionHandler::SetStatus(bool On) +{ + if (on != On) { + Lock(); + statusCount++; + for (cFilter *fi = filters.First(); fi; fi = filters.Next(fi)) { + fi->SetStatus(false); + if (On) + fi->SetStatus(true); + } + Unlock(); + on = On; + } +} + +void cSectionHandler::Action(void) +{ + active = true; + while (active) { + + Lock(); + int NumFilters = filterHandles.Count(); + pollfd pfd[NumFilters]; + for (cFilterHandle *fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) { + int i = fh->Index(); + pfd[i].fd = fh->handle; + pfd[i].events = POLLIN; + } + int oldStatusCount = statusCount; + Unlock(); + + if (poll(pfd, NumFilters, 1000) != 0) { + for (int i = 0; i < NumFilters; i++) { + if (pfd[i].revents & POLLIN) { + cFilterHandle *fh = NULL; + LOCK_THREAD; + if (statusCount != oldStatusCount) + break; + for (fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) { + if (pfd[i].fd == fh->handle) + break; + } + if (fh) { + // Read section data: + unsigned char buf[4096]; // max. allowed size for any EIT section + int r = safe_read(fh->handle, buf, sizeof(buf)); + if (r > 3) { // minimum number of bytes necessary to get section length + int len = (((buf[1] & 0x0F) << 8) | (buf[2] & 0xFF)) + 3; + if (len == r) { + // Distribute data to all attached filters: + int pid = fh->filterData.pid; + int tid = buf[0]; + for (cFilter *fi = filters.First(); fi; fi = filters.Next(fi)) { + if (fi->Matches(pid, tid)) + fi->Process(pid, tid, buf, len); + } + } + else + dsyslog("read incomplete section - len = %d, r = %d", len, r); + } + } + } + } + } + } +} diff --git a/sections.h b/sections.h new file mode 100644 index 00000000..1f4f462b --- /dev/null +++ b/sections.h @@ -0,0 +1,45 @@ +/* + * sections.h: Section data handling + * + * See the main source file 'vdr.c' for copyright information and + * how to reach the author. + * + * $Id: sections.h 1.1 2003/12/21 14:37:00 kls Exp $ + */ + +#ifndef __SECTIONS_H +#define __SECTIONS_H + +#include "filter.h" +#include "thread.h" +#include "tools.h" + +class cDevice; +class cFilterHandle; + +class cSectionHandler : public cThread { + friend class cFilter; +private: + cDevice *device; + bool active; + int source; + int transponder; + int statusCount; + bool on; + cList filters; + cList filterHandles; + void Add(const cFilterData *FilterData); + void Del(const cFilterData *FilterData); + virtual void Action(void); +public: + cSectionHandler(cDevice *Device); + virtual ~cSectionHandler(); + int Source(void) { return source; } + int Transponder(void) { return transponder; } + void Attach(cFilter *Filter); + void Detach(cFilter *Filter); + void SetSource(int Source, int Transponder); + void SetStatus(bool On); + }; + +#endif //__SECTIONS_H diff --git a/svdrp.c b/svdrp.c index 228911e0..009f2f01 100644 --- a/svdrp.c +++ b/svdrp.c @@ -10,7 +10,7 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 1.55 2003/08/31 11:24:47 kls Exp $ + * $Id: svdrp.c 1.56 2003/12/21 13:37:10 kls Exp $ */ #include "svdrp.h" @@ -155,7 +155,7 @@ bool cPUTEhandler::Process(const char *s) else { rewind(f); if (cSchedules::Read(f)) { - cSIProcessor::TriggerDump(); + cSchedules::Cleanup(true); status = 250; message = "EPG data processed"; } @@ -458,7 +458,7 @@ void cSVDRP::CmdCHAN(const char *Option) void cSVDRP::CmdCLRE(const char *Option) { - cSIProcessor::Clear(); + cSchedules::ClearAll(); Reply(250, "EPG data cleared"); } @@ -707,8 +707,8 @@ void cSVDRP::CmdLSTC(const char *Option) void cSVDRP::CmdLSTE(const char *Option) { - cMutexLock MutexLock; - const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock); + cSchedulesLock SchedulesLock; + const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { FILE *f = fdopen(file, "w"); if (f) { diff --git a/thread.c b/thread.c index f76e8447..31e14a2b 100644 --- a/thread.c +++ b/thread.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.c 1.28 2003/10/18 13:00:04 kls Exp $ + * $Id: thread.c 1.29 2003/12/21 15:17:24 kls Exp $ */ #include "thread.h" @@ -80,6 +80,39 @@ void cCondVar::Signal(void) } */ +// --- cRWlock --------------------------------------------------------------- + +cRWlock::cRWlock(bool PreferWriter) +{ + pthread_rwlockattr_t attr = { PreferWriter ? PTHREAD_RWLOCK_PREFER_WRITER_NP : PTHREAD_RWLOCK_PREFER_READER_NP }; + pthread_rwlock_init(&rwlock, &attr); +} + +cRWlock::~cRWlock() +{ + pthread_rwlock_destroy(&rwlock); +} + +bool cRWlock::Lock(bool Write, int TimeoutMs) +{ + int Result = 0; + struct timespec abstime; + if (TimeoutMs) { + abstime.tv_sec = TimeoutMs / 1000; + abstime.tv_nsec = (TimeoutMs % 1000) * 1000000; + } + if (Write) + Result = TimeoutMs ? pthread_rwlock_timedwrlock(&rwlock, &abstime) : pthread_rwlock_wrlock(&rwlock); + else + Result = TimeoutMs ? pthread_rwlock_timedrdlock(&rwlock, &abstime) : pthread_rwlock_rdlock(&rwlock); + return Result == 0; +} + +void cRWlock::Unlock(void) +{ + pthread_rwlock_unlock(&rwlock); +} + // --- cMutex ---------------------------------------------------------------- cMutex::cMutex(void) diff --git a/thread.h b/thread.h index fc60588c..124a930e 100644 --- a/thread.h +++ b/thread.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: thread.h 1.18 2003/10/18 12:56:20 kls Exp $ + * $Id: thread.h 1.19 2003/12/21 15:44:31 kls Exp $ */ #ifndef __THREAD_H @@ -28,6 +28,16 @@ public: //void Signal(void); }; +class cRWlock { +private: + pthread_rwlock_t rwlock; +public: + cRWlock(bool PreferWriter = false); + ~cRWlock(); + bool Lock(bool Write, int TimeoutMs = 0); + void Unlock(void); + }; + class cMutex { friend class cCondVar; private: diff --git a/timers.c b/timers.c index a4ab3c16..36e249c3 100644 --- a/timers.c +++ b/timers.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.c 1.6 2003/10/12 10:33:09 kls Exp $ + * $Id: timers.c 1.7 2003/12/13 13:06:29 kls Exp $ */ #include "timers.h" @@ -44,14 +44,14 @@ cTimer::cTimer(bool Instant, bool Pause) snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : channel->Name()); } -cTimer::cTimer(const cEventInfo *EventInfo) +cTimer::cTimer(const cEvent *Event) { startTime = stopTime = 0; recording = pending = false; active = true; - channel = Channels.GetByChannelID(EventInfo->GetChannelID(), true); - time_t tstart = EventInfo->GetTime(); - time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60; + channel = Channels.GetByChannelID(Event->ChannelID(), true); + time_t tstart = Event->StartTime(); + time_t tstop = tstart + Event->Duration() + Setup.MarginStop * 60; tstart -= Setup.MarginStart * 60; struct tm tm_r; struct tm *time = localtime_r(&tstart, &tm_r); @@ -64,9 +64,9 @@ cTimer::cTimer(const cEventInfo *EventInfo) priority = Setup.DefaultPriority; lifetime = Setup.DefaultLifetime; *file = 0; - const char *Title = EventInfo->GetTitle(); + const char *Title = Event->Title(); if (!isempty(Title)) - strn0cpy(file, EventInfo->GetTitle(), sizeof(file)); + strn0cpy(file, Event->Title(), sizeof(file)); firstday = 0; summary = NULL; } diff --git a/timers.h b/timers.h index 3b1a3ca4..b70983c2 100644 --- a/timers.h +++ b/timers.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.h 1.5 2003/05/11 13:35:53 kls Exp $ + * $Id: timers.h 1.6 2003/12/13 13:04:21 kls Exp $ */ #ifndef __TIMERS_H @@ -12,7 +12,7 @@ #include "channels.h" #include "config.h" -#include "eit.h" +#include "epg.h" #include "tools.h" enum eTimerActive { taInactive = 0, @@ -39,7 +39,7 @@ private: char *summary; public: cTimer(bool Instant = false, bool Pause = false); - cTimer(const cEventInfo *EventInfo); + cTimer(const cEvent *Event); virtual ~cTimer(); cTimer& operator= (const cTimer &Timer); virtual bool operator< (const cListObject &ListObject); diff --git a/vdr.c b/vdr.c index e1aca589..4adb1868 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.170 2003/10/19 15:14:42 kls Exp $ + * $Id: vdr.c 1.171 2003/12/22 13:29:24 kls Exp $ */ #include @@ -39,6 +39,7 @@ #include "diseqc.h" #include "dvbdevice.h" #include "eitscan.h" +#include "epg.h" #include "i18n.h" #include "interface.h" #include "keys.h" @@ -93,10 +94,12 @@ int main(int argc, char *argv[]) #define DEFAULTSVDRPPORT 2001 #define DEFAULTWATCHDOG 0 // seconds #define DEFAULTPLUGINDIR PLUGINDIR +#define DEFAULTEPGDATAFILENAME "epg.data" int SVDRPport = DEFAULTSVDRPPORT; const char *AudioCommand = NULL; const char *ConfigDirectory = NULL; + const char *EpgDataFileName = DEFAULTEPGDATAFILENAME; bool DisplayHelp = false; bool DisplayVersion = false; bool DaemonMode = false; @@ -146,7 +149,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg); return 2; break; - case 'E': cSIProcessor::SetEpgDataFileName(*optarg != '-' ? optarg : NULL); + case 'E': EpgDataFileName = (*optarg != '-' ? optarg : NULL); break; case 'h': DisplayHelp = true; break; @@ -239,7 +242,8 @@ int main(int argc, char *argv[]) " there may be several -D options (default: all DVB\n" " devices will be used)\n" " -E FILE --epgfile=FILE write the EPG data into the given FILE (default is\n" - " %s); use '-E-' to disable this\n" + " '%s' in the video directory)\n" + " '-E-' disables this\n" " if FILE is a directory, the default EPG file will be\n" " created in that directory\n" " -h, --help print this help and exit\n" @@ -261,7 +265,7 @@ int main(int argc, char *argv[]) " -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n" " seconds (default: %d); '0' disables the watchdog\n" "\n", - cSIProcessor::GetEpgDataFileName() ? cSIProcessor::GetEpgDataFileName() : "'-'", + DEFAULTEPGDATAFILENAME, DEFAULTPLUGINDIR, DEFAULTSVDRPPORT, VideoDirectory, @@ -360,6 +364,17 @@ int main(int argc, char *argv[]) cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]); + // EPG data: + + if (EpgDataFileName) { + if (DirectoryOk(EpgDataFileName)) + EpgDataFileName = AddDirectory(EpgDataFileName, DEFAULTEPGDATAFILENAME); + else if (*EpgDataFileName != '/' && *EpgDataFileName != '.') + EpgDataFileName = AddDirectory(VideoDirectory, EpgDataFileName); + } + cSchedules::SetEpgDataFileName(EpgDataFileName); + cSchedules::Read(); + // DVB interfaces: cDvbDevice::Initialize(); @@ -438,8 +453,6 @@ int main(int argc, char *argv[]) else cDevice::PrimaryDevice()->SetVolume(Setup.CurrentVolume, true); - cSIProcessor::Read(); - // Signal handlers: if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN); @@ -781,6 +794,7 @@ int main(int argc, char *argv[]) } // Disk housekeeping: RemoveDeletedRecordings(); + cSchedules::Cleanup(); // Plugins housekeeping: PluginManager.Housekeeping(); } @@ -801,6 +815,7 @@ int main(int argc, char *argv[]) Setup.Save(); cDevice::Shutdown(); PluginManager.Shutdown(true); + ReportEpgBugFixStats(); if (WatchdogTimeout > 0) dsyslog("max. latency time %d seconds", MaxLatencyTime); isyslog("exiting");