using Gst; //Compile with: valac gst_my_filter.vala --pkg gstreamer-0.10 -C -H gst_my_filter.h ; gcc gst_my_filter.c -shared -fPIC -o tmp.so $(pkg-config --cflags gstreamer-0.10) -DPACKAGE="\"plugin\"" -DVERSION="\"01\"" [CCode (lower_case_cprefix = "")] namespace Macros { extern const string VERSION; extern const string PACKAGE; } private static bool plugin_init(Gst.Plugin plugin) { return Gst.Element.register(plugin, "myfilter", Gst.Rank.SECONDARY, typeof(Gst.MyFilter)); } public const Gst.PluginDesc gst_plugin_desc = { Gst.VERSION_MAJOR, Gst.VERSION_MINOR, "myfilterplugin", "My filter plugin", plugin_init, Macros.VERSION, "LGPL", Macros.PACKAGE, "GStreamer", "http://gstreamer.net/" }; public class Gst.MyFilter : Gst.Element { private static Gst.StaticPadTemplate sinktempl; private static Gst.StaticPadTemplate srctempl; class construct { sinktempl = Gst.StaticPadTemplate() { name_template = "sink", direction = Gst.PadDirection.SINK, presence = Gst.PadPresence.ALWAYS, static_caps = { "ANY" } }; srctempl = Gst.StaticPadTemplate() { name_template = "src", direction = Gst.PadDirection.SRC, presence = Gst.PadPresence.ALWAYS, static_caps = { "ANY" } }; // set the plugin information set_details_simple("My filter plugin in vala", "audio/filters", "A good filter plugin, described here", "Author "); // create and add the sink template add_pad_template(sinktempl.get()); // create and add the src template add_pad_template(srctempl.get()); } construct { this.sinkpad = new Gst.Pad.from_static_template (sinktempl, "sink"); this.sinkpad.set_setcaps_function(Gst.MyFilter.set_caps); this.sinkpad.set_getcaps_function(Gst.Pad.proxy_getcaps); this.sinkpad.set_chain_function(Gst.MyFilter.chain); this.srcpad = new Gst.Pad.from_static_template (srctempl, "src"); this.srcpad.set_getcaps_function(Gst.Pad.proxy_getcaps); this.add_pad(this.srcpad); this.add_pad(this.sinkpad); this.silent = false; } [Description(nick = "verbose", blurb = "If the filter should be verbose.")] public bool silent { get; set; default = false; } public Gst.Pad sinkpad; public Gst.Pad srcpad; private static bool set_caps(Gst.Pad pad, Gst.Caps caps) { Gst.MyFilter filter = (Gst.MyFilter) pad.get_parent(); /* When requested for some caps to an end (i.e., output/input), request the same caps as at the other end (i.e., input/output), so that we can just forward incoming buffers without touching them (look at chain function) */ if(pad == filter.srcpad) { return filter.sinkpad.set_caps(caps); } else { return filter.srcpad.set_caps(caps); } } private static Gst.FlowReturn chain(Gst.Pad pad, owned Gst.Buffer buf) { Gst.MyFilter filter = (Gst.MyFilter) pad.get_parent(); if(filter.silent == false) { stderr.printf("I'm plugged, therefore I'm in.\n"); } /* just push out the incoming buffer without touching it */ return filter.srcpad.push (buf); } }