Elements:_basics.md 4.54 KB
Newer Older
1 2 3 4 5 6 7
# PyGST Tutorial/Elements: basics

The purpose of this tutorial is to give you a basic working PyGst
plugin, and explain what each part does succinctly. This is a jumpstart,
not a replacement for the GStreamer Plugin Tutorial.

I will try to walk you through creating a new element that acts as a
luz.paz's avatar
luz.paz committed
8
filter (has both a sink and source, this one won't actually do any
9
filtering :)), which receives a buffer and pushes it forward. As such it
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
should help you avoid the pain.

:   source

## explanations

:   We will only be talking about the code in NewElement, the rest can
    be found in the [ source](elements_basics.py.md).
:   still needs a lot of work.

The image below shows the most important parts of a filter element, the
sink a gst.Pad, the elements chain function and the source a gst.Pad.

![filter element](Filter_element.elements_basics.png "filter element")

The image below shows how data flows through elements, and what type
each element is.

![source filter and sink
elements](Src-filter-sink.elemets-basics.png "source filter and sink elements")

All new elements are derived from gst.Element or a class derived from
gst.Element, gst.PushSrc is such an example. There are several basic
steps common to all plugins which include registering the element with
34
gstreamer, and initialising the plugin like you would any other object.
35 36
When initialising a derivied gst.Element you must do several things,
create the gst.Pads which describe media streams (buffers) the element
37 38
can receive and send, and make the pads by calling the
gst.Element.add\_pad(gst.Pad) method. You must also override the
39
functions specific to what you are trying to do, we are creating a
40
filter (an element which both receives and sends buffers) in this case
41
we must at minimum override the gst.Pad.set\_caps function which is used
42
to negotiate which type of buffers can be received and the gst.Pad.chain
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
function which handles incoming buffers.

NewElement is derived from gst.Element

    class NewElement(gst.Element):
        """ A basic, buffer forwarding gstreamer element """

Every new class derived from gst.Element (or another class derived from
gst.Element) must register it's self

        #here we register our plugin details
        __gstdetails__ = (
            "NewElement plugin",
            "newelement.py",
            "gst.Element, that passes a buffer from source to sink (a filter)",
            "Stephen Griffiths <scgmk5@gmail.com>")

        #source pad (template): we send buffers forward through here
        _srctemplate = gst.PadTemplate ('src',
            gst.PAD_SRC,
            gst.PAD_ALWAYS,
            gst.caps_new_any())

66
        #sink pad (template): we receive buffers from our sink pad
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
        _sinktemplate = gst.PadTemplate ('sink',
            gst.PAD_SINK,
            gst.PAD_ALWAYS,
            gst.caps_new_any())

        #register our pad templates
        __gsttemplates__ = (_srctemplate, _sinktemplate)

When we initialise the class, we must create the pads required to
communicate with other elements.

        def __init__(self, *args, **kwargs):
            #initialise parent class
            gst.Element.__init__(self, *args, **kwargs)

            #source pad, outgoing data
            self.srcpad = gst.Pad(self._srctemplate)

            #sink pad, incoming data
            self.sinkpad = gst.Pad(self._sinktemplate)
            self.sinkpad.set_setcaps_function(self._sink_setcaps)
            self.sinkpad.set_chain_function(self._sink_chain)

            #make pads available
            self.add_pad(self.srcpad)
            self.add_pad(self.sinkpad)

the pad setcaps function is called when we need to negotiate the
capabilities of our element relative to the element we are negotiating
with.

        def _sink_setcaps(self, pad, caps):
            #we negotiate our capabilities here, this function is called
            #as autovideosink accepts anything, we just say yes we can handle the
            #incoming data
            return True

104 105
the pad chain function is called on sink caps (the ones receiving data),
a buffer is received and pushed forward. Normally this is where we would
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
make changes to a buffer.

        def _sink_chain(self, pad, buf):
            #this is where we do filtering
            #and then push a buffer to the next element, returning a value saying
             it was either successful or not.
            return self.srcpad.push(buf)

### source

[elements\_basics.py](elements_basics.py.md)

## Other Resources

-   [GStreamer
    documentation](http://gstreamer.freedesktop.org/documentation/)
-   [PyGST documentation](http://pygstdocs.berlios.de/)