Thanks for your help, that vala code is a great reference for me to look at also. One question, where is vala documentation for ClutterGst and Gst plugins? Anyway, I finally got a working clutter-gst from a filesrc! Once bug is resolved: https://bugzilla.gnome.org/show_bug.cgi?id=624648 This is working code (assuming bug fixed): using Clutter;using Gst;using ClutterGst; // You provide the filename and the sink and we'll make it just work.public class VideoPlayer { private string fileName; private Pipeline pipeline; private Element src; private Element sink; private Element decode; private Element colorspace; public VideoPlayer(string? _fileName, Element _sink) { fileName = _fileName; sink = _sink; setup_pipeline(); } public void play() { if(pipeline.current_state == State.PLAYING) pipeline.set_state(State.PAUSED); else pipeline.set_state(State.PLAYING); } public void stop() { pipeline.set_state(State.READY); } private void setup_pipeline() { pipeline = new Pipeline("pipeline"); // To play a video file you need these elements: // - "filesrc" to read file or "v4l2src" (src) // - "decodebin" to decode file (filter) // - "ffmpegcolorspace" to do colorspace conversion (filter) // - Some sink that we have passed in. // If we don't have a fileName, then use the video camera, which is fun. if(fileName == null) { src = ElementFactory.make("v4l2src", null); } else { src = ElementFactory.make("filesrc", null); // Unlike in GOBject where we use .set_attribute, here we use .set as this is // built into vala, I guess. src.set("location", fileName); } decode = ElementFactory.make("decodebin", null); colorspace = ElementFactory.make("ffmpegcolorspace", null); // decodebins output (src) isnt created until after the state != State.READY. So we wait // for the new-decoded-pad event and hook up those pads at that time. // // The last argument is because on_new_decoded_pad is static so we need to // provide a reference to the instance variables it will need. // // We should be able to simply do: // // decode.new_decoded_pad.connect(on_new_decoded_pad); // // Where on_new_decoded_pad would be an instance method. However // There is a bug that requires we do this crap. See on_new_decoded_pad comments. Signal.connect(decode, "new-decoded-pad", (GLib.Callback) on_new_decoded_pad, colorspace); // Add all our elements to the pipeline pipeline.add_many(src, decode, colorspace, sink); // Hook up the elements that we can hook up. Which pads to hook up is // resolved automatically by direction and type when not ambiguous. src.link(decode); colorspace.link(sink); } // The last argument inherits from GPointer in C which in the context means any reference type. // We declare this method to be static and use the last arg to get a ref back to the instance, // instead of just making this an instance method because of bug: (which I don't totally understand) // https://bugzilla.gnome.org/show_bug.cgi?id=615979 private static void on_new_decoded_pad(Element decodebin, Pad pad, bool last, Element colorspace) { pad.link(colorspace.get_pad("sink")); }} // Clutter.Texture is an actor, for drawing images on. We are going// to draw video frames on this texture. It exposes a public attribute// player which is an instance of VideoPlayer.class VideoTexture : Clutter.Texture { public VideoPlayer player; private ClutterGst.VideoSink sink; // Input args private string videoFile; public VideoTexture(string? _videoFile) { videoFile = _videoFile; // ClutterGst.VideoSink is a Gst sink element. We pass in this // actor so that this sink knows to copy frames to that texture. sink = new ClutterGst.VideoSink(this); // Create the player player = new VideoPlayer(videoFile, sink); }} bool on_keypress_event(KeyEvent e) { Clutter.main_quit(); return true;} void main(string[] args) { var vid1 = null; // Initialize both Clutter and ClutterGst Clutter.init(ref args); Gst.init (ref args); ClutterGst.init(ref args); // Each window by default has a stage associated with it var stage = Stage.get_default(); stage.color = Color.from_string("black"); stage.title = "Awesome"; stage.x = 800; stage.y = 600; stage.hide.connect(Clutter.main_quit); stage.key_press_event.connect(on_keypress_event); VideoTexture awesome1 = new VideoTexture(vid1); // Add the target of the pipeline, the clutter texture (this), // to the stage so we can see it. stage.add_actor(awesome1); stage.show_all(); // Play must be called after the stage has been shown or else segfault!! // Calling play sets the gst pipelines state to State.PLAYING awesome1.player.play(); Clutter.main();}
On 18 July 2010 12:05, Steve Salazar <[email protected]> wrote: > > Sorry about the last post, here is the correct link: > http://gist.github.com/479975 > Also, to answer the last question about trying the pipeline with gst-launch, > I've tried this and it works fine: > gst-launch filesrc location=/home/esalazar/Desktop/Rendezvous.avi ! decodebin > ! ffmpegcolorspace ! xvimagesink > Which should be identical to what I'm doing. Instead of linking decodebin to the next element, you should connect to its `new-decoded-pad` event and link from there. See these C and Vala examples: http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/gst/playback/test6.c http://gitorious.org/spek/spek/blobs/bccc4997868333df89d1dc5594fcb2c88a8e28e8/src/spek-source.vala#line82 Alex _______________________________________________ vala-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/vala-list
