gstreamer/docs/pwg/appendix-porting.xml

164 lines
8.3 KiB
XML
Raw Normal View History

<chapter id="chapter-porting">
<title>Porting 0.8 plug-ins to 0.9</title>
<para>
This section of the appendix will discuss shortly what changes to
plugins will be needed to quickly and conveniently port most
applications from &GStreamer;-0.8 to &GStreamer;-0.9, with references
to the relevant sections in this Plugin Writer's Guide where needed.
With this list, it should be possible to port most plugins to
&GStreamer;-0.9 in less than a day. Exceptions are elements that will
require a base class in 0.9 (sources, sinks), in which case it may take
a lot longer, depending on the coder's skills (however, when using the
<classname>GstBaseSink</classname> and <classname>GstBaseSrc</classname>
base-classes, it shouldn't be all too bad), and elements requiring
the deprecated bytestream interface, which should take 1-2 days with
random access. The scheduling parts of muxers will also need a rewrite,
which will take about the same amount of time.
</para>
<sect1 id="section-porting-objects">
<title>List of changes</title>
<itemizedlist>
<listitem>
<para>
Most functions returning an object or an object property have
been changed to return its own reference rather than a constant
reference of the one owned by the object itself. The reason for
this change is primarily threadsafety. This means effectively
that return values of functions such as
<function>gst_element_get_pad ()</function>,
<function>gst_pad_get_name ()</function> and many more like these
have to be free'ed or unreferenced after use. Check the API
references of each function to know for sure whether return
values should be free'ed or not.
</para>
</listitem>
<listitem>
<para>
In 0.8, scheduling could happen in any way. Source elements could
be <function>_get ()</function>-based or <function>_loop
()</function>-based, and any other element could be <function>_chain
()</function>-based or <function>_loop ()</function>-based, with
no limitations. Scheduling in 0.9 is simpler for the scheduler,
and the element is expected to do some more work. Pads get
assigned a scheduling mode, based on which they can either
operate in random access-mode, in pipeline driving mode or in
push-mode. all this is documented in detail in <xref
linkend="chapter-scheduling"/>. As a result of this, the bytestream
object no longer exists. Elements requiring byte-level access should
now use random access on their sinkpads.
</para>
</listitem>
<listitem>
<para>
Negotiation is asynchronous. This means that downstream negotiation
is done as data comes in and upstream negotiation is done whenever
renegotiation is required. All details are described in
<xref linkend="chapter-negotiation"/>.
</para>
</listitem>
<listitem>
<para>
For as far as possible, elements should try to use existing base
classes in 0.9. Sink and source elements, for example, could derive
from <classname>GstBaseSrc</classname> and
<classname>GstBaseSink</classname>. Audio sinks or sources could even
derive from audio-specific base classes. All existing base classes
have been discussed in <xref linkend="chapter-other-base"/> and the
next few chapters.
</para>
</listitem>
<listitem>
<para>
In 0.9, event handling and buffers are separated once again. This
means that in order to receive events, one no longer has to set the
<classname>GST_FLAG_EVENT_AWARE</classname> flag, but can simply
set an event handling function on the element's sinkpad(s), using
the function <function>gst_pad_set_event_function ()</function>. The
<function>_chain ()</function>-function will only receive buffers.
</para>
</listitem>
<listitem>
<para>
Although core will wrap most threading-related locking for you (e.g.
it takes the stream lock before calling your data handling
functions), you are still responsible for locking around certain
functions, e.g. object properties. Be sure to lock properly here,
since applications will change those properties in a different thread
than the thread which does the actual data passing! You can use the
<function>GST_LOCK ()</function> and <function>GST_UNLOCK
()</function> helpers in most cases, fortunately, which grabs the
default property lock of the element.
</para>
</listitem>
<listitem>
<para>
<classname>GstValueFixedList</classname> and all
<function>*_fixed_list_* ()</function> functions were renamed to
<classname>GstValueArray</classname> and <function>*_array_*
()</function>.
</para>
</listitem>
<listitem>
<para>
The semantics of <symbol>GST_STATE_PAUSED</symbol> and
<symbol>GST_STATE_PLAYING</symbol> have changed for elements that
are not sink elements. Non-sink elements need to be able to accept
and process data already in the <symbol>GST_STATE_PAUSED</symbol>
state now (ie. when prerolling the pipeline). More details can be
found in <xref linkend="chapter-statemanage-states"/>.
</para>
</listitem>
<listitem>
<para>
If your plugin's state change function hasn't been superseded by
virtual start() and stop() methods of one of the new base classes,
then your plugin's state change functions may need to be changed in
order to safely handle concurrent access by multiple threads. Your
typical state change function will now first handle upwards state
changes, then chain up to the state change function of the parent
class (usually GstElementClass in these cases), and only then handle
downwards state changes. See the vorbis decoder plugin in
gst-plugins-base for an example.
</para>
<para>
The reason for this is that in the case of downwards state changes
you don't want to destroy allocated resources while your plugin's
chain function (for example) is still accessing those resources in
another thread. Whether your chain function might be running or not
depends on the state of your plugin's pads, and the state of those
pads is closely linked to the state of the element. Pad states are
handled in the GstElement class's state change function, including
proper locking, that's why it is essential to chain up before
destroying allocated resources.
</para>
<para>
As already mentioned above, you should really rewrite your plugin
to derive from one of the new base classes though, so you don't have
to worry about these things, as the base class will handle it for you.
There are no base classes for decoders and encoders yet, so the above
paragraphs about state changes definitively apply if your plugin is a
decoder or an encoder.
</para>
</listitem>
<listitem>
<para>
<function>gst_pad_set_link_function ()</function>, which used to set
a function that would be called when a format was negotiated between
two <classname>GstPad</classname>s, now sets a function that is
called when two elements are linked together in an application. For
all practical purposes, you most likely want to use the function
<function>gst_pad_set_setcaps_function ()</function>, nowadays, which
sets a function that is called when the format streaming over a pad
changes (so similar to <function>_set_link_function ()</function> in
&GStreamer;-0.8).
</para>
<para>
If the element is derived from a <classname>GstBase</classname> class,
then override the <function>set_caps ()</function>.
</para>
</listitem>
</itemizedlist>
</sect1>
</chapter>