Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public abstract class ValaAbstractVideoSink : Gst.Video.Sink {
- Gst.Video.Info* info;
- ~ValaAbstractVideoSink() {
- Gst.Video.Info.free (info);
- }
- construct {
- info = Gst.Video.Info.new();
- info->init();
- }
- public override bool set_caps (Gst.Caps caps) {
- if (info->from_caps (caps))
- set_video_size (info->width, info->height);
- return true;
- }
- public override Gst.FlowReturn show_frame (Gst.Buffer buffer) {
- Gst.Video.Frame frame;
- if (Gst.Video.Frame.map (out frame, info, buffer, Gst.MapFlags.READ)) {
- last_surface = new Cairo.ImageSurface.for_data (
- (uchar[])frame.data[0],
- Cairo.Format.ARGB32,
- info->width,
- info->height,
- frame.info.stride[0]);
- show_surface (last_surface);
- }
- return Gst.FlowReturn.OK;
- }
- public Cairo.Surface last_surface { get; private set; }
- public abstract void set_video_size (int width, int height);
- public abstract void show_surface (Cairo.Surface surface);
- }
- public class ValaVideoSink : ValaAbstractVideoSink {
- class construct {
- string format = "{ xRGB, ARGB }";
- if (ByteOrder.HOST == ByteOrder.LITTLE_ENDIAN)
- format = "{ BGRx, BGRA }";
- string caps_str = "video/x-raw, format = (string) %s, width = (int) [ 1, max ], height = (int) [ 1, max ], framerate = (fraction) [ 0, max ]".printf (format);
- Gst.StaticCaps caps = { null, caps_str };
- Gst.StaticPadTemplate sink_template = {
- "sink",
- Gst.PadDirection.SINK,
- Gst.PadPresence.ALWAYS,
- caps
- };
- add_pad_template (sink_template.get());
- }
- construct {
- widget = new ValaWidget();
- }
- public override void set_video_size (int width, int height) {
- if (widget.video_height == 0)
- widget.set_video_size (width, height);
- }
- public override void show_surface (Cairo.Surface surface) {
- if (widget.get_realized())
- widget.queue_surface (surface);
- }
- public ValaWidget widget { get; private set; }
- }
- public class ValaWidget : Gtk.DrawingArea {
- Cairo.Surface surface;
- public override bool draw (Cairo.Context context) {
- if (surface == null)
- return false;
- Gst.Video.Rectangle src = {
- 0,
- 0,
- video_width,
- video_height
- };
- Gst.Video.Rectangle dst = {
- 0,
- 0,
- get_allocated_width(),
- get_allocated_height()
- };
- Gst.Video.Rectangle result;
- Gst.Video.center_rectangle (src, dst, out result);
- double dx = (double)get_allocated_width() / video_width;
- double dy = (double)get_allocated_height() / video_height;
- dx = double.min (dx, dy);
- dy = dx;
- context.translate ((double)result.x, (double)result.y);
- context.scale (dx, dy);
- context.rectangle (0, 0, (double)result.w, (double)result.h);
- context.set_source_surface (surface, 0, 0);
- context.paint();
- return false;
- }
- public int video_height { get; private set; }
- public int video_width { get; private set; }
- internal void set_video_size (int width, int height) {
- video_height = height;
- video_width = width;
- }
- public void queue_surface (Cairo.Surface surf) {
- surface = surf;
- Idle.add_full (Priority.DEFAULT, () => {
- queue_draw();
- return Source.REMOVE;
- });
- }
- }
- public static void main (string[] args) {
- Gst.init (ref args);
- Gtk.init (ref args);
- int index = 0;
- var bin = Gst.ElementFactory.make ("playbin", "bin");
- var sink = new ValaVideoSink();
- bin["video-sink"] = sink;
- var window = new Gtk.Window();
- var bar = new Gtk.HeaderBar();
- bar.title = "test";
- bar.show_close_button = true;
- window.set_titlebar (bar);
- window.add (sink.widget);
- sink.widget.realize.connect (() => {
- bin["uri"] = "http://www.w3schools.com/html/mov_bbb.mp4";
- bin.set_state (Gst.State.PLAYING);
- });
- window.show_all();
- Gtk.main();
- }
Add Comment
Please, Sign In to add comment