# Implementing Rygel Media Engines

## Implementing Media Engines: Overview

This library may be used to create Rygel media engines by implementing the RygelMediaEngine class. Rygel media engines contain knowledge about the streaming and (optionally) the transcoding and seeking capabilites of the media library in use.

The actual media engine used by Rygel at runtime is specified by the media-engine configuration key. For instance, in `rygel.conf`: `media-engine=librygel-media-engine-gst.so`

A media engines should derive its own RygelDataSource, returning an instance of it from its create_data_source() implementation.

Optionally, a derived RygelMediaEngine may implement the get_dlna_profiles() and get_transcoders() virtual functions.

Rygel itself provides two media engines:

1. gstreamer: A media engine that uses GStreamer for transcoding and seeking.

2. simple: A media engine that uses no multimedia framework, and therefore offers no transcoding or time-based seeking.

## Implementing Media Engines: Full Example

In addition, the external rygel-gst-0-10-media-engine project provides a Rygel media engine that uses an older GStreamer version and is an example of an external Rygel media-engine implemented in C.

The media engine plugin provides a `module_get_instance()` function, called by Rygel, which returns an instance of our derived RygelDataSource class.

This `RygelGstMediaEngine` class implements the virtual functions from its RygelMediaEngine base class, such as `get_dlna_profiles()`, `get_transcoders()` to report what DLNA profiles this media engine supports and what transcoding capabilities it offers.

It also implements the `create_data_source()` virtual function, returning an instance of our `RygelGstDataSource` class, which implements the RygelDataSource interface. This implements the virtual functions of the RygelDataSource interface, such as `start()`, `freeze()`, `thaw()`, and `stop()` by setting the state of its GStreamer `GstPipeline`.

The list of transcoders returned by the `RygelGstMediaEngine` `get_transcoders()` implementation provides instances of every transcoder provided by our media engine. These classes derive from RygelTranscoder, implementing its `create_source()` virtual function, returning an instance of our `RygelGstDataSource` class which uses a GStreamer `GstBin` that uses a GStreamer decoder and encoder to transcode the original data into the desired format. These derived RygelTranscoder objects also have appropriate values for the `mime-type`, `dlna-profile`, and `extension` properties, allowing Rygel to decide which transcoder to use.

The derived RygelTranscoder classes also implement the `add_resource` virtual function, to set transcoder-specific details on a `GUPnPDIDLLiteResource` that is first instantiated by calling the `add_resource` implementation in the base class. For instance, by calling `gupnp_didl_lite_resource_set_bitrate()`.