From dab203efe9e24f1dade33ee1da6a39b26f8501f0 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 21 Aug 2005 18:00:00 +0200 Subject: Version 1.3.30 - Improved responsiveness inside CAM menus. - Added handling of the 'Close MMI' tag to avoid error log messages with CAMs that actually use it. - Now waiting at startup until all DVB devices are ready. This includes having all CAMs initialized and ready to decrypt, so that no more "channel not available" happens if VDR is started with the current channel being an encrypted one, or a timer on such a channel hits right after starting VDR. - Fixed cVideoRepacker to better handle errors in data (thanks to Reinhard Nissl). - Fixed cDvbTuner to avoid lockups on NPTL systems (thanks to Marcel Wiesweg). - Added 'Service' functions to the plugin interface (thanks to Udo Richter). See PLUGINS.html, section "Custom services" for details. - Replaced the get/put_unaligned() macros from with own inline functions to avoid problems on platforms that don't provide these (thanks to David Woodhouse for his help). --- PLUGINS.html | 117 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 30 deletions(-) (limited to 'PLUGINS.html') diff --git a/PLUGINS.html b/PLUGINS.html index 67b96d9..29d8351 100644 --- a/PLUGINS.html +++ b/PLUGINS.html @@ -9,23 +9,23 @@
Version 1.3

-Copyright © 2004 Klaus Schmidinger
+Copyright © 2005 Klaus Schmidinger
kls@cadsoft.de
www.cadsoft.de/vdr

-
  -Important modifications introduced in version 1.3.18 are marked like this. -
-
  +
  Important modifications introduced in version 1.3.19 are marked like this.
-
  +
  Important modifications introduced in version 1.3.20 are marked like this.
-
  +
  Important modifications introduced in version 1.3.21 are marked like this.
+
  +Important modifications introduced in version 1.3.30 are marked like this. +

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

  • Command line arguments
  • Command line help
  • Getting started -
      +
     
  • Shutting down
  • Main menu entry @@ -68,6 +68,9 @@ structures and allows it to hook itself into specific areas to perform special a
  • The Setup menu
  • Configuration files
  • Internationalization +
      +
  • Custom services +
  • Loading plugins into VDR
  • Building the distribution package @@ -81,7 +84,7 @@ structures and allows it to hook itself into specific areas to perform special a
  • Skins
  • Themes
  • Devices -
      +
     
  • Audio
  • Remote Control @@ -308,7 +311,7 @@ since VDR, for instance, has to create the plugin objects in order to get their command line help - and after that immediately destroys them again.

    The destructor has to clean up any data created by the plugin. -
      +
      Any threads the plugin may have created shall be stopped in the Stop() function.
    @@ -506,7 +509,7 @@ VDR to exit. If the plugin doesn't implement any background functionality or internationalized texts, it doesn't need to implement either of these functions. -
      +
     

    Shutting down

    Stop it, right there!

    @@ -866,6 +869,77 @@ Texts are first searched for in the Phrases registered for this plugin (i and then in the global VDR texts. So a plugin can make use of texts defined by the core VDR code. +
      +

    Custom services

    + +
    What can I do for you?

    + +In some situations, two plugins may want to communicate directly, talking about things +that VDR doesn't handle itself. For example, a plugin may want to use features +that some other plugin offers, or it may want to inform other plugins about important +things it does. To receive requests or messages, a plugin can implement the +following function: + +

    +virtual bool Service(const char *Id, void *Data = NULL);
    +

    + +Id is a unique identification string that identifies the service protocol. +To avoid collisions, the string should contain a service name, the plugin name (unless +the service is not related to a single plugin) and a protocol version number. +Data points to a custom data structure. For each id string +there should be a specification that describes the format of the data +structure, and any change to the format should be reflected by a change +of the id string. +

    +The function shall return true for any service id string it handles, and false +otherwise. The plugins have to agreee in which situations the service +may be called, for example whether the service may be called from every thread, or +just from the main thread. A possible implementation could look like this: + +

    +struct Hello_SetGreetingTime_v1_0 {
    +  int NewGreetingTime;
    +  };
    +
    +bool cPluginHello::Service(const char *Id, void *Data)
    +{
    +  if (strcmp(Id, "Hello-SetGreetingTime-v1.0") == 0) {
    +     if (Data == NULL)
    +        return true;
    +     GreetingTime = ((Hello_SetGreetingTime_v1_0*)Data)->NewGreetingTime;
    +     return true;
    +     }
    +  return false;
    +}
    +

    + +Plugins should expect to be called with Data set to NULL and may use +this as a 'service supported' check without performing any actions. +

    +To send messages to, or request services from a specific plugin, one plugin can directly +call another plugin's service function: + +

    +Hello_SetGreetingTime_v1_0 hellodata;
    +hellodata.NewGreetingTime = 3;
    +cPlugin *Plugin = cPluginManager::GetPlugin("hello");
    +if (Plugin)
    +   Plugin->Service("Hello-SetGreetingTime-v1.0", >hellodata);
    +

    + +To send messages to, or request services from some plugin that offers the protocol, a +plugin can call the function cPluginManager::CallFirstService(). This function +will send the request to all plugins until one plugin handles it. +The function returns a pointer to the plugin that handled the request, or NULL +if no plugin handled it. +

    +To send a messages to all plugins, a plugin can call the function +cPluginManager::CallAllServices(). This function returns true if +any plugin handled the request, or false if no plugin handled the request. + +

    +


    Loading plugins into VDR

    Saddling up!

    @@ -1046,7 +1120,6 @@ public: Take a look at the files player.h and dvbplayer.c to see how VDR implements its own player for the VDR recordings.

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

    @@ -1060,7 +1133,6 @@ is attached to. There are no prerequisites regarding the length or alignment of
     individual block of data. The sum of all blocks must simply result in the
     desired data stream, and it must be delivered fast enough so that the
     DVB device doesn't run out of data.
    -
    To avoid busy loops the player should call its member function

    @@ -1069,7 +1141,6 @@ bool DevicePoll(cPoller &Poller, int TimeoutMs = 0);
     
     to determine whether the device is ready for further data.
     

    -
      By default all audio track handling is done by the device a player is attached to. If the player can provide more than a single audio track, and has special @@ -1088,7 +1159,6 @@ bool DeviceSetAvailableTrack(eTrackType Type, int Index, uint16_t Id, const char

    See device.h for details about the parameters for track handling. -

    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: @@ -1206,7 +1276,7 @@ public: }; cMyReceiver::cMyReceiver(int Pid) -
      +
      :cReceiver(0, -1, Pid)
    { @@ -1384,9 +1454,7 @@ public: virtual cSkinDisplayMenu *DisplayMenu(void); virtual cSkinDisplayReplay *DisplayReplay(bool ModeOnly); virtual cSkinDisplayVolume *DisplayVolume(void); -
      virtual cSkinDisplayMessage *DisplayTrack(int NumTracks, const char * const *Tracks); -
    virtual cSkinDisplayMessage *DisplayMessage(void); };

    @@ -1513,13 +1581,11 @@ repectively. If the device can provide more than a single audio track, it can implement the following function to make them available: -
     

     virtual void SetAudioTrackDevice(eTrackType Type);
     virtual int GetAudioChannelDevice(void);
     virtual void SetAudioChannelDevice(int AudioChannel);
     

    -

    Recording @@ -1539,15 +1605,6 @@ 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 GetTSPacket() must deliver exactly one such packet (if one is currently available).

    -If this device allows receiving several different data streams, it can -implement - -

    -virtual bool CanBeReUsed(int Frequency, int Vpid);
    -

    - -to indicate this to VDR. -

    Replaying

    The functions to implement replaying capabilites are @@ -1678,7 +1735,7 @@ private: virtual void Action(void); public: cMyAudio(void); -
      +
      virtual void Play(const uchar *Data, int Length, uchar Id);
    virtual void Mute(bool On); -- cgit v1.2.3