summaryrefslogtreecommitdiff
path: root/PLUGINS.html
diff options
context:
space:
mode:
Diffstat (limited to 'PLUGINS.html')
-rw-r--r--PLUGINS.html207
1 files changed, 184 insertions, 23 deletions
diff --git a/PLUGINS.html b/PLUGINS.html
index 2535c68..2002d60 100644
--- a/PLUGINS.html
+++ b/PLUGINS.html
@@ -12,7 +12,7 @@ This interface allows programmers to develop additional functionality for VDR co
separate from the core VDR source, without the need of patching the original
VDR code (and all the problems of correlating various patches).
<p>
-<!--X1.1.3--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
This document is divided into two parts, the first one describing the
<a href="#Part I - The Outside Interface"><i>outside</i> interface</a>
of the plugin system, and the second one describing the
@@ -23,18 +23,18 @@ The <i>inside</i> interface provides the plugin code access to VDR's internal da
structures and allows it to hook itself into specific areas to perform special actions.
<!--X1.1.3--></td></tr></table>
<p>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
-Important modifications introduced in version 1.1.2 are marked like this.
-<!--X1.1.2--></td></tr></table>
-<!--X1.1.3--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.3 are marked like this.
<!--X1.1.3--></td></tr></table>
-<!--X1.1.4--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
+<!--X1.1.4--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.4 are marked like this.
<!--X1.1.4--></td></tr></table>
-<!--X1.1.5--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<!--X1.1.5--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
Important modifications introduced in version 1.1.5 are marked like this.
<!--X1.1.5--></td></tr></table>
+<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+Important modifications introduced in version 1.1.6 are marked like this.
+<!--X1.1.6--></td></tr></table>
<a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center>
@@ -131,15 +131,12 @@ from the web, it will typically have a name like
<p>
and will unpack into a directory named
<p>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<tt>hello-0.0.1</tt>
-<!--X1.1.2--></td></tr></table>
<p>
To use the <tt>plugins</tt> and <tt>plugins-clean</tt> targets from the VDR <tt>Makefile</tt>
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
-<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
ln -s hello-0.0.1 hello
</pre></td></tr></table><p>
@@ -149,7 +146,6 @@ of only lowercase characters and digits, it will only follow the symbolic links,
should lead to the current version of the plugin you want to use. This way you can
have several different versions of a plugin source (like <tt>hello-0.0.1</tt> and
<tt>hello-0.0.2</tt>) and define which one to actually use through the symbolic link.
-<!--X1.1.2--></td></tr></table>
<a name="Initializing a new plugin directory"><hr><h2>Initializing a new plugin directory</h2>
@@ -422,11 +418,9 @@ 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>,
it needs to implement the function
-<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
virtual bool Start(void);
</pre></td></tr></table><p>
-<!--X1.1.2--></td></tr></table>
which is called once for each plugin at program startup.
Inside this function the plugin must set up everything necessary to perform
@@ -434,12 +428,10 @@ its task. This may, for instance, be a thread that collects data from the DVB
stream, which is later presented to the user via a function that is available
from the main menu.
<p>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
A return value of <i>false</i> indicates that something has gone wrong and the
plugin will not be able to perform its task. In that case, the plugin should
write a proper error message to the log file. The first plugin that returns
<i>false</i> from its <tt>Start()</tt> function will cause VDR to exit.
-<!--X1.1.2--></td></tr></table>
<p>
If the plugin doesn't implement any background functionality or internationalized
texts, it doesn't need to implement this function.
@@ -498,7 +490,6 @@ interaction is possible. If a specific action takes longer than a few seconds,
the plugin should launch a separate thread to do this.
</b>
-<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<hr><h2>Housekeeping</h2>
<center><i><b>Chores, chores...</b></i></center><p>
@@ -523,7 +514,6 @@ as possible! As long as the program stays inside this function, no other user
interaction is possible. If a specific action takes longer than a few seconds,
the plugin should launch a separate thread to do this.
</b>
-<!--X1.1.2--></td></tr></table>
<a name="Setup parameters"><hr><h2>Setup parameters</h2>
@@ -656,7 +646,6 @@ You can first assign the temporary values to the global variables and then do th
your setup parameters and use that one to copy all parameters with one single statement
(like VDR does with its cSetup class).
-<!--X1.1.2--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<hr><h2>Configuration files</h2>
<center><i><b>I want my own stuff!</b></i></center><p>
@@ -711,7 +700,6 @@ plugin class, by writing
<p><table><tr><td bgcolor=#F0F0F0><pre><br>
const char *MyConfigDir = cPlugin::ConfigDirectory();
</pre></td></tr></table><p>
-<!--X1.1.2--></td></tr></table>
<a name="Internationalization"><hr><h2>Internationalization</h2>
@@ -826,7 +814,7 @@ and display their help and/or version information in addition to its own output.
If you want to make your plugin available to other VDR users, you'll need to
make a package that can be easily distributed.
-<!--X1.1.3--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
The <tt>Makefile</tt> that has been created by the call to
<a href="#Initializing a new plugin directory"><tt>newplugin</tt></a>
provides the target <tt>dist</tt>, which does this for you.
@@ -848,7 +836,7 @@ vdr-hello-0.0.1.tgz
in your source directory, where <tt>hello</tt> will be replaced with your actual
plugin's name, and <tt>0.0.1</tt> will be your plugin's current version number.
-<!--X1.1.3--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
+<!--X1.1.3--><table width=100%><tr><td bgcolor=#0000AA>&nbsp;</td><td width=100%>
<a name="Part II - The Inside Interface"><hr><center><h1>Part II - The Inside Interface</h1></center>
<hr><h2>Status monitor</h2>
@@ -925,7 +913,7 @@ member functions are available in <tt>cStatus</tt>. You only need to implement
the functions you actually want to use.
<!--X1.1.3--></td></tr></table>
-<!--X1.1.4--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
+<!--X1.1.4--><table width=100%><tr><td bgcolor=#00AA00>&nbsp;</td><td width=100%>
<hr><h2>Players</h2>
<center><i><b>Play it again, Sam!</b></i></center><p>
@@ -1076,7 +1064,63 @@ that they already know. If you absolutely want to do things differently, just go
ahead - it's your show...
<!--X1.1.4--></td></tr></table>
-<!--X1.1.5--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<hr><h2>Receivers</h2>
+
+<center><i><b>Tapping into the stream...</b></i></center><p>
+
+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:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+#include &lt;vdr/receiver.h&gt;
+
+class cMyReceiver : public cReceiver, cThread {
+protected:
+ virtual void Activate(bool On);
+ virtual void Receive(uchar *Data, int Length);
+public:
+ cMyReceiver(int Pid);
+ };
+
+cMyReceiver::cMyReceiver(int Pid)
+:cReceiver(0, -1, 1, Pid)
+{
+}
+
+void cMyReceiver::Activate(bool On)
+{
+ // start your own thread for processing the received data
+}
+
+void cMyReceiver::Receive(uchar *Data, int Length)
+{
+ // buffer the data for processing in a separate thread
+}
+</pre></td></tr></table><p>
+
+See the comments in <tt>VDR/receiver.h</tt> for details about the various
+member functions of <tt>cReceiver</tt>.
+<p>
+The above example sets up a receiver that wants to receive data from only one
+PID (for example the Teletext PID). In order to not interfere with other recording
+operations, it sets its priority to <tt>-1</tt> (any negative value will allow
+a <tt>cReceiver</tt> to be detached from its <tt>cDevice</tt> at any time.
+<p>
+Once a <tt>cReceiver</tt> has been created, it needs to be <i>attached</i> to
+a <tt>cDevice</tt>:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+cMyReceiver *Receiver = new cMyReceiver(123);
+
+cDevice::PrimaryDevice()-&gt;AttachReceiver(Receiver);
+</pre></td></tr></table><p>
+
+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>.
+<!--X1.1.6--></td></tr></table>
+
+<!--X1.1.5--><table width=100%><tr><td bgcolor=#AA0000>&nbsp;</td><td width=100%>
<hr><h2>The On Screen Display</h2>
<center><i><b>Express yourself</b></i></center><p>
@@ -1108,5 +1152,122 @@ of these functions, and VDR/osd.c to see how VDR opens the OSD and sets up
its windows and color depths).
<!--X1.1.5--></td></tr></table>
+<!--X1.1.6--><table width=100%><tr><td bgcolor=#FF0000>&nbsp;</td><td width=100%>
+<hr><h2>Devices</h2>
+
+<center><i><b>Expanding the possibilities</b></i></center><p>
+
+By default VDR is based on using DVB PCI cards that are supported by the
+LinuxDVB driver. However, a plugin can implement additional devices that
+can be used as sources of MPEG data for viewing or recording, and also
+as output devices for replaying. Such a device can be a physical card
+that is installed in the PC (like, for instance, an MPEG encoder card that
+allows the analog signal of a proprietary set-top box to be integrated
+into a VDR system; or an analog TV receiver card, which does the MPEG encoding
+"on the fly" - assuming your machine is fast enough), or just a software program that takes an MPEG data
+stream and displays it, for instance, on an existing graphics adapter.
+<p>
+To implement an additional device, a plugin must derive a class from cDevice:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+#include &lt;vdr/device.h&gt;
+
+class cMyDevice : public cDevice {
+ ...
+ };
+</pre></td></tr></table><p>
+
+The derived class must implement several virtual functions, according to
+the abilities this new class of devices can provide. See the comments in the
+file <tt>VDR/device.h</tt> for more information on the various functions,
+and also <tt>VDR/dvbdevice.[hc]</tt> for details on the implementation of
+the <tt>cDvbDevice</tt>, which is used to access the DVB PCI cards.
+<p>
+<b>Channel selection</b>
+<p>
+If the new device can receive, it most likely needs to provide a way of
+selecting which channel it shall tune to:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+virtual bool SetChannelDevice(const cChannel *Channel);
+</pre></td></tr></table><p>
+
+This function will be called with the desired channel and shall return whether
+tuning to it was successful.
+<p>
+<b>Recording</b>
+<p>
+A device that can be used for recording must implement the functions
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
+virtual bool OpenDvr(void);
+virtual void CloseDvr(void);
+virtual int GetTSPacket(uchar *Data);
+</pre></td></tr></table><p>
+
+which allow VDR to set the PIDs that shall be recorded, set up the device fro
+recording (and shut it down again), and receive the MPEG data stream. The data
+must be delivered in the form of a Transport Stream (TS), which consists of
+packets that are all 188 bytes in size. Each call to <tt>GetTSPacket()</tt>
+must deliver exactly one such packet (if one is currently available).
+<p>
+If this device allows receiving several different data streams, it can
+implement
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+virtual bool CanBeReUsed(int Frequency, int Vpid);
+</pre></td></tr></table><p>
+
+to indicate this to VDR.
+<p>
+<b>Replaying</b>
+<p>
+The functions to implement replaying capabilites are
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+virtual bool HasDecoder(void) const;
+virtual int SetPlayMode(bool On);
+virtual void TrickSpeed(int Speed);
+virtual void Clear(void);
+virtual void Play(void);
+virtual void Freeze(void);
+virtual void Mute(void);
+virtual void StillPicture(const uchar *Data, int Length);
+virtual int PlayVideo(const uchar *Data, int Length);
+</pre></td></tr></table><p>
+
+In addition, the following functions may be implemented to provide further
+functionality:
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int Si
+virtual void SetVideoFormat(bool VideoFormat16_9);
+virtual void SetVolumeDevice(int Volume);
+</pre></td></tr></table><p>
+
+<b>Initializing new devices</b>
+<p>
+A derived cDevice class shall implement a static function
+
+<p><table><tr><td bgcolor=#F0F0F0><pre><br>
+static bool Initialize(void);
+</pre></td></tr></table><p>
+
+in which it determines whether the necessary hardware to run this sort of
+device is actually present in this machine (or whatever other prerequisites
+might be important), and then creates as many device objects as necessary.
+See <tt>VDR/dvbdevice.c</tt> for the implementation of the <tt>cDvbDevice</tt>
+initialize function.
+<p>
+A plugin that adds devices to a VDR instance shall call this initializing
+function from its <a href="#Getting started"><tt>Start()</tt></a> function.
+<p>
+Nothing needs to be done to shut down the devices. VDR will automatically
+shut down (delete) all devices when the program terminates. It is therefore
+important that the devices are created on the heap, using the <tt>new</tt>
+operator!
+<!--X1.1.6--></td></tr></table>
+
</body>
</html>