## 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()`.