Back to development
[platform/upstream/gstreamer.git] / subprojects / gst-python / old_examples / pipeline-tester
1 #!/usr/bin/env python
2 #
3 # gst-python
4 # Copyright (C) 2005 Andy Wingo <wingo@pobox.com>
5 #
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Library General Public
8 # License as published by the Free Software Foundation; either
9 # version 2 of the License, or (at your option) any later version.
10 #
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # Library General Public License for more details.
15 #
16 # You should have received a copy of the GNU Library General Public
17 # License along with this library; if not, write to the
18 # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 # Boston, MA 02110-1301, USA.
20
21
22 # A test more of gst-plugins than of gst-python.
23
24
25 import sys
26
27 import pygtk
28 pygtk.require('2.0')
29 import gtk
30 import gtk.gdk
31 import pango
32 import gobject
33
34 import pygst
35 pygst.require('0.10')
36 import gst
37
38 import debugslider
39
40
41 data = (('Video capture via V4L',
42          'v4lsrc name=source \n'
43          '    ! videorate \n'
44          '    ! ffmpegcolorspace ! autovideosink'),
45         ('Video capture via V4L, fixed frame rate',
46          'v4lsrc name=source autoprobe=false autoprobe-fps=false \n'
47          '    ! video/x-raw-yuv,format=(fourcc)I420,framerate=(double)7.5 \n'
48          '    ! videorate \n'
49          '    ! ffmpegcolorspace \n'
50          '    ! autovideosink'),
51         ('Sound capture',
52          'gconfaudiosrc\n'
53          '    ! audio/x-raw-int,rate=22050,depth=16,channels=1,width=16,signed=(boolean)TRUE,endianness=(int)BYTE_ORDER\n'
54          '    ! level message=true\n'
55          '    ! fakesink'),
56         ('Streaming Ogg/Theora+Vorbis playback, tee to disk',
57          'gnomevfssrc location=http://gstreamer.freedesktop.org/media/small/cooldance.ogg \n'
58          '    ! tee name=tee \n'
59          '    tee. ! oggdemux name=demux \n'
60          '    demux. ! queue ! theoradec ! ffmpegcolorspace ! autovideosink \n'
61          '    demux. ! queue ! vorbisdec ! audioconvert ! autoaudiosink \n'
62          '    tee. ! queue ! filesink location=/tmp/cooldance.ogg'),
63         ('Video test, YUV format',
64          'videotestsrc \n'
65          '    ! video/x-raw-yuv,format=(fourcc)I420 \n'
66          '    ! ffmpegcolorspace ! autovideosink'),
67         ('Video test, RGB format',
68          'videotestsrc \n'
69          '    ! video/x-raw-rgb,red_mask=0xff00 \n'
70          '    ! ffmpegcolorspace \n'
71          '    ! autovideosink'),
72         ('Software scaling',
73          'videotestsrc \n'
74          '    ! video/x-raw-rgb,height=200,width=320 \n'
75          '    ! videoscale method=2 \n'
76          '    ! ffmpegcolorspace ! autovideosink'),
77         ('Reencode Vorbis to mulaw, play',
78          'filesrc location=/tmp/cooldance.ogg \n'
79          '    ! oggdemux \n'
80          '    ! vorbisdec ! audioconvert \n'
81          '    ! mulawenc ! mulawdec ! autoaudiosink'),
82         ('Capture DV via firewire, transcode into Ogg',
83          'dv1394src \n'
84          '    ! dvdemux name=demux \n'
85          '    ! queue \n'
86          '    ! video/x-dv,systemstream=(boolean)false \n'
87          '    ! dvdec drop-factor=2 \n'
88          '    ! videorate \n'
89          '    ! videoscale \n'
90          '    ! video/x-raw-yuv,width=360,height=288 \n'
91          '    ! videoscale \n'
92          '    ! video/x-raw-yuv,width=240,height=192,framerate=10.0,format=(fourcc)YUY2 \n'
93          '    ! ffmpegcolorspace \n'
94          '    ! theoraenc \n'
95          '    ! oggmux name=mux \n'
96          '    ! filesink location=/tmp/dv.ogg \n'
97          ' \n'
98          '    demux. \n'
99          '    ! audio/x-raw-int \n'
100          '    ! queue \n'
101          '    ! audioconvert \n'
102          '    ! vorbisenc \n'
103          '    ! mux.'))
104
105
106 def escape(s, chars, escaper='\\'):
107     for c in chars:
108         s = s.replace(c, '%s%s' % (escaper, c))
109     return s
110
111
112 def make_model():
113     m = gtk.ListStore(str, str)
114     for pair in data:
115         i = m.append()
116         m.set_value(i, 0, pair[0])
117         m.set_value(i, 1, pair[1])
118     return m
119
120
121 class Window(gtk.Window):
122     def __init__(self):
123         gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
124         self.playing = False
125         self.selected_pipe = None
126         self.pipeline = None
127         self.prepare_ui()
128
129     def prepare_ui(self):
130         self.set_default_size(300,400)
131         self.set_title('GStreamer Pipeline Tester')
132         self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
133         self.connect('delete-event', lambda *x: gtk.main_quit())
134         self.set_border_width(18)
135         b = gtk.VBox(False, 12)
136         b.show()
137         self.add(b)
138         l = gtk.Label()
139         l.set_markup('<big><b>GStreamer Pipeline Tester</b></big>')
140         l.show()
141         b.pack_start(l, False, False, 6)
142         l = gtk.Label('Choose a pipeline below to run.')
143         l.show()
144         b.pack_start(l, False, False, 0)
145         sw = gtk.ScrolledWindow()
146         sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
147         sw.set_shadow_type(gtk.SHADOW_IN)
148         sw.show()
149         b.pack_start(sw, True, True, 6)
150         tv = gtk.TreeView(make_model())
151         tv.set_property('can-default', False)
152         r = gtk.CellRendererText()
153         r.set_property('xalign', 0.5)
154         c = gtk.TreeViewColumn('System', r, text=0)
155         tv.append_column(c)
156         tv.set_headers_visible(False)
157         tv.show()
158         sw.add(tv)
159         ds = debugslider.DebugSlider()
160         ds.show()
161         b.pack_start(ds, False, False, 0)
162         l = gtk.Label()
163         l.set_selectable(True)
164         l.show()
165         b.pack_start(l, False, False, 0)
166         bb = gtk.HButtonBox()
167         bb.set_layout(gtk.BUTTONBOX_SPREAD)
168         bb.show()
169         b.pack_start(bb, False, False, 0)
170         bu = gtk.Button(stock=gtk.STOCK_MEDIA_PLAY)
171         bu.set_property('can-default', True)
172         bu.set_focus_on_click(False)
173         bu.show()
174         bb.pack_start(bu, True, False, 0)
175         bu.set_property('has-default', True)
176         self.button = bu
177
178         def on_changed(s):
179             m, i = s.get_selected()
180             if m:
181                 self.selected_pipe = m.get_value(i, 1)
182                 pasteable = escape(self.selected_pipe, '\n)(')
183                 l.set_markup('<small><tt>%s</tt></small>' % pasteable)
184             else:
185                 self.selected_pipe = None
186                 l.set_markup('')
187         tv.get_selection().connect('changed', on_changed)
188
189         tv.connect('row-activated', lambda *x: self.play_toggled())
190
191         bu.connect('clicked', lambda *x: self.play_toggled())
192
193     def error(self, message, secondary=None):
194         m = gtk.MessageDialog(self,
195                               gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
196                               gtk.MESSAGE_ERROR,
197                               gtk.BUTTONS_OK,
198                               message)
199         if secondary:
200             m.format_secondary_text(secondary)
201         m.run()
202         m.destroy()
203         self.stop()
204
205     def on_message(self, bus, message):
206         t = message.type
207         print message
208         if t == gst.MESSAGE_STATE_CHANGED:
209             pass
210         elif t == gst.MESSAGE_ERROR:
211             err, debug = message.parse_error()
212             self.error("%s" % err, debug)
213         elif t == gst.MESSAGE_EOS:
214             self.play_toggled()
215         else:
216             print '%s: %s:' % (message.src.get_path_string(),
217                                message.type.value_nicks[1])
218             if message.structure:
219                 print '    %s' % message.structure.to_string()
220             else:
221                 print '    (no structure)'
222         return True
223
224     def play(self):
225         pipestr = self.selected_pipe
226         try:
227             self.set_sensitive(False)
228             pipeline = gst.parse_launch(pipestr)
229             self.set_sensitive(True)
230         except gobject.GError, e:
231             self.set_sensitive(True)
232             self.error('Could not create pipeline', str(e))
233             return False
234         
235         bus = pipeline.get_bus()
236         bus.add_signal_watch()
237         watch_id = bus.connect('message', self.on_message)
238         self.pipeline = pipeline
239         self.watch_id = watch_id
240         pipeline.set_state(gst.STATE_PLAYING)
241
242     def stop(self):
243         bus = self.pipeline.get_bus()
244         bus.disconnect(self.watch_id)
245         bus.remove_signal_watch()
246         self.pipeline.set_state(gst.STATE_NULL)
247         self.pipeline = None
248         del self.watch_id
249
250     def play_toggled(self):
251         if self.playing:
252             self.stop()
253             self.button.set_label(gtk.STOCK_MEDIA_PLAY)
254             self.playing = False
255         else:
256             self.play()
257             self.playing = True
258             self.button.set_label(gtk.STOCK_MEDIA_STOP)
259
260 if __name__ == '__main__':
261     w = Window()
262     w.show()
263     gtk.main()