Implementing Server Plugins: Full Example

In addition, the external rygel-gst-0-10-plugins project provides a Rygel Server plugin that uses an older GStreamer version and is an example of an external Rygel Server plugin implemented in C. Its media-export plugin exposes the contents of a directory via UPnP.

The module_init function first checks that the plugin has not been disabled and then creates an instance of its RygelMediaExportPlugin, which it adds to the provided RygelPluginLoader instance.

The RygelMediaExportPlugin class, derived from RygelMediaServerPlugin, simply instantiates its RygelMediaExportRootContainer class, derived from RygelMediaContainer, providing it to the base class as the root container.

The RygelMediaExportRootContainer creates an instance of a RygelMediaExportMediaCache class and a RygelMediaExportHarvester class. The harvester finds files on the filesystem, and stores them in the media cache, which uses SQLite to keep track of them.

RygelMediaExportRootContainer informs the media cache that it should have a child container for the media content as organised on the filesystem, and additionally some virtual folders for Music, Pictures, Video and Playlists, with further sub-divisions under these, for instance by publication year. These containers are added to the media cache via instances of the RygelMediaExportNullContainer class, but that is just to simplify the media cache API and these instances then serve no further purpose. The virtual folders are re-added whenever the filesystem's container is updated, so that they can show the updated content, though that is not particularly efficient.

RygelMediaExportRootContainer then delegates its RygelMediaContainer virtual function implementations to this media cache, which in turn uses the RygelMediaExportObjectFactory to instantiate new containers for each request based on their ID. For instance, it returns a RygelMediaExportDBContainer if the requested ID indicates a virtual container, using the definition in the rest of the ID to build a suitable SQL query.

The root container derives from TrackableDbContainer, which in turn implements the RygelTrackableContainer interface, to implement the change tracking profile of the UPnP ContentDirectory:3 specification. Therefore, whenever the root container, or its child items, have changed, we call the rygel_trackable_container_updated() function.

Any filesystem folders are implemented as UPnP containers via the RygelMediaExportWritableDbContainer class, which implements the RygelWritableContainer interface to allow new files to be uploaded to the filesystem via UPnP.