summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY12
-rw-r--r--PLUGINS.html33
-rw-r--r--PLUGINS/src/epgtableid0/COPYING340
-rw-r--r--PLUGINS/src/epgtableid0/HISTORY6
-rw-r--r--PLUGINS/src/epgtableid0/Makefile114
-rw-r--r--PLUGINS/src/epgtableid0/README19
-rw-r--r--PLUGINS/src/epgtableid0/epgtableid0.c98
-rw-r--r--eit.c80
-rw-r--r--epg.c154
-rw-r--r--epg.h67
-rw-r--r--vdr.54
-rw-r--r--vdr.c3
12 files changed, 878 insertions, 52 deletions
diff --git a/HISTORY b/HISTORY
index e701788c..35fa7422 100644
--- a/HISTORY
+++ b/HISTORY
@@ -6960,7 +6960,7 @@ Video Disk Recorder Revision History
which was made in version 1.1.10, so please report if this has any unwanted
side effects.
-2012-03-08: Version 1.7.26
+2012-03-10: Version 1.7.26
- Now checking for NULL in cOsd::AddPixmap() (suggested by Christoph Haubrich).
- Fixed the German translation of "VDR will shut down in %s minutes" (thanks to
@@ -6999,3 +6999,13 @@ Video Disk Recorder Revision History
is selected, but it works at any time (and is more obvious).
- Revoked "If the first event in a schedule has a table id of 0x00, any incoming EIT data for
that schedule from the DVB stream will be completely ignored".
+- Added a new plugin interface for implementing EPG handlers.
+ + A plugin can implement an EPG handler by creating an object derived from
+ cEpgHandler and implementing the necessary member functions.
+ + The special handling of events with table id 0x00 has been dropped.
+ For backwards compatibility EPG events with table ids lower than 0x4E will
+ be treated as if they had a table id of 0x4E, and the new plugin 'epgtableid0'
+ can be used to have them handled like in previous versions.
+ + The default table id for a newly created cEvent has been changed to 0xFF,
+ which is higher than any normal table id that is broadcast in the EIT data.
+ See PLUGINS.html, section "Electronic Program Guide" for more information.
diff --git a/PLUGINS.html b/PLUGINS.html
index 4d939430..82164bff 100644
--- a/PLUGINS.html
+++ b/PLUGINS.html
@@ -102,6 +102,7 @@ structures and allows it to hook itself into specific areas to perform special a
<li><a href="#Audio">Audio</a>
<li><a href="#Remote Control">Remote Control</a>
<li><a href="#Conditional Access">Conditional Access</a>
+<li><modified><a href="#Electronic Program Guide">Electronic Program Guide</modified></a>
</ul>
</ul>
@@ -2212,5 +2213,37 @@ virtual bool Assign(cDevice *Device, bool Query = false);
See the description of this function in <tt>ci.h</tt> for details.
+<div class="modified">
+<hr><h2><a name="Electronic Program Guide">Electronic Program Guide</a></h2>
+
+<div class="blurb">The grass is always greener on the other side...</div><p>
+
+In case the <i>Electronic Program Guide (EPG)</i> provided by the broadcaster
+isn't sufficient for your taste, you can implement a <tt>cEpgHandler</tt> to
+improve it from external sources. For instance, to replace the description
+of the broadcaster's EPG with one from some external database, you could do:
+
+<p><table><tr><td class="code"><pre>
+#include &lt;vdr/epg.h&gt;
+
+class cMyEpgHandler : public cEpgHandler {
+public:
+ virtual bool SetDescription(cEvent *Event, const char *Description);
+ };
+
+bool cMyEpgHandler::SetDescription(cEvent *Event, const char *Description)
+{
+ Event-&gt;SetDescription(DescriptionFromDatabase(Event));
+ return true;
+}
+</pre></td></tr></table><p>
+
+where <tt>DescriptionFromDatabase()</tt> would derive the description of the
+ given event from some external source. Note that the function returns <tt>true</tt>
+to signal VDR that no other EPG handlers shall be queried after this one.
+<p>
+See <tt>VDR/epg.h</tt> for details.
+</div modified>
+
</body>
</html>
diff --git a/PLUGINS/src/epgtableid0/COPYING b/PLUGINS/src/epgtableid0/COPYING
new file mode 100644
index 00000000..f90922ee
--- /dev/null
+++ b/PLUGINS/src/epgtableid0/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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
+
+ 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) <year> <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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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) year 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 Lesser General
+Public License instead of this License.
diff --git a/PLUGINS/src/epgtableid0/HISTORY b/PLUGINS/src/epgtableid0/HISTORY
new file mode 100644
index 00000000..7f732add
--- /dev/null
+++ b/PLUGINS/src/epgtableid0/HISTORY
@@ -0,0 +1,6 @@
+VDR Plugin 'epgtableid0' Revision History
+-----------------------------------------
+
+2012-03-10: Version 0.0.1
+
+- Initial revision.
diff --git a/PLUGINS/src/epgtableid0/Makefile b/PLUGINS/src/epgtableid0/Makefile
new file mode 100644
index 00000000..5653e28e
--- /dev/null
+++ b/PLUGINS/src/epgtableid0/Makefile
@@ -0,0 +1,114 @@
+#
+# Makefile for a Video Disk Recorder plugin
+#
+# $Id: Makefile 1.1 2012/03/10 14:23:58 kls Exp $
+
+# The official name of this plugin.
+# This name will be used in the '-P...' option of VDR to load the plugin.
+# By default the main source file also carries this name.
+# IMPORTANT: the presence of this macro is important for the Make.config
+# file. So it must be defined, even if it is not used here!
+#
+PLUGIN = epgtableid0
+
+### The version number of this plugin (taken from the main source file):
+
+VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
+
+### The C++ compiler and options:
+
+CXX ?= g++
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
+
+### The directory environment:
+
+VDRDIR ?= ../../..
+LIBDIR ?= ../../lib
+TMPDIR ?= /tmp
+
+### Make sure that necessary options are included:
+
+include $(VDRDIR)/Make.global
+
+### Allow user defined options to overwrite defaults:
+
+-include $(VDRDIR)/Make.config
+
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
+
+APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
+
+### The name of the distribution archive:
+
+ARCHIVE = $(PLUGIN)-$(VERSION)
+PACKAGE = vdr-$(ARCHIVE)
+
+### Includes and Defines (add further entries here):
+
+INCLUDES += -I$(VDRDIR)/include
+
+DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+
+### The object files (add further files here):
+
+OBJS = $(PLUGIN).o
+
+### The main target:
+
+all: libvdr-$(PLUGIN).so i18n
+
+### Implicit rules:
+
+%.o: %.c
+ $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
+
+### Dependencies:
+
+MAKEDEP = $(CXX) -MM -MG
+DEPFILE = .dependencies
+$(DEPFILE): Makefile
+ @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
+
+-include $(DEPFILE)
+
+### Internationalization (I18N):
+
+PODIR = po
+LOCALEDIR = $(VDRDIR)/locale
+I18Npo = $(wildcard $(PODIR)/*.po)
+I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
+I18Npot = $(PODIR)/$(PLUGIN).pot
+
+%.mo: %.po
+ msgfmt -c -o $@ $<
+
+$(I18Npot): $(wildcard *.c)
+ xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ $^
+
+%.po: $(I18Npot)
+ msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
+ @touch $@
+
+$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
+ @mkdir -p $(dir $@)
+ cp $< $@
+
+.PHONY: i18n
+i18n: $(I18Nmsgs) $(I18Npot)
+
+### Targets:
+
+libvdr-$(PLUGIN).so: $(OBJS)
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) -o $@
+ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+
+dist: $(I18Npo) clean
+ @-rm -rf $(TMPDIR)/$(ARCHIVE)
+ @mkdir $(TMPDIR)/$(ARCHIVE)
+ @cp -a * $(TMPDIR)/$(ARCHIVE)
+ @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
+ @-rm -rf $(TMPDIR)/$(ARCHIVE)
+ @echo Distribution package created as $(PACKAGE).tgz
+
+clean:
+ @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot
diff --git a/PLUGINS/src/epgtableid0/README b/PLUGINS/src/epgtableid0/README
new file mode 100644
index 00000000..8c2436dd
--- /dev/null
+++ b/PLUGINS/src/epgtableid0/README
@@ -0,0 +1,19 @@
+This is a "plugin" for the Video Disk Recorder (VDR).
+
+Written by: Klaus Schmidinger <kls@tvdr.de>
+
+Project's homepage: http://www.tvdr.de
+
+Latest version available at: http://www.tvdr.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.
+See the file COPYING for more information.
+
+Description:
+
+The special handling of EPG events with table id 0x00 has been dropped
+in VDR version 1.7.26, and replaced by a more felxible "EPG Handler"
+concept. You can use this plugin to get the previous functionality back.
diff --git a/PLUGINS/src/epgtableid0/epgtableid0.c b/PLUGINS/src/epgtableid0/epgtableid0.c
new file mode 100644
index 00000000..d400b48c
--- /dev/null
+++ b/PLUGINS/src/epgtableid0/epgtableid0.c
@@ -0,0 +1,98 @@
+/*
+ * epgtableid0.c: A plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: epgtableid0.c 1.1 2012/03/10 15:10:43 kls Exp $
+ */
+
+#include <vdr/epg.h>
+#include <vdr/plugin.h>
+
+static const char *VERSION = "0.0.1";
+static const char *DESCRIPTION = "EPG handler for events with table id 0x00";
+
+// --- cTable0Handler --------------------------------------------------------
+
+class cTable0Handler : public cEpgHandler {
+private:
+ bool Ignore(cEvent *Event) { return Event->TableID() == 0x00; }
+public:
+ virtual bool SetEventID(cEvent *Event, tEventID EventID);
+ virtual bool SetStartTime(cEvent *Event, time_t StartTime);
+ virtual bool SetDuration(cEvent *Event, int Duration);
+ virtual bool SetTitle(cEvent *Event, const char *Title);
+ virtual bool SetShortText(cEvent *Event, const char *ShortText);
+ virtual bool SetDescription(cEvent *Event, const char *Description);
+ virtual bool SetContents(cEvent *Event, uchar *Contents);
+ virtual bool SetParentalRating(cEvent *Event, int ParentalRating);
+ virtual bool SetVps(cEvent *Event, time_t Vps);
+ virtual bool FixEpgBugs(cEvent *Event);
+ };
+
+bool cTable0Handler::SetEventID(cEvent *Event, tEventID EventID)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::SetStartTime(cEvent *Event, time_t StartTime)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::SetDuration(cEvent *Event, int Duration)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::SetTitle(cEvent *Event, const char *Title)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::SetShortText(cEvent *Event, const char *ShortText)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::SetDescription(cEvent *Event, const char *Description)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::SetContents(cEvent *Event, uchar *Contents)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::SetParentalRating(cEvent *Event, int ParentalRating)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::SetVps(cEvent *Event, time_t Vps)
+{
+ return Ignore(Event);
+}
+
+bool cTable0Handler::FixEpgBugs(cEvent *Event)
+{
+ return Ignore(Event);
+}
+
+// --- cPluginEpgtableid0 ----------------------------------------------------
+
+class cPluginEpgtableid0 : public cPlugin {
+public:
+ virtual const char *Version(void) { return VERSION; }
+ virtual const char *Description(void) { return DESCRIPTION; }
+ virtual bool Initialize(void);
+ };
+
+bool cPluginEpgtableid0::Initialize(void)
+{
+ new cTable0Handler;
+ return true;
+}
+
+VDRPLUGINCREATOR(cPluginEpgtableid0); // Don't touch this!
diff --git a/eit.c b/eit.c
index b1fe9955..1b8c84c4 100644
--- a/eit.c
+++ b/eit.c
@@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
*
- * $Id: eit.c 2.14 2012/03/08 15:05:45 kls Exp $
+ * $Id: eit.c 2.15 2012/03/10 14:43:52 kls Exp $
*/
#include "eit.h"
@@ -36,12 +36,13 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
cChannel *channel = Channels.GetByChannelID(channelID, true);
if (!channel)
return; // only collect data for known channels
+ if (EpgHandlers.IgnoreChannel(channel))
+ return;
cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channel, true);
bool Empty = true;
bool Modified = false;
- bool HasExternalData = false;
time_t SegmentStart = 0;
time_t SegmentEnd = 0;
time_t Now = time(NULL);
@@ -53,7 +54,8 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
SI::EIT::Event SiEitEvent;
for (SI::Loop::Iterator it; eventLoop.getNext(SiEitEvent, it); ) {
- bool ExternalData = false;
+ if (EpgHandlers.HandleEitEvent(pSchedule, &SiEitEvent, Tid, getVersionNumber()))
+ continue; // an EPG handler has done all of the processing
time_t StartTime = SiEitEvent.getStartTime();
int Duration = SiEitEvent.getDuration();
// Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number.
@@ -72,23 +74,17 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
// If we don't have that event yet, we create a new one.
// Otherwise we copy the information into the existing event anyway, because the data might have changed.
pEvent = newEvent = new cEvent(SiEitEvent.getEventId());
- if (!pEvent)
- continue;
+ newEvent->SetStartTime(StartTime);
+ newEvent->SetDuration(Duration);
+ pSchedule->AddEvent(newEvent);
}
else {
// We have found an existing event, either through its event ID or its start time.
pEvent->SetSeen();
- // If the existing event has a zero table ID it was defined externally and shall
- // not be overwritten.
- uchar TableID = pEvent->TableID();
- if (TableID == 0x00) {
- if (pEvent->Version() == getVersionNumber())
- continue;
- HasExternalData = ExternalData = true;
- }
+ uchar TableID = max(pEvent->TableID(), uchar(0x4E)); // for backwards compatibility, table ids less than 0x4E are treated as if they were "present"
// If the new event has a higher table ID, let's skip it.
// The lower the table ID, the more "current" the information.
- else if (Tid > TableID)
+ if (Tid > TableID)
continue;
// If the new event comes from the same table and has the same version number
// as the existing one, let's skip it to avoid unnecessary work.
@@ -98,21 +94,20 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
// to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers.
else if (Tid == TableID && pEvent->Version() == getVersionNumber())
continue;
+ EpgHandlers.SetEventID(pEvent, SiEitEvent.getEventId()); // unfortunately some stations use different event ids for the same event in different tables :-(
+ EpgHandlers.SetStartTime(pEvent, StartTime);
+ EpgHandlers.SetDuration(pEvent, Duration);
}
- if (!ExternalData) {
- pEvent->SetEventID(SiEitEvent.getEventId()); // unfortunately some stations use different event ids for the same event in different tables :-(
+ if (pEvent->TableID() > 0x4E) // for backwards compatibility, table ids less than 0x4E are never overwritten
pEvent->SetTableID(Tid);
- pEvent->SetStartTime(StartTime);
- pEvent->SetDuration(Duration);
- }
- if (newEvent)
- pSchedule->AddEvent(newEvent);
if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
if (SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning)
pSchedule->SetRunningStatus(pEvent, SiEitEvent.getRunningStatus(), channel);
}
- if (OnlyRunningStatus)
+ if (OnlyRunningStatus) {
+ pEvent->SetVersion(0xFF); // we have already changed the table id above, so set the version to an invalid value to make sure the next full run will be executed
continue; // do this before setting the version, so that the full update can be done later
+ }
pEvent->SetVersion(getVersionNumber());
int LanguagePreferenceShort = -1;
@@ -124,10 +119,6 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
cLinkChannels *LinkChannels = NULL;
cComponents *Components = NULL;
for (SI::Loop::Iterator it2; (d = SiEitEvent.eventDescriptors.getNext(it2)); ) {
- if (ExternalData && d->getDescriptorTag() != SI::ComponentDescriptorTag) {
- delete d;
- continue;
- }
switch (d->getDescriptorTag()) {
case SI::ExtendedEventDescriptorTag: {
SI::ExtendedEventDescriptor *eed = (SI::ExtendedEventDescriptor *)d;
@@ -164,7 +155,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
NumContents++;
}
}
- pEvent->SetContents(Contents);
+ EpgHandlers.SetContents(pEvent, Contents);
}
break;
case SI::ParentalRatingDescriptorTag: {
@@ -183,7 +174,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
case 0x13: ParentalRating = 16; break;
default: ParentalRating = 0;
}
- pEvent->SetParentalRating(ParentalRating);
+ EpgHandlers.SetParentalRating(pEvent, ParentalRating);
}
}
}
@@ -202,7 +193,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
else if (month == 0 && t.tm_mon == 11) // current month is jan, but event is in dec
t.tm_year--;
time_t vps = mktime(&t);
- pEvent->SetVps(vps);
+ EpgHandlers.SetVps(pEvent, vps);
}
break;
case SI::TimeShiftedEventDescriptorTag: {
@@ -213,9 +204,9 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
rEvent = (cEvent *)rSchedule->GetEvent(tsed->getReferenceEventId());
if (!rEvent)
break;
- pEvent->SetTitle(rEvent->Title());
- pEvent->SetShortText(rEvent->ShortText());
- pEvent->SetDescription(rEvent->Description());
+ EpgHandlers.SetTitle(pEvent, rEvent->Title());
+ EpgHandlers.SetShortText(pEvent, rEvent->ShortText());
+ EpgHandlers.SetDescription(pEvent, rEvent->Description());
}
break;
case SI::LinkageDescriptorTag: {
@@ -273,30 +264,30 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
if (!rEvent) {
if (ShortEventDescriptor) {
char buffer[Utf8BufSize(256)];
- pEvent->SetTitle(ShortEventDescriptor->name.getText(buffer, sizeof(buffer)));
- pEvent->SetShortText(ShortEventDescriptor->text.getText(buffer, sizeof(buffer)));
+ EpgHandlers.SetTitle(pEvent, ShortEventDescriptor->name.getText(buffer, sizeof(buffer)));
+ EpgHandlers.SetShortText(pEvent, ShortEventDescriptor->text.getText(buffer, sizeof(buffer)));
}
- else if (!HasExternalData) {
- pEvent->SetTitle(NULL);
- pEvent->SetShortText(NULL);
+ else {
+ EpgHandlers.SetTitle(pEvent, NULL);
+ EpgHandlers.SetShortText(pEvent, NULL);
}
if (ExtendedEventDescriptors) {
char buffer[Utf8BufSize(ExtendedEventDescriptors->getMaximumTextLength(": ")) + 1];
- pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": "));
+ EpgHandlers.SetDescription(pEvent, ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": "));
}
- else if (!HasExternalData)
- pEvent->SetDescription(NULL);
+ else
+ EpgHandlers.SetDescription(pEvent, NULL);
}
delete ExtendedEventDescriptors;
delete ShortEventDescriptor;
pEvent->SetComponents(Components);
- if (!HasExternalData)
- pEvent->FixEpgBugs();
+ EpgHandlers.FixEpgBugs(pEvent);
if (LinkChannels)
channel->SetLinkChannels(LinkChannels);
Modified = true;
+ EpgHandlers.HandleEvent(pEvent);
}
if (Tid == 0x4E) {
if (Empty && getSectionNumber() == 0)
@@ -307,9 +298,8 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
if (OnlyRunningStatus)
return;
if (Modified) {
- pSchedule->Sort();
- if (!HasExternalData)
- pSchedule->DropOutdated(SegmentStart, SegmentEnd, Tid, getVersionNumber());
+ EpgHandlers.SortSchedule(pSchedule);
+ EpgHandlers.DropOutdated(pSchedule, SegmentStart, SegmentEnd, Tid, getVersionNumber());
Schedules->SetModified(pSchedule);
}
}
diff --git a/epg.c b/epg.c
index 2ff10528..f5c9b3a3 100644
--- a/epg.c
+++ b/epg.c
@@ -7,7 +7,7 @@
* 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 2.11 2012/02/13 14:58:19 kls Exp $
+ * $Id: epg.c 2.12 2012/03/10 13:14:27 kls Exp $
*/
#include "epg.h"
@@ -114,7 +114,7 @@ cEvent::cEvent(tEventID EventID)
{
schedule = NULL;
eventID = EventID;
- tableID = 0;
+ tableID = 0xFF; // actual table ids are 0x4E..0x60
version = 0xFF; // actual version numbers are 0..31
runningStatus = SI::RunningStatusUndefined;
title = NULL;
@@ -1296,3 +1296,153 @@ void cEpgDataReader::Action(void)
{
cSchedules::Read();
}
+
+// --- cEpgHandler -----------------------------------------------------------
+
+cEpgHandler::cEpgHandler(void)
+{
+ EpgHandlers.Add(this);
+}
+
+cEpgHandler::~cEpgHandler()
+{
+ EpgHandlers.Del(this, false);
+}
+
+// --- cEpgHandlers ----------------------------------------------------------
+
+cEpgHandlers EpgHandlers;
+
+bool cEpgHandlers::IgnoreChannel(const cChannel *Channel)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->IgnoreChannel(Channel))
+ return true;
+ }
+ return false;
+}
+
+bool cEpgHandlers::HandleEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->HandleEitEvent(Schedule, EitEvent, TableID, Version))
+ return true;
+ }
+ return false;
+}
+
+void cEpgHandlers::SetEventID(cEvent *Event, tEventID EventID)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetEventID(Event, EventID))
+ return;
+ }
+ Event->SetEventID(EventID);
+}
+
+void cEpgHandlers::SetTitle(cEvent *Event, const char *Title)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetTitle(Event, Title))
+ return;
+ }
+ Event->SetTitle(Title);
+}
+
+void cEpgHandlers::SetShortText(cEvent *Event, const char *ShortText)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetShortText(Event, ShortText))
+ return;
+ }
+ Event->SetShortText(ShortText);
+}
+
+void cEpgHandlers::SetDescription(cEvent *Event, const char *Description)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetDescription(Event, Description))
+ return;
+ }
+ Event->SetDescription(Description);
+}
+
+void cEpgHandlers::SetContents(cEvent *Event, uchar *Contents)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetContents(Event, Contents))
+ return;
+ }
+ Event->SetContents(Contents);
+}
+
+void cEpgHandlers::SetParentalRating(cEvent *Event, int ParentalRating)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetParentalRating(Event, ParentalRating))
+ return;
+ }
+ Event->SetParentalRating(ParentalRating);
+}
+
+void cEpgHandlers::SetStartTime(cEvent *Event, time_t StartTime)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetStartTime(Event, StartTime))
+ return;
+ }
+ Event->SetStartTime(StartTime);
+}
+
+void cEpgHandlers::SetDuration(cEvent *Event, int Duration)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetDuration(Event, Duration))
+ return;
+ }
+ Event->SetDuration(Duration);
+}
+
+void cEpgHandlers::SetVps(cEvent *Event, time_t Vps)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SetVps(Event, Vps))
+ return;
+ }
+ Event->SetVps(Vps);
+}
+
+void cEpgHandlers::FixEpgBugs(cEvent *Event)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->FixEpgBugs(Event))
+ return;
+ }
+ Event->FixEpgBugs();
+}
+
+void cEpgHandlers::HandleEvent(cEvent *Event)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->HandleEvent(Event))
+ break;
+ }
+}
+
+void cEpgHandlers::SortSchedule(cSchedule *Schedule)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->SortSchedule(Schedule))
+ return;
+ }
+ Schedule->Sort();
+}
+
+void cEpgHandlers::DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version)
+{
+ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
+ if (eh->DropOutdated(Schedule, SegmentStart, SegmentEnd, TableID, Version))
+ return;
+ }
+ Schedule->DropOutdated(SegmentStart, SegmentEnd, TableID, Version);
+}
diff --git a/epg.h b/epg.h
index 580cbe6b..e4cec9b9 100644
--- a/epg.h
+++ b/epg.h
@@ -7,13 +7,14 @@
* 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 2.7 2012/02/26 13:58:26 kls Exp $
+ * $Id: epg.h 2.8 2012/03/10 13:50:10 kls Exp $
*/
#ifndef __EPG_H
#define __EPG_H
#include "channels.h"
+#include "libsi/section.h"
#include "thread.h"
#include "tools.h"
@@ -221,4 +222,68 @@ public:
void ReportEpgBugFixStats(bool Reset = false);
+class cEpgHandler : public cListObject {
+public:
+ cEpgHandler(void);
+ ///< Constructs a new EPG handler and adds it to the list of EPG handlers.
+ ///< Whenever an event is received from the EIT data stream, the EPG
+ ///< handlers are queried in the order they have been created.
+ ///< As soon as one of the EPG handlers returns true in a member function,
+ ///< none of the remaining handlers will be queried. If none of the EPG
+ ///< handlers returns true in a particular call, the default processing
+ ///< will take place.
+ ///< EPG handlers will be deleted automatically at the end of the program.
+ virtual ~cEpgHandler();
+ virtual bool IgnoreChannel(const cChannel *Channel) { return false; }
+ ///< Before any EIT data for the given Channel is processed, the EPG handlers
+ ///< are asked whether this Channel shall be completely ignored. If any of
+ ///< the EPG handlers returns true in this function, no EIT data at all will
+ ///< be processed for this Channel.
+ virtual bool HandleEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version) { return false; }
+ ///< Before the raw EitEvent for the given Schedule is processed, the
+ ///< EPG handlers are queried to see if any of them would like to do the
+ ///< complete processing by itself. TableID and Version are from the
+ ///< incoming section data.
+ virtual bool SetEventID(cEvent *Event, tEventID EventID) { return false; }
+ virtual bool SetTitle(cEvent *Event, const char *Title) { return false; }
+ virtual bool SetShortText(cEvent *Event, const char *ShortText) { return false; }
+ virtual bool SetDescription(cEvent *Event, const char *Description) { return false; }
+ virtual bool SetContents(cEvent *Event, uchar *Contents) { return false; }
+ virtual bool SetParentalRating(cEvent *Event, int ParentalRating) { return false; }
+ virtual bool SetStartTime(cEvent *Event, time_t StartTime) { return false; }
+ virtual bool SetDuration(cEvent *Event, int Duration) { return false; }
+ virtual bool SetVps(cEvent *Event, time_t Vps) { return false; }
+ virtual bool FixEpgBugs(cEvent *Event) { return false; }
+ ///< Fixes some known problems with EPG data.
+ virtual bool HandleEvent(cEvent *Event) { return false; }
+ ///< After all modifications of the Event have been done, the EPG handler
+ ///< can take a final look at it.
+ virtual bool SortSchedule(cSchedule *Schedule) { return false; }
+ ///< Sorts the Schedule after the complete table has been processed.
+ virtual bool DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version) { return false; }
+ ///< Takes a look at all EPG events between SegmentStart and SegmentEnd and
+ ///< drops outdated events.
+ };
+
+class cEpgHandlers : public cList<cEpgHandler> {
+public:
+ bool IgnoreChannel(const cChannel *Channel);
+ bool HandleEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version);
+ void SetEventID(cEvent *Event, tEventID EventID);
+ void SetTitle(cEvent *Event, const char *Title);
+ void SetShortText(cEvent *Event, const char *ShortText);
+ void SetDescription(cEvent *Event, const char *Description);
+ void SetContents(cEvent *Event, uchar *Contents);
+ void SetParentalRating(cEvent *Event, int ParentalRating);
+ void SetStartTime(cEvent *Event, time_t StartTime);
+ void SetDuration(cEvent *Event, int Duration);
+ void SetVps(cEvent *Event, time_t Vps);
+ void FixEpgBugs(cEvent *Event);
+ void HandleEvent(cEvent *Event);
+ void SortSchedule(cSchedule *Schedule);
+ void DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version);
+ };
+
+extern cEpgHandlers EpgHandlers;
+
#endif //__EPG_H
diff --git a/vdr.5 b/vdr.5
index 84635502..a606dde8 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
-.\" $Id: vdr.5 2.28 2012/02/27 11:05:15 kls Exp $
+.\" $Id: vdr.5 2.29 2012/03/10 14:56:01 kls Exp $
.\"
.TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files"
.SH NAME
@@ -861,7 +861,7 @@ l l.
<event id> @is a 32 bit unsigned int, uniquely identifying this event
<start time> @is the time (as a time_t integer) in UTC when this event starts
<duration> @is the time (in seconds) that this event will take
-<table id> @is a hex number that indicates the table this event is contained in (if this is left empty or 0 this event will not be overwritten or modified by data that comes from the DVB stream)
+<table id> @is a hex number that indicates the table this event is contained in (if this is left empty it will be set to 0x00; and value less than 0x4E it will be treated as if it were 0x4E)
<version> @is a hex number that indicates the event's version number inside its table (optional, ignored when reading EPG data)
<title> @is the title of the event
<short text> @is the short text of the event (typically the name of the episode etc.)
diff --git a/vdr.c b/vdr.c
index b19730b0..6df53fdd 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.tvdr.de
*
- * $Id: vdr.c 2.33 2012/03/08 09:51:52 kls Exp $
+ * $Id: vdr.c 2.34 2012/03/09 09:55:15 kls Exp $
*/
#include <getopt.h>
@@ -1300,6 +1300,7 @@ Exit:
Setup.Save();
}
cDevice::Shutdown();
+ EpgHandlers.Clear();
PluginManager.Shutdown(true);
cSchedules::Cleanup(true);
ReportEpgBugFixStats();