Hi, 

did you get my other reply? After two days of trial and error, I managed
to make a (statically) registered plugin, that works in a pipeline
without warnings or errors (attached). It doesn't do anything useful,
though.

Please let me know if you are making any progress with your sink.

alberto


On Sat, 2009-01-17 at 23:16 +0200, [email protected] wrote:
> hello, I want to make gentral gstreamer v4l2 sink, and prefer to make
> it with vala to bypass all gobject stuff, is it possible now? and if
> possible can you point me where to start?
> 
-- 
Alberto Colombo, MSc

PhD student at Digital Imaging Research Centre
Kingston University, London

e-mail: [email protected]
 phone: +44 (0)20 8547 8642
  http://cism.kingston.ac.uk/people/details.php?AuthorID=925


This email has been scanned for all viruses by the MessageLabs Email
Security System.
using Gst, GLib;

// compile with:
// valac --pkg gstreamer-0.10 --pkg gstreamer-video-0.10 gst-app.vala

class Gstapp : GLib.Object
{
    MainLoop loop = new MainLoop(null, false);
    Bin pipeline;
    Bin decoder;
    Element sink;
    Element filter;

    /** reacts to messages from the pipeline bus */
    private bool bus_watch(Bus bus, Message message)
    {
        //stdout.printf("Got %s message", Message.type_get_name(message.type));
        switch (message.type)
        {
            case MessageType.ERROR:
            {
                Error err;
                string debug;
                message.parse_error(out err, out debug);
                stdout.printf("Error: %s\n", err.message);
                loop.quit();
                break;
            }
            case MessageType.EOS:
            {
                loop.quit();
                break;
            }
            default: break;
        }
        //stdout.putc('\n');
        return true;
    }

    /** called by decodebin when a new pad is created */
    private void on_new_pad(Pad pad)
    {
        Pad sinkpad = sink.get_pad("sink");
        if (pad.can_link(sinkpad)) pad.link(sinkpad);
    }

    /** the main method */
	public int run(string[] args)
	{
	    Gst.init(ref args);
	    if (args.length != 2)
	    {
	        stdout.printf("usage: %s FILE\n", args[0]);
	        return 1;
        }
        bool plugin_registered = Plugin.register_static(
            VERSION_MAJOR, VERSION_MINOR, "my-plugin-name", "description of it", plugin_init, "0.1",
            "GPL", "source",  "package name", "http://mywebsite.nil";);
        assert(plugin_registered);
        filter = ElementFactory.make("MyAdvancedTransform", "filter");
        assert(filter != null);
        assert(filter.name == "filter");
        string location = args[1];
        pipeline = new Pipeline("pipeline");
        decoder = (Bin)ElementFactory.make("decodebin", "decoder");
        Signal.connect_swapped(decoder, "new-decoded-pad", (Callback)on_new_pad, this);
        dynamic Element source = ElementFactory.make("filesrc", "source");
        source.location = location;
        sink = ElementFactory.make("autovideosink", "sink");
        var colorspace = ElementFactory.make("ffmpegcolorspace", "colorspace");
        pipeline.add_many(source, decoder, colorspace, sink);
        pipeline.add(filter);
        source.link(decoder);
        filter.link(colorspace);
        colorspace.link(sink);
        sink = filter;
        pipeline.get_bus().add_watch(bus_watch);
		pipeline.set_state(State.PLAYING);
		loop.run();
		pipeline.set_state(State.NULL);
		return 0;
	}
	
	public static int main(string[] args)
	{
	    var app = new Gstapp();
	    return app.run(args);
	}
}

/** 
Class that inherits from Basetransform. It should be easier to implement than
subclassing Element, but still doesn't work.
*/
class MyAdvancedTransform : VideoFilter
{
    static const ElementDetails details = {
        "MyAdvancedTransform",
        "Example/SecondExample",
        "Try to make a plugin using Vala",
        "alberto <[email protected]>"
    };
    
    static StaticPadTemplate sink_factory;    
    static StaticPadTemplate src_factory;
    
    class construct
    {
        sink_factory.name_template = "sink";
        sink_factory.direction = PadDirection.SINK;
        sink_factory.presence = PadPresence.ALWAYS;
        sink_factory.static_caps.str = "ANY";
        src_factory.name_template = "src";
        src_factory.direction = PadDirection.SRC;
        src_factory.presence = PadPresence.ALWAYS;
        src_factory.static_caps.str = "ANY";
        add_pad_template(src_facto...@get());
        add_pad_template(sink_facto...@get());        
        set_details(details);
    }
    
    public override Gst.FlowReturn transform_ip(Buffer buf)
    {
        GLib.debug("Data is flowing!");        
        return Gst.FlowReturn.OK;
    }
}

bool plugin_init(Plugin p)
{
    bool res = true;
    res &= Element.register(p, "MyAdvancedTransform", Rank.NONE, typeof(MyAdvancedTransform));
    return res;
}


/*

I have removed the following bits of code to minimise clutter.
They may be reintroduced in the appropriate sections later, if at all.

    // from bus callback
            case MessageType.TAG:
            {
		        TagList taglist;
		        message.parse_tag(out taglist);
		        // generates a warning in the C sources		        
		        taglist.foreach( (list, tag) => {
	                string val, niceval;
	                if (list.get_string(tag, out val))
	                    niceval = " = \""+val+"\"";
                    else
                        niceval = "";
		            stdout.printf(": %s%s", tag, niceval);
	            });      
	            break;      
            }
            case MessageType.ELEMENT:
            {
                Structure s = message.get_structure();
                // generates a warning in the C sources
                s.foreach( (field_id, val) => {
                    stdout.printf("\tfield %s\n", field_id.to_string());
                    return true;
                });                
                break;
            }
            case MessageType.STATE_CHANGED:
            {
                State oldstate, newstate, pending;
		        message.parse_state_changed(out oldstate, out newstate, out pending);
                stdout.printf(": %d -> %d (%d)", (int)oldstate, (int)newstate, (int)pending);
                break;
            }
    


    // MUST be static, otherwise valac will silently omit them in the C sources... 
    static string? vfs_location;
    static string? rtsp_location;
    static string? file_location;
    const OptionEntry[] entries = {
            {"vfs", 'v', 0, OptionArg.STRING, out vfs_location, 
            "play video from URI", "URI"},
            {"rtsp", 'r', 0, OptionArg.STRING, out rtsp_location,
            "play RTSP stream", "RTSP"},
            {"file", 'f', 0, OptionArg.FILENAME, out file_location,
            "play video from FILE", "FILE"},
            {null}
        };


        OptionContext ctx = new OptionContext(" -- play video from file or RTSP");
        OptionGroup gstgroup = Gst.init_get_option_group();
        ctx.add_main_entries(entries, null);
        ctx.add_group(#gstgroup);
        Element source;
        try
        {
            GLib.Object src;
            ctx.parse(ref args);
            if (rtsp_location != null)
            {
                src = ElementFactory.make("rtspsrc", "source");
                src.set("location", rtsp_location);
            }
            else if (vfs_location != null)
            {
                src = ElementFactory.make("gnomevfssrc", "source");
                src.set("location", vfs_location);
            }
            else if (file_location != null)
            {
                src = ElementFactory.make("filesrc", "source");
                src.set("location", file_location);
            }
            else
            {
                stdout.printf("%s", ctx.get_help(true, null));
                throw new OptionError.FAILED("please specify a file/uri to play");
            }
            assert(src != null);
            source = (Element)src;
        }
        catch (OptionError e)
        {
            stdout.printf("Error: %s\n\n", e.message);
            return 1;
        }
*/
_______________________________________________
Vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to