mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Changed section handling; replaced 'libdtv' with 'libsi'
This commit is contained in:
parent
84b99ea810
commit
7ff59171e3
@ -642,6 +642,7 @@ Marcel Wiesweg <marcel.wiesweg@gmx.de>
|
|||||||
for reporting a problem with cReceivers that want to receive from PIDs that are
|
for reporting a problem with cReceivers that want to receive from PIDs that are
|
||||||
currently not transmitting
|
currently not transmitting
|
||||||
for fixing volume display in case a plugin has its own OSD open
|
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 <torsten.herz@web.de>
|
Torsten Herz <torsten.herz@web.de>
|
||||||
for fixing a possible deadlock when using the "Blue" button in the "Schedules" menu
|
for fixing a possible deadlock when using the "Blue" button in the "Schedules" menu
|
||||||
|
17
HISTORY
17
HISTORY
@ -2393,7 +2393,7 @@ Video Disk Recorder Revision History
|
|||||||
not loaded (suggested by Alexander Wetzel).
|
not loaded (suggested by Alexander Wetzel).
|
||||||
- Fixed checking for VIDEO_STREAM_S in cRemux::SetBrokenLink() (thanks to Oliver
|
- Fixed checking for VIDEO_STREAM_S in cRemux::SetBrokenLink() (thanks to Oliver
|
||||||
Endriss).
|
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).
|
(suggested by Oliver Endriss).
|
||||||
- Made cOsdMenu::Display() virtual, which allows plugins to do some additional
|
- Made cOsdMenu::Display() virtual, which allows plugins to do some additional
|
||||||
processing after calling the base class function (suggested by Jan Rieger).
|
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.
|
- 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").
|
- Changed thread handling to make it work with NPTL ("Native Posix Thread Library").
|
||||||
Thanks to Jon Burgess, Andreas Schultz, Werner Fink and Stefan Huelswitt.
|
Thanks to Jon Burgess, Andreas Schultz, Werner Fink and Stefan Huelswitt.
|
||||||
@ -2489,3 +2489,16 @@ Video Disk Recorder Revision History
|
|||||||
provided by Alessio Sangalli).
|
provided by Alessio Sangalli).
|
||||||
- Greek language texts now use iso8859-7 character set (thanks to Dimitrios
|
- Greek language texts now use iso8859-7 character set (thanks to Dimitrios
|
||||||
Dimitrakos).
|
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').
|
||||||
|
24
Makefile
24
Makefile
@ -4,7 +4,7 @@
|
|||||||
# See the main source file 'vdr.c' for copyright information and
|
# See the main source file 'vdr.c' for copyright information and
|
||||||
# how to reach the author.
|
# 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:
|
.DELETE_ON_ERROR:
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ CXX ?= g++
|
|||||||
CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual
|
CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual
|
||||||
|
|
||||||
DVBDIR = ../DVB
|
DVBDIR = ../DVB
|
||||||
DTVDIR = ./libdtv
|
LSIDIR = ./libsi
|
||||||
MANDIR = /usr/local/man
|
MANDIR = /usr/local/man
|
||||||
BINDIR = /usr/local/bin
|
BINDIR = /usr/local/bin
|
||||||
|
|
||||||
@ -31,12 +31,12 @@ DOXYFILE = Doxyfile
|
|||||||
|
|
||||||
INCLUDES = -I$(DVBDIR)/include
|
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\
|
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\
|
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 player.o plugin.o rcu.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 sources.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
|
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
|
FIXFONT_ISO8859_1 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
|
||||||
@ -89,8 +89,8 @@ $(DEPFILE): Makefile
|
|||||||
|
|
||||||
# The main program:
|
# The main program:
|
||||||
|
|
||||||
vdr: $(OBJS) $(DTVLIB)
|
vdr: $(OBJS) $(SILIB)
|
||||||
$(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) -ljpeg -lpthread -ldl $(LIBDIRS) $(DTVLIB) -o vdr
|
$(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) -ljpeg -lpthread -ldl $(LIBDIRS) $(SILIB) -o vdr
|
||||||
|
|
||||||
# The font files:
|
# The font files:
|
||||||
|
|
||||||
@ -112,10 +112,10 @@ fontsml_iso8859_1.c:
|
|||||||
genfontfile: genfontfile.c
|
genfontfile: genfontfile.c
|
||||||
$(CC) $(CFLAGS) -o $@ -L/usr/X11R6/lib $< -lX11
|
$(CC) $(CFLAGS) -o $@ -L/usr/X11R6/lib $< -lX11
|
||||||
|
|
||||||
# The libdtv library:
|
# The libsi library:
|
||||||
|
|
||||||
$(DTVLIB) $(DTVDIR)/libdtv.h:
|
$(SILIB):
|
||||||
$(MAKE) -C $(DTVDIR) all
|
$(MAKE) -C $(LSIDIR) all
|
||||||
|
|
||||||
# The 'include' directory (for plugins):
|
# The 'include' directory (for plugins):
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ srcdoc:
|
|||||||
# Housekeeping:
|
# Housekeeping:
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C $(DTVDIR) clean
|
$(MAKE) -C $(LSIDIR) clean
|
||||||
-rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core* *~
|
-rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core* *~
|
||||||
-rm -rf include
|
-rm -rf include
|
||||||
-rm -rf srcdoc
|
-rm -rf srcdoc
|
||||||
|
220
PLUGINS.html
220
PLUGINS.html
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<center><h1>The VDR Plugin System</h1></center>
|
<center><h1>The VDR Plugin System</h1></center>
|
||||||
|
|
||||||
<center><b>Version 1.2.6</b></center>
|
<center><b>Version 1.3</b></center>
|
||||||
<p>
|
<p>
|
||||||
<center>
|
<center>
|
||||||
Copyright © 2003 Klaus Schmidinger<br>
|
Copyright © 2003 Klaus Schmidinger<br>
|
||||||
@ -14,9 +14,12 @@ Copyright © 2003 Klaus Schmidinger<br>
|
|||||||
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
|
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
|
||||||
</center>
|
</center>
|
||||||
<p>
|
<p>
|
||||||
<!--X1.1.32--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
<!--X1.2.6--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||||
Important modifications introduced in version 1.2.6 are marked like this.
|
Important modifications introduced in version 1.2.6 are marked like this.
|
||||||
<!--X1.1.32--></td></tr></table>
|
<!--X1.2.6--></td></tr></table>
|
||||||
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
|
Important modifications introduced in version 1.3.0 are marked like this.
|
||||||
|
<!--X1.3.0--></td></tr></table>
|
||||||
<p>
|
<p>
|
||||||
VDR provides an easy to use plugin interface that allows additional functionality
|
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.
|
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
|
|||||||
<li><a href="#Status monitor">Status monitor</a>
|
<li><a href="#Status monitor">Status monitor</a>
|
||||||
<li><a href="#Players">Players</a>
|
<li><a href="#Players">Players</a>
|
||||||
<li><a href="#Receivers">Receivers</a>
|
<li><a href="#Receivers">Receivers</a>
|
||||||
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
|
<li><a href="#Filters">Filters</a>
|
||||||
|
<!--X1.3.0--></td></tr></table>
|
||||||
<li><a href="#The On Screen Display">The On Screen Display</a>
|
<li><a href="#The On Screen Display">The On Screen Display</a>
|
||||||
<li><a href="#Devices">Devices</a>
|
<li><a href="#Devices">Devices</a>
|
||||||
<li><a href="#Dolby Digital">Dolby Digital</a>
|
<li><a href="#Dolby Digital">Dolby Digital</a>
|
||||||
@ -112,7 +118,7 @@ No other characters should be used here.
|
|||||||
<p>
|
<p>
|
||||||
A plugin can access its name through the (non virtual) member function
|
A plugin can access its name through the (non virtual) member function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
const char *Name(void);
|
const char *Name(void);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -127,7 +133,7 @@ By default plugins are located in a directory named <tt>PLUGINS</tt> below the
|
|||||||
VDR source directory. Inside this directory the following subdirectory structure
|
VDR source directory. Inside this directory the following subdirectory structure
|
||||||
is used:
|
is used:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
VDR/PLUGINS/src
|
VDR/PLUGINS/src
|
||||||
VDR/PLUGINS/src/hello
|
VDR/PLUGINS/src/hello
|
||||||
VDR/PLUGINS/lib
|
VDR/PLUGINS/lib
|
||||||
@ -172,7 +178,7 @@ To use the <tt>plugins</tt> and <tt>plugins-clean</tt> targets from the VDR <tt>
|
|||||||
you need to unpack such an archive into the <tt>VDR/PLUGINS/src</tt> directory and
|
you need to unpack such an archive into the <tt>VDR/PLUGINS/src</tt> directory and
|
||||||
create a symbolic link with the basic plugin name, as in
|
create a symbolic link with the basic plugin name, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
ln -s hello-0.0.1 hello
|
ln -s hello-0.0.1 hello
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -226,7 +232,7 @@ If your plugin shall not be accessible through VDR's main menu, simply remove
|
|||||||
<p>
|
<p>
|
||||||
At the end of the plugin's source file you will find a line that looks like this:
|
At the end of the plugin's source file you will find a line that looks like this:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
VDRPLUGINCREATOR(cPluginHello);
|
VDRPLUGINCREATOR(cPluginHello);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -239,7 +245,7 @@ source directory and adjust the <tt>Makefile</tt> accordingly.
|
|||||||
Header files usually contain preprocessor statements that prevent the same
|
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
|
file (or rather its contents, to be precise) from being included more than once, like
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#ifndef __I18N_H
|
#ifndef __I18N_H
|
||||||
#define __I18N_H
|
#define __I18N_H
|
||||||
|
|
||||||
@ -274,7 +280,7 @@ and two replacing the dot).
|
|||||||
|
|
||||||
The constructor and destructor of a plugin are defined as
|
The constructor and destructor of a plugin are defined as
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
cPlugin(void);
|
cPlugin(void);
|
||||||
virtual ~cPlugin();
|
virtual ~cPlugin();
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
@ -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.
|
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
|
VDR requests a plugin's version number through a call to the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual const char *Version(void) = 0;
|
virtual const char *Version(void) = 0;
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -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.
|
be as long as really necessary, and shall not contain the plugin's name itself.
|
||||||
Here's an example:
|
Here's an example:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
static const char *VERSION = "0.0.1";
|
static const char *VERSION = "0.0.1";
|
||||||
|
|
||||||
const char *cPluginHello::Version(void)
|
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
|
In order to tell the user what exactly a plugin does, it must implement the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual const char *Description(void) = 0;
|
virtual const char *Description(void) = 0;
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
which returns a short, one line description of the plugin's purpose:
|
which returns a short, one line description of the plugin's purpose:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
static const char *DESCRIPTION = "A friendly greeting";
|
static const char *DESCRIPTION = "A friendly greeting";
|
||||||
|
|
||||||
virtual const char *Description(void)
|
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
|
If a plugin wants to react on command line arguments, it needs to implement
|
||||||
the function
|
the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual bool ProcessArgs(int argc, char *argv[]);
|
virtual bool ProcessArgs(int argc, char *argv[]);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -390,7 +396,7 @@ these arguments. As with any normal C program, the strings pointed to by <tt>arg
|
|||||||
will survive the entire lifetime of the plugin, so it is safe to store pointers to
|
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:
|
these values inside the plugin. Here's an example:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
bool cPluginHello::ProcessArgs(int argc, char *argv[])
|
bool cPluginHello::ProcessArgs(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
// Implement command line argument processing here if applicable.
|
// 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
|
If a plugin accepts command line options, it should implement the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual const char *CommandLineHelp(void);
|
virtual const char *CommandLineHelp(void);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -433,7 +439,7 @@ which will be called if the user enters the <b><tt>-h</tt></b> option when start
|
|||||||
The returned string should contain the command line help for this plugin, formatted
|
The returned string should contain the command line help for this plugin, formatted
|
||||||
in the same way as done by VDR itself:
|
in the same way as done by VDR itself:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
const char *cPluginHello::CommandLineHelp(void)
|
const char *cPluginHello::CommandLineHelp(void)
|
||||||
{
|
{
|
||||||
// Return a string that describes all known command line options.
|
// 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 <a href="#Internationalization">internationalization</a>,
|
thread of its own), or wants to make use of <a href="#Internationalization">internationalization</a>,
|
||||||
it needs to implement one of the functions
|
it needs to implement one of the functions
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual bool Initialize(void);
|
virtual bool Initialize(void);
|
||||||
virtual bool Start(void);
|
virtual bool Start(void);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
@ -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
|
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
|
from VDR's main menu, it needs to implement the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual const char *MainMenuEntry(void);
|
virtual const char *MainMenuEntry(void);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -501,7 +507,7 @@ The default implementation returns a <tt>NULL</tt> pointer, which means that
|
|||||||
this plugin will not have an item in the main menu. Here's an example of a
|
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:
|
plugin that will have a main menu item:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
static const char *MAINMENUENTRY = "Hello";
|
static const char *MAINMENUENTRY = "Hello";
|
||||||
|
|
||||||
const char *cPluginHello::MainMenuEntry(void)
|
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
|
If the user selects the main menu entry of a plugin, VDR calls the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual cOsdObject *MainMenuAction(void);
|
virtual cOsdObject *MainMenuAction(void);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -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
|
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
|
up some files or other things. In order to do this it can implement the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual void Housekeeping(void);
|
virtual void Housekeeping(void);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -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
|
If a plugin requires its own setup parameters, it needs to implement the following
|
||||||
functions to handle these parameters:
|
functions to handle these parameters:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual cMenuSetupPage *SetupMenu(void);
|
virtual cMenuSetupPage *SetupMenu(void);
|
||||||
virtual bool SetupParse(const char *Name, const char *Value);
|
virtual bool SetupParse(const char *Name, const char *Value);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
@ -594,7 +600,7 @@ an error. If <i>false</i> is returned, an error message will be written to
|
|||||||
the log file (and program execution will continue).
|
the log file (and program execution will continue).
|
||||||
A possible implementation of <tt>SetupParse()</tt> could look like this:
|
A possible implementation of <tt>SetupParse()</tt> could look like this:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
bool cPluginHello::SetupParse(const char *Name, const char *Value)
|
bool cPluginHello::SetupParse(const char *Name, const char *Value)
|
||||||
{
|
{
|
||||||
// Parse your own setup parameters and store their values.
|
// Parse your own setup parameters and store their values.
|
||||||
@ -620,7 +626,7 @@ plugins need not worry about this.
|
|||||||
<p>
|
<p>
|
||||||
To store its values in the global setup, a plugin has to call the function
|
To store its values in the global setup, a plugin has to call the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
void SetupStore(const char *Name, <i>type</i> Value);
|
void SetupStore(const char *Name, <i>type</i> Value);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -653,7 +659,7 @@ To implement a <i>Setup</i> menu, a plugin needs to derive a class from
|
|||||||
<tt>cMenuSetupPage</tt> and implement its constructor and the pure virtual
|
<tt>cMenuSetupPage</tt> and implement its constructor and the pure virtual
|
||||||
<tt>Store()</tt> member function:
|
<tt>Store()</tt> member function:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
int GreetingTime = 3;
|
int GreetingTime = 3;
|
||||||
int UseAlternateGreeting = false;
|
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
|
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
|
where other configuration data already exists. VDR provides the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
const char *ConfigDirectory(const char *PluginName = NULL);
|
const char *ConfigDirectory(const char *PluginName = NULL);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -737,7 +743,7 @@ these in a subdirectory of its own, named after the plugin. To easily get such a
|
|||||||
the <tt>ConfigDirectory()</tt> function can be given an additional string that will
|
the <tt>ConfigDirectory()</tt> function can be given an additional string that will
|
||||||
be appended to the returned directory name, as in
|
be appended to the returned directory name, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
const char *MyConfigDir = ConfigDirectory(Name());
|
const char *MyConfigDir = ConfigDirectory(Name());
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -754,7 +760,7 @@ The <tt>ConfigDirectory()</tt> function is a static member function of the <tt>c
|
|||||||
class. This allows it to be called even from outside any member function of the derived
|
class. This allows it to be called even from outside any member function of the derived
|
||||||
plugin class, by writing
|
plugin class, by writing
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
const char *MyConfigDir = cPlugin::ConfigDirectory();
|
const char *MyConfigDir = cPlugin::ConfigDirectory();
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -765,7 +771,7 @@ const char *MyConfigDir = cPlugin::ConfigDirectory();
|
|||||||
If a plugin displays texts to the user, it should implement internationalized
|
If a plugin displays texts to the user, it should implement internationalized
|
||||||
versions of these texts and call the function
|
versions of these texts and call the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
void RegisterI18n(const tI18nPhrase * const Phrases);
|
void RegisterI18n(const tI18nPhrase * const Phrases);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -774,7 +780,7 @@ to register them with VDR's internationalization mechanism.
|
|||||||
The call to this function must be done in the <a href="#Getting started"><tt>Initialize()</tt></a>
|
The call to this function must be done in the <a href="#Getting started"><tt>Initialize()</tt></a>
|
||||||
or <a href="#Getting started"><tt>Start()</tt></a> function of the plugin:
|
or <a href="#Getting started"><tt>Start()</tt></a> function of the plugin:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
const tI18nPhrase Phrases[] = {
|
const tI18nPhrase Phrases[] = {
|
||||||
{ "Hello world!",
|
{ "Hello world!",
|
||||||
"Hallo Welt!",
|
"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
|
The actual runtime selection of the texts corresponding to the selected language
|
||||||
is done by wrapping each internationalized text with the <tt>tr()</tt> macro:
|
is done by wrapping each internationalized text with the <tt>tr()</tt> macro:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
const char *s = tr("Hello world!");
|
const char *s = tr("Hello world!");
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -833,20 +839,20 @@ core VDR code.
|
|||||||
|
|
||||||
Plugins are loaded into VDR using the command line option <b><tt>-P</tt></b>, as in
|
Plugins are loaded into VDR using the command line option <b><tt>-P</tt></b>, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
vdr -Phello
|
vdr -Phello
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
If the plugin accepts command line options, they are given as part of the argument
|
If the plugin accepts command line options, they are given as part of the argument
|
||||||
to the <b><tt>-P</tt></b> option, which then has to be enclosed in quotes:
|
to the <b><tt>-P</tt></b> option, which then has to be enclosed in quotes:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
vdr -P"hello -a abc -b"
|
vdr -P"hello -a abc -b"
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
Any number of plugins can be loaded this way, each with its own <b><tt>-P</tt></b> option:
|
Any number of plugins can be loaded this way, each with its own <b><tt>-P</tt></b> option:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
vdr -P"hello -a abc -b" -Pdvd -Pmp3
|
vdr -P"hello -a abc -b" -Pdvd -Pmp3
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -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
|
cannot be found at their default location) you need to tell VDR the location of
|
||||||
the plugins through the <b><tt>-L</tt></b> option:
|
the plugins through the <b><tt>-L</tt></b> option:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
vdr -L/usr/lib/vdr -Phello
|
vdr -L/usr/lib/vdr -Phello
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -879,14 +885,14 @@ provides the target <tt>dist</tt>, which does this for you.
|
|||||||
<p>
|
<p>
|
||||||
Simply change into your source directory and execute <tt>make dist</tt>:
|
Simply change into your source directory and execute <tt>make dist</tt>:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
cd VDR/PLUGINS/src/hello
|
cd VDR/PLUGINS/src/hello
|
||||||
make dist
|
make dist
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
After this you should find a file named like
|
After this you should find a file named like
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
vdr-hello-0.0.1.tgz
|
vdr-hello-0.0.1.tgz
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -902,7 +908,7 @@ plugin's name, and <tt>0.0.1</tt> 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
|
If a plugin wants to get informed on various events in VDR, it can derive a class from
|
||||||
<tt>cStatus</tt>, as in
|
<tt>cStatus</tt>, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/status.h>
|
#include <vdr/status.h>
|
||||||
|
|
||||||
class cMyStatusMonitor : public cStatus {
|
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
|
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:
|
the DVB devices. It could be used in a plugin like this:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/plugin.h>
|
#include <vdr/plugin.h>
|
||||||
|
|
||||||
class cPluginStatus : public cPlugin {
|
class cPluginStatus : public cPlugin {
|
||||||
@ -975,7 +981,7 @@ the functions you actually want to use.
|
|||||||
Implementing a player is a two step process.
|
Implementing a player is a two step process.
|
||||||
First you need the actual player class, which is derived from the abstract <tt>cPlayer</tt>:
|
First you need the actual player class, which is derived from the abstract <tt>cPlayer</tt>:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/player.h>
|
#include <vdr/player.h>
|
||||||
|
|
||||||
class cMyPlayer : public cPlayer {
|
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
|
thread which, e.g., reads data from a file, you can additionally derive your class from
|
||||||
<tt>cThread</tt> and implement the necessary functionality:
|
<tt>cThread</tt> and implement the necessary functionality:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/player.h>
|
#include <vdr/player.h>
|
||||||
|
|
||||||
class cMyPlayer : public cPlayer, cThread {
|
class cMyPlayer : public cPlayer, cThread {
|
||||||
@ -1009,7 +1015,7 @@ its own player for the VDR recordings.
|
|||||||
<p>
|
<p>
|
||||||
To play the video data, the player needs to call its member function
|
To play the video data, the player needs to call its member function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
int PlayVideo(const uchar *Data, int Length);
|
int PlayVideo(const uchar *Data, int Length);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -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.
|
DVB device doesn't run out of data.
|
||||||
To avoid busy loops the player should call its member function
|
To avoid busy loops the player should call its member function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
bool DevicePoll(cPoller &Poller, int TimeoutMs = 0);
|
bool DevicePoll(cPoller &Poller, int TimeoutMs = 0);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -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
|
If the player can provide more than a single audio track, it can implement the
|
||||||
following functions to make them available:
|
following functions to make them available:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual int NumAudioTracks(void) const;
|
virtual int NumAudioTracks(void) const;
|
||||||
virtual const char **GetAudioTracks(int *CurrentTrack = NULL);
|
virtual const char **GetAudioTracks(int *CurrentTrack = NULL);
|
||||||
virtual void SetAudioTrack(int Index);
|
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,
|
If there is an additional audio track that has to be replayed with external hardware,
|
||||||
the player shall call its member function
|
the player shall call its member function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
void PlayAudio(const uchar *Data, int Length);
|
void PlayAudio(const uchar *Data, int Length);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -1048,7 +1054,7 @@ where <tt>Data</tt> points to a complete audio PES packet of <tt>Length</tt> byt
|
|||||||
The second part needed here is a control object that receives user input from the main
|
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:
|
program loop and reacts on this by telling the player what to do:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/player.h>
|
#include <vdr/player.h>
|
||||||
|
|
||||||
class cMyControl : public cControl {
|
class cMyControl : public cControl {
|
||||||
@ -1066,7 +1072,7 @@ public:
|
|||||||
hand over a pointer to it to the <tt>cControl</tt> base class, so that it
|
hand over a pointer to it to the <tt>cControl</tt> base class, so that it
|
||||||
can be later attached to the primary DVB device:
|
can be later attached to the primary DVB device:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
cMyControl::cMyControl(void)
|
cMyControl::cMyControl(void)
|
||||||
:cControl(player = new cMyPlayer)
|
: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
|
infrastructure like displaying a list of playable stuff etc) simply has to call the
|
||||||
static function <tt>cControl::Launch()</tt> with the player control object, as in
|
static function <tt>cControl::Launch()</tt> with the player control object, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
cControl::Launch(new cMyControl);
|
cControl::Launch(new cMyControl);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -1104,7 +1110,7 @@ use the primary DVB device, or the user decides to start a different replay).
|
|||||||
<p>
|
<p>
|
||||||
The <tt>cPlayer</tt> class has a member function
|
The <tt>cPlayer</tt> class has a member function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
void DeviceStillPicture(const uchar *Data, int Length);
|
void DeviceStillPicture(const uchar *Data, int Length);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -1149,7 +1155,7 @@ ahead - it's your show...
|
|||||||
In order to receive any kind of data from a <tt>cDevice</tt>, a plugin must set up an
|
In order to receive any kind of data from a <tt>cDevice</tt>, a plugin must set up an
|
||||||
object derived from the <tt>cReceiver</tt> class:
|
object derived from the <tt>cReceiver</tt> class:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/receiver.h>
|
#include <vdr/receiver.h>
|
||||||
|
|
||||||
class cMyReceiver : public cReceiver, cThread {
|
class cMyReceiver : public cReceiver, cThread {
|
||||||
@ -1187,7 +1193,7 @@ a <tt>cReceiver</tt> to be detached from its <tt>cDevice</tt> at any time.
|
|||||||
Once a <tt>cReceiver</tt> has been created, it needs to be <i>attached</i> to
|
Once a <tt>cReceiver</tt> has been created, it needs to be <i>attached</i> to
|
||||||
a <tt>cDevice</tt>:
|
a <tt>cDevice</tt>:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
cMyReceiver *Receiver = new cMyReceiver(123);
|
cMyReceiver *Receiver = new cMyReceiver(123);
|
||||||
|
|
||||||
cDevice::ActualDevice()->AttachReceiver(Receiver);
|
cDevice::ActualDevice()->AttachReceiver(Receiver);
|
||||||
@ -1201,6 +1207,49 @@ Mode</i>).
|
|||||||
If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i>
|
If the <tt>cReceiver</tt> isn't needed any more, it may simply be <i>deleted</i>
|
||||||
and will automatically detach itself from the <tt>cDevice</tt>.
|
and will automatically detach itself from the <tt>cDevice</tt>.
|
||||||
|
|
||||||
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
|
<a name="Filters"><hr><h2>Filters</h2>
|
||||||
|
|
||||||
|
<center><i><b>A Fistful of Datas</b></i></center><p>
|
||||||
|
|
||||||
|
If you want to receive section data you have to implement a derived <tt>cFilter</tt>
|
||||||
|
class which at least implements the <tt>Process()</tt> function and a constructor
|
||||||
|
that sets the (initial) filter parameters:
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
#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
|
||||||
|
}
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
An instance of such a filter needs to be attached to the device from
|
||||||
|
which it shall receive data, as in
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
cMyFilter Filter;
|
||||||
|
|
||||||
|
cDevice::ActualDevice()->AttachFilter(Filter);
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
See VDR/eit.c or VDR/pat.c to learn how to process filter data.
|
||||||
|
<!--X1.3.0--></td></tr></table>
|
||||||
|
|
||||||
<a name="The On Screen Display"><hr><h2>The On Screen Display</h2>
|
<a name="The On Screen Display"><hr><h2>The On Screen Display</h2>
|
||||||
|
|
||||||
<center><i><b>Express yourself</b></i></center><p>
|
<center><i><b>Express yourself</b></i></center><p>
|
||||||
@ -1213,7 +1262,7 @@ windows and color depths.
|
|||||||
If a plugin needs to have total control over the OSD, it can call the
|
If a plugin needs to have total control over the OSD, it can call the
|
||||||
static function
|
static function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/osd.h>
|
#include <vdr/osd.h>
|
||||||
|
|
||||||
cOsdBase *MyOsd = cOsd::OpenRaw(x, y);
|
cOsdBase *MyOsd = cOsd::OpenRaw(x, y);
|
||||||
@ -1223,7 +1272,7 @@ where <tt>x</tt> and <tt>y</tt> are the coordinates of the upper left corner
|
|||||||
of the OSD area on the screen. Such a "raw" OSD doesn't display anything
|
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
|
yet, so you need to at least call the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
MyOsd->Create(...);
|
MyOsd->Create(...);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -1247,7 +1296,7 @@ stream and displays it, for instance, on an existing graphics adapter.
|
|||||||
<p>
|
<p>
|
||||||
To implement an additional device, a plugin must derive a class from cDevice:
|
To implement an additional device, a plugin must derive a class from cDevice:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/device.h>
|
#include <vdr/device.h>
|
||||||
|
|
||||||
class cMyDevice : public cDevice {
|
class cMyDevice : public cDevice {
|
||||||
@ -1266,7 +1315,7 @@ the <tt>cDvbDevice</tt>, which is used to access the DVB PCI cards.
|
|||||||
If the new device can receive, it most likely needs to provide a way of
|
If the new device can receive, it most likely needs to provide a way of
|
||||||
selecting which channel it shall tune to:
|
selecting which channel it shall tune to:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual bool ProvidesSource(int Source) const;
|
virtual bool ProvidesSource(int Source) const;
|
||||||
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL);
|
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL);
|
||||||
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
|
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
|
If the device can provide more than a single audio track, it can implement the
|
||||||
following functions to make them available:
|
following functions to make them available:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual int NumAudioTracksDevice(void) const;
|
virtual int NumAudioTracksDevice(void) const;
|
||||||
virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
|
virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
|
||||||
virtual void SetAudioTrackDevice(int Index);
|
virtual void SetAudioTrackDevice(int Index);
|
||||||
@ -1292,7 +1341,7 @@ virtual void SetAudioTrackDevice(int Index);
|
|||||||
<p>
|
<p>
|
||||||
A device that can be used for recording must implement the functions
|
A device that can be used for recording must implement the functions
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
|
virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
|
||||||
virtual bool OpenDvr(void);
|
virtual bool OpenDvr(void);
|
||||||
virtual void CloseDvr(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
|
If this device allows receiving several different data streams, it can
|
||||||
implement
|
implement
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual bool CanBeReUsed(int Frequency, int Vpid);
|
virtual bool CanBeReUsed(int Frequency, int Vpid);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -1318,13 +1367,13 @@ to indicate this to VDR.
|
|||||||
<p>
|
<p>
|
||||||
The functions to implement replaying capabilites are
|
The functions to implement replaying capabilites are
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual bool HasDecoder(void) const;
|
virtual bool HasDecoder(void) const;
|
||||||
virtual bool CanReplay(void) const;
|
virtual bool CanReplay(void) const;
|
||||||
virtual bool SetPlayMode(ePlayMode PlayMode);
|
virtual bool SetPlayMode(ePlayMode PlayMode);
|
||||||
<!--X1.1.32--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
<!--X1.2.6--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||||
virtual int64_t GetSTC(void);
|
virtual int64_t GetSTC(void);
|
||||||
<!--X1.1.32--></td></tr></table>
|
<!--X1.2.6--></td></tr></table>
|
||||||
virtual void TrickSpeed(int Speed);
|
virtual void TrickSpeed(int Speed);
|
||||||
virtual void Clear(void);
|
virtual void Clear(void);
|
||||||
virtual void Play(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
|
In addition, the following functions may be implemented to provide further
|
||||||
functionality:
|
functionality:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int Si
|
virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int Si
|
||||||
virtual void SetVideoFormat(bool VideoFormat16_9);
|
virtual void SetVideoFormat(bool VideoFormat16_9);
|
||||||
virtual void SetVolumeDevice(int Volume);
|
virtual void SetVolumeDevice(int Volume);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
<!--X1.3.0--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||||
|
<p>
|
||||||
|
<b>Section Filtering</b>
|
||||||
|
<p>
|
||||||
|
If your device provides section filtering capabilities it can implement
|
||||||
|
the function
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
which must open a file handle that delivers section data for the given
|
||||||
|
filter parameters.
|
||||||
|
<p>
|
||||||
|
In order to actually start section handling, the
|
||||||
|
device also needs to call the function
|
||||||
|
|
||||||
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
|
StartSectionHandler();
|
||||||
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
from its constructor.
|
||||||
|
<p>
|
||||||
|
See <a href="#Filters">Filters</a> on how to set up actual filters that can
|
||||||
|
handle section data.
|
||||||
|
<!--X1.3.0--></td></tr></table>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>On Screen Display</b>
|
<b>On Screen Display</b>
|
||||||
<p>
|
<p>
|
||||||
@ -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
|
that is supposed to be used as a primary device should do), it can implement
|
||||||
the function
|
the function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual cOsdBase *NewOsd(int x, int y);
|
virtual cOsdBase *NewOsd(int x, int y);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -1391,7 +1467,7 @@ audio replay facility.
|
|||||||
To implement a new audio output facility, simply derive a class from <tt>cAudio</tt>,
|
To implement a new audio output facility, simply derive a class from <tt>cAudio</tt>,
|
||||||
as in
|
as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/audio.h>
|
#include <vdr/audio.h>
|
||||||
#include <vdr/thread.h>
|
#include <vdr/thread.h>
|
||||||
|
|
||||||
@ -1435,7 +1511,7 @@ remote control, so a plugin can use the <tt>cRemote</tt> class to do that.
|
|||||||
The simplest method for a plugin to issue commands to VDR is to call the
|
The simplest method for a plugin to issue commands to VDR is to call the
|
||||||
static function <tt>cRemote::Put(eKeys Key)</tt>, as in
|
static function <tt>cRemote::Put(eKeys Key)</tt>, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
cRemote::Put(kUp);
|
cRemote::Put(kUp);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -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
|
be supported by the actual remote control in use, you may want to derive your
|
||||||
own remote control class from <tt>cRemote</tt>, as in
|
own remote control class from <tt>cRemote</tt>, as in
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
#include <vdr/remote.h>
|
#include <vdr/remote.h>
|
||||||
#include <vdr/thread.h>
|
#include <vdr/thread.h>
|
||||||
|
|
||||||
@ -1472,7 +1548,7 @@ when the program ends).
|
|||||||
<p>
|
<p>
|
||||||
The constructor of your remote control class should look like this
|
The constructor of your remote control class should look like this
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
cMyRemote::cMyRemote(const char *Name)
|
cMyRemote::cMyRemote(const char *Name)
|
||||||
:cRemote(Name)
|
:cRemote(Name)
|
||||||
{
|
{
|
||||||
@ -1492,7 +1568,7 @@ member variables, you should do so before calling <tt>Start()</tt>.
|
|||||||
If your remote control for some reason can't work (maybe because it was unable to
|
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
|
open some file handle it requires) it can implement the virtual function
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
virtual bool Ready(void);
|
virtual bool Ready(void);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -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
|
readily available next time VDR starts (without having to go through the initialization
|
||||||
procedure again) it can use the <tt>cRemote</tt> member functions
|
procedure again) it can use the <tt>cRemote</tt> member functions
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
void PutSetup(const char *Setup);
|
void PutSetup(const char *Setup);
|
||||||
const char *GetSetup(void);
|
const char *GetSetup(void);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
@ -1527,7 +1603,7 @@ The <tt>cRemote</tt> class assumes that any incoming remote control code can be
|
|||||||
expressed as a character string. So whatever data your remote control provides
|
expressed as a character string. So whatever data your remote control provides
|
||||||
needs to be given to the base class by calling
|
needs to be given to the base class by calling
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
Put(const char *Code, bool Repeat = false, bool Release = false);
|
Put(const char *Code, bool Repeat = false, bool Release = false);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
@ -1538,7 +1614,7 @@ Since a common case for remote control data is to be given as a numerical
|
|||||||
value, there is another <tt>Put()</tt> function available for your convenience,
|
value, there is another <tt>Put()</tt> function available for your convenience,
|
||||||
which takes a 64 bit unsigned integer value instead of a character string:
|
which takes a 64 bit unsigned integer value instead of a character string:
|
||||||
|
|
||||||
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
|
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||||
Put(uint64 Code, bool Repeat = false, bool Release = false);
|
Put(uint64 Code, bool Repeat = false, bool Release = false);
|
||||||
</pre></td></tr></table><p>
|
</pre></td></tr></table><p>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for a Video Disk Recorder plugin
|
# 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.
|
# The official name of this plugin.
|
||||||
# This name will be used in the '-P...' option of VDR to load the 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
|
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):
|
### The object files (add further files here):
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for a Video Disk Recorder plugin
|
# 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.
|
# The official name of this plugin.
|
||||||
# This name will be used in the '-P...' option of VDR to load the 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
|
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):
|
### The object files (add further files here):
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for a Video Disk Recorder plugin
|
# 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.
|
# The official name of this plugin.
|
||||||
# This name will be used in the '-P...' option of VDR to load the 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
|
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):
|
### The object files (add further files here):
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for a Video Disk Recorder plugin
|
# 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.
|
# The official name of this plugin.
|
||||||
# This name will be used in the '-P...' option of VDR to load the 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
|
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):
|
### The object files (add further files here):
|
||||||
|
|
||||||
|
53
device.c
53
device.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "device.h"
|
||||||
@ -13,7 +13,6 @@
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "eit.h"
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "receiver.h"
|
#include "receiver.h"
|
||||||
@ -45,6 +44,10 @@ cDevice::cDevice(void)
|
|||||||
mute = false;
|
mute = false;
|
||||||
volume = Setup.CurrentVolume;
|
volume = Setup.CurrentVolume;
|
||||||
|
|
||||||
|
sectionHandler = NULL;
|
||||||
|
eitFilter = NULL;
|
||||||
|
patFilter = NULL;
|
||||||
|
|
||||||
ciHandler = NULL;
|
ciHandler = NULL;
|
||||||
player = NULL;
|
player = NULL;
|
||||||
|
|
||||||
@ -65,6 +68,9 @@ cDevice::~cDevice()
|
|||||||
for (int i = 0; i < MAXRECEIVERS; i++)
|
for (int i = 0; i < MAXRECEIVERS; i++)
|
||||||
Detach(receiver[i]);
|
Detach(receiver[i]);
|
||||||
delete ciHandler;
|
delete ciHandler;
|
||||||
|
delete eitFilter;
|
||||||
|
delete patFilter;
|
||||||
|
delete sectionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDevice::SetUseDevice(int n)
|
void cDevice::SetUseDevice(int n)
|
||||||
@ -313,6 +319,31 @@ bool cDevice::SetPid(cPidHandle *Handle, int Type, bool On)
|
|||||||
return false;
|
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
|
bool cDevice::ProvidesSource(int Source) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -401,15 +432,25 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel
|
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;
|
Result = scrFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Result == scrOk) {
|
if (Result == scrOk) {
|
||||||
if (LiveView && IsPrimaryDevice()) {
|
if (LiveView && IsPrimaryDevice())
|
||||||
cSIProcessor::SetCurrentChannelID(Channel->GetChannelID());
|
|
||||||
currentChannel = Channel->Number();
|
currentChannel = Channel->Number();
|
||||||
}
|
|
||||||
cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
|
cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
device.h
26
device.h
@ -4,13 +4,17 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __DEVICE_H
|
||||||
#define __DEVICE_H
|
#define __DEVICE_H
|
||||||
|
|
||||||
#include "ci.h"
|
#include "ci.h"
|
||||||
|
#include "eit.h"
|
||||||
|
#include "filter.h"
|
||||||
|
#include "pat.h"
|
||||||
|
#include "sections.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
@ -222,6 +226,26 @@ protected:
|
|||||||
///< Type indicates some special types of PIDs, which the device may
|
///< Type indicates some special types of PIDs, which the device may
|
||||||
///< need to set in a specific way.
|
///< 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:
|
// Common Interface facilities:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
55
dvbdevice.c
55
dvbdevice.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "dvbdevice.h"
|
||||||
@ -274,7 +274,7 @@ void cDvbTuner::Action(void)
|
|||||||
if (tunerStatus != tsCam) {//XXX TODO update in case the CA descriptors have changed
|
if (tunerStatus != tsCam) {//XXX TODO update in case the CA descriptors have changed
|
||||||
for (int Slot = 0; Slot < ciHandler->NumSlots(); Slot++) {
|
for (int Slot = 0; Slot < ciHandler->NumSlots(); Slot++) {
|
||||||
uchar buffer[2048];
|
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) {
|
if (length > 0) {
|
||||||
cCiCaPmt CaPmt(channel.Sid());
|
cCiCaPmt CaPmt(channel.Sid());
|
||||||
CaPmt.AddCaDescriptor(length, buffer);
|
CaPmt.AddCaDescriptor(length, buffer);
|
||||||
@ -312,7 +312,6 @@ cDvbDevice::cDvbDevice(int n)
|
|||||||
{
|
{
|
||||||
dvbTuner = NULL;
|
dvbTuner = NULL;
|
||||||
frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
|
frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
|
||||||
siProcessor = NULL;
|
|
||||||
spuDecoder = NULL;
|
spuDecoder = NULL;
|
||||||
playMode = pmNone;
|
playMode = pmNone;
|
||||||
|
|
||||||
@ -368,7 +367,6 @@ cDvbDevice::cDvbDevice(int n)
|
|||||||
|
|
||||||
if (fd_frontend >= 0) {
|
if (fd_frontend >= 0) {
|
||||||
dvb_frontend_info feinfo;
|
dvb_frontend_info feinfo;
|
||||||
siProcessor = new cSIProcessor(DvbName(DEV_DVB_DEMUX, n));
|
|
||||||
if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
|
if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
|
||||||
frontendType = feinfo.type;
|
frontendType = feinfo.type;
|
||||||
ciHandler = cCiHandler::CreateCiHandler(DvbName(DEV_DVB_CA, n));
|
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);
|
esyslog("ERROR: can't open DVB device %d", n);
|
||||||
|
|
||||||
aPid1 = aPid2 = 0;
|
aPid1 = aPid2 = 0;
|
||||||
|
|
||||||
|
StartSectionHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
cDvbDevice::~cDvbDevice()
|
cDvbDevice::~cDvbDevice()
|
||||||
{
|
{
|
||||||
delete spuDecoder;
|
delete spuDecoder;
|
||||||
delete siProcessor;
|
|
||||||
delete dvbTuner;
|
delete dvbTuner;
|
||||||
// We're not explicitly closing any device files here, since this sometimes
|
// We're not explicitly closing any device files here, since this sometimes
|
||||||
// caused segfaults. Besides, the program is about to terminate anyway...
|
// 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;
|
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)
|
void cDvbDevice::TurnOffLiveMode(void)
|
||||||
{
|
{
|
||||||
// Avoid noise while switching:
|
// Avoid noise while switching:
|
||||||
@ -715,13 +738,6 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
|||||||
TurnOnLivePIDs = false;
|
TurnOnLivePIDs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop SI filtering:
|
|
||||||
|
|
||||||
if (siProcessor) {
|
|
||||||
siProcessor->SetCurrentTransponder(0, 0);
|
|
||||||
siProcessor->SetStatus(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turn off live PIDs if necessary:
|
// Turn off live PIDs if necessary:
|
||||||
|
|
||||||
if (TurnOffLivePIDs)
|
if (TurnOffLivePIDs)
|
||||||
@ -746,13 +762,6 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
|
|||||||
else if (StartTransferMode)
|
else if (StartTransferMode)
|
||||||
cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid1(), Channel->Apid2(), Channel->Dpid1(), Channel->Dpid2()));
|
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;
|
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_SELECT_SOURCE, AUDIO_SOURCE_DEMUX));
|
||||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
|
||||||
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
|
CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false));
|
||||||
if (siProcessor)
|
|
||||||
siProcessor->SetStatus(true);
|
|
||||||
break;
|
break;
|
||||||
case pmAudioVideo:
|
case pmAudioVideo:
|
||||||
if (playMode == pmNone)
|
if (playMode == pmNone)
|
||||||
TurnOffLiveMode();
|
TurnOffLiveMode();
|
||||||
// continue with next...
|
// continue with next...
|
||||||
case pmAudioOnlyBlack:
|
case pmAudioOnlyBlack:
|
||||||
if (siProcessor)
|
|
||||||
siProcessor->SetStatus(false);
|
|
||||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||||
CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
|
CHECK(ioctl(fd_audio, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY));
|
||||||
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, PlayMode == pmAudioVideo));
|
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));
|
CHECK(ioctl(fd_video, VIDEO_PLAY));
|
||||||
break;
|
break;
|
||||||
case pmAudioOnly:
|
case pmAudioOnly:
|
||||||
if (siProcessor)
|
|
||||||
siProcessor->SetStatus(false);
|
|
||||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, true));
|
||||||
CHECK(ioctl(fd_audio, AUDIO_STOP, true));
|
CHECK(ioctl(fd_audio, AUDIO_STOP, true));
|
||||||
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
CHECK(ioctl(fd_audio, AUDIO_CLEAR_BUFFER));
|
||||||
@ -858,8 +861,6 @@ bool cDvbDevice::SetPlayMode(ePlayMode PlayMode)
|
|||||||
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
|
CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false));
|
||||||
break;
|
break;
|
||||||
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
case pmExtern_THIS_SHOULD_BE_AVOIDED:
|
||||||
if (siProcessor)
|
|
||||||
siProcessor->SetStatus(false);
|
|
||||||
close(fd_video);
|
close(fd_video);
|
||||||
close(fd_audio);
|
close(fd_audio);
|
||||||
fd_video = fd_audio = -1;
|
fd_video = fd_audio = -1;
|
||||||
|
13
dvbdevice.h
13
dvbdevice.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __DVBDEVICE_H
|
||||||
@ -14,7 +14,6 @@
|
|||||||
#include <linux/dvb/version.h>
|
#include <linux/dvb/version.h>
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "dvbspu.h"
|
#include "dvbspu.h"
|
||||||
#include "eit.h"
|
|
||||||
|
|
||||||
#if DVB_API_VERSION != 3
|
#if DVB_API_VERSION != 3
|
||||||
#error VDR requires Linux DVB driver API version 3!
|
#error VDR requires Linux DVB driver API version 3!
|
||||||
@ -71,6 +70,11 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
|
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
|
// Image Grab facilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -95,11 +99,6 @@ protected:
|
|||||||
virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
|
virtual const char **GetAudioTracksDevice(int *CurrentTrack = NULL) const;
|
||||||
virtual void SetAudioTrackDevice(int Index);
|
virtual void SetAudioTrackDevice(int Index);
|
||||||
|
|
||||||
// EIT facilities
|
|
||||||
|
|
||||||
private:
|
|
||||||
cSIProcessor *siProcessor;
|
|
||||||
|
|
||||||
// Player facilities
|
// Player facilities
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
190
eit.h
190
eit.h
@ -1,186 +1,22 @@
|
|||||||
/***************************************************************************
|
/*
|
||||||
eit.h - description
|
* eit.h: EIT section filter
|
||||||
-------------------
|
*
|
||||||
begin : Fri Aug 25 2000
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
copyright : (C) 2000 by Robert Schneider
|
* how to reach the author.
|
||||||
email : Robert.Schneider@web.de
|
*
|
||||||
|
* $Id: eit.h 1.30 2003/12/21 14:51:50 kls Exp $
|
||||||
2001-08-15: Adapted to 'libdtv' by Rolf Hakenes <hakenes@hippomi.de>
|
*/
|
||||||
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* *
|
|
||||||
* 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 $
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __EIT_H
|
#ifndef __EIT_H
|
||||||
#define __EIT_H
|
#define __EIT_H
|
||||||
|
|
||||||
#include "channels.h"
|
#include "filter.h"
|
||||||
#include "thread.h"
|
|
||||||
#include "tools.h"
|
|
||||||
|
|
||||||
#define MAXEPGBUGFIXLEVEL 2
|
class cEitFilter : public cFilter {
|
||||||
|
|
||||||
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)
|
|
||||||
protected:
|
protected:
|
||||||
void SetTableID(unsigned char tableid);
|
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
|
||||||
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);
|
|
||||||
public:
|
public:
|
||||||
~cEventInfo();
|
cEitFilter(void);
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class cSchedule : public cListObject {
|
#endif //__EIT_H
|
||||||
friend class cSchedules;
|
|
||||||
friend class cEIT;
|
|
||||||
private:
|
|
||||||
cEventInfo *pPresent;
|
|
||||||
cEventInfo *pFollowing;
|
|
||||||
tChannelID channelID;
|
|
||||||
cList<cEventInfo> 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<cSchedule> {
|
|
||||||
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<cCaDescriptor> 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
|
|
||||||
|
669
epg.c
Normal file
669
epg.c
Normal file
@ -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 <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||||
|
*
|
||||||
|
* $Id: epg.c 1.1 2003/12/22 13:07:32 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "epg.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
// --- 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;
|
||||||
|
}
|
||||||
|
|
130
epg.h
Normal file
130
epg.h
Normal file
@ -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 <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||||
|
*
|
||||||
|
* $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<cEvent> 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<cSchedule> {
|
||||||
|
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
|
126
filter.c
Normal file
126
filter.c
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
74
filter.h
Normal file
74
filter.h
Normal file
@ -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 <sys/types.h>
|
||||||
|
#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<cFilterData> 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
|
339
libdtv/COPYING
339
libdtv/COPYING
@ -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.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) 19yy <name of author>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 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.
|
|
@ -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 <hakenes@hippomi.de>, 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
|
|
@ -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 <hakenes@hippomi.de>, 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.
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) 19yy <name of author>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 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.
|
|
@ -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 <hakenes@hippomi.de>, 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
|
|
||||||
|
|
@ -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 <hakenes@hippomi.de>, 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
|
|
@ -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 <hakenes@hippomi.de>, 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 <string.h>
|
|
||||||
#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);
|
|
||||||
}
|
|
@ -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 <hakenes@hippomi.de>, 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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
@ -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.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) 19yy <name of author>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 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.
|
|
@ -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 <hakenes@hippomi.de>, 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
|
|
@ -1,2 +0,0 @@
|
|||||||
DVB - System Information Library
|
|
||||||
================================
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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 <hakenes@hippomi.de>, 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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
@ -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 <hakenes@hippomi.de>, 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
|
|
File diff suppressed because it is too large
Load Diff
@ -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.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) 19yy <name of author>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
<signature of Ty Coon>, 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.
|
|
@ -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 <hakenes@hippomi.de>, 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
|
|
||||||
|
|
@ -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 <hakenes@hippomi.de>, 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 <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <liblx.h>
|
|
||||||
#include <libsi.h>
|
|
||||||
#include <si_tables.h>
|
|
||||||
#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);
|
|
||||||
}
|
|
@ -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 <hakenes@hippomi.de>, 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
|
|
184
menu.c
184
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "menu.h"
|
||||||
@ -16,7 +16,6 @@
|
|||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "cutter.h"
|
#include "cutter.h"
|
||||||
#include "eit.h"
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "menuitems.h"
|
#include "menuitems.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
@ -1128,29 +1127,29 @@ eOSState cMenuTimers::ProcessKey(eKeys Key)
|
|||||||
|
|
||||||
class cMenuEvent : public cOsdMenu {
|
class cMenuEvent : public cOsdMenu {
|
||||||
private:
|
private:
|
||||||
const cEventInfo *eventInfo;
|
const cEvent *event;
|
||||||
public:
|
public:
|
||||||
cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch = false);
|
cMenuEvent(const cEvent *Event, bool CanSwitch = false);
|
||||||
cMenuEvent(bool Now);
|
cMenuEvent(bool Now);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch)
|
cMenuEvent::cMenuEvent(const cEvent *Event, bool CanSwitch)
|
||||||
:cOsdMenu(tr("Event"))
|
:cOsdMenu(tr("Event"))
|
||||||
{
|
{
|
||||||
eventInfo = EventInfo;
|
event = Event;
|
||||||
if (eventInfo) {
|
if (event) {
|
||||||
cChannel *channel = Channels.GetByChannelID(eventInfo->GetChannelID(), true);
|
cChannel *channel = Channels.GetByChannelID(event->ChannelID(), true);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
char *buffer;
|
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);
|
SetTitle(buffer, false);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
int Line = 2;
|
int Line = 2;
|
||||||
cMenuTextItem *item;
|
cMenuTextItem *item;
|
||||||
const char *Title = eventInfo->GetTitle();
|
const char *Title = event->Title();
|
||||||
const char *Subtitle = eventInfo->GetSubtitle();
|
const char *Subtitle = event->ShortText();
|
||||||
const char *ExtendedDescription = eventInfo->GetExtendedDescription();
|
const char *ExtendedDescription = event->Description();
|
||||||
if (!isempty(Title)) {
|
if (!isempty(Title)) {
|
||||||
Add(item = new cMenuTextItem(Title, 1, Line, Setup.OSDwidth - 2, -1, clrCyan));
|
Add(item = new cMenuTextItem(Title, 1, Line, Setup.OSDwidth - 2, -1, clrCyan));
|
||||||
Line += item->Height() + 1;
|
Line += item->Height() + 1;
|
||||||
@ -1185,16 +1184,16 @@ eOSState cMenuEvent::ProcessKey(eKeys Key)
|
|||||||
|
|
||||||
class cMenuWhatsOnItem : public cOsdItem {
|
class cMenuWhatsOnItem : public cOsdItem {
|
||||||
public:
|
public:
|
||||||
const cEventInfo *eventInfo;
|
const cEvent *event;
|
||||||
cMenuWhatsOnItem(const cEventInfo *EventInfo);
|
cMenuWhatsOnItem(const cEvent *Event);
|
||||||
};
|
};
|
||||||
|
|
||||||
cMenuWhatsOnItem::cMenuWhatsOnItem(const cEventInfo *EventInfo)
|
cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event)
|
||||||
{
|
{
|
||||||
eventInfo = EventInfo;
|
event = Event;
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
cChannel *channel = Channels.GetByNumber(eventInfo->GetChannelNumber());
|
cChannel *channel = Channels.GetByNumber(event->ChannelNumber());
|
||||||
asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", eventInfo->GetChannelNumber(), 6, channel ? channel->Name() : "???", 5, eventInfo->GetTimeString(), eventInfo->GetTitle());
|
asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", event->ChannelNumber(), 6, channel ? channel->Name() : "???", 5, event->GetTimeString(), event->Title());
|
||||||
SetText(buffer, false);
|
SetText(buffer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1205,36 +1204,36 @@ private:
|
|||||||
eOSState Record(void);
|
eOSState Record(void);
|
||||||
eOSState Switch(void);
|
eOSState Switch(void);
|
||||||
static int currentChannel;
|
static int currentChannel;
|
||||||
static const cEventInfo *scheduleEventInfo;
|
static const cEvent *scheduleEvent;
|
||||||
public:
|
public:
|
||||||
cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr);
|
cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr);
|
||||||
static int CurrentChannel(void) { return currentChannel; }
|
static int CurrentChannel(void) { return currentChannel; }
|
||||||
static void SetCurrentChannel(int ChannelNr) { currentChannel = ChannelNr; }
|
static void SetCurrentChannel(int ChannelNr) { currentChannel = ChannelNr; }
|
||||||
static const cEventInfo *ScheduleEventInfo(void);
|
static const cEvent *ScheduleEvent(void);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
int cMenuWhatsOn::currentChannel = 0;
|
int cMenuWhatsOn::currentChannel = 0;
|
||||||
const cEventInfo *cMenuWhatsOn::scheduleEventInfo = NULL;
|
const cEvent *cMenuWhatsOn::scheduleEvent = NULL;
|
||||||
|
|
||||||
static int CompareEventChannel(const void *p1, const void *p2)
|
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)
|
cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr)
|
||||||
:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6)
|
:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6)
|
||||||
{
|
{
|
||||||
const cSchedule *Schedule = Schedules->First();
|
const cSchedule *Schedule = Schedules->First();
|
||||||
const cEventInfo **pArray = NULL;
|
const cEvent **pArray = NULL;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
||||||
while (Schedule) {
|
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();
|
pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
|
||||||
if (pArray[num]) {
|
if (pArray[num]) {
|
||||||
cChannel *channel = Channels.GetByChannelID(pArray[num]->GetChannelID(), true);
|
cChannel *channel = Channels.GetByChannelID(pArray[num]->ChannelID(), true);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
pArray[num]->SetChannelNumber(channel->Number());
|
pArray[num]->SetChannelNumber(channel->Number());
|
||||||
num++;
|
num++;
|
||||||
@ -1243,20 +1242,20 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha
|
|||||||
Schedule = (const cSchedule *)Schedules->Next(Schedule);
|
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++)
|
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;
|
currentChannel = CurrentChannelNr;
|
||||||
free(pArray);
|
free(pArray);
|
||||||
SetHelp(Count() ? tr("Record") : NULL, Now ? tr("Next") : tr("Now"), tr("Button$Schedule"), tr("Switch"));
|
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;
|
const cEvent *ei = scheduleEvent;
|
||||||
scheduleEventInfo = NULL;
|
scheduleEvent = NULL;
|
||||||
return ei;
|
return ei;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1264,7 +1263,7 @@ eOSState cMenuWhatsOn::Switch(void)
|
|||||||
{
|
{
|
||||||
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
||||||
if (item) {
|
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))
|
if (channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true))
|
||||||
return osEnd;
|
return osEnd;
|
||||||
}
|
}
|
||||||
@ -1276,7 +1275,7 @@ eOSState cMenuWhatsOn::Record(void)
|
|||||||
{
|
{
|
||||||
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
||||||
if (item) {
|
if (item) {
|
||||||
cTimer *timer = new cTimer(item->eventInfo);
|
cTimer *timer = new cTimer(item->event);
|
||||||
cTimer *t = Timers.GetTimer(timer);
|
cTimer *t = Timers.GetTimer(timer);
|
||||||
if (t) {
|
if (t) {
|
||||||
delete timer;
|
delete timer;
|
||||||
@ -1300,14 +1299,14 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
|
|||||||
case kGreen: {
|
case kGreen: {
|
||||||
cMenuWhatsOnItem *mi = (cMenuWhatsOnItem *)Get(Current());
|
cMenuWhatsOnItem *mi = (cMenuWhatsOnItem *)Get(Current());
|
||||||
if (mi) {
|
if (mi) {
|
||||||
scheduleEventInfo = mi->eventInfo;
|
scheduleEvent = mi->event;
|
||||||
currentChannel = mi->eventInfo->GetChannelNumber();
|
currentChannel = mi->event->ChannelNumber();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kBlue: return Switch();
|
case kBlue: return Switch();
|
||||||
case kOk: if (Count())
|
case kOk: if (Count())
|
||||||
return AddSubMenu(new cMenuEvent(((cMenuWhatsOnItem *)Get(Current()))->eventInfo, true));
|
return AddSubMenu(new cMenuEvent(((cMenuWhatsOnItem *)Get(Current()))->event, true));
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@ -1319,15 +1318,15 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
|
|||||||
|
|
||||||
class cMenuScheduleItem : public cOsdItem {
|
class cMenuScheduleItem : public cOsdItem {
|
||||||
public:
|
public:
|
||||||
const cEventInfo *eventInfo;
|
const cEvent *event;
|
||||||
cMenuScheduleItem(const cEventInfo *EventInfo);
|
cMenuScheduleItem(const cEvent *Event);
|
||||||
};
|
};
|
||||||
|
|
||||||
cMenuScheduleItem::cMenuScheduleItem(const cEventInfo *EventInfo)
|
cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event)
|
||||||
{
|
{
|
||||||
eventInfo = EventInfo;
|
event = Event;
|
||||||
char *buffer = NULL;
|
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);
|
SetText(buffer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1335,7 +1334,7 @@ cMenuScheduleItem::cMenuScheduleItem(const cEventInfo *EventInfo)
|
|||||||
|
|
||||||
class cMenuSchedule : public cOsdMenu {
|
class cMenuSchedule : public cOsdMenu {
|
||||||
private:
|
private:
|
||||||
cMutexLock mutexLock;
|
cSchedulesLock schedulesLock;
|
||||||
const cSchedules *schedules;
|
const cSchedules *schedules;
|
||||||
bool now, next;
|
bool now, next;
|
||||||
int otherChannel;
|
int otherChannel;
|
||||||
@ -1356,7 +1355,7 @@ cMenuSchedule::cMenuSchedule(void)
|
|||||||
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
||||||
if (channel) {
|
if (channel) {
|
||||||
cMenuWhatsOn::SetCurrentChannel(channel->Number());
|
cMenuWhatsOn::SetCurrentChannel(channel->Number());
|
||||||
schedules = cSIProcessor::Schedules(mutexLock);
|
schedules = cSchedules::Schedules(schedulesLock);
|
||||||
PrepareSchedule(channel);
|
PrepareSchedule(channel);
|
||||||
SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"));
|
SetHelp(Count() ? tr("Record") : NULL, tr("Now"), tr("Next"));
|
||||||
}
|
}
|
||||||
@ -1364,12 +1363,12 @@ cMenuSchedule::cMenuSchedule(void)
|
|||||||
|
|
||||||
cMenuSchedule::~cMenuSchedule()
|
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)
|
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)
|
void cMenuSchedule::PrepareSchedule(cChannel *Channel)
|
||||||
@ -1382,17 +1381,17 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
|
|||||||
if (schedules) {
|
if (schedules) {
|
||||||
const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID());
|
const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID());
|
||||||
int num = Schedule->NumEvents();
|
int num = Schedule->NumEvents();
|
||||||
const cEventInfo **pArray = MALLOC(const cEventInfo *, num);
|
const cEvent **pArray = MALLOC(const cEvent *, num);
|
||||||
if (pArray) {
|
if (pArray) {
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
int numreal = 0;
|
int numreal = 0;
|
||||||
for (int a = 0; a < num; a++) {
|
for (int a = 0; a < num; a++) {
|
||||||
const cEventInfo *EventInfo = Schedule->GetEventNumber(a);
|
const cEvent *Event = Schedule->GetEventNumber(a);
|
||||||
if (EventInfo->GetTime() + EventInfo->GetDuration() > now)
|
if (Event->StartTime() + Event->Duration() > now)
|
||||||
pArray[numreal++] = EventInfo;
|
pArray[numreal++] = Event;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(pArray, numreal, sizeof(cEventInfo *), CompareEventTime);
|
qsort(pArray, numreal, sizeof(cEvent *), CompareEventTime);
|
||||||
|
|
||||||
for (int a = 0; a < numreal; a++)
|
for (int a = 0; a < numreal; a++)
|
||||||
Add(new cMenuScheduleItem(pArray[a]));
|
Add(new cMenuScheduleItem(pArray[a]));
|
||||||
@ -1405,7 +1404,7 @@ eOSState cMenuSchedule::Record(void)
|
|||||||
{
|
{
|
||||||
cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current());
|
cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current());
|
||||||
if (item) {
|
if (item) {
|
||||||
cTimer *timer = new cTimer(item->eventInfo);
|
cTimer *timer = new cTimer(item->event);
|
||||||
cTimer *t = Timers.GetTimer(timer);
|
cTimer *t = Timers.GetTimer(timer);
|
||||||
if (t) {
|
if (t) {
|
||||||
delete timer;
|
delete timer;
|
||||||
@ -1438,7 +1437,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
|
|||||||
if (!now && !next) {
|
if (!now && !next) {
|
||||||
int ChannelNr = 0;
|
int ChannelNr = 0;
|
||||||
if (Count()) {
|
if (Count()) {
|
||||||
cChannel *channel = Channels.GetByChannelID(((cMenuScheduleItem *)Get(Current()))->eventInfo->GetChannelID(), true);
|
cChannel *channel = Channels.GetByChannelID(((cMenuScheduleItem *)Get(Current()))->event->ChannelID(), true);
|
||||||
if (channel)
|
if (channel)
|
||||||
ChannelNr = channel->Number();
|
ChannelNr = channel->Number();
|
||||||
}
|
}
|
||||||
@ -1456,16 +1455,16 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
|
|||||||
return Switch();
|
return Switch();
|
||||||
break;
|
break;
|
||||||
case kOk: if (Count())
|
case kOk: if (Count())
|
||||||
return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->eventInfo, otherChannel));
|
return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->event, otherChannel));
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!HasSubMenu()) {
|
else if (!HasSubMenu()) {
|
||||||
now = next = false;
|
now = next = false;
|
||||||
const cEventInfo *ei = cMenuWhatsOn::ScheduleEventInfo();
|
const cEvent *ei = cMenuWhatsOn::ScheduleEvent();
|
||||||
if (ei) {
|
if (ei) {
|
||||||
cChannel *channel = Channels.GetByChannelID(ei->GetChannelID(), true);
|
cChannel *channel = Channels.GetByChannelID(ei->ChannelID(), true);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
PrepareSchedule(channel);
|
PrepareSchedule(channel);
|
||||||
if (channel->Number() != cDevice::CurrentChannel()) {
|
if (channel->Number() != cDevice::CurrentChannel()) {
|
||||||
@ -2633,10 +2632,10 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched)
|
|||||||
int EpgLines = withInfo ? 5 : 1;
|
int EpgLines = withInfo ? 5 : 1;
|
||||||
lines = 0;
|
lines = 0;
|
||||||
number = 0;
|
number = 0;
|
||||||
cChannel *channel = Channels.GetByNumber(Number);
|
channel = Channels.GetByNumber(Number);
|
||||||
Interface->Open(Setup.OSDwidth, Setup.ChannelInfoPos ? EpgLines : -EpgLines);
|
Interface->Open(Setup.OSDwidth, Setup.ChannelInfoPos ? EpgLines : -EpgLines);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
DisplayChannel(channel);
|
DisplayChannel();
|
||||||
DisplayInfo();
|
DisplayInfo();
|
||||||
}
|
}
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
@ -2660,16 +2659,16 @@ cDisplayChannel::~cDisplayChannel()
|
|||||||
Interface->Close();
|
Interface->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDisplayChannel::DisplayChannel(const cChannel *Channel)
|
void cDisplayChannel::DisplayChannel(void)
|
||||||
{
|
{
|
||||||
int BufSize = Width() + 1;
|
int BufSize = Width() + 1;
|
||||||
char buffer[BufSize];
|
char buffer[BufSize];
|
||||||
*buffer = 0;
|
*buffer = 0;
|
||||||
if (Channel) {
|
if (channel) {
|
||||||
if (Channel->GroupSep())
|
if (channel->GroupSep())
|
||||||
snprintf(buffer, BufSize, "%s", Channel->Name());
|
snprintf(buffer, BufSize, "%s", channel->Name());
|
||||||
else
|
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)
|
else if (number)
|
||||||
snprintf(buffer, BufSize, "%d-", number);
|
snprintf(buffer, BufSize, "%d-", number);
|
||||||
@ -2684,28 +2683,28 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel)
|
|||||||
|
|
||||||
void cDisplayChannel::DisplayInfo(void)
|
void cDisplayChannel::DisplayInfo(void)
|
||||||
{
|
{
|
||||||
if (withInfo) {
|
if (withInfo && channel) {
|
||||||
const cEventInfo *Present = NULL, *Following = NULL;
|
const cEvent *Present = NULL, *Following = NULL;
|
||||||
cMutexLock MutexLock;
|
cSchedulesLock SchedulesLock;
|
||||||
const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
|
const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
|
||||||
if (Schedules) {
|
if (Schedules) {
|
||||||
const cSchedule *Schedule = Schedules->GetSchedule();
|
const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
|
||||||
if (Schedule) {
|
if (Schedule) {
|
||||||
const char *PresentTitle = NULL, *PresentSubtitle = NULL, *FollowingTitle = NULL, *FollowingSubtitle = NULL;
|
const char *PresentTitle = NULL, *PresentSubtitle = NULL, *FollowingTitle = NULL, *FollowingSubtitle = NULL;
|
||||||
int Lines = 0;
|
int Lines = 0;
|
||||||
if ((Present = Schedule->GetPresentEvent()) != NULL) {
|
if ((Present = Schedule->GetPresentEvent()) != NULL) {
|
||||||
PresentTitle = Present->GetTitle();
|
PresentTitle = Present->Title();
|
||||||
if (!isempty(PresentTitle))
|
if (!isempty(PresentTitle))
|
||||||
Lines++;
|
Lines++;
|
||||||
PresentSubtitle = Present->GetSubtitle();
|
PresentSubtitle = Present->ShortText();
|
||||||
if (!isempty(PresentSubtitle))
|
if (!isempty(PresentSubtitle))
|
||||||
Lines++;
|
Lines++;
|
||||||
}
|
}
|
||||||
if ((Following = Schedule->GetFollowingEvent()) != NULL) {
|
if ((Following = Schedule->GetFollowingEvent()) != NULL) {
|
||||||
FollowingTitle = Following->GetTitle();
|
FollowingTitle = Following->Title();
|
||||||
if (!isempty(FollowingTitle))
|
if (!isempty(FollowingTitle))
|
||||||
Lines++;
|
Lines++;
|
||||||
FollowingSubtitle = Following->GetSubtitle();
|
FollowingSubtitle = Following->ShortText();
|
||||||
if (!isempty(FollowingSubtitle))
|
if (!isempty(FollowingSubtitle))
|
||||||
Lines++;
|
Lines++;
|
||||||
}
|
}
|
||||||
@ -2733,7 +2732,7 @@ void cDisplayChannel::DisplayInfo(void)
|
|||||||
Interface->Flush();
|
Interface->Flush();
|
||||||
lines = Lines;
|
lines = Lines;
|
||||||
lastTime = time_ms();
|
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)
|
void cDisplayChannel::Refresh(void)
|
||||||
{
|
{
|
||||||
Interface->Clear();
|
Interface->Clear();
|
||||||
DisplayChannel(Channels.GetByNumber(cDevice::CurrentChannel()));
|
channel = Channels.GetByNumber(cDevice::CurrentChannel());
|
||||||
|
DisplayChannel();
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
lines = 0;
|
lines = 0;
|
||||||
}
|
}
|
||||||
@ -2761,20 +2761,21 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
if (number >= 0) {
|
if (number >= 0) {
|
||||||
number = number * 10 + Key - k0;
|
number = number * 10 + Key - k0;
|
||||||
if (number > 0) {
|
if (number > 0) {
|
||||||
cChannel *channel = Channels.GetByNumber(number);
|
channel = Channels.GetByNumber(number);
|
||||||
Interface->Clear();
|
Interface->Clear();
|
||||||
withInfo = false;
|
withInfo = false;
|
||||||
DisplayChannel(channel);
|
DisplayChannel();
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
// Lets see if there can be any useful further input:
|
// Lets see if there can be any useful further input:
|
||||||
int n = channel ? number * 10 : 0;
|
int n = channel ? number * 10 : 0;
|
||||||
while (channel && (channel = Channels.Next(channel)) != NULL) {
|
cChannel *ch = channel;
|
||||||
if (!channel->GroupSep()) {
|
while (ch && (ch = Channels.Next(ch)) != NULL) {
|
||||||
if (n <= channel->Number() && channel->Number() <= n + 9) {
|
if (!ch->GroupSep()) {
|
||||||
|
if (n <= ch->Number() && ch->Number() <= n + 9) {
|
||||||
n = 0;
|
n = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (channel->Number() > n)
|
if (ch->Number() > n)
|
||||||
n *= 10;
|
n *= 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2805,10 +2806,10 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
group = Channels.GetPrevGroup(group < 1 ? 1 : group);
|
group = Channels.GetPrevGroup(group < 1 ? 1 : group);
|
||||||
if (group < 0)
|
if (group < 0)
|
||||||
group = SaveGroup;
|
group = SaveGroup;
|
||||||
cChannel *channel = Channels.Get(group);
|
channel = Channels.Get(group);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
Interface->Clear();
|
Interface->Clear();
|
||||||
DisplayChannel(channel);
|
DisplayChannel();
|
||||||
if (!channel->GroupSep())
|
if (!channel->GroupSep())
|
||||||
group = -1;
|
group = -1;
|
||||||
}
|
}
|
||||||
@ -2835,7 +2836,8 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
|||||||
Channels.SwitchTo(number);
|
Channels.SwitchTo(number);
|
||||||
else {
|
else {
|
||||||
number = 0;
|
number = 0;
|
||||||
DisplayChannel(NULL);
|
channel = NULL;
|
||||||
|
DisplayChannel();
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
return osContinue;
|
return osContinue;
|
||||||
}
|
}
|
||||||
@ -2967,7 +2969,7 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key)
|
|||||||
|
|
||||||
cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
|
cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
|
||||||
{
|
{
|
||||||
eventInfo = NULL;
|
event = NULL;
|
||||||
instantId = NULL;
|
instantId = NULL;
|
||||||
fileName = NULL;
|
fileName = NULL;
|
||||||
recorder = NULL;
|
recorder = NULL;
|
||||||
@ -2986,10 +2988,10 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
|
|||||||
const char *Title = NULL;
|
const char *Title = NULL;
|
||||||
const char *Subtitle = NULL;
|
const char *Subtitle = NULL;
|
||||||
const char *Summary = NULL;
|
const char *Summary = NULL;
|
||||||
if (GetEventInfo()) {
|
if (GetEvent()) {
|
||||||
Title = eventInfo->GetTitle();
|
Title = event->Title();
|
||||||
Subtitle = eventInfo->GetSubtitle();
|
Subtitle = event->ShortText();
|
||||||
Summary = eventInfo->GetExtendedDescription();
|
Summary = event->Description();
|
||||||
dsyslog("Title: '%s' Subtitle: '%s'", Title, Subtitle);
|
dsyslog("Title: '%s' Subtitle: '%s'", Title, Subtitle);
|
||||||
}
|
}
|
||||||
cRecording Recording(timer, Title, Subtitle, Summary);
|
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
|
#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();
|
const cChannel *channel = timer->Channel();
|
||||||
time_t Time = timer->Active() == taActInst ? timer->StartTime() + INSTANT_REC_EPG_LOOKAHEAD : timer->StartTime() + (timer->StopTime() - timer->StartTime()) / 2;
|
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++) {
|
for (int seconds = 0; seconds <= MAXWAIT4EPGINFO; seconds++) {
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock;
|
cSchedulesLock SchedulesLock;
|
||||||
const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
|
const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
|
||||||
if (Schedules) {
|
if (Schedules) {
|
||||||
const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
|
const cSchedule *Schedule = Schedules->GetSchedule(channel->GetChannelID());
|
||||||
if (Schedule) {
|
if (Schedule) {
|
||||||
eventInfo = Schedule->GetEventAround(Time);
|
event = Schedule->GetEventAround(Time);
|
||||||
if (eventInfo) {
|
if (event) {
|
||||||
if (seconds > 0)
|
if (seconds > 0)
|
||||||
dsyslog("got EPG info after %d seconds", seconds);
|
dsyslog("got EPG info after %d seconds", seconds);
|
||||||
return true;
|
return true;
|
||||||
|
10
menu.h
10
menu.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __MENU_H
|
||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "ci.h"
|
#include "ci.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "epg.h"
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
#include "dvbplayer.h"
|
#include "dvbplayer.h"
|
||||||
#include "recorder.h"
|
#include "recorder.h"
|
||||||
@ -36,7 +37,8 @@ private:
|
|||||||
int lines;
|
int lines;
|
||||||
int lastTime;
|
int lastTime;
|
||||||
int number;
|
int number;
|
||||||
void DisplayChannel(const cChannel *Channel);
|
cChannel *channel;
|
||||||
|
void DisplayChannel(void);
|
||||||
void DisplayInfo(void);
|
void DisplayInfo(void);
|
||||||
void Refresh(void);
|
void Refresh(void);
|
||||||
public:
|
public:
|
||||||
@ -113,10 +115,10 @@ private:
|
|||||||
cDevice *device;
|
cDevice *device;
|
||||||
cTimer *timer;
|
cTimer *timer;
|
||||||
cRecorder *recorder;
|
cRecorder *recorder;
|
||||||
const cEventInfo *eventInfo;
|
const cEvent *event;
|
||||||
char *instantId;
|
char *instantId;
|
||||||
char *fileName;
|
char *fileName;
|
||||||
bool GetEventInfo(void);
|
bool GetEvent(void);
|
||||||
public:
|
public:
|
||||||
cRecordControl(cDevice *Device, cTimer *Timer = NULL, bool Pause = false);
|
cRecordControl(cDevice *Device, cTimer *Timer = NULL, bool Pause = false);
|
||||||
virtual ~cRecordControl();
|
virtual ~cRecordControl();
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# See the main source file 'vdr.c' for copyright information and
|
# See the main source file 'vdr.c' for copyright information and
|
||||||
# how to reach the author.
|
# 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 <name>\n";
|
$PLUGIN_NAME = $ARGV[0] || die "Usage: newplugin <name>\n";
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ PACKAGE = vdr-\$(ARCHIVE)
|
|||||||
|
|
||||||
INCLUDES += -I\$(VDRDIR)/include -I\$(DVBDIR)/include
|
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):
|
### The object files (add further files here):
|
||||||
|
|
||||||
|
219
pat.c
Normal file
219
pat.c
Normal file
@ -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 <malloc.h>
|
||||||
|
#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<cCaDescriptor> {
|
||||||
|
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 <hakenes@hippomi.de>.
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
36
pat.h
Normal file
36
pat.h
Normal file
@ -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
|
180
sections.c
Normal file
180
sections.c
Normal file
@ -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 <unistd.h>
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
sections.h
Normal file
45
sections.h
Normal file
@ -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<cFilter> filters;
|
||||||
|
cList<cFilterHandle> 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
|
10
svdrp.c
10
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* 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"
|
#include "svdrp.h"
|
||||||
@ -155,7 +155,7 @@ bool cPUTEhandler::Process(const char *s)
|
|||||||
else {
|
else {
|
||||||
rewind(f);
|
rewind(f);
|
||||||
if (cSchedules::Read(f)) {
|
if (cSchedules::Read(f)) {
|
||||||
cSIProcessor::TriggerDump();
|
cSchedules::Cleanup(true);
|
||||||
status = 250;
|
status = 250;
|
||||||
message = "EPG data processed";
|
message = "EPG data processed";
|
||||||
}
|
}
|
||||||
@ -458,7 +458,7 @@ void cSVDRP::CmdCHAN(const char *Option)
|
|||||||
|
|
||||||
void cSVDRP::CmdCLRE(const char *Option)
|
void cSVDRP::CmdCLRE(const char *Option)
|
||||||
{
|
{
|
||||||
cSIProcessor::Clear();
|
cSchedules::ClearAll();
|
||||||
Reply(250, "EPG data cleared");
|
Reply(250, "EPG data cleared");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,8 +707,8 @@ void cSVDRP::CmdLSTC(const char *Option)
|
|||||||
|
|
||||||
void cSVDRP::CmdLSTE(const char *Option)
|
void cSVDRP::CmdLSTE(const char *Option)
|
||||||
{
|
{
|
||||||
cMutexLock MutexLock;
|
cSchedulesLock SchedulesLock;
|
||||||
const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock);
|
const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
|
||||||
if (Schedules) {
|
if (Schedules) {
|
||||||
FILE *f = fdopen(file, "w");
|
FILE *f = fdopen(file, "w");
|
||||||
if (f) {
|
if (f) {
|
||||||
|
35
thread.c
35
thread.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#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::cMutex(void)
|
cMutex::cMutex(void)
|
||||||
|
12
thread.h
12
thread.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __THREAD_H
|
||||||
@ -28,6 +28,16 @@ public:
|
|||||||
//void Signal(void);
|
//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 {
|
class cMutex {
|
||||||
friend class cCondVar;
|
friend class cCondVar;
|
||||||
private:
|
private:
|
||||||
|
14
timers.c
14
timers.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#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());
|
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;
|
startTime = stopTime = 0;
|
||||||
recording = pending = false;
|
recording = pending = false;
|
||||||
active = true;
|
active = true;
|
||||||
channel = Channels.GetByChannelID(EventInfo->GetChannelID(), true);
|
channel = Channels.GetByChannelID(Event->ChannelID(), true);
|
||||||
time_t tstart = EventInfo->GetTime();
|
time_t tstart = Event->StartTime();
|
||||||
time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60;
|
time_t tstop = tstart + Event->Duration() + Setup.MarginStop * 60;
|
||||||
tstart -= Setup.MarginStart * 60;
|
tstart -= Setup.MarginStart * 60;
|
||||||
struct tm tm_r;
|
struct tm tm_r;
|
||||||
struct tm *time = localtime_r(&tstart, &tm_r);
|
struct tm *time = localtime_r(&tstart, &tm_r);
|
||||||
@ -64,9 +64,9 @@ cTimer::cTimer(const cEventInfo *EventInfo)
|
|||||||
priority = Setup.DefaultPriority;
|
priority = Setup.DefaultPriority;
|
||||||
lifetime = Setup.DefaultLifetime;
|
lifetime = Setup.DefaultLifetime;
|
||||||
*file = 0;
|
*file = 0;
|
||||||
const char *Title = EventInfo->GetTitle();
|
const char *Title = Event->Title();
|
||||||
if (!isempty(Title))
|
if (!isempty(Title))
|
||||||
strn0cpy(file, EventInfo->GetTitle(), sizeof(file));
|
strn0cpy(file, Event->Title(), sizeof(file));
|
||||||
firstday = 0;
|
firstday = 0;
|
||||||
summary = NULL;
|
summary = NULL;
|
||||||
}
|
}
|
||||||
|
6
timers.h
6
timers.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __TIMERS_H
|
||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include "channels.h"
|
#include "channels.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "eit.h"
|
#include "epg.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
enum eTimerActive { taInactive = 0,
|
enum eTimerActive { taInactive = 0,
|
||||||
@ -39,7 +39,7 @@ private:
|
|||||||
char *summary;
|
char *summary;
|
||||||
public:
|
public:
|
||||||
cTimer(bool Instant = false, bool Pause = false);
|
cTimer(bool Instant = false, bool Pause = false);
|
||||||
cTimer(const cEventInfo *EventInfo);
|
cTimer(const cEvent *Event);
|
||||||
virtual ~cTimer();
|
virtual ~cTimer();
|
||||||
cTimer& operator= (const cTimer &Timer);
|
cTimer& operator= (const cTimer &Timer);
|
||||||
virtual bool operator< (const cListObject &ListObject);
|
virtual bool operator< (const cListObject &ListObject);
|
||||||
|
27
vdr.c
27
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/vdr
|
* 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 <getopt.h>
|
#include <getopt.h>
|
||||||
@ -39,6 +39,7 @@
|
|||||||
#include "diseqc.h"
|
#include "diseqc.h"
|
||||||
#include "dvbdevice.h"
|
#include "dvbdevice.h"
|
||||||
#include "eitscan.h"
|
#include "eitscan.h"
|
||||||
|
#include "epg.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
@ -93,10 +94,12 @@ int main(int argc, char *argv[])
|
|||||||
#define DEFAULTSVDRPPORT 2001
|
#define DEFAULTSVDRPPORT 2001
|
||||||
#define DEFAULTWATCHDOG 0 // seconds
|
#define DEFAULTWATCHDOG 0 // seconds
|
||||||
#define DEFAULTPLUGINDIR PLUGINDIR
|
#define DEFAULTPLUGINDIR PLUGINDIR
|
||||||
|
#define DEFAULTEPGDATAFILENAME "epg.data"
|
||||||
|
|
||||||
int SVDRPport = DEFAULTSVDRPPORT;
|
int SVDRPport = DEFAULTSVDRPPORT;
|
||||||
const char *AudioCommand = NULL;
|
const char *AudioCommand = NULL;
|
||||||
const char *ConfigDirectory = NULL;
|
const char *ConfigDirectory = NULL;
|
||||||
|
const char *EpgDataFileName = DEFAULTEPGDATAFILENAME;
|
||||||
bool DisplayHelp = false;
|
bool DisplayHelp = false;
|
||||||
bool DisplayVersion = false;
|
bool DisplayVersion = false;
|
||||||
bool DaemonMode = false;
|
bool DaemonMode = false;
|
||||||
@ -146,7 +149,7 @@ int main(int argc, char *argv[])
|
|||||||
fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg);
|
fprintf(stderr, "vdr: invalid DVB device number: %s\n", optarg);
|
||||||
return 2;
|
return 2;
|
||||||
break;
|
break;
|
||||||
case 'E': cSIProcessor::SetEpgDataFileName(*optarg != '-' ? optarg : NULL);
|
case 'E': EpgDataFileName = (*optarg != '-' ? optarg : NULL);
|
||||||
break;
|
break;
|
||||||
case 'h': DisplayHelp = true;
|
case 'h': DisplayHelp = true;
|
||||||
break;
|
break;
|
||||||
@ -239,7 +242,8 @@ int main(int argc, char *argv[])
|
|||||||
" there may be several -D options (default: all DVB\n"
|
" there may be several -D options (default: all DVB\n"
|
||||||
" devices will be used)\n"
|
" devices will be used)\n"
|
||||||
" -E FILE --epgfile=FILE write the EPG data into the given FILE (default is\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"
|
" if FILE is a directory, the default EPG file will be\n"
|
||||||
" created in that directory\n"
|
" created in that directory\n"
|
||||||
" -h, --help print this help and exit\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"
|
" -w SEC, --watchdog=SEC activate the watchdog timer with a timeout of SEC\n"
|
||||||
" seconds (default: %d); '0' disables the watchdog\n"
|
" seconds (default: %d); '0' disables the watchdog\n"
|
||||||
"\n",
|
"\n",
|
||||||
cSIProcessor::GetEpgDataFileName() ? cSIProcessor::GetEpgDataFileName() : "'-'",
|
DEFAULTEPGDATAFILENAME,
|
||||||
DEFAULTPLUGINDIR,
|
DEFAULTPLUGINDIR,
|
||||||
DEFAULTSVDRPPORT,
|
DEFAULTSVDRPPORT,
|
||||||
VideoDirectory,
|
VideoDirectory,
|
||||||
@ -360,6 +364,17 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
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:
|
// DVB interfaces:
|
||||||
|
|
||||||
cDvbDevice::Initialize();
|
cDvbDevice::Initialize();
|
||||||
@ -438,8 +453,6 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
cDevice::PrimaryDevice()->SetVolume(Setup.CurrentVolume, true);
|
cDevice::PrimaryDevice()->SetVolume(Setup.CurrentVolume, true);
|
||||||
|
|
||||||
cSIProcessor::Read();
|
|
||||||
|
|
||||||
// Signal handlers:
|
// Signal handlers:
|
||||||
|
|
||||||
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
||||||
@ -781,6 +794,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
// Disk housekeeping:
|
// Disk housekeeping:
|
||||||
RemoveDeletedRecordings();
|
RemoveDeletedRecordings();
|
||||||
|
cSchedules::Cleanup();
|
||||||
// Plugins housekeeping:
|
// Plugins housekeeping:
|
||||||
PluginManager.Housekeeping();
|
PluginManager.Housekeeping();
|
||||||
}
|
}
|
||||||
@ -801,6 +815,7 @@ int main(int argc, char *argv[])
|
|||||||
Setup.Save();
|
Setup.Save();
|
||||||
cDevice::Shutdown();
|
cDevice::Shutdown();
|
||||||
PluginManager.Shutdown(true);
|
PluginManager.Shutdown(true);
|
||||||
|
ReportEpgBugFixStats();
|
||||||
if (WatchdogTimeout > 0)
|
if (WatchdogTimeout > 0)
|
||||||
dsyslog("max. latency time %d seconds", MaxLatencyTime);
|
dsyslog("max. latency time %d seconds", MaxLatencyTime);
|
||||||
isyslog("exiting");
|
isyslog("exiting");
|
||||||
|
Loading…
Reference in New Issue
Block a user