| <chapter id="chapter-other-base" xreflabel="Pre-made base classes"> |
| <title>Pre-made base classes</title> |
| <para> |
| So far, we've been looking at low-level concepts of creating any type of |
| &GStreamer; element. Now, let's assume that all you want is to create an |
| simple audiosink that works exactly the same as, say, |
| <quote>esdsink</quote>, or a filter that simply normalizes audio volume. |
| Such elements are very general in concept and since they do nothing |
| special, they should be easier to code than to provide your own scheduler |
| activation functions and doing complex caps negotiation. For this purpose, |
| &GStreamer; provides base classes that simplify some types of elements. |
| Those base classes will be discussed in this chapter. |
| </para> |
| |
| <sect1 id="section-base-sink" xreflabel="Writing a sink"> |
| <title>Writing a sink</title> |
| <para> |
| Sinks are special elements in &GStreamer;. This is because sink elements |
| have to take care of <emphasis>preroll</emphasis>, which is the process |
| that takes care that elements going into the |
| <classname>GST_STATE_PAUSED</classname> state will have buffers ready |
| after the state change. The result of this is that such elements can |
| start processing data immediately after going into the |
| <classname>GST_STATE_PLAYING</classname> state, without requiring to |
| take some time to initialize outputs or set up decoders; all that is done |
| already before the state-change to <classname>GST_STATE_PAUSED</classname> |
| successfully completes. |
| </para> |
| <para> |
| Preroll, however, is a complex process that would require the same |
| code in many elements. Therefore, sink elements can derive from the |
| <classname>GstBaseSink</classname> base-class, which does preroll and |
| a few other utility functions automatically. The derived class only |
| needs to implement a bunch of virtual functions and will work |
| automatically. |
| </para> |
| <para> |
| The base class implement much of the synchronization logic that a |
| sink has to perform. |
| </para> |
| <para> |
| The <classname>GstBaseSink</classname> base-class specifies some |
| limitations on elements, though: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| It requires that the sink only has one sinkpad. Sink elements that |
| need more than one sinkpad, must make a manager element with |
| multiple GstBaseSink elements inside. |
| </para> |
| </listitem> |
| </itemizedlist> |
| <para> |
| Sink elements can derive from <classname>GstBaseSink</classname> using |
| the usual <classname>GObject</classname> convenience macro |
| <function>G_DEFINE_TYPE ()</function>: |
| </para> |
| <programlisting> |
| G_DEFINE_TYPE (GstMySink, gst_my_sink, GST_TYPE_BASE_SINK); |
| |
| [..] |
| |
| static void |
| gst_my_sink_class_init (GstMySinkClass * klass) |
| { |
| klass->set_caps = [..]; |
| klass->render = [..]; |
| [..] |
| } |
| </programlisting> |
| <para> |
| The advantages of deriving from <classname>GstBaseSink</classname> are |
| numerous: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| Derived implementations barely need to be aware of preroll, and do |
| not need to know anything about the technical implementation |
| requirements of preroll. The base-class does all the hard work. |
| </para> |
| <para> |
| Less code to write in the derived class, shared code (and thus |
| shared bugfixes). |
| </para> |
| </listitem> |
| </itemizedlist> |
| <para> |
| There are also specialized base classes for audio and video, let's look |
| at those a bit. |
| </para> |
| |
| <sect2 id="section-base-audiosink" xreflabel="Writing an audio sink"> |
| <title>Writing an audio sink</title> |
| <para> |
| Essentially, audio sink implementations are just a special case of a |
| general sink. An audio sink has the added complexity that it needs to |
| schedule playback of samples. It must match the clock selected in the |
| pipeline against the clock of the audio device and calculate and |
| compensate for drift and jitter. |
| </para> |
| <para> |
| There are two audio base classes that you can choose to |
| derive from, depending on your needs: |
| <classname>GstAudioBasesink</classname> and |
| <classname>GstAudioSink</classname>. The audiobasesink provides full |
| control over how synchronization and scheduling is handled, by using |
| a ringbuffer that the derived class controls and provides. The |
| audiosink base-class is a derived class of the audiobasesink, |
| implementing a standard ringbuffer implementing default |
| synchronization and providing a standard audio-sample clock. Derived |
| classes of this base class merely need to provide a <function>_open |
| ()</function>, <function>_close ()</function> and a <function>_write |
| ()</function> function implementation, and some optional functions. |
| This should suffice for many sound-server output elements and even |
| most interfaces. More demanding audio systems, such as Jack, would |
| want to implement the <classname>GstAudioBaseSink</classname> |
| base-class. |
| </para> |
| <para> |
| The <classname>GstAudioBaseSink</classname> has little to no |
| limitations and should fit virtually every implementation, but is |
| hard to implement. The <classname>GstAudioSink</classname>, on the |
| other hand, only fits those systems with a simple <function>open |
| ()</function> / <function>close ()</function> / <function>write |
| ()</function> API (which practically means pretty much all of them), |
| but has the advantage that it is a lot easier to implement. The |
| benefits of this second base class are large: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| Automatic synchronization, without any code in the derived class. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Also automatically provides a clock, so that other sinks (e.g. in |
| case of audio/video playback) are synchronized. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Features can be added to all audiosinks by making a change in the |
| base class, which makes maintenance easy. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Derived classes require only three small functions, plus some |
| <classname>GObject</classname> boilerplate code. |
| </para> |
| </listitem> |
| </itemizedlist> |
| <para> |
| In addition to implementing the audio base-class virtual functions, |
| derived classes can (should) also implement the |
| <classname>GstBaseSink</classname> <function>set_caps ()</function> and |
| <function>get_caps ()</function> virtual functions for negotiation. |
| </para> |
| </sect2> |
| |
| <sect2 id="section-base-videosink" xreflabel="Writing a general sink"> |
| <title>Writing a video sink</title> |
| <para> |
| Writing a videosink can be done using the |
| <classname>GstVideoSink</classname> base-class, which derives from |
| <classname>GstBaseSink</classname> internally. Currently, it does |
| nothing yet but add another compile dependency, so derived classes |
| will need to implement all base-sink virtual functions. When they do |
| this correctly, this will have some positive effects on the end user |
| experience with the videosink: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| Because of preroll (and the <function>preroll ()</function> virtual |
| function), it is possible to display a video frame already when |
| going into the <classname>GST_STATE_PAUSED</classname> state. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| By adding new features to <classname>GstVideoSink</classname>, it |
| will be possible to add extensions to videosinks that affect all of |
| them, but only need to be coded once, which is a huge maintenance |
| benefit. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </sect2> |
| </sect1> |
| |
| <sect1 id="section-base-src" xreflabel="Writing a source"> |
| <title>Writing a source</title> |
| <para> |
| In the previous part, particularly <xref |
| linkend="section-scheduling-randomxs"/>, we have learned that some types |
| of elements can provide random access. This applies most definitely to |
| source elements reading from a randomly seekable location, such as file |
| sources. However, other source elements may be better described as a |
| live source element, such as a camera source, an audio card source and |
| such; those are not seekable and do not provide byte-exact access. For |
| all such use cases, &GStreamer; provides two base classes: |
| <classname>GstBaseSrc</classname> for the basic source functionality, and |
| <classname>GstPushSrc</classname>, which is a non-byte exact source |
| base-class. The pushsource base class itself derives from basesource as |
| well, and thus all statements about the basesource apply to the |
| pushsource, too. |
| </para> |
| <para> |
| The basesrc class does several things automatically for derived classes, |
| so they no longer have to worry about it: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| Fixes to <classname>GstBaseSrc</classname> apply to all derived |
| classes automatically. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Automatic pad activation handling, and task-wrapping in case we get |
| assigned to start a task ourselves. |
| </para> |
| </listitem> |
| </itemizedlist> |
| <para> |
| The <classname>GstBaseSrc</classname> may not be suitable for all cases, |
| though; it has limitations: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| There is one and only one sourcepad. Source elements requiring |
| multiple sourcepads must implement a manager bin and use multiple |
| source elements internally or make a manager element that uses |
| a source element and a demuxer inside. |
| </para> |
| </listitem> |
| </itemizedlist> |
| <para> |
| It is possible to use special memory, such as X server memory pointers |
| or <function>mmap ()</function>'ed memory areas, as data pointers in |
| buffers returned from the <function>create()</function> virtual function. |
| </para> |
| |
| <sect2 id="section-base-audiosrc" xreflabel="Writing an audio source"> |
| <title>Writing an audio source</title> |
| <para> |
| An audio source is nothing more but a special case of a pushsource. |
| Audio sources would be anything that reads audio, such as a source |
| reading from a soundserver, a kernel interface (such as ALSA) or a |
| test sound / signal generator. &GStreamer; provides two base classes, |
| similar to the two audiosinks described in <xref |
| linkend="section-base-audiosink"/>; one is ringbuffer-based, and |
| requires the derived class to take care of its own scheduling, |
| synchronization and such. The other is based on this |
| <classname>GstAudioBaseSrc</classname> and is called |
| <classname>GstAudioSrc</classname>, and provides a simple |
| <function>open ()</function>, <function>close ()</function> and |
| <function>read ()</function> interface, which is rather simple to |
| implement and will suffice for most soundserver sources and audio |
| interfaces (e.g. ALSA or OSS) out there. |
| </para> |
| <para> |
| The <classname>GstAudioSrc</classname> base-class has several benefits |
| for derived classes, on top of the benefits of the |
| <classname>GstPushSrc</classname> base-class that it is based on: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| Does syncronization and provides a clock. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| New features can be added to it and will apply to all derived |
| classes automatically. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </sect2> |
| </sect1> |
| |
| <sect1 id="section-base-transform" |
| xreflabel="Writing a transformation element"> |
| <title>Writing a transformation element</title> |
| <para> |
| A third base-class that &GStreamer; provides is the |
| <classname>GstBaseTransform</classname>. This is a base class for |
| elements with one sourcepad and one sinkpad which act as a filter |
| of some sort, such as volume changing, audio resampling, audio format |
| conversion, and so on and so on. There is quite a lot of bookkeeping |
| that such elements need to do in order for things such as buffer |
| allocation forwarding, passthrough, in-place processing and such to all |
| work correctly. This base class does all that for you, so that you just |
| need to do the actual processing. |
| </para> |
| <para> |
| Since the <classname>GstBaseTransform</classname> is based on the 1-to-1 |
| model for filters, it may not apply well to elements such as decoders, |
| which may have to parse properties from the stream. Also, it will not |
| work for elements requiring more than one sourcepad or sinkpad. |
| </para> |
| </sect1> |
| </chapter> |