| <chapter id="chapter-checklist-element"> |
| <title>Things to check when writing an element</title> |
| <para> |
| This chapter contains a fairly random selection of things to take care |
| of when writing an element. It's up to you how far you're going to stick |
| to those guidelines. However, keep in mind that when you're writing an |
| element and hope for it to be included in the mainstream &GStreamer; |
| distribution, it <emphasis>has to</emphasis> meet those requirements. |
| As far as possible, we will try to explain why those requirements are |
| set. |
| </para> |
| |
| <sect1 id="section-checklist-states"> |
| <title>About states</title> |
| |
| <itemizedlist> |
| <listitem> |
| <para> |
| Make sure the state of an element gets reset when going to |
| <classname>NULL</classname>. Ideally, this should set all |
| object properties to their original state. This function |
| should also be called from _init. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Make sure an element forgets <emphasis>everything</emphasis> |
| about its contained stream when going from |
| <classname>PAUSED</classname> to <classname>READY</classname>. In |
| <classname>READY</classname>, all stream states are reset. An |
| element that goes from <classname>PAUSED</classname> to |
| <classname>READY</classname> and back to |
| <classname>PAUSED</classname> should start reading the |
| stream from he start again. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| People that use <command>gst-launch</command> for testing have |
| the tendency to not care about cleaning up. This is |
| <emphasis>wrong</emphasis>. An element should be tested using |
| various applications, where testing not only means to <quote>make |
| sure it doesn't crash</quote>, but also to test for memory leaks |
| using tools such as <command>valgrind</command>. Elements have to |
| be reusable in a pipeline after having been reset. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </sect1> |
| |
| <sect1 id="section-checklist-debug"> |
| <title>Debugging</title> |
| |
| <itemizedlist> |
| <listitem> |
| <para> |
| Elements should <emphasis>never</emphasis> use their standard |
| output for debugging (using functions such as <function>printf |
| ()</function> or <function>g_print ()</function>). Instead, |
| elements should use the logging functions provided by &GStreamer;, |
| named <function>GST_DEBUG ()</function>, |
| <function>GST_LOG ()</function>, <function>GST_INFO ()</function>, |
| <function>GST_WARNING ()</function> and |
| <function>GST_ERROR ()</function>. The various logging levels can |
| be turned on and off at runtime and can thus be used for solving |
| issues as they turn up. Instead of <function>GST_LOG ()</function> |
| (as an example), you can also use <function>GST_LOG_OBJECT |
| ()</function> to print the object that you're logging output for. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Ideally, elements should use their own debugging category. Most |
| elements use the following code to do that: |
| </para> |
| <programlisting> |
| GST_DEBUG_CATEGORY_STATIC (myelement_debug); |
| #define GST_CAT_DEFAULT myelement_debug |
| |
| [..] |
| |
| static void |
| gst_myelement_class_init (GstMyelementClass *klass) |
| { |
| [..] |
| GST_DEBUG_CATEGORY_INIT (myelement_debug, "myelement", |
| 0, "My own element"); |
| } |
| </programlisting> |
| <para> |
| At runtime, you can turn on debugging using the commandline |
| option <command>--gst-debug=myelement:5</command>. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Elements should use GST_DEBUG_FUNCPTR when setting pad functions or |
| overriding element class methods, for example: |
| <programlisting> |
| gst_pad_set_event_func (myelement->srcpad, |
| GST_DEBUG_FUNCPTR (my_element_src_event)); |
| </programlisting> |
| This makes debug output much easier to read later on. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Elements that are aimed for inclusion into one of the GStreamer |
| modules should ensure consistent naming of the element name, |
| structures and function names. For example, if the element type is |
| GstYellowFooDec, functions should be prefixed with |
| gst_yellow_foo_dec_ and the element should be registered |
| as 'yellowfoodec'. Separate words should be separate in this scheme, |
| so it should be GstFooDec and gst_foo_dec, and not GstFoodec and |
| gst_foodec. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </sect1> |
| |
| <sect1 id="section-checklist-query"> |
| <title>Querying, events and the like</title> |
| |
| <itemizedlist> |
| <listitem> |
| <para> |
| All elements to which it applies (sources, sinks, demuxers) |
| should implement query functions on their pads, so that |
| applications and neighbour elements can request the current |
| position, the stream length (if known) and so on. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Elements should make sure they forward events they do not |
| handle with gst_pad_event_default (pad, event) instead of |
| just dropping them. Events should never be dropped unless |
| specifically intended. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Elements should make sure they forward queries they do not |
| handle with gst_pad_query_default (pad, query) instead of |
| just dropping them. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Elements should use gst_pad_get_parent() in event and query |
| functions, so that they hold a reference to the element while they |
| are operating. Note that gst_pad_get_parent() increases the |
| reference count of the element, so you must be very careful to call |
| gst_object_unref (element) before returning from your query or |
| event function, otherwise you will leak memory. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </sect1> |
| |
| <sect1 id="section-checklist-testing"> |
| <title>Testing your element</title> |
| |
| <itemizedlist> |
| <listitem> |
| <para> |
| <command>gst-launch</command> is <emphasis>not</emphasis> a good |
| tool to show that your element is finished. Applications such as |
| Rhythmbox and Totem (for GNOME) or AmaroK (for KDE) |
| <emphasis>are</emphasis>. <command>gst-launch</command> will not |
| test various things such as proper clean-up on reset, interrupt |
| event handling, querying and so on. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Parsers and demuxers should make sure to check their input. Input |
| cannot be trusted. Prevent possible buffer overflows and the like. |
| Feel free to error out on unrecoverable stream errors. Test your |
| demuxer using stream corruption elements such as |
| <classname>breakmydata</classname> (included in gst-plugins). It |
| will randomly insert, delete and modify bytes in a stream, and is |
| therefore a good test for robustness. If your element crashes |
| when adding this element, your element needs fixing. If it errors |
| out properly, it's good enough. Ideally, it'd just continue to |
| work and forward data as much as possible. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Demuxers should not assume that seeking works. Be prepared to |
| work with unseekable input streams (e.g. network sources) as |
| well. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| Sources and sinks should be prepared to be assigned another clock |
| then the one they expose themselves. Always use the provided clock |
| for synchronization, else you'll get A/V sync issues. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </sect1> |
| </chapter> |