aboutsummaryrefslogtreecommitdiff
path: root/docs/pwg/appendix-checklist.xml
blob: bd118c4038c2a5f0687bcca241c4685ca96e566a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
<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 the 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, parent, 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, parent, query) instead of
          just dropping them.
        </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, 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>