Initial commit
[fillmore] / src / marina / thumbnailsink.vala
1 class ThumbnailSink : Gst.BaseSink {
2     int width;
3     int height;
4     
5     const string caps_string = """video/x-raw-rgb,bpp = (int) 32, depth = (int) 32,
6                                   endianness = (int) BIG_ENDIAN,
7                                   blue_mask = (int)  0xFF000000,
8                                   green_mask = (int) 0x00FF0000,
9                                   red_mask = (int)   0x0000FF00,
10                                   width = (int) [ 1, max ],
11                                   height = (int) [ 1, max ],
12                                   framerate = (fraction) [ 0, max ]""";
13
14     public signal void have_thumbnail(Gdk.Pixbuf b);
15     
16     class construct {
17         Gst.StaticPadTemplate pad;        
18         pad.name_template = "sink";
19         pad.direction = Gst.PadDirection.SINK;
20         pad.presence = Gst.PadPresence.ALWAYS;
21         pad.static_caps.str = caps_string;
22         
23         add_pad_template(pad.get());        
24     }
25     
26     // This empty construct block eliminates a build warning about chaining up to a private
27     // constructor.
28     construct {
29     }
30     
31     public ThumbnailSink() {
32         set_sync(false);
33     }
34     
35     public override bool set_caps(Gst.Caps c) {
36         if (c.get_size() < 1)
37             return false;
38             
39         Gst.Structure s = c.get_structure(0);
40         
41         if (!s.get_int("width", out width) ||
42             !s.get_int("height", out height))
43             return false;
44         return true;
45     }
46     
47     void convert_pixbuf_to_rgb(Gdk.Pixbuf buf) {
48         uchar* data = buf.get_pixels();
49         int limit = buf.get_width() * buf.get_height();
50         
51         while (limit-- != 0) {
52             uchar temp = data[0];
53             data[0] = data[2];
54             data[2] = temp;
55             
56             data += 4;
57         }
58     }
59     
60     public override Gst.FlowReturn preroll(Gst.Buffer b) {
61         Gdk.Pixbuf buf = new Gdk.Pixbuf.from_data(b.data, Gdk.Colorspace.RGB, 
62                                                     true, 8, width, height, width * 4, null);
63         convert_pixbuf_to_rgb(buf);
64         
65         have_thumbnail(buf);
66         return Gst.FlowReturn.OK;
67     }
68 }