├── .gitlab-ci.yml ├── AUTHORS ├── COPYING ├── ChangeLog ├── NEWS ├── README ├── RELEASE ├── TODO ├── examples ├── README.md ├── dynamic_src.py ├── helloworld.py ├── plugins │ └── python │ │ ├── audioplot.py │ │ ├── exampleTransform.py │ │ ├── identity.py │ │ ├── mixer.py │ │ ├── py_audiotestsrc.py │ │ └── sinkelement.py ├── record_sound.py └── requirements.txt ├── gi ├── meson.build └── overrides │ ├── Gst.py │ ├── GstPbutils.py │ ├── gstmodule.c │ └── meson.build ├── gst-python.doap ├── hooks └── pre-commit.hook ├── meson.build ├── meson_options.txt ├── old_examples ├── audio-controller.py ├── audioconcat.py ├── bps.py ├── buffer-draw.py ├── cp.py ├── cutter.py ├── debugslider.py ├── decodebin.py ├── f2f.py ├── filesrc.py ├── fvumeter.py ├── gst-discover ├── gstfile.py ├── helloworld.py ├── maemogst.py ├── mixer.py ├── option-parser.py ├── pipeline-tester ├── play.py ├── pyidentity.py ├── remuxer.py ├── segments.py ├── sinkelement-registry.py ├── sinkelement.py ├── switch.py ├── synchronizer.py ├── tagsetter.py ├── video-controller.py └── vumeter.py ├── plugin ├── gstpythonplugin.c └── meson.build └── testsuite ├── __init__.py ├── common.py ├── gstpython.supp ├── meson.build ├── old ├── test-object.c ├── test-object.h ├── test_adapter.py ├── test_audio.py ├── test_bin.py ├── test_buffer.py ├── test_bus.py ├── test_caps.py ├── test_element.py ├── test_event.py ├── test_ghostpad.py ├── test_interface.py ├── test_iterator.py ├── test_libtag.py ├── test_message.py ├── test_pad.py ├── test_pbutils.py ├── test_pipeline.py ├── test_registry.py ├── test_segment.py ├── test_struct.py ├── test_taglist.py ├── test_typefind.py ├── test_xml.py └── testhelpermodule.c ├── overrides_hack.py ├── python.supp ├── python └── identity.py ├── runtests.py ├── test_gst.py ├── test_plugin.py └── test_types.py /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | include: "https://gitlab.freedesktop.org/gstreamer/gst-ci/raw/master/gitlab/ci_template.yml" 2 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | This file will be autogenerated. Please read README-docs. 2 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This file will be autogenerated. Please read README-docs. 2 | -------------------------------------------------------------------------------- /RELEASE: -------------------------------------------------------------------------------- 1 | This is GStreamer gst-python 1.19.2. 2 | 3 | GStreamer 1.19 is the development branch leading up to the next major 4 | stable version which will be 1.20. 5 | 6 | The 1.19 development series adds new features on top of the 1.18 series and is 7 | part of the API and ABI-stable 1.x release series of the GStreamer multimedia 8 | framework. 9 | 10 | Full release notes will one day be found at: 11 | 12 | https://gstreamer.freedesktop.org/releases/1.20/ 13 | 14 | Binaries for Android, iOS, Mac OS X and Windows will usually be provided 15 | shortly after the release. 16 | 17 | This module will not be very useful by itself and should be used in conjunction 18 | with other GStreamer modules for a complete multimedia experience. 19 | 20 | - gstreamer: provides the core GStreamer libraries and some generic plugins 21 | 22 | - gst-plugins-base: a basic set of well-supported plugins and additional 23 | media-specific GStreamer helper libraries for audio, 24 | video, rtsp, rtp, tags, OpenGL, etc. 25 | 26 | - gst-plugins-good: a set of well-supported plugins under our preferred 27 | license 28 | 29 | - gst-plugins-ugly: a set of well-supported plugins which might pose 30 | problems for distributors 31 | 32 | - gst-plugins-bad: a set of plugins of varying quality that have not made 33 | their way into one of core/base/good/ugly yet, for one 34 | reason or another. Many of these are are production quality 35 | elements, but may still be missing documentation or unit 36 | tests; others haven't passed the rigorous quality testing 37 | we expect yet. 38 | 39 | - gst-libav: a set of codecs plugins based on the ffmpeg library. This is 40 | where you can find audio and video decoders and encoders 41 | for a wide variety of formats including H.264, AAC, etc. 42 | 43 | - gstreamer-vaapi: hardware-accelerated video decoding and encoding using 44 | VA-API on Linux. Primarily for Intel graphics hardware. 45 | 46 | - gst-omx: hardware-accelerated video decoding and encoding, primarily for 47 | embedded Linux systems that provide an OpenMax 48 | implementation layer such as the Raspberry Pi. 49 | 50 | - gst-rtsp-server: library to serve files or streaming pipelines via RTSP 51 | 52 | - gst-editing-services: library an plugins for non-linear editing 53 | 54 | ==== Download ==== 55 | 56 | You can find source releases of gstreamer in the download 57 | directory: https://gstreamer.freedesktop.org/src/gstreamer/ 58 | 59 | The git repository and details how to clone it can be found at 60 | https://gitlab.freedesktop.org/gstreamer/ 61 | 62 | ==== Homepage ==== 63 | 64 | The project's website is https://gstreamer.freedesktop.org/ 65 | 66 | ==== Support and Bugs ==== 67 | 68 | We have recently moved from GNOME Bugzilla to GitLab on freedesktop.org 69 | for bug reports and feature requests: 70 | 71 | https://gitlab.freedesktop.org/gstreamer 72 | 73 | Please submit patches via GitLab as well, in form of Merge Requests. See 74 | 75 | https://gstreamer.freedesktop.org/documentation/contribute/ 76 | 77 | for more details. 78 | 79 | For help and support, please subscribe to and send questions to the 80 | gstreamer-devel mailing list (see below for details). 81 | 82 | There is also a #gstreamer IRC channel on the Freenode IRC network. 83 | 84 | ==== Developers ==== 85 | 86 | GStreamer source code repositories can be found on GitLab on freedesktop.org: 87 | 88 | https://gitlab.freedesktop.org/gstreamer 89 | 90 | and can also be cloned from there and this is also where you can submit 91 | Merge Requests or file issues for bugs or feature requests. 92 | 93 | Interested developers of the core library, plugins, and applications should 94 | subscribe to the gstreamer-devel list: 95 | 96 | https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel 97 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Port old examples to GStreamer 1.0 2 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | 3 | Some of the examples require external python dependencies, for this purpose 4 | an illustrative requirements.txt is provided, with annotations documenting 5 | which example requires a dependency. 6 | 7 | You can install all the dependencies with: 8 | 9 | ``` 10 | python3 -m pip install -r requirements.txt --user 11 | ``` 12 | -------------------------------------------------------------------------------- /examples/dynamic_src.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | Simple example to demonstrate dynamically adding and removing source elements 5 | to a playing pipeline. 6 | ''' 7 | 8 | import sys 9 | import random 10 | 11 | import gi 12 | gi.require_version('Gst', '1.0') 13 | gi.require_version('GLib', '2.0') 14 | gi.require_version('GObject', '2.0') 15 | from gi.repository import GLib, GObject, Gst 16 | 17 | class ProbeData: 18 | def __init__(self, pipe, src): 19 | self.pipe = pipe 20 | self.src = src 21 | 22 | def bus_call(bus, message, loop): 23 | t = message.type 24 | if t == Gst.MessageType.EOS: 25 | sys.stdout.write("End-of-stream\n") 26 | loop.quit() 27 | elif t == Gst.MessageType.ERROR: 28 | err, debug = message.parse_error() 29 | sys.stderr.write("Error: %s: %s\n" % (err, debug)) 30 | loop.quit() 31 | return True 32 | 33 | def dispose_src_cb(src): 34 | src.set_state(Gst.State.NULL) 35 | 36 | def probe_cb(pad, info, pdata): 37 | peer = pad.get_peer() 38 | pad.unlink(peer) 39 | pdata.pipe.remove(pdata.src) 40 | # Can't set the state of the src to NULL from its streaming thread 41 | GLib.idle_add(dispose_src_cb, pdata.src) 42 | 43 | pdata.src = Gst.ElementFactory.make('videotestsrc') 44 | pdata.src.props.pattern = random.randint(0, 24) 45 | pdata.pipe.add(pdata.src) 46 | srcpad = pdata.src.get_static_pad ("src") 47 | srcpad.link(peer) 48 | pdata.src.sync_state_with_parent() 49 | 50 | GLib.timeout_add_seconds(1, timeout_cb, pdata) 51 | 52 | return Gst.PadProbeReturn.REMOVE 53 | 54 | def timeout_cb(pdata): 55 | srcpad = pdata.src.get_static_pad('src') 56 | srcpad.add_probe(Gst.PadProbeType.IDLE, probe_cb, pdata) 57 | return GLib.SOURCE_REMOVE 58 | 59 | def main(args): 60 | GObject.threads_init() 61 | Gst.init(None) 62 | 63 | pipe = Gst.Pipeline.new('dynamic') 64 | src = Gst.ElementFactory.make('videotestsrc') 65 | sink = Gst.ElementFactory.make('autovideosink') 66 | pipe.add(src, sink) 67 | src.link(sink) 68 | 69 | pdata = ProbeData(pipe, src) 70 | 71 | loop = GObject.MainLoop() 72 | 73 | GLib.timeout_add_seconds(1, timeout_cb, pdata) 74 | 75 | bus = pipe.get_bus() 76 | bus.add_signal_watch() 77 | bus.connect ("message", bus_call, loop) 78 | 79 | # start play back and listen to events 80 | pipe.set_state(Gst.State.PLAYING) 81 | try: 82 | loop.run() 83 | except: 84 | pass 85 | 86 | # cleanup 87 | pipe.set_state(Gst.State.NULL) 88 | 89 | if __name__ == '__main__': 90 | sys.exit(main(sys.argv)) 91 | -------------------------------------------------------------------------------- /examples/helloworld.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | import gi 6 | gi.require_version('Gst', '1.0') 7 | from gi.repository import GObject, Gst 8 | 9 | def bus_call(bus, message, loop): 10 | t = message.type 11 | if t == Gst.MessageType.EOS: 12 | sys.stdout.write("End-of-stream\n") 13 | loop.quit() 14 | elif t == Gst.MessageType.ERROR: 15 | err, debug = message.parse_error() 16 | sys.stderr.write("Error: %s: %s\n" % (err, debug)) 17 | loop.quit() 18 | return True 19 | 20 | def main(args): 21 | if len(args) != 2: 22 | sys.stderr.write("usage: %s \n" % args[0]) 23 | sys.exit(1) 24 | 25 | GObject.threads_init() 26 | Gst.init(None) 27 | 28 | playbin = Gst.ElementFactory.make("playbin", None) 29 | if not playbin: 30 | sys.stderr.write("'playbin' gstreamer plugin missing\n") 31 | sys.exit(1) 32 | 33 | # take the commandline argument and ensure that it is a uri 34 | if Gst.uri_is_valid(args[1]): 35 | uri = args[1] 36 | else: 37 | uri = Gst.filename_to_uri(args[1]) 38 | playbin.set_property('uri', uri) 39 | 40 | # create and event loop and feed gstreamer bus mesages to it 41 | loop = GObject.MainLoop() 42 | 43 | bus = playbin.get_bus() 44 | bus.add_signal_watch() 45 | bus.connect ("message", bus_call, loop) 46 | 47 | # start play back and listed to events 48 | playbin.set_state(Gst.State.PLAYING) 49 | try: 50 | loop.run() 51 | except: 52 | pass 53 | 54 | # cleanup 55 | playbin.set_state(Gst.State.NULL) 56 | 57 | if __name__ == '__main__': 58 | sys.exit(main(sys.argv)) 59 | -------------------------------------------------------------------------------- /examples/plugins/python/exampleTransform.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # exampleTransform.py 3 | # 2019 Daniel Klamt 4 | 5 | # Inverts a grayscale image in place, requires numpy. 6 | # 7 | # gst-launch-1.0 videotestsrc ! ExampleTransform ! videoconvert ! xvimagesink 8 | 9 | import gi 10 | gi.require_version('Gst', '1.0') 11 | gi.require_version('GstBase', '1.0') 12 | gi.require_version('GstVideo', '1.0') 13 | 14 | from gi.repository import Gst, GObject, GstBase, GstVideo 15 | 16 | import numpy as np 17 | 18 | Gst.init(None) 19 | FIXED_CAPS = Gst.Caps.from_string('video/x-raw,format=GRAY8,width=[1,2147483647],height=[1,2147483647]') 20 | 21 | class ExampleTransform(GstBase.BaseTransform): 22 | __gstmetadata__ = ('ExampleTransform Python','Transform', 23 | 'example gst-python element that can modify the buffer gst-launch-1.0 videotestsrc ! ExampleTransform ! videoconvert ! xvimagesink', 'dkl') 24 | 25 | __gsttemplates__ = (Gst.PadTemplate.new("src", 26 | Gst.PadDirection.SRC, 27 | Gst.PadPresence.ALWAYS, 28 | FIXED_CAPS), 29 | Gst.PadTemplate.new("sink", 30 | Gst.PadDirection.SINK, 31 | Gst.PadPresence.ALWAYS, 32 | FIXED_CAPS)) 33 | 34 | def do_set_caps(self, incaps, outcaps): 35 | struct = incaps.get_structure(0) 36 | self.width = struct.get_int("width").value 37 | self.height = struct.get_int("height").value 38 | return True 39 | 40 | def do_transform_ip(self, buf): 41 | try: 42 | with buf.map(Gst.MapFlags.READ | Gst.MapFlags.WRITE) as info: 43 | # Create a NumPy ndarray from the memoryview and modify it in place: 44 | A = np.ndarray(shape = (self.height, self.width), dtype = np.uint8, buffer = info.data) 45 | A[:] = np.invert(A) 46 | 47 | return Gst.FlowReturn.OK 48 | except Gst.MapError as e: 49 | Gst.error("Mapping error: %s" % e) 50 | return Gst.FlowReturn.ERROR 51 | 52 | GObject.type_register(ExampleTransform) 53 | __gstelementfactory__ = ("ExampleTransform", Gst.Rank.NONE, ExampleTransform) 54 | -------------------------------------------------------------------------------- /examples/plugins/python/identity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # identity.py 6 | # 2016 Marianna S. Buschle 7 | # 8 | # Simple identity element in python 9 | # 10 | # You can run the example from the source doing from gst-python/: 11 | # 12 | # $ export GST_PLUGIN_PATH=$GST_PLUGIN_PATH:$PWD/plugin:$PWD/examples/plugins 13 | # $ GST_DEBUG=python:4 gst-launch-1.0 fakesrc num-buffers=10 ! identity_py ! fakesink 14 | 15 | import gi 16 | gi.require_version('GstBase', '1.0') 17 | 18 | from gi.repository import Gst, GObject, GstBase 19 | Gst.init(None) 20 | 21 | # 22 | # Simple Identity element created entirely in python 23 | # 24 | class Identity(GstBase.BaseTransform): 25 | __gstmetadata__ = ('Identity Python','Transform', \ 26 | 'Simple identity element written in python', 'Marianna S. Buschle') 27 | 28 | __gsttemplates__ = (Gst.PadTemplate.new("src", 29 | Gst.PadDirection.SRC, 30 | Gst.PadPresence.ALWAYS, 31 | Gst.Caps.new_any()), 32 | Gst.PadTemplate.new("sink", 33 | Gst.PadDirection.SINK, 34 | Gst.PadPresence.ALWAYS, 35 | Gst.Caps.new_any())) 36 | 37 | def do_transform_ip(self, buffer): 38 | Gst.info("timestamp(buffer):%s" % (Gst.TIME_ARGS(buffer.pts))) 39 | return Gst.FlowReturn.OK 40 | 41 | GObject.type_register(Identity) 42 | __gstelementfactory__ = ("identity_py", Gst.Rank.NONE, Identity) 43 | -------------------------------------------------------------------------------- /examples/plugins/python/mixer.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Simple mixer element, accepts 320 x 240 RGBA at 30 fps 3 | on any number of sinkpads. 4 | 5 | Requires PIL (Python Imaging Library) 6 | 7 | Example pipeline: 8 | 9 | gst-launch-1.0 py_videomixer name=mixer ! videoconvert ! autovideosink \ 10 | videotestsrc ! mixer. \ 11 | videotestsrc pattern=ball ! mixer. \ 12 | videotestsrc pattern=snow ! mixer. 13 | ''' 14 | 15 | import gi 16 | 17 | gi.require_version('Gst', '1.0') 18 | gi.require_version('GstBase', '1.0') 19 | gi.require_version('GObject', '2.0') 20 | 21 | from gi.repository import Gst, GObject, GstBase 22 | 23 | Gst.init(None) 24 | 25 | try: 26 | from PIL import Image 27 | except ImportError: 28 | Gst.error('py_videomixer requires PIL') 29 | raise 30 | 31 | # Completely fixed input / output 32 | ICAPS = Gst.Caps(Gst.Structure('video/x-raw', 33 | format='RGBA', 34 | width=320, 35 | height=240, 36 | framerate=Gst.Fraction(30, 1))) 37 | 38 | OCAPS = Gst.Caps(Gst.Structure('video/x-raw', 39 | format='RGBA', 40 | width=320, 41 | height=240, 42 | framerate=Gst.Fraction(30, 1))) 43 | 44 | class BlendData: 45 | def __init__(self, outimg): 46 | self.outimg = outimg 47 | self.pts = 0 48 | self.eos = True 49 | 50 | class Videomixer(GstBase.Aggregator): 51 | __gstmetadata__ = ('Videomixer','Video/Mixer', \ 52 | 'Python video mixer', 'Mathieu Duponchelle') 53 | 54 | __gsttemplates__ = ( 55 | Gst.PadTemplate.new_with_gtype("sink_%u", 56 | Gst.PadDirection.SINK, 57 | Gst.PadPresence.REQUEST, 58 | ICAPS, 59 | GstBase.AggregatorPad.__gtype__), 60 | Gst.PadTemplate.new_with_gtype("src", 61 | Gst.PadDirection.SRC, 62 | Gst.PadPresence.ALWAYS, 63 | OCAPS, 64 | GstBase.AggregatorPad.__gtype__) 65 | ) 66 | 67 | def mix_buffers(self, agg, pad, bdata): 68 | buf = pad.pop_buffer() 69 | _, info = buf.map(Gst.MapFlags.READ) 70 | 71 | img = Image.frombuffer('RGBA', (320, 240), info.data, "raw", 'RGBA', 0, 1) 72 | 73 | bdata.outimg = Image.blend(bdata.outimg, img, alpha=0.5) 74 | bdata.pts = buf.pts 75 | 76 | buf.unmap(info) 77 | 78 | bdata.eos = False 79 | 80 | return True 81 | 82 | def do_aggregate(self, timeout): 83 | outimg = Image.new('RGBA', (320, 240), 0x00000000) 84 | 85 | bdata = BlendData(outimg) 86 | 87 | self.foreach_sink_pad(self.mix_buffers, bdata) 88 | 89 | data = bdata.outimg.tobytes() 90 | 91 | outbuf = Gst.Buffer.new_allocate(None, len(data), None) 92 | outbuf.fill(0, data) 93 | outbuf.pts = bdata.pts 94 | self.finish_buffer (outbuf) 95 | 96 | # We are EOS when no pad was ready to be aggregated, 97 | # this would obviously not work for live 98 | if bdata.eos: 99 | return Gst.FlowReturn.EOS 100 | 101 | return Gst.FlowReturn.OK 102 | 103 | GObject.type_register(Videomixer) 104 | __gstelementfactory__ = ("py_videomixer", Gst.Rank.NONE, Videomixer) 105 | -------------------------------------------------------------------------------- /examples/plugins/python/py_audiotestsrc.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Element that generates a sine audio wave with the specified frequency 3 | 4 | Requires numpy 5 | 6 | Example pipeline: 7 | 8 | gst-launch-1.0 py_audiotestsrc ! autoaudiosink 9 | ''' 10 | 11 | import gi 12 | 13 | gi.require_version('Gst', '1.0') 14 | gi.require_version('GstBase', '1.0') 15 | gi.require_version('GstAudio', '1.0') 16 | 17 | from gi.repository import Gst, GLib, GObject, GstBase, GstAudio 18 | 19 | try: 20 | import numpy as np 21 | except ImportError: 22 | Gst.error('py_audiotestsrc requires numpy') 23 | raise 24 | 25 | OCAPS = Gst.Caps.from_string ( 26 | 'audio/x-raw, format=F32LE, layout=interleaved, rate=44100, channels=2') 27 | 28 | SAMPLESPERBUFFER = 1024 29 | 30 | DEFAULT_FREQ = 440 31 | DEFAULT_VOLUME = 0.8 32 | DEFAULT_MUTE = False 33 | DEFAULT_IS_LIVE = False 34 | 35 | class AudioTestSrc(GstBase.BaseSrc): 36 | __gstmetadata__ = ('CustomSrc','Src', \ 37 | 'Custom test src element', 'Mathieu Duponchelle') 38 | 39 | __gproperties__ = { 40 | "freq": (int, 41 | "Frequency", 42 | "Frequency of test signal", 43 | 1, 44 | GLib.MAXINT, 45 | DEFAULT_FREQ, 46 | GObject.ParamFlags.READWRITE 47 | ), 48 | "volume": (float, 49 | "Volume", 50 | "Volume of test signal", 51 | 0.0, 52 | 1.0, 53 | DEFAULT_VOLUME, 54 | GObject.ParamFlags.READWRITE 55 | ), 56 | "mute": (bool, 57 | "Mute", 58 | "Mute the test signal", 59 | DEFAULT_MUTE, 60 | GObject.ParamFlags.READWRITE 61 | ), 62 | "is-live": (bool, 63 | "Is live", 64 | "Whether to act as a live source", 65 | DEFAULT_IS_LIVE, 66 | GObject.ParamFlags.READWRITE 67 | ), 68 | } 69 | 70 | __gsttemplates__ = Gst.PadTemplate.new("src", 71 | Gst.PadDirection.SRC, 72 | Gst.PadPresence.ALWAYS, 73 | OCAPS) 74 | 75 | def __init__(self): 76 | GstBase.BaseSrc.__init__(self) 77 | self.info = GstAudio.AudioInfo() 78 | 79 | self.freq = DEFAULT_FREQ 80 | self.volume = DEFAULT_VOLUME 81 | self.mute = DEFAULT_MUTE 82 | 83 | self.set_live(DEFAULT_IS_LIVE) 84 | self.set_format(Gst.Format.TIME) 85 | 86 | def do_set_caps(self, caps): 87 | self.info.from_caps(caps) 88 | self.set_blocksize(self.info.bpf * SAMPLESPERBUFFER) 89 | return True 90 | 91 | def do_get_property(self, prop): 92 | if prop.name == 'freq': 93 | return self.freq 94 | elif prop.name == 'volume': 95 | return self.volume 96 | elif prop.name == 'mute': 97 | return self.mute 98 | elif prop.name == 'is-live': 99 | return self.is_live 100 | else: 101 | raise AttributeError('unknown property %s' % prop.name) 102 | 103 | def do_set_property(self, prop, value): 104 | if prop.name == 'freq': 105 | self.freq = value 106 | elif prop.name == 'volume': 107 | self.volume = value 108 | elif prop.name == 'mute': 109 | self.mute = value 110 | elif prop.name == 'is-live': 111 | self.set_live(value) 112 | else: 113 | raise AttributeError('unknown property %s' % prop.name) 114 | 115 | def do_start (self): 116 | self.next_sample = 0 117 | self.next_byte = 0 118 | self.next_time = 0 119 | self.accumulator = 0 120 | self.generate_samples_per_buffer = SAMPLESPERBUFFER 121 | 122 | return True 123 | 124 | def do_gst_base_src_query(self, query): 125 | if query.type == Gst.QueryType.LATENCY: 126 | latency = Gst.util_uint64_scale_int(self.generate_samples_per_buffer, 127 | Gst.SECOND, self.info.rate) 128 | is_live = self.is_live 129 | query.set_latency(is_live, latency, Gst.CLOCK_TIME_NONE) 130 | res = True 131 | else: 132 | res = GstBase.BaseSrc.do_query(self, query) 133 | return res 134 | 135 | def do_get_times(self, buf): 136 | end = 0 137 | start = 0 138 | if self.is_live: 139 | ts = buf.pts 140 | if ts != Gst.CLOCK_TIME_NONE: 141 | duration = buf.duration 142 | if duration != Gst.CLOCK_TIME_NONE: 143 | end = ts + duration 144 | start = ts 145 | else: 146 | start = Gst.CLOCK_TIME_NONE 147 | end = Gst.CLOCK_TIME_NONE 148 | 149 | return start, end 150 | 151 | def do_fill(self, offset, length, buf): 152 | if length == -1: 153 | samples = SAMPLESPERBUFFER 154 | else: 155 | samples = int(length / self.info.bpf) 156 | 157 | self.generate_samples_per_buffer = samples 158 | 159 | bytes_ = samples * self.info.bpf 160 | 161 | next_sample = self.next_sample + samples 162 | next_byte = self.next_byte + bytes_ 163 | next_time = Gst.util_uint64_scale_int(next_sample, Gst.SECOND, self.info.rate) 164 | 165 | try: 166 | with buf.map(Gst.MapFlags.WRITE) as info: 167 | array = np.ndarray(shape = self.info.channels * samples, dtype = np.float32, buffer = info.data) 168 | if not self.mute: 169 | r = np.repeat(np.arange(self.accumulator, self.accumulator + samples), 170 | self.info.channels) 171 | np.sin(2 * np.pi * r * self.freq / self.info.rate, out=array) 172 | array *= self.volume 173 | else: 174 | array[:] = 0 175 | except Exception as e: 176 | Gst.error("Mapping error: %s" % e) 177 | return Gst.FlowReturn.ERROR 178 | 179 | buf.offset = self.next_sample 180 | buf.offset_end = next_sample 181 | buf.pts = self.next_time 182 | buf.duration = next_time - self.next_time 183 | 184 | self.next_time = next_time 185 | self.next_sample = next_sample 186 | self.next_byte = next_byte 187 | self.accumulator += samples 188 | self.accumulator %= self.info.rate / self.freq 189 | 190 | return (Gst.FlowReturn.OK, buf) 191 | 192 | 193 | __gstelementfactory__ = ("py_audiotestsrc", Gst.Rank.NONE, AudioTestSrc) 194 | -------------------------------------------------------------------------------- /examples/plugins/python/sinkelement.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # sinkelement.py 6 | # (c) 2005 Edward Hervey 7 | # (c) 2007 Jan Schmidt 8 | # Licensed under LGPL 9 | # 10 | # Small test application to show how to write a sink element 11 | # in 20 lines in python and place into the gstreamer registry 12 | # so it can be autoplugged or used from parse_launch. 13 | # 14 | # You can run the example from the source doing from gst-python/: 15 | # 16 | # $ export GST_PLUGIN_PATH=$GST_PLUGIN_PATH:$PWD/plugin:$PWD/examples/plugins 17 | # $ GST_DEBUG=python:4 gst-launch-1.0 fakesrc num-buffers=10 ! mysink 18 | 19 | from gi.repository import Gst, GObject, GstBase 20 | Gst.init(None) 21 | 22 | # 23 | # Simple Sink element created entirely in python 24 | # 25 | class MySink(GstBase.BaseSink): 26 | __gstmetadata__ = ('CustomSink','Sink', \ 27 | 'Custom test sink element', 'Edward Hervey') 28 | 29 | __gsttemplates__ = Gst.PadTemplate.new("sink", 30 | Gst.PadDirection.SINK, 31 | Gst.PadPresence.ALWAYS, 32 | Gst.Caps.new_any()) 33 | 34 | def do_render(self, buffer): 35 | Gst.info("timestamp(buffer):%s" % (Gst.TIME_ARGS(buffer.pts))) 36 | return Gst.FlowReturn.OK 37 | 38 | GObject.type_register(MySink) 39 | __gstelementfactory__ = ("mysink", Gst.Rank.NONE, MySink) 40 | -------------------------------------------------------------------------------- /examples/record_sound.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' 4 | Simple example to demonstrate using Gst.DeviceMonitor and `transcodebin` to 5 | record audio from a microphone into an .oga file 6 | ''' 7 | import gi 8 | import sys 9 | gi.require_version('Gst', '1.0') 10 | gi.require_version('GstPbutils', '1.0') 11 | gi.require_version('GLib', '2.0') 12 | gi.require_version('GObject', '2.0') 13 | from gi.repository import GLib, GObject, Gst, GstPbutils 14 | 15 | def bus_call(bus, message, loop): 16 | t = message.type 17 | Gst.debug_bin_to_dot_file_with_ts(pipeline, Gst.DebugGraphDetails.ALL, "test") 18 | if t == Gst.MessageType.EOS: 19 | sys.stdout.write("End-of-stream\n") 20 | loop.quit() 21 | elif t == Gst.MessageType.ERROR: 22 | err, debug = message.parse_error() 23 | sys.stderr.write("Error: %s: %s\n" % (err, debug)) 24 | loop.quit() 25 | return True 26 | 27 | def stop(loop, pipeline): 28 | _, position = pipeline.query_position(Gst.Format.TIME) 29 | print("Position: %s\r" % Gst.TIME_ARGS(position)) 30 | 31 | if position > 10 * Gst.SECOND: 32 | loop.quit() 33 | print("Stopping after 10 seconds") 34 | return False 35 | 36 | return True 37 | 38 | if __name__ == "__main__": 39 | Gst.init(sys.argv) 40 | 41 | if len(sys.argv) != 2: 42 | print("Missing parametter") 43 | sys.exit(1) 44 | 45 | monitor = Gst.DeviceMonitor.new() 46 | monitor.add_filter("Audio/Source", None) 47 | monitor.start() 48 | 49 | # This is happening synchonously, use the GstBus based API and 50 | # monitor.start() to avoid blocking the main thread. 51 | devices = monitor.get_devices() 52 | 53 | if not devices: 54 | print("No microphone found...") 55 | sys.exit(1) 56 | 57 | default = [d for d in devices if d.get_properties().get_value("is-default") is True] 58 | if len(default) == 1: 59 | device = default[0] 60 | else: 61 | print("Avalaible microphones:") 62 | for i, d in enumerate(devices): 63 | print("%d - %s" % (i, d.get_display_name())) 64 | res = int(input("Select device: ")) 65 | device = devices[res] 66 | 67 | pipeline = Gst.ElementFactory.make("pipeline", None) 68 | source = device.create_element() 69 | transcodebin = Gst.ElementFactory.make("transcodebin", None) 70 | Gst.util_set_object_arg(transcodebin, "profile", "video/ogg:audio/x-opus") 71 | filesink = Gst.ElementFactory.make("filesink", None) 72 | filesink.props.location = sys.argv[1] 73 | 74 | pipeline.add(source, transcodebin, filesink) 75 | source.link(transcodebin) 76 | transcodebin.link(filesink) 77 | 78 | pipeline.set_state(Gst.State.PLAYING) 79 | 80 | bus = pipeline.get_bus() 81 | bus.add_signal_watch() 82 | 83 | loop = GLib.MainLoop() 84 | GLib.timeout_add_seconds(1, stop, loop, pipeline) 85 | bus.connect ("message", bus_call, loop) 86 | loop.run() 87 | 88 | pipeline.set_state(Gst.State.NULL) 89 | pipeline.get_state(Gst.CLOCK_TIME_NONE) -------------------------------------------------------------------------------- /examples/requirements.txt: -------------------------------------------------------------------------------- 1 | # py_videomixer plugin 2 | Pillow >= 5.1.0 3 | 4 | # audioplot plugin 5 | matplotlib >= 2.1.1 6 | numpy_ringbuffer >= 0.2.1 7 | 8 | # audioplot and py_audiotestsrc plugins 9 | numpy >= 1.14.5 10 | -------------------------------------------------------------------------------- /gi/meson.build: -------------------------------------------------------------------------------- 1 | subdir('overrides') 2 | -------------------------------------------------------------------------------- /gi/overrides/GstPbutils.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python; py-indent-offset: 4 -*- 2 | # vim: tabstop=4 shiftwidth=4 expandtab 3 | # 4 | # Gst.py 5 | # 6 | # Copyright (C) 2012 Alessandro Decina 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Lesser General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2.1 of the License, or (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Lesser General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Lesser General Public 19 | # License along with this program; if not, write to the 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | # Boston, MA 02110-1301, USA. 22 | # This program is free software; you can redistribute it and/or modify 23 | # it under the terms of the GNU General Public License as published by 24 | # the Free Software Foundation; either version 3, or (at your option) 25 | # any later version. 26 | 27 | from ..overrides import override as override_ 28 | from ..module import get_introspection_module 29 | 30 | import gi 31 | gi.require_version('Gst', '1.0') 32 | 33 | from gi.repository import Gst # noqa 34 | 35 | GstPbutils = get_introspection_module('GstPbutils') 36 | __all__ = [] 37 | 38 | 39 | def override(cls): 40 | name = cls.__name__ 41 | globals()[name] = override_(cls) 42 | __all__.append(name) 43 | 44 | return cls 45 | 46 | real_init = GstPbutils.pb_utils_init 47 | def init(): 48 | if not Gst.is_initialized(): 49 | raise RuntimeError("Gst.init() needs to be called before importing GstPbutils") 50 | 51 | real_init() 52 | 53 | @override 54 | class EncodingVideoProfile(GstPbutils.EncodingVideoProfile): 55 | def __init__(self, format, preset=None, restriction=None, presence=0): 56 | GstPbutils.EncodingVideoProfile.__init__(self) 57 | self.set_format(format) 58 | if preset is not None: 59 | self.set_preset(preset) 60 | if restriction is None: 61 | restriction = Gst.Caps('ANY') 62 | self.set_restriction(restriction) 63 | self.set_presence(presence) 64 | 65 | @override 66 | class EncodingAudioProfile(GstPbutils.EncodingAudioProfile): 67 | def __init__(self, format, preset=None, restriction=None, presence=0): 68 | GstPbutils.EncodingAudioProfile.__init__(self) 69 | self.set_format(format) 70 | if preset is not None: 71 | self.set_preset(preset) 72 | if restriction is None: 73 | restriction = Gst.Caps('ANY') 74 | self.set_restriction(restriction) 75 | self.set_presence(presence) 76 | 77 | @override 78 | class EncodingContainerProfile(GstPbutils.EncodingContainerProfile): 79 | def __init__(self, name, description, format, preset=None): 80 | GstPbutils.EncodingContainerProfile.__init__(self) 81 | self.set_format(format) 82 | if name is not None: 83 | self.set_name(name) 84 | if description is not None: 85 | self.set_description(description) 86 | if preset is not None: 87 | self.set_preset(preset) 88 | 89 | GstPbutils.pb_utils_init = init 90 | GstPbutils.init = init 91 | if Gst.is_initialized(): 92 | init() -------------------------------------------------------------------------------- /gi/overrides/meson.build: -------------------------------------------------------------------------------- 1 | pysources = ['Gst.py', 'GstPbutils.py'] 2 | install_data(pysources, 3 | install_dir: pygi_override_dir) 4 | 5 | gstpython = python.extension_module('_gi_gst', 6 | sources: ['gstmodule.c'], 7 | install: true, 8 | install_dir : pygi_override_dir, 9 | include_directories : [configinc], 10 | dependencies : [gst_dep, python_dep, pygobject_dep]) 11 | -------------------------------------------------------------------------------- /hooks/pre-commit.hook: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Check that the code follows a consistant code style 4 | # 5 | 6 | # Check for existence of indent, and error out if not present. 7 | # On some *bsd systems the binary seems to be called gnunindent, 8 | # so check for that first. 9 | 10 | version=`gnuindent --version 2>/dev/null` 11 | if test "x$version" = "x"; then 12 | version=`gindent --version 2>/dev/null` 13 | if test "x$version" = "x"; then 14 | version=`indent --version 2>/dev/null` 15 | if test "x$version" = "x"; then 16 | echo "GStreamer git pre-commit hook:" 17 | echo "Did not find GNU indent, please install it before continuing." 18 | exit 1 19 | else 20 | INDENT=indent 21 | fi 22 | else 23 | INDENT=gindent 24 | fi 25 | else 26 | INDENT=gnuindent 27 | fi 28 | 29 | case `$INDENT --version` in 30 | GNU*) 31 | ;; 32 | default) 33 | echo "GStreamer git pre-commit hook:" 34 | echo "Did not find GNU indent, please install it before continuing." 35 | echo "(Found $INDENT, but it doesn't seem to be GNU indent)" 36 | exit 1 37 | ;; 38 | esac 39 | 40 | INDENT_PARAMETERS="--braces-on-if-line \ 41 | --case-brace-indentation0 \ 42 | --case-indentation2 \ 43 | --braces-after-struct-decl-line \ 44 | --line-length80 \ 45 | --no-tabs \ 46 | --cuddle-else \ 47 | --dont-line-up-parentheses \ 48 | --continuation-indentation4 \ 49 | --honour-newlines \ 50 | --tab-size8 \ 51 | --indent-level2 \ 52 | --leave-preprocessor-space" 53 | 54 | echo "--Checking style--" 55 | for file in `git diff-index --cached --name-only HEAD --diff-filter=ACMR| grep "\.c$"` ; do 56 | # nf is the temporary checkout. This makes sure we check against the 57 | # revision in the index (and not the checked out version). 58 | nf=`git checkout-index --temp ${file} | cut -f 1` 59 | newfile=`mktemp /tmp/${nf}.XXXXXX` || exit 1 60 | $INDENT ${INDENT_PARAMETERS} \ 61 | $nf -o $newfile 2>> /dev/null 62 | # FIXME: Call indent twice as it tends to do line-breaks 63 | # different for every second call. 64 | $INDENT ${INDENT_PARAMETERS} \ 65 | $newfile 2>> /dev/null 66 | diff -u -p "${nf}" "${newfile}" 67 | r=$? 68 | rm "${newfile}" 69 | rm "${nf}" 70 | if [ $r != 0 ] ; then 71 | echo "=================================================================================================" 72 | echo " Code style error in: $file " 73 | echo " " 74 | echo " Please fix before committing. Don't forget to run git add before trying to commit again. " 75 | echo " If the whole file is to be committed, this should work (run from the top-level directory): " 76 | echo " " 77 | echo " gst-indent $file; git add $file; git commit" 78 | echo " " 79 | echo "=================================================================================================" 80 | exit 1 81 | fi 82 | done 83 | echo "--Checking style pass--" 84 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('gst-python', 'c', 'cpp', 2 | version : '1.19.2', 3 | meson_version : '>= 0.54', 4 | default_options : [ 'warning_level=1', 5 | 'c_std=gnu99', 6 | 'buildtype=debugoptimized' ]) 7 | 8 | gst_version = meson.project_version() 9 | version_arr = gst_version.split('.') 10 | gst_version_major = version_arr[0] 11 | gst_version_minor = version_arr[1] 12 | api_version = '@0@.0'.format(gst_version_major) 13 | 14 | add_project_arguments('-DHAVE_CONFIG_H', language: 'c') 15 | 16 | gst_req = '>= @0@.@1@.0'.format(gst_version_major, gst_version_minor) 17 | 18 | gst_dep = dependency('gstreamer-1.0', version : gst_req, 19 | fallback : ['gstreamer', 'gst_dep']) 20 | gstbase_dep = dependency('gstreamer-base-1.0', version : gst_req, 21 | fallback : ['gstreamer', 'gst_base_dep']) 22 | gmodule_dep = dependency('gmodule-2.0') 23 | pygobject_dep = dependency('pygobject-3.0', fallback: ['pygobject', 'pygobject_dep'], version : '>= 3.8') 24 | 25 | pymod = import('python') 26 | python = pymod.find_installation(get_option('python')) 27 | pythonver = python.language_version() 28 | if pythonver.version_compare('<3.0') 29 | error('Python2 is not supported anymore, please port your code to python3 (@0@ specified)'.format(python.language_version())) 30 | endif 31 | 32 | python_dep = python.dependency(embed:true, required : true) 33 | 34 | python_abi_flags = python.get_variable('ABIFLAGS', '') 35 | pylib_loc = get_option('libpython-dir') 36 | if pylib_loc == '' 37 | check_path_exists = 'import os, sys; assert(os.path.exists(sys.argv[1]))' 38 | pylib_loc = python.get_variable('LIBPL', '') 39 | if host_machine.system() != 'windows' and host_machine.system() != 'darwin' 40 | pylib_ldlibrary = python.get_variable('LDLIBRARY', '') 41 | if run_command(python, '-c', check_path_exists, join_paths(pylib_loc, pylib_ldlibrary)).returncode() != 0 42 | # Workaround for Fedora 43 | pylib_loc = python.get_variable('LIBDIR', '') 44 | message('pylib_loc = @0@'.format(pylib_loc)) 45 | endif 46 | 47 | assert( 48 | run_command(python, '-c', check_path_exists, join_paths(pylib_loc, pylib_ldlibrary)).returncode() == 0, 49 | 'Python dynamic library path could not be determined' 50 | ) 51 | endif 52 | endif 53 | 54 | message('python_abi_flags = @0@'.format(python_abi_flags)) 55 | message('pylib_loc = @0@'.format(pylib_loc)) 56 | 57 | pygi_override_dir = get_option('pygi-overrides-dir') 58 | 59 | if pygi_override_dir == '' 60 | pygi_override_dir = python.get_install_dir( 61 | subdir : join_paths('gi', 'overrides') 62 | ) 63 | endif 64 | 65 | message('pygobject overrides directory = @0@'.format(pygi_override_dir)) 66 | 67 | # libdir has to be built from pieces. 68 | libdir = get_option('prefix')+'/'+get_option('libdir') 69 | 70 | 71 | pylib_suffix = 'so' 72 | if host_machine.system() == 'windows' 73 | pylib_suffix = 'dll' 74 | elif host_machine.system() == 'darwin' 75 | pylib_suffix = 'dylib' 76 | endif 77 | cdata = configuration_data() 78 | cdata.set('PACKAGE', '"gst-python"') 79 | cdata.set('VERSION', '"@0@"'.format(gst_version)) 80 | cdata.set('GST_PACKAGE_NAME', '"GStreamer Python"') 81 | cdata.set('PACKAGE_NAME', '"GStreamer Python"') 82 | cdata.set('GST_API_VERSION', '"@0@"'.format(api_version)) 83 | cdata.set('PLUGINDIR', '"@0@/gstreamer-1.0"'.format(libdir)) 84 | cdata.set('PY_LIB_LOC', '"@0@"'.format(pylib_loc)) 85 | cdata.set('PY_ABI_FLAGS', '"@0@"'.format(python_abi_flags)) 86 | cdata.set('PY_LIB_SUFFIX', '"@0@"'.format(pylib_suffix)) 87 | cdata.set('PYTHON_VERSION', '"@0@"'.format(python_dep.version())) 88 | configure_file(output : 'config.h', configuration : cdata) 89 | configinc = include_directories('.') 90 | 91 | pkgconfig = import('pkgconfig') 92 | plugins_install_dir = join_paths(libdir, 'gstreamer-1.0') 93 | plugins_pkgconfig_install_dir = join_paths(plugins_install_dir, 'pkgconfig') 94 | if get_option('default_library') == 'shared' 95 | # If we don't build static plugins there is no need to generate pc files 96 | plugins_pkgconfig_install_dir = disabler() 97 | endif 98 | 99 | subdir('gi') 100 | subdir('plugin') 101 | subdir('testsuite') 102 | 103 | run_command(python, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")') 104 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('pygi-overrides-dir', type : 'string', value : '', 2 | description: 'Path to pygobject overrides directory') 3 | option('libpython-dir', type : 'string', value : '', 4 | description: 'Path to find libpythonXX.so') 5 | option('python', type : 'string', value : 'python3') 6 | -------------------------------------------------------------------------------- /old_examples/audio-controller.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # audio-controller.py 6 | # (c) 2005 Edward Hervey 7 | # Test case for the GstController on sinesrc -> alsasink 8 | # Inspired from ensonic's examples/controller/audio-controller.c 9 | 10 | import pygst 11 | pygst.require('0.10') 12 | import gst 13 | import time 14 | 15 | def main(): 16 | pipeline = gst.Pipeline("audiocontroller") 17 | src = gst.element_factory_make("audiotestsrc", "src") 18 | sink = gst.element_factory_make("alsasink", "sink") 19 | pipeline.add(src, sink) 20 | src.link(sink) 21 | 22 | control = gst.Controller(src, "freq", "volume") 23 | control.set_interpolation_mode("volume", gst.INTERPOLATE_LINEAR) 24 | control.set_interpolation_mode("freq", gst.INTERPOLATE_LINEAR) 25 | 26 | control.set("volume", 0, 0.0) 27 | control.set("volume", 2 * gst.SECOND, 1.0) 28 | control.set("volume", 4 * gst.SECOND, 0.0) 29 | control.set("volume", 6 * gst.SECOND, 1.0) 30 | 31 | control.set("freq", 0, 440.0) 32 | control.set("freq", 3 * gst.SECOND, 3000.0) 33 | control.set("freq", 6 * gst.SECOND, 880.0) 34 | 35 | pipeline.set_state(gst.STATE_PLAYING) 36 | 37 | time.sleep(7) 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /old_examples/audioconcat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # audioconcat.py - Concatenates multiple audio files to single ogg/vorbis file 6 | # Uses the gnonlin elements (http://gnonlin.sf.net/) 7 | # Copyright (C) 2005 Edward Hervey 8 | # 2006 Jason Gerard DeRose 9 | # 10 | # This library is free software; you can redistribute it and/or 11 | # modify it under the terms of the GNU Library General Public 12 | # License as published by the Free Software Foundation; either 13 | # version 2 of the License, or (at your option) any later version. 14 | # 15 | # This library is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | # Library General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU Library General Public 21 | # License along with this library; if not, write to the 22 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 23 | # Boston, MA 02110-1301, USA. 24 | # 25 | 26 | import sys 27 | 28 | import gobject 29 | gobject.threads_init() 30 | 31 | import pygst 32 | pygst.require('0.10') 33 | import gst 34 | from gst.extend.discoverer import Discoverer 35 | 36 | 37 | 38 | class AudioDec(gst.Bin): 39 | '''Decodes audio file, outputs at specified caps''' 40 | 41 | def __init__(self, location, caps): 42 | gst.Bin.__init__(self) 43 | 44 | # Create elements 45 | src = gst.element_factory_make('filesrc') 46 | dec = gst.element_factory_make('decodebin') 47 | conv = gst.element_factory_make('audioconvert') 48 | rsmpl = gst.element_factory_make('audioresample') 49 | ident = gst.element_factory_make('identity') 50 | 51 | # Set 'location' property on filesrc 52 | src.set_property('location', location) 53 | 54 | # Connect handler for 'new-decoded-pad' signal 55 | dec.connect('new-decoded-pad', self.__on_new_decoded_pad) 56 | 57 | # Add elements to bin 58 | self.add(src, dec, conv, rsmpl, ident) 59 | 60 | # Link *some* elements 61 | # This is completed in self.__on_new_decoded_pad() 62 | src.link(dec) 63 | conv.link(rsmpl) 64 | rsmpl.link(ident, caps) 65 | 66 | # Reference used in self.__on_new_decoded_pad() 67 | self.__apad = conv.get_pad('sink') 68 | 69 | # Add ghost pad 70 | self.add_pad(gst.GhostPad('src', ident.get_pad('src'))) 71 | 72 | 73 | def __on_new_decoded_pad(self, element, pad, last): 74 | caps = pad.get_caps() 75 | name = caps[0].get_name() 76 | print '\n__on_new_decoded_pad:', name 77 | if 'audio' in name: 78 | if not self.__apad.is_linked(): # Only link once 79 | pad.link(self.__apad) 80 | 81 | 82 | 83 | 84 | class AudioConcat: 85 | '''Concatenates multiple audio files to single ogg/vorbis file''' 86 | 87 | caps = gst.caps_from_string('audio/x-raw-float, rate=44100, channels=2, endianness=1234, width=32') 88 | 89 | def __init__(self, infiles, outfile): 90 | # These are used in iteration through infiles 91 | self.infiles = infiles 92 | self.i = 0 93 | self.start = 0L 94 | 95 | # The pipeline 96 | self.pipeline = gst.Pipeline() 97 | 98 | # Create bus and connect 'eos' and 'error' handlers 99 | self.bus = self.pipeline.get_bus() 100 | self.bus.add_signal_watch() 101 | self.bus.connect('message::eos', self.on_eos) 102 | self.bus.connect('message::error', self.on_error) 103 | 104 | # Create elements 105 | self.comp = gst.element_factory_make('gnlcomposition') 106 | self.enc = gst.element_factory_make('vorbisenc') 107 | self.mux = gst.element_factory_make('oggmux') 108 | self.sink = gst.element_factory_make('filesink') 109 | 110 | # Connect handler for 'pad-added' signal 111 | self.comp.connect('pad-added', self.on_pad_added) 112 | 113 | # Set 'location' property on filesink 114 | self.sink.set_property('location', outfile) 115 | 116 | # Add elements to pipeline 117 | self.pipeline.add(self.comp, self.enc, self.mux, self.sink) 118 | 119 | # Link *some* elements 120 | # This in completed in self.on_pad_added() 121 | gst.element_link_many(self.enc, self.mux, self.sink) 122 | 123 | # Reference used in self.on_pad_added() 124 | self.apad = self.enc.get_pad('sink') 125 | 126 | # The MainLoop 127 | self.mainloop = gobject.MainLoop() 128 | 129 | # Iterate through infiles 130 | gobject.idle_add(self.discover) 131 | self.mainloop.run() 132 | 133 | 134 | def discover(self): 135 | infile = self.infiles[self.i] 136 | discoverer = Discoverer(infile) 137 | discoverer.connect('discovered', self.on_discovered, infile) 138 | discoverer.discover() 139 | return False # Don't repeat idle call 140 | 141 | 142 | def on_discovered(self, discoverer, ismedia, infile): 143 | print '\non_discovered:', infile 144 | discoverer.print_info() 145 | if discoverer.is_audio: 146 | dec = AudioDec(infile, self.caps) 147 | src = gst.element_factory_make('gnlsource') 148 | src.add(dec) 149 | src.set_property('media-start', 0L) 150 | src.set_property('media-duration', discoverer.audiolength) 151 | src.set_property('start', self.start) 152 | src.set_property('duration', discoverer.audiolength) 153 | self.comp.add(src) 154 | self.start += discoverer.audiolength 155 | self.i += 1 156 | if self.i < len(self.infiles): 157 | gobject.idle_add(self.discover) 158 | else: 159 | if self.start > 0: # At least 1 infile is_audio and audiolength > 0 160 | self.pipeline.set_state(gst.STATE_PLAYING) 161 | else: 162 | self.mainloop.quit() 163 | 164 | 165 | def on_pad_added(self, element, pad): 166 | caps = pad.get_caps() 167 | name = caps[0].get_name() 168 | print '\non_pad_added:', name 169 | if name == 'audio/x-raw-float': 170 | if not self.apad.is_linked(): # Only link once 171 | pad.link(self.apad) 172 | 173 | 174 | def on_eos(self, bus, msg): 175 | print '\non_eos' 176 | self.mainloop.quit() 177 | 178 | 179 | def on_error(self, bus, msg): 180 | error = msg.parse_error() 181 | print '\non_error:', error[1] 182 | self.mainloop.quit() 183 | 184 | 185 | 186 | 187 | if __name__ == '__main__': 188 | if len(sys.argv) >= 3: 189 | AudioConcat(sys.argv[1:-1], sys.argv[-1]) 190 | else: 191 | print 'Usage: %s ' % sys.argv[0] 192 | print 'Example: %s song1.mp3 song2.ogg output.ogg' % sys.argv[0] 193 | -------------------------------------------------------------------------------- /old_examples/bps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # gst-python 6 | # Copyright (C) 2003 David I. Lehn 7 | # 8 | # This library is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Library General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2 of the License, or (at your option) any later version. 12 | # 13 | # This library is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Library General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Library General Public 19 | # License along with this library; if not, write to the 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | # Boston, MA 02110-1301, USA. 22 | # 23 | # Author: David I. Lehn 24 | # 25 | 26 | import pygtk 27 | pygtk.require('2.0') 28 | 29 | import sys 30 | import time 31 | import gobject 32 | import gtk 33 | 34 | import pygst 35 | pygst.require('0.10') 36 | 37 | import gst 38 | 39 | class BPS(object): 40 | def __init__(self): 41 | self.buffers = 0 42 | self.start = 0 43 | 44 | def done(self): 45 | end = time.time() 46 | dt = end - self.start 47 | bps = self.buffers/dt 48 | spb = dt/self.buffers 49 | print '\t%d buffers / %fs\t= %f bps\t= %f spb' % (self.buffers, dt, bps, spb) 50 | 51 | def fakesrc(self, buffers): 52 | src = gst.element_factory_make('fakesrc','src') 53 | src.set_property('silent', 1) 54 | src.set_property('num_buffers', buffers) 55 | return src 56 | 57 | def fakesink(self): 58 | sink = gst.element_factory_make('fakesink','sink') 59 | sink.set_property('silent', 1) 60 | return sink 61 | 62 | def build_pipeline(self, buffers): 63 | pipeline = gst.Pipeline('pipeline') 64 | 65 | src = self.fakesrc(buffers) 66 | pipeline.add(src) 67 | sink = self.fakesink() 68 | pipeline.add(sink) 69 | src.link(sink) 70 | 71 | return pipeline 72 | 73 | def idle(self, pipeline): 74 | return pipeline.iterate() 75 | 76 | def test(self): 77 | self.bus = self.pipeline.get_bus() 78 | 79 | self.start = time.time() 80 | 81 | self.pipeline.set_state(gst.STATE_PLAYING) 82 | 83 | while 1: 84 | msg = self.bus.poll(gst.MESSAGE_EOS | gst.MESSAGE_ERROR, gst.SECOND) 85 | if msg: 86 | break 87 | 88 | self.pipeline.set_state(gst.STATE_NULL) 89 | self.done() 90 | 91 | def run(self, buffers): 92 | self.buffers = buffers 93 | 94 | print '# Testing buffer processing rate for "fakesrc ! fakesink"' 95 | print '# bps = buffers per second' 96 | print '# spb = seconds per buffer' 97 | 98 | self.pipeline = self.build_pipeline(buffers) 99 | assert self.pipeline 100 | 101 | self.test() 102 | 103 | def main(args): 104 | "GStreamer Buffers-Per-Second tester" 105 | 106 | if len(args) < 2: 107 | print 'usage: %s buffers' % args[0] 108 | return 1 109 | 110 | bps = BPS() 111 | 112 | buffers = int(args[1]) 113 | if buffers < 1: 114 | print 'buffers must be higher than 0' 115 | return 116 | 117 | bps.run(buffers) 118 | 119 | if __name__ == '__main__': 120 | sys.exit(main(sys.argv)) 121 | -------------------------------------------------------------------------------- /old_examples/buffer-draw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import traceback 5 | from math import pi 6 | 7 | import pygtk 8 | pygtk.require ("2.0") 9 | import gobject 10 | gobject.threads_init() 11 | 12 | import pygst 13 | pygst.require('0.10') 14 | import gst 15 | 16 | import cairo 17 | 18 | WIDTH, HEIGHT = 640, 480 19 | FRAMES = 300 20 | FRAMERATE = 15 21 | 22 | class PyGstBufferDraw(gst.Element): 23 | _sinkpadtemplate = gst.PadTemplate ("sink", 24 | gst.PAD_SINK, 25 | gst.PAD_ALWAYS, 26 | gst.caps_from_string ("video/x-raw-rgb,bpp=32,depth=32,blue_mask=-16777216,green_mask=16711680, red_mask=65280, alpha_mask=255,width=[ 1, 2147483647 ],height=[ 1, 2147483647 ],framerate=[ 0/1, 2147483647/1 ]")) 27 | _srcpadtemplate = gst.PadTemplate ("src", 28 | gst.PAD_SRC, 29 | gst.PAD_ALWAYS, 30 | gst.caps_from_string ("video/x-raw-rgb,bpp=32,depth=32,blue_mask=-16777216,green_mask=16711680, red_mask=65280, alpha_mask=255,width=[ 1, 2147483647 ],height=[ 1, 2147483647 ],framerate=[ 0/1, 2147483647/1 ]")) 31 | 32 | def __init__(self): 33 | gst.Element.__init__(self) 34 | 35 | self.sinkpad = gst.Pad(self._sinkpadtemplate, "sink") 36 | self.sinkpad.set_chain_function(self.chainfunc) 37 | self.sinkpad.set_event_function(self.eventfunc) 38 | self.sinkpad.set_getcaps_function(gst.Pad.proxy_getcaps) 39 | self.sinkpad.set_setcaps_function(gst.Pad.proxy_setcaps) 40 | self.add_pad (self.sinkpad) 41 | 42 | self.srcpad = gst.Pad(self._srcpadtemplate, "src") 43 | 44 | self.srcpad.set_event_function(self.srceventfunc) 45 | self.srcpad.set_query_function(self.srcqueryfunc) 46 | self.srcpad.set_getcaps_function(gst.Pad.proxy_getcaps) 47 | self.srcpad.set_setcaps_function(gst.Pad.proxy_setcaps) 48 | self.add_pad (self.srcpad) 49 | 50 | def chainfunc(self, pad, buffer): 51 | try: 52 | outbuf = buffer.copy_on_write () 53 | self.draw_on (outbuf) 54 | return self.srcpad.push (outbuf) 55 | except: 56 | return GST_FLOW_ERROR 57 | 58 | def eventfunc(self, pad, event): 59 | return self.srcpad.push_event (event) 60 | 61 | def srcqueryfunc (self, pad, query): 62 | return self.sinkpad.query (query) 63 | def srceventfunc (self, pad, event): 64 | return self.sinkpad.push_event (event) 65 | 66 | def draw_on (self, buf): 67 | try: 68 | caps = buf.get_caps() 69 | width = caps[0]['width'] 70 | height = caps[0]['height'] 71 | framerate = caps[0]['framerate'] 72 | surface = cairo.ImageSurface.create_for_data (buf, cairo.FORMAT_ARGB32, width, height, 4 * width) 73 | ctx = cairo.Context(surface) 74 | except: 75 | print "Failed to create cairo surface for buffer" 76 | traceback.print_exc() 77 | return 78 | 79 | try: 80 | center_x = width/4 81 | center_y = 3*height/4 82 | 83 | # draw a circle 84 | radius = float (min (width, height)) * 0.25 85 | ctx.set_source_rgba (0.0, 0.0, 0.0, 0.9) 86 | ctx.move_to (center_x, center_y) 87 | ctx.arc (center_x, center_y, radius, 0, 2.0*pi) 88 | ctx.close_path() 89 | ctx.fill() 90 | ctx.set_source_rgba (1.0, 1.0, 1.0, 1.0) 91 | ctx.set_font_size(0.3 * radius) 92 | txt = "Hello World" 93 | extents = ctx.text_extents (txt) 94 | ctx.move_to(center_x - extents[2]/2, center_y + extents[3]/2) 95 | ctx.text_path(txt) 96 | ctx.fill() 97 | 98 | except: 99 | print "Failed cairo render" 100 | traceback.print_exc() 101 | 102 | gobject.type_register(PyGstBufferDraw) 103 | 104 | pipe = gst.Pipeline() 105 | vt = gst.element_factory_make ("videotestsrc") 106 | cf = gst.element_factory_make ("capsfilter") 107 | c1 = PyGstBufferDraw() 108 | color = gst.element_factory_make ("ffmpegcolorspace") 109 | scale = gst.element_factory_make ("videoscale") 110 | q1 = gst.element_factory_make ("queue") 111 | sink = gst.element_factory_make ("autovideosink") 112 | 113 | caps = gst.caps_from_string ("video/x-raw-rgb,width=%d,height=%d,framerate=%d/1" % (WIDTH, HEIGHT, FRAMERATE)) 114 | cf.set_property ("caps", caps) 115 | 116 | vt.set_property ("num-buffers", FRAMES) 117 | 118 | pipe.add (vt, cf, c1, q1, color, scale, sink) 119 | gst.element_link_many (vt, cf, c1, q1, color, scale, sink) 120 | 121 | def on_eos (bus, msg): 122 | mainloop.quit() 123 | 124 | bus = pipe.get_bus() 125 | bus.add_signal_watch() 126 | bus.connect('message::eos', on_eos) 127 | 128 | pipe.set_state (gst.STATE_PLAYING) 129 | 130 | mainloop = gobject.MainLoop() 131 | try: 132 | mainloop.run() 133 | except: 134 | pass 135 | 136 | pipe.set_state (gst.STATE_NULL) 137 | pipe.get_state (gst.CLOCK_TIME_NONE) 138 | 139 | -------------------------------------------------------------------------------- /old_examples/cp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # gst-python 6 | # Copyright (C) 2002 David I. Lehn 7 | # 2004 Johan Dahlin 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Library General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Library General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Library General Public 20 | # License along with this library; if not, write to the 21 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 | # Boston, MA 02110-1301, USA. 23 | # 24 | # Author: David I. Lehn 25 | # 26 | 27 | import sys 28 | 29 | import gobject 30 | gobject.threads_init() 31 | 32 | import pygst 33 | pygst.require('0.10') 34 | import gst 35 | 36 | 37 | mainloop = gobject.MainLoop() 38 | 39 | def on_eos(bus, msg): 40 | mainloop.quit() 41 | 42 | def filter(input, output): 43 | "A GStreamer copy pipeline which can add arbitrary filters" 44 | 45 | # create a new bin to hold the elements 46 | bin = gst.parse_launch('filesrc name=source ! ' + 47 | 'progressreport ! ' + 48 | # This 'statistics' element is depreciated in 0.10 49 | #'statistics silent=false buffer-update-freq=1 ' + 50 | #'update_on_eos=true ! ' + 51 | 'filesink name=sink') 52 | filesrc = bin.get_by_name('source') 53 | filesrc.set_property('location', input) 54 | 55 | filesink = bin.get_by_name('sink') 56 | filesink.set_property('location', output) 57 | 58 | bus = bin.get_bus() 59 | bus.add_signal_watch() 60 | bus.connect('message::eos', on_eos) 61 | 62 | # start playing 63 | bin.set_state(gst.STATE_PLAYING) 64 | 65 | try: 66 | mainloop.run() 67 | except KeyboardInterrupt: 68 | pass 69 | 70 | # stop the bin 71 | bin.set_state(gst.STATE_NULL) 72 | 73 | def main(args): 74 | "A GStreamer based cp(1) with stats" 75 | 76 | if len(args) != 3: 77 | print 'usage: %s source dest' % (sys.argv[0]) 78 | return -1 79 | 80 | return filter(args[1], args[2]) 81 | 82 | if __name__ == '__main__': 83 | sys.exit(main(sys.argv)) 84 | -------------------------------------------------------------------------------- /old_examples/cutter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # gst-python 6 | # Copyright (C) 2005 Thomas Vander Stichele 7 | # 8 | # This library is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Library General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2 of the License, or (at your option) any later version. 12 | # 13 | # This library is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Library General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Library General Public 19 | # License along with this library; if not, write to the 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | # Boston, MA 02110-1301, USA. 22 | 23 | import gst 24 | import time 25 | 26 | import gobject 27 | #gobject.threads_init() # so we can safely receive signals from threads 28 | 29 | count = 0 30 | 31 | def on_message_application(cutter, message, loop): 32 | global count 33 | s = message.structure 34 | which = 'below' 35 | if s['above']: which = 'above' 36 | print "%s: %s threshold" % (gst.TIME_ARGS(s['timestamp']), which) 37 | if s['above']: count += 1 38 | if count > 2: loop.quit() 39 | 40 | def main(): 41 | type = 'async' 42 | loop = gobject.MainLoop() 43 | 44 | pipeline = gst.Pipeline("cutter") 45 | src = gst.element_factory_make("sinesrc", "src") 46 | cutter = gst.element_factory_make("cutter") 47 | cutter.set_property('threshold', 0.5) 48 | sink = gst.element_factory_make("fakesink", "sink") 49 | pipeline.add(src, cutter, sink) 50 | src.link(cutter) 51 | cutter.link(sink) 52 | 53 | control = gst.Controller(src, "volume") 54 | control.set_interpolation_mode("volume", gst.INTERPOLATE_LINEAR) 55 | 56 | control.set("volume", 0, 0.0) 57 | control.set("volume", 2 * gst.SECOND, 1.0) 58 | control.set("volume", 4 * gst.SECOND, 0.0) 59 | control.set("volume", 6 * gst.SECOND, 1.0) 60 | control.set("volume", 8 * gst.SECOND, 0.0) 61 | control.set("volume", 10 * gst.SECOND, 1.0) 62 | 63 | bus = pipeline.get_bus() 64 | 65 | if type == 'async': 66 | bus.add_signal_watch() 67 | bus.connect('message::element', on_message_application, loop) 68 | else: 69 | # FIXME: needs wrapping in gst-python 70 | bus.set_sync_handler(bus.sync_signal_handler) 71 | bus.connect('sync-message::element', on_message_application, loop) 72 | 73 | pipeline.set_state(gst.STATE_PLAYING) 74 | 75 | loop.run() 76 | 77 | pipeline.set_state(gst.STATE_NULL) 78 | 79 | if __name__ == "__main__": 80 | main() 81 | -------------------------------------------------------------------------------- /old_examples/debugslider.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # gst-python 6 | # Copyright (C) 2005 Fluendo S.L. 7 | # 8 | # This library is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Library General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2 of the License, or (at your option) any later version. 12 | # 13 | # This library is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Library General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Library General Public 19 | # License along with this library; if not, write to the 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | # Boston, MA 02110-1301, USA. 22 | # 23 | # Author: Andy Wingo 24 | 25 | import gtk 26 | from gtk import gdk 27 | import gobject 28 | 29 | import pygst 30 | pygst.require('0.10') 31 | import gst 32 | 33 | class DebugSlider(gtk.HScale): 34 | def __init__(self): 35 | adj = gtk.Adjustment(int(gst.debug_get_default_threshold()), 36 | 0, 5, 1, 0, 0) 37 | gtk.HScale.__init__(self, adj) 38 | self.set_digits(0) 39 | self.set_draw_value(True) 40 | self.set_value_pos(gtk.POS_TOP) 41 | 42 | def value_changed(self): 43 | newlevel = int(self.get_adjustment().get_value()) 44 | gst.debug_set_default_threshold(newlevel) 45 | 46 | self.connect('value-changed', value_changed) 47 | 48 | if __name__ == '__main__': 49 | p = gst.parse_launch('fakesrc ! fakesink') 50 | p.set_state(gst.STATE_PLAYING) 51 | 52 | w = gtk.Window() 53 | s = DebugSlider() 54 | w.add(s) 55 | s.show() 56 | w.set_default_size(200, 40) 57 | w.show() 58 | w.connect('delete-event', lambda *args: gtk.main_quit()) 59 | gtk.main() 60 | -------------------------------------------------------------------------------- /old_examples/decodebin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # decodebin.py - Audio autopluging example using 'decodebin' element 4 | # Copyright (C) 2006 Jason Gerard DeRose 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 | import sys 22 | 23 | import gobject 24 | gobject.threads_init() 25 | 26 | import pygst 27 | pygst.require('0.10') 28 | import gst 29 | 30 | 31 | class Decodebin: 32 | def __init__(self, location): 33 | # The pipeline 34 | self.pipeline = gst.Pipeline() 35 | 36 | # Create bus and connect several handlers 37 | self.bus = self.pipeline.get_bus() 38 | self.bus.add_signal_watch() 39 | self.bus.connect('message::eos', self.on_eos) 40 | self.bus.connect('message::tag', self.on_tag) 41 | self.bus.connect('message::error', self.on_error) 42 | 43 | # Create elements 44 | self.src = gst.element_factory_make('filesrc') 45 | self.dec = gst.element_factory_make('decodebin') 46 | self.conv = gst.element_factory_make('audioconvert') 47 | self.rsmpl = gst.element_factory_make('audioresample') 48 | self.sink = gst.element_factory_make('alsasink') 49 | 50 | # Set 'location' property on filesrc 51 | self.src.set_property('location', location) 52 | 53 | # Connect handler for 'new-decoded-pad' signal 54 | self.dec.connect('new-decoded-pad', self.on_new_decoded_pad) 55 | 56 | # Add elements to pipeline 57 | self.pipeline.add(self.src, self.dec, self.conv, self.rsmpl, self.sink) 58 | 59 | # Link *some* elements 60 | # This is completed in self.on_new_decoded_pad() 61 | self.src.link(self.dec) 62 | gst.element_link_many(self.conv, self.rsmpl, self.sink) 63 | 64 | # Reference used in self.on_new_decoded_pad() 65 | self.apad = self.conv.get_pad('sink') 66 | 67 | # The MainLoop 68 | self.mainloop = gobject.MainLoop() 69 | 70 | # And off we go! 71 | self.pipeline.set_state(gst.STATE_PLAYING) 72 | self.mainloop.run() 73 | 74 | 75 | def on_new_decoded_pad(self, element, pad, last): 76 | caps = pad.get_caps() 77 | name = caps[0].get_name() 78 | print 'on_new_decoded_pad:', name 79 | if name == 'audio/x-raw-float' or name == 'audio/x-raw-int': 80 | if not self.apad.is_linked(): # Only link once 81 | pad.link(self.apad) 82 | 83 | 84 | def on_eos(self, bus, msg): 85 | print 'on_eos' 86 | self.mainloop.quit() 87 | 88 | 89 | def on_tag(self, bus, msg): 90 | taglist = msg.parse_tag() 91 | print 'on_tag:' 92 | for key in taglist.keys(): 93 | print '\t%s = %s' % (key, taglist[key]) 94 | 95 | 96 | def on_error(self, bus, msg): 97 | error = msg.parse_error() 98 | print 'on_error:', error[1] 99 | self.mainloop.quit() 100 | 101 | 102 | 103 | 104 | 105 | if __name__ == '__main__': 106 | if len(sys.argv) == 2: 107 | Decodebin(sys.argv[1]) 108 | else: 109 | print 'Usage: %s /path/to/media/file' % sys.argv[0] 110 | -------------------------------------------------------------------------------- /old_examples/f2f.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # gst-python 6 | # Copyright (C) 2002 David I. Lehn 7 | # 8 | # This library is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Library General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2 of the License, or (at your option) any later version. 12 | # 13 | # This library is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Library General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Library General Public 19 | # License along with this library; if not, write to the 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | # Boston, MA 02110-1301, USA. 22 | # 23 | # Author: David I. Lehn 24 | # 25 | 26 | import sys 27 | 28 | import pygst 29 | pygst.require('0.10') 30 | 31 | import gst 32 | 33 | def handoff_cb(sender, *args): 34 | print sender.get_name(), args 35 | 36 | def main(args): 37 | # create a new bin to hold the elements 38 | #gst_debug_set_categories(-1) 39 | bin = gst.parse_launch('fakesrc name=source silent=1 num-buffers=10 signal-handoffs=true ! ' + 40 | 'fakesink name=sink silent=1 signal-handoffs=true') 41 | source = bin.get_by_name('source') 42 | source.connect('handoff', handoff_cb) 43 | source.get_pad("src").connect("have-data", handoff_cb) 44 | sink = bin.get_by_name('sink') 45 | sink.connect('handoff', handoff_cb) 46 | sink.get_pad("sink").connect('have-data', handoff_cb) 47 | 48 | print source, sink 49 | 50 | bus = bin.get_bus() 51 | 52 | res = bin.set_state(gst.STATE_PLAYING); 53 | assert res 54 | 55 | while 1: 56 | msg = bus.poll(gst.MESSAGE_EOS | gst.MESSAGE_ERROR, gst.SECOND) 57 | if msg: 58 | break 59 | 60 | res = bin.set_state(gst.STATE_NULL) 61 | assert res 62 | 63 | if __name__ == '__main__': 64 | sys.exit(main(sys.argv)) 65 | -------------------------------------------------------------------------------- /old_examples/filesrc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # GStreamer python bindings 6 | # Copyright (C) 2002 David I. Lehn 7 | # 2004 Johan Dahlin 8 | # 9 | # filesrc.py: implements a file source element completely in python 10 | # 11 | # This library is free software; you can redistribute it and/or 12 | # modify it under the terms of the GNU Library General Public 13 | # License as published by the Free Software Foundation; either 14 | # version 2 of the License, or (at your option) any later version. 15 | # 16 | # This library is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | # Library General Public License for more details. 20 | # 21 | # You should have received a copy of the GNU Library General Public 22 | # License along with this library; if not, write to the 23 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24 | # Boston, MA 02110-1301, USA. 25 | 26 | import sys 27 | import gobject; gobject.threads_init() 28 | import pygst 29 | pygst.require('0.10') 30 | import gst 31 | 32 | class FileSource(gst.BaseSrc): 33 | __gsttemplates__ = ( 34 | gst.PadTemplate("src", 35 | gst.PAD_SRC, 36 | gst.PAD_ALWAYS, 37 | gst.caps_new_any()), 38 | ) 39 | 40 | blocksize = 4096 41 | fd = None 42 | 43 | def __init__(self, name): 44 | self.__gobject_init__() 45 | self.curoffset = 0 46 | self.set_name(name) 47 | 48 | def set_property(self, name, value): 49 | if name == 'location': 50 | self.fd = open(value, 'r') 51 | 52 | def do_create(self, offset, size): 53 | if offset != self.curoffset: 54 | self.fd.seek(offset, 0) 55 | data = self.fd.read(self.blocksize) 56 | if data: 57 | self.curoffset += len(data) 58 | return gst.FLOW_OK, gst.Buffer(data) 59 | else: 60 | return gst.FLOW_UNEXPECTED, None 61 | gobject.type_register(FileSource) 62 | 63 | def main(args): 64 | if len(args) != 3: 65 | print 'Usage: %s input output' % (args[0]) 66 | return -1 67 | 68 | bin = gst.Pipeline('pipeline') 69 | 70 | filesrc = FileSource('filesource') 71 | assert filesrc 72 | filesrc.set_property('location', args[1]) 73 | 74 | filesink = gst.element_factory_make('filesink', 'sink') 75 | filesink.set_property('location', args[2]) 76 | 77 | bin.add(filesrc, filesink) 78 | gst.element_link_many(filesrc, filesink) 79 | 80 | bin.set_state(gst.STATE_PLAYING); 81 | mainloop = gobject.MainLoop() 82 | 83 | def bus_event(bus, message): 84 | t = message.type 85 | if t == gst.MESSAGE_EOS: 86 | mainloop.quit() 87 | elif t == gst.MESSAGE_ERROR: 88 | err, debug = message.parse_error() 89 | print "Error: %s" % err, debug 90 | mainloop.quit() 91 | return True 92 | bin.get_bus().add_watch(bus_event) 93 | 94 | mainloop.run() 95 | bin.set_state(gst.STATE_NULL) 96 | 97 | if __name__ == '__main__': 98 | sys.exit(main(sys.argv)) 99 | 100 | -------------------------------------------------------------------------------- /old_examples/gst-discover: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # gst-python 3 | # Copyright (C) 2006 Andy Wingo 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Library General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Library General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Library General Public 16 | # License along with this library; if not, write to the 17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | 21 | import os 22 | import sys 23 | 24 | import pygtk 25 | pygtk.require('2.0') 26 | import gobject 27 | gobject.threads_init() 28 | import pygst 29 | pygst.require('0.10') 30 | import gst 31 | from gst.extend import discoverer 32 | 33 | def fail(path): 34 | print "error: %r does not appear to be a media file" % path 35 | sys.exit(1) 36 | 37 | def succeed(d): 38 | def pp(prop, val): 39 | print '%s: %s' % (prop, val) 40 | pp('media type', d.mimetype) 41 | 42 | pp('has video', d.is_video) 43 | if d.is_video: 44 | pp('video caps', d.videocaps) 45 | pp('video width (pixels)', d.videowidth) 46 | pp('video height (pixels)', d.videoheight) 47 | pp('video length (hh:mm:ss)', gst.TIME_ARGS(d.videolength)) 48 | pp('framerate (fps)', '%s/%s' % (d.videorate.num, d.videorate.denom)) 49 | 50 | pp('has audio', d.is_audio) 51 | if d.is_audio: 52 | pp('audio caps', d.audiocaps) 53 | pp('audio format', d.audiofloat and 'floating-point' or 'integer') 54 | pp('sample rate (Hz)', d.audiorate) 55 | pp('sample width (bits)', d.audiowidth) 56 | pp('sample depth (bits)', d.audiodepth) 57 | pp('audio length (hh:mm:ss)', gst.TIME_ARGS(d.audiolength)) 58 | pp('audio channels', d.audiochannels) 59 | 60 | sys.exit(0) 61 | 62 | def discover(path): 63 | def discovered(d, is_media): 64 | if is_media: 65 | succeed(d) 66 | else: 67 | fail(path) 68 | 69 | d = discoverer.Discoverer(path) 70 | d.connect('discovered', discovered) 71 | d.discover() 72 | gobject.MainLoop().run() 73 | 74 | def usage(): 75 | print >>sys.stderr, "usage: gst-discover PATH-TO-MEDIA-FILE" 76 | sys.exit(1) 77 | 78 | def main(argv): 79 | if len(argv) != 2: 80 | usage() 81 | path = argv.pop() 82 | if not os.path.isfile(path): 83 | print >>sys.stderr, "error: file %r does not exist" % path 84 | usage() 85 | 86 | return discover(path) 87 | 88 | if __name__ == '__main__': 89 | sys.exit(main(sys.argv)) 90 | -------------------------------------------------------------------------------- /old_examples/gstfile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # gstfile.py 6 | # (c) 2005 Edward Hervey 7 | # Discovers and prints out multimedia information of files 8 | 9 | # This example shows how to use gst-python: 10 | # _ in an object-oriented way (Discoverer class) 11 | # _ subclassing a gst.Pipeline 12 | # _ and overidding existing methods (do_iterate()) 13 | 14 | import os 15 | import sys 16 | 17 | import gobject 18 | gobject.threads_init() 19 | 20 | import pygst 21 | pygst.require('0.10') 22 | 23 | from gst.extend.discoverer import Discoverer 24 | 25 | class GstFile: 26 | """ 27 | Analyses one or more files and prints out the multimedia information of 28 | each file. 29 | """ 30 | 31 | def __init__(self, files): 32 | self.files = files 33 | self.mainloop = gobject.MainLoop() 34 | self.current = None 35 | 36 | def run(self): 37 | gobject.idle_add(self._discover_one) 38 | self.mainloop.run() 39 | 40 | def _discovered(self, discoverer, ismedia): 41 | discoverer.print_info() 42 | self.current = None 43 | if len(self.files): 44 | print "\n" 45 | gobject.idle_add(self._discover_one) 46 | 47 | def _discover_one(self): 48 | if not len(self.files): 49 | gobject.idle_add(self.mainloop.quit) 50 | return False 51 | filename = self.files.pop(0) 52 | if not os.path.isfile(filename): 53 | gobject.idle_add(self._discover_one) 54 | return False 55 | print "Running on", filename 56 | # create a discoverer for that file 57 | self.current = Discoverer(filename) 58 | # connect a callback on the 'discovered' signal 59 | self.current.connect('discovered', self._discovered) 60 | # start the discovery 61 | self.current.discover() 62 | return False 63 | 64 | def main(args): 65 | if len(args) < 2: 66 | print 'usage: %s files...' % args[0] 67 | return 2 68 | 69 | gstfile = GstFile(args[1:]) 70 | gstfile.run() 71 | 72 | if __name__ == '__main__': 73 | sys.exit(main(sys.argv)) 74 | -------------------------------------------------------------------------------- /old_examples/helloworld.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | import gobject 6 | gobject.threads_init() 7 | 8 | import pygst 9 | pygst.require('0.10') 10 | import gst 11 | 12 | def bus_call(bus, message, loop): 13 | t = message.type 14 | if t == gst.MESSAGE_EOS: 15 | sys.stout.write("End-of-stream\n") 16 | loop.quit() 17 | elif t == gst.MESSAGE_ERROR: 18 | err, debug = message.parse_error() 19 | sys.stderr.write("Error: %s: %s\n" % err, debug) 20 | loop.quit() 21 | return True 22 | 23 | def main(args): 24 | if len(args) != 2: 25 | sys.stderr.write("usage: %s \n" % args[0]) 26 | sys.exit(1) 27 | 28 | playbin = gst.element_factory_make("playbin2", None) 29 | if not playbin: 30 | sys.stderr.write("'playbin2' gstreamer plugin missing\n") 31 | sys.exit(1) 32 | 33 | # take the commandline argument and ensure that it is a uri 34 | if gst.uri_is_valid(args[1]): 35 | uri = args[1] 36 | else: 37 | uri = gst.filename_to_uri(args[1]) 38 | playbin.set_property('uri', uri) 39 | 40 | # create and event loop and feed gstreamer bus mesages to it 41 | loop = gobject.MainLoop() 42 | 43 | bus = playbin.get_bus() 44 | bus.add_watch(bus_call, loop) 45 | 46 | # start play back and listed to events 47 | playbin.set_state(gst.STATE_PLAYING) 48 | loop.run() 49 | 50 | # cleanup 51 | playbin.set_state(gst.STATE_NULL) 52 | 53 | if __name__ == '__main__': 54 | sys.exit(main(sys.argv)) 55 | -------------------------------------------------------------------------------- /old_examples/maemogst.py: -------------------------------------------------------------------------------- 1 | import gobject 2 | gobject.threads_init() 3 | import gtk 4 | gtk.gdk.threads_init() 5 | import hildon 6 | import gst 7 | import sys 8 | 9 | # VideoWidget taken from play.py in gst-python examples 10 | class VideoWidget(gtk.DrawingArea): 11 | def __init__(self): 12 | gtk.DrawingArea.__init__(self) 13 | self.imagesink = None 14 | self.unset_flags(gtk.DOUBLE_BUFFERED) 15 | 16 | def do_expose_event(self, event): 17 | if self.imagesink: 18 | self.imagesink.expose() 19 | return False 20 | else: 21 | return True 22 | 23 | def set_sink(self, sink): 24 | assert self.window.xid 25 | self.imagesink = sink 26 | self.imagesink.set_xwindow_id(self.window.xid) 27 | 28 | class MaemoGstView: 29 | 30 | def __init__(self): 31 | # hildon has one program instance per app, so get instance 32 | self.p = hildon.Program.get_instance() 33 | # set name of application: this shows in titlebar 34 | gtk.set_application_name("Maemo GStreamer VideoTest") 35 | # stackable window in case we want more windows in future in app 36 | self.w = hildon.StackableWindow() 37 | box = gtk.VBox() 38 | self.video_widget = VideoWidget() 39 | # video widget we want to expand to size 40 | box.pack_start(self.video_widget, True, True, 0) 41 | # a button finger height to play/pause 42 | self.button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, 43 | hildon.BUTTON_ARRANGEMENT_VERTICAL, title="Pause") 44 | self.button.connect_after("clicked", self.on_button_clicked) 45 | # don't want button to expand or fill, just stay finger height 46 | box.pack_start(self.button, False, False, 0) 47 | self.w.add(box) 48 | self.w.connect("delete-event", gtk.main_quit) 49 | self.p.add_window(self.w) 50 | self.w.show_all() 51 | self.start_streaming() 52 | 53 | def start_streaming(self): 54 | # we use ximagesink solely for screenshotting ability 55 | # less cpu usage would happen with videotestsrc ! xvimagesink 56 | self.pipeline = \ 57 | gst.parse_launch("videotestsrc ! videoscale ! ximagesink") 58 | bus = self.pipeline.get_bus() 59 | # need to connect to sync message handler so we get the sink to be 60 | # embedded at the right time and not have a temporary new window 61 | bus.enable_sync_message_emission() 62 | bus.add_signal_watch() 63 | bus.connect("sync-message::element", self.on_sync_message) 64 | bus.connect("message", self.on_message) 65 | self.pipeline.set_state(gst.STATE_PLAYING) 66 | 67 | def on_sync_message(self, bus, message): 68 | if message.structure is None: 69 | return 70 | if message.structure.get_name() == 'prepare-xwindow-id': 71 | # all this is needed to sync with the X server before giving the 72 | # x id to the sink 73 | gtk.gdk.threads_enter() 74 | gtk.gdk.display_get_default().sync() 75 | self.video_widget.set_sink(message.src) 76 | message.src.set_property("force-aspect-ratio", True) 77 | gtk.gdk.threads_leave() 78 | 79 | def on_message(self, bus, message): 80 | if message.type == gst.MESSAGE_ERROR: 81 | err, debug = message.parse_error() 82 | hildon.hildon_banner_show_information(self.w, '', 83 | "Error: %s" % err) 84 | 85 | def on_button_clicked(self, widget): 86 | success, state, pending = self.pipeline.get_state(1) 87 | # do not listen if in middle of state change 88 | if not pending: 89 | if state == gst.STATE_PLAYING: 90 | self.pipeline.set_state(gst.STATE_PAUSED) 91 | self.button.set_label("Play") 92 | else: 93 | self.pipeline.set_state(gst.STATE_PLAYING) 94 | self.button.set_label("Pause") 95 | 96 | def main(): 97 | view = MaemoGstView() 98 | gtk.main() 99 | 100 | if __name__ == '__main__': 101 | sys.exit(main()) 102 | -------------------------------------------------------------------------------- /old_examples/mixer.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | 4 | import sys 5 | 6 | import gst 7 | import gst.interfaces 8 | 9 | pipeline = "alsasrc" 10 | if sys.argv[1:]: 11 | pipeline = " ".join(sys.argv[1:]) 12 | a = gst.element_factory_make(pipeline) 13 | print dir(a) 14 | 15 | res = a.set_state(gst.STATE_PAUSED) 16 | if res != gst.STATE_CHANGE_SUCCESS: 17 | print "Could not set pipeline %s to PAUSED" % pipeline 18 | 19 | print "Inputs:" 20 | for t in a.list_tracks(): 21 | if t.flags & gst.interfaces.MIXER_TRACK_INPUT: 22 | sys.stdout.write(t.label) 23 | sys.stdout.write(': %d - %d' % (t.min_volume, t.max_volume)) 24 | volumes = a.get_volume(t) 25 | sys.stdout.write(': %r' % (volumes, )) 26 | if t.props.num_channels > 0: 27 | a.set_volume(t, volumes=volumes) 28 | if t.flags & gst.interfaces.MIXER_TRACK_RECORD: 29 | sys.stdout.write(' (selected)') 30 | sys.stdout.write('\n') 31 | 32 | -------------------------------------------------------------------------------- /old_examples/option-parser.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | import sys 6 | 7 | import pygtk 8 | pygtk.require('2.0') 9 | 10 | from gobject.option import OptionParser, OptionGroup 11 | import pygst 12 | pygst.require('0.10') 13 | 14 | import gstoption 15 | 16 | def main(args): 17 | parser = OptionParser() 18 | 19 | group = OptionGroup('flumotion', 'Flumotion options', 20 | option_list=[]) 21 | group.add_option('-v', '--verbose', 22 | action="store_true", dest="verbose", 23 | help="be verbose") 24 | group.add_option('', '--version', 25 | action="store_true", dest="version", 26 | default=False, 27 | help="show version information") 28 | parser.add_option_group(group) 29 | 30 | parser.add_option_group(gstoption.get_group()) 31 | 32 | options, args = parser.parse_args(args) 33 | 34 | if options.verbose: 35 | print 'Verbose mode' 36 | 37 | import gst 38 | 39 | if options.version: 40 | print sys.version, gst.version 41 | 42 | if __name__ == '__main__': 43 | sys.exit(main(sys.argv)) 44 | -------------------------------------------------------------------------------- /old_examples/pyidentity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import pygtk 4 | pygtk.require ("2.0") 5 | import gobject 6 | gobject.threads_init() 7 | 8 | import pygst 9 | pygst.require('0.10') 10 | import gst 11 | 12 | class PyIdentity(gst.Element): 13 | _sinkpadtemplate = gst.PadTemplate ("sink", 14 | gst.PAD_SINK, 15 | gst.PAD_ALWAYS, 16 | gst.caps_new_any()) 17 | _srcpadtemplate = gst.PadTemplate ("src", 18 | gst.PAD_SRC, 19 | gst.PAD_ALWAYS, 20 | gst.caps_new_any()) 21 | 22 | def __init__(self): 23 | gst.Element.__init__(self) 24 | 25 | self.sinkpad = gst.Pad(self._sinkpadtemplate, "sink") 26 | self.sinkpad.set_chain_function(self.chainfunc) 27 | self.sinkpad.set_event_function(self.eventfunc) 28 | self.sinkpad.set_getcaps_function(gst.Pad.proxy_getcaps) 29 | self.sinkpad.set_setcaps_function(gst.Pad.proxy_setcaps) 30 | self.add_pad (self.sinkpad) 31 | 32 | self.srcpad = gst.Pad(self._srcpadtemplate, "src") 33 | 34 | self.srcpad.set_event_function(self.srceventfunc) 35 | self.srcpad.set_query_function(self.srcqueryfunc) 36 | self.srcpad.set_getcaps_function(gst.Pad.proxy_getcaps) 37 | self.srcpad.set_setcaps_function(gst.Pad.proxy_setcaps) 38 | self.add_pad (self.srcpad) 39 | 40 | def chainfunc(self, pad, buffer): 41 | gst.log ("Passing buffer with ts %d" % (buffer.timestamp)) 42 | return self.srcpad.push (buffer) 43 | 44 | def eventfunc(self, pad, event): 45 | return self.srcpad.push_event (event) 46 | 47 | def srcqueryfunc (self, pad, query): 48 | return self.sinkpad.query (query) 49 | def srceventfunc (self, pad, event): 50 | return self.sinkpad.push_event (event) 51 | 52 | gobject.type_register(PyIdentity) 53 | 54 | pipe = gst.Pipeline() 55 | vt = gst.element_factory_make ("videotestsrc") 56 | i1 = PyIdentity() 57 | color = gst.element_factory_make ("ffmpegcolorspace") 58 | scale = gst.element_factory_make ("videoscale") 59 | q1 = gst.element_factory_make ("queue") 60 | i2 = PyIdentity() 61 | sink = gst.element_factory_make ("autovideosink") 62 | 63 | pipe.add (vt, i1, q1, i2, color, scale, sink) 64 | gst.element_link_many (vt, i1, q1, i2, color, scale, sink) 65 | 66 | pipe.set_state (gst.STATE_PLAYING) 67 | 68 | gobject.MainLoop().run() 69 | -------------------------------------------------------------------------------- /old_examples/segments.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Segments.py 5 | # Copyright (C) 2006 Artem Popov 6 | # 7 | # This example demonstrates segment seeking 8 | # and seamless looping within playbin. 9 | 10 | import pygst 11 | pygst.require ("0.10") 12 | import gst 13 | 14 | import pygtk 15 | pygtk.require ("2.0") 16 | import gobject 17 | 18 | class Looper (gobject.GObject): 19 | __gproperties__ = { 20 | "loop": (gobject.TYPE_BOOLEAN, 21 | "loop", 22 | "Whether to loop the segment", 23 | False, 24 | gobject.PARAM_READWRITE), 25 | "start-pos": (gobject.TYPE_UINT64, 26 | "start position", 27 | "The segment start marker", 28 | 0, 29 | 0xfffffffffffffff, # max long possible 30 | 0, 31 | gobject.PARAM_READWRITE), 32 | "stop-pos": (gobject.TYPE_UINT64, 33 | "stop position", 34 | "The segment stop marker", 35 | 0, 36 | 0xfffffffffffffff, # max long possible 37 | 0, 38 | gobject.PARAM_READWRITE), 39 | } # __gproperties__ 40 | 41 | __gsignals__ = { 42 | "stopped": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), 43 | "position-updated": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_FLOAT,)), 44 | "error": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)) 45 | } # __gsignals__ 46 | 47 | def __init__ (self, location = None): 48 | gobject.GObject.__init__ (self) 49 | 50 | self.__playbin = gst.element_factory_make ("playbin") 51 | self.__playbin.props.video_sink = gst.element_factory_make ("fakesink") 52 | 53 | bus = self.__playbin.get_bus () 54 | bus.add_watch (self.__on_bus_message) 55 | 56 | self.__loop = False 57 | self.__start_pos = 0 58 | self.__stop_pos = 0 59 | 60 | self.__timeout_id = 0 61 | 62 | if location: 63 | self.load (location) 64 | 65 | def load (self, location): 66 | self.__playbin.props.uri = location 67 | self.__start_position = 0 68 | self.__stop_position = 0 69 | 70 | def set_segment (self, start, stop): 71 | self.props.start_pos = start 72 | self.props.stop_pos = stop 73 | 74 | def play (self): 75 | if not (self.__start_pos or self.__stop_pos): 76 | raise RuntimeError, "Cannot start playback, segment was not set!" 77 | 78 | self.__playbin.set_state (gst.STATE_PLAYING) 79 | 80 | def stop (self, silent = False): 81 | self.__playbin.set_state (gst.STATE_NULL) 82 | if not silent: 83 | self.emit ("stopped") 84 | 85 | def do_get_property (self, property): 86 | if property.name == "loop": 87 | return self.__loop 88 | elif property.name == "start-pos": 89 | return self.__start_pos 90 | elif property.name == "stop-pos": 91 | return self.__stop_pos 92 | else: 93 | raise AttributeError, "Unknown property %s" % property.name 94 | 95 | def do_set_property (self, property, value): 96 | if property.name == "loop": 97 | self.__loop = value 98 | elif property.name == "start-pos": 99 | self.__start_pos = value 100 | elif property.name == "stop-pos": 101 | self.__stop_pos = value 102 | else: 103 | raise AttributeError, "Unknown property %s" % property.name 104 | 105 | def do_stopped (self): 106 | if self.__timeout_id: 107 | gobject.source_remove (self.__timeout_id) 108 | self.__timeout_id = 0 109 | 110 | def __seek (self, start, stop, flush): 111 | flags = gst.SEEK_FLAG_SEGMENT | gst.SEEK_FLAG_ACCURATE 112 | if flush: 113 | flags = flags | gst.SEEK_FLAG_FLUSH 114 | self.__playbin.seek (1.0, gst.FORMAT_TIME, flags, 115 | gst.SEEK_TYPE_SET, start, 116 | gst.SEEK_TYPE_SET, stop) 117 | 118 | def __on_timeout (self): 119 | position = self.__playbin.query_position (gst.FORMAT_TIME) [0] 120 | self.emit ("position-updated", float (position)) 121 | return True 122 | 123 | def __on_bus_message (self, bus, message): 124 | if message.type == gst.MESSAGE_ERROR: 125 | error, debug = message.parse_error () 126 | self.stop () # this looks neccessary here 127 | self.emit ("error", (error, debug)) 128 | 129 | elif message.type == gst.MESSAGE_NEW_CLOCK: 130 | # we connect the timeout handler here to be sure that further queries succeed 131 | interval = int ((self.__stop_position - self.__start_position) / (2 * gst.SECOND) + 50) 132 | self.__timeout_id = gobject.timeout_add (interval, self.__on_timeout) 133 | 134 | elif message.type == gst.MESSAGE_STATE_CHANGED: 135 | old_state, new_state, pending = message.parse_state_changed () 136 | if old_state == gst.STATE_READY and new_state == gst.STATE_PAUSED and message.src == self.__playbin: 137 | self.__seek (self.__start_pos, self.__stop_pos, True) 138 | 139 | elif message.type == gst.MESSAGE_SEGMENT_DONE: 140 | if self.__loop: 141 | self.__seek (self.__start_pos, self.__stop_pos, False) 142 | else: 143 | src = self.__playbin.get_property ("source") 144 | pad = src.get_pad ('src') 145 | pad.push_event (gst.event_new_eos ()) 146 | 147 | # this is the good old way: 148 | # 149 | # pads = src.src_pads () 150 | # while True: 151 | # try: 152 | # pad = pads.next () 153 | # pad.push_event (gst.event_new_eos ()) 154 | # except: 155 | # break 156 | 157 | elif message.type == gst.MESSAGE_EOS: 158 | self.stop () 159 | 160 | return True 161 | 162 | mainloop = gobject.MainLoop () 163 | 164 | def on_looper_stopped (looper): 165 | mainloop.quit () 166 | 167 | def on_looper_pos_updated (looper, position): 168 | print round (position / gst.SECOND, 2) 169 | 170 | def on_looper_error (looper, error_tuple): 171 | error, debug = error_tuple 172 | print "\n\n%s\n\n%s\n\n" % (error, debug) 173 | mainloop.quit () 174 | 175 | if __name__ == "__main__": 176 | import sys 177 | if len (sys.argv) != 5: 178 | print "Usage: %s " % sys.argv [0] 179 | sys.exit (1) 180 | 181 | if "://" in sys.argv [1]: 182 | uri = sys.argv [1] 183 | else: 184 | import os.path 185 | uri = "file://" + os.path.abspath (sys.argv [1]) 186 | 187 | looper = Looper (uri) 188 | 189 | looper.props.start_pos = long (sys.argv [2]) * gst.SECOND 190 | looper.props.stop_pos = long (sys.argv [3]) * gst.SECOND 191 | looper.props.loop = int (sys.argv [4]) 192 | 193 | looper.connect ("stopped", on_looper_stopped) 194 | looper.connect ("position-updated", on_looper_pos_updated) 195 | looper.connect ("error", on_looper_error) 196 | 197 | looper.play () 198 | mainloop.run () 199 | -------------------------------------------------------------------------------- /old_examples/sinkelement-registry.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # sinkelement.py 6 | # (c) 2005 Edward Hervey 7 | # (c) 2007 Jan Schmidt 8 | # Licensed under LGPL 9 | # 10 | # Small test application to show how to write a sink element 11 | # in 20 lines in python and place into the gstreamer registry 12 | # so it can be autoplugged or used from parse_launch. 13 | # 14 | # Run this script with GST_DEBUG=python:5 to see the debug 15 | # messages 16 | 17 | import pygst 18 | pygst.require('0.10') 19 | import gst 20 | import gobject 21 | gobject.threads_init () 22 | 23 | # 24 | # Simple Sink element created entirely in python 25 | # 26 | 27 | class MySink(gst.Element): 28 | __gstdetails__ = ('CustomSink','Sink', \ 29 | 'Custom test sink element', 'Edward Hervey') 30 | 31 | _sinkpadtemplate = gst.PadTemplate ("sinkpadtemplate", 32 | gst.PAD_SINK, 33 | gst.PAD_ALWAYS, 34 | gst.caps_new_any()) 35 | 36 | def __init__(self): 37 | gst.Element.__init__(self) 38 | gst.info('creating sinkpad') 39 | self.sinkpad = gst.Pad(self._sinkpadtemplate, "sink") 40 | gst.info('adding sinkpad to self') 41 | self.add_pad(self.sinkpad) 42 | 43 | gst.info('setting chain/event functions') 44 | self.sinkpad.set_chain_function(self.chainfunc) 45 | self.sinkpad.set_event_function(self.eventfunc) 46 | 47 | def chainfunc(self, pad, buffer): 48 | self.info("%s timestamp(buffer):%d" % (pad, buffer.timestamp)) 49 | return gst.FLOW_OK 50 | 51 | def eventfunc(self, pad, event): 52 | self.info("%s event:%r" % (pad, event.type)) 53 | return True 54 | 55 | gobject.type_register(MySink) 56 | 57 | # Register the element into this process' registry. 58 | gst.element_register (MySink, 'mysink', gst.RANK_MARGINAL) 59 | 60 | print "Use --gst-debug=python:3 to see output from this example" 61 | 62 | # 63 | # Code to test the MySink class 64 | # 65 | gst.info('About to create MySink') 66 | pipeline = gst.parse_launch ("fakesrc ! mysink") 67 | pipeline.set_state(gst.STATE_PLAYING) 68 | 69 | gobject.MainLoop().run() 70 | -------------------------------------------------------------------------------- /old_examples/sinkelement.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # sinkelement.py 6 | # (c) 2005 Edward Hervey 7 | # Licensed under LGPL 8 | # 9 | # Small test application to show how to write a sink element 10 | # in 20 lines in python 11 | # 12 | # Run this script with GST_DEBUG=python:5 to see the debug 13 | # messages 14 | 15 | import pygst 16 | pygst.require('0.10') 17 | import gst 18 | import gobject 19 | gobject.threads_init () 20 | 21 | # 22 | # Simple Sink element created entirely in python 23 | # 24 | 25 | class MySink(gst.Element): 26 | 27 | _sinkpadtemplate = gst.PadTemplate ("sinkpadtemplate", 28 | gst.PAD_SINK, 29 | gst.PAD_ALWAYS, 30 | gst.caps_new_any()) 31 | 32 | def __init__(self): 33 | gst.Element.__init__(self) 34 | gst.info('creating sinkpad') 35 | self.sinkpad = gst.Pad(self._sinkpadtemplate, "sink") 36 | gst.info('adding sinkpad to self') 37 | self.add_pad(self.sinkpad) 38 | 39 | gst.info('setting chain/event functions') 40 | self.sinkpad.set_chain_function(self.chainfunc) 41 | self.sinkpad.set_event_function(self.eventfunc) 42 | 43 | def chainfunc(self, pad, buffer): 44 | self.info("%s timestamp(buffer):%d" % (pad, buffer.timestamp)) 45 | return gst.FLOW_OK 46 | 47 | def eventfunc(self, pad, event): 48 | self.info("%s event:%r" % (pad, event.type)) 49 | return True 50 | 51 | gobject.type_register(MySink) 52 | 53 | # 54 | # Code to test the MySink class 55 | # 56 | 57 | src = gst.element_factory_make('fakesrc') 58 | gst.info('About to create MySink') 59 | sink = MySink() 60 | 61 | pipeline = gst.Pipeline() 62 | pipeline.add(src, sink) 63 | 64 | src.link(sink) 65 | 66 | pipeline.set_state(gst.STATE_PLAYING) 67 | 68 | gobject.MainLoop().run() 69 | -------------------------------------------------------------------------------- /old_examples/switch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | import pygtk 6 | pygtk.require('2.0') 7 | 8 | import sys 9 | 10 | import gobject 11 | gobject.threads_init() 12 | 13 | import pygst 14 | pygst.require('0.10') 15 | import gst 16 | import gst.interfaces 17 | import gtk 18 | gtk.gdk.threads_init() 19 | 20 | class SwitchTest: 21 | def __init__(self, videowidget): 22 | self.playing = False 23 | pipestr = ('videotestsrc pattern=0 ! queue ! s.sink0' 24 | ' videotestsrc pattern=1 ! queue ! s.sink1' 25 | ' input-selector name=s ! autovideosink') 26 | self.pipeline = gst.parse_launch(pipestr) 27 | self.videowidget = videowidget 28 | 29 | bus = self.pipeline.get_bus() 30 | bus.enable_sync_message_emission() 31 | bus.add_signal_watch() 32 | bus.connect('sync-message::element', self.on_sync_message) 33 | bus.connect('message', self.on_message) 34 | 35 | def on_sync_message(self, bus, message): 36 | if message.structure is None: 37 | return 38 | if message.structure.get_name() == 'prepare-xwindow-id': 39 | # Sync with the X server before giving the X-id to the sink 40 | gtk.gdk.threads_enter() 41 | gtk.gdk.display_get_default().sync() 42 | self.videowidget.set_sink(message.src) 43 | message.src.set_property('force-aspect-ratio', True) 44 | gtk.gdk.threads_leave() 45 | 46 | def on_message(self, bus, message): 47 | t = message.type 48 | if t == gst.MESSAGE_ERROR: 49 | err, debug = message.parse_error() 50 | print "Error: %s" % err, debug 51 | if self.on_eos: 52 | self.on_eos() 53 | self.playing = False 54 | elif t == gst.MESSAGE_EOS: 55 | if self.on_eos: 56 | self.on_eos() 57 | self.playing = False 58 | 59 | def play(self): 60 | self.playing = True 61 | gst.info("playing player") 62 | self.pipeline.set_state(gst.STATE_PLAYING) 63 | 64 | def stop(self): 65 | self.pipeline.set_state(gst.STATE_NULL) 66 | gst.info("stopped player") 67 | self.playing = False 68 | 69 | def get_state(self, timeout=1): 70 | return self.pipeline.get_state(timeout=timeout) 71 | 72 | def is_playing(self): 73 | return self.playing 74 | 75 | def switch(self, padname): 76 | switch = self.pipeline.get_by_name('s') 77 | stop_time = switch.emit('block') 78 | newpad = switch.get_static_pad(padname) 79 | start_time = newpad.get_property('running-time') 80 | 81 | gst.warning('stop time = %d' % (stop_time,)) 82 | gst.warning('stop time = %s' % (gst.TIME_ARGS(stop_time),)) 83 | 84 | gst.warning('start time = %d' % (start_time,)) 85 | gst.warning('start time = %s' % (gst.TIME_ARGS(start_time),)) 86 | 87 | gst.warning('switching from %r to %r' 88 | % (switch.get_property('active-pad'), padname)) 89 | switch.emit('switch', newpad, stop_time, start_time) 90 | 91 | class VideoWidget(gtk.DrawingArea): 92 | def __init__(self): 93 | gtk.DrawingArea.__init__(self) 94 | self.imagesink = None 95 | self.unset_flags(gtk.DOUBLE_BUFFERED) 96 | 97 | def do_expose_event(self, event): 98 | if self.imagesink: 99 | self.imagesink.expose() 100 | return False 101 | else: 102 | return True 103 | 104 | def set_sink(self, sink): 105 | assert self.window.xid 106 | self.imagesink = sink 107 | self.imagesink.set_xwindow_id(self.window.xid) 108 | 109 | class SwitchWindow(gtk.Window): 110 | UPDATE_INTERVAL = 500 111 | def __init__(self): 112 | gtk.Window.__init__(self) 113 | self.set_default_size(410, 325) 114 | 115 | self.create_ui() 116 | self.player = SwitchTest(self.videowidget) 117 | self.populate_combobox() 118 | 119 | self.update_id = -1 120 | self.changed_id = -1 121 | self.seek_timeout_id = -1 122 | 123 | self.p_position = gst.CLOCK_TIME_NONE 124 | self.p_duration = gst.CLOCK_TIME_NONE 125 | 126 | def on_delete_event(): 127 | self.player.stop() 128 | gtk.main_quit() 129 | self.connect('delete-event', lambda *x: on_delete_event()) 130 | 131 | def load_file(self, location): 132 | self.player.set_location(location) 133 | 134 | def play(self): 135 | self.player.play() 136 | 137 | def populate_combobox(self): 138 | switch = self.player.pipeline.get_by_name('s') 139 | for i, pad in enumerate([p for p in switch.pads() 140 | if p.get_direction() == gst.PAD_SINK]): 141 | self.combobox.append_text(pad.get_name()) 142 | if switch.get_property('active-pad') == pad.get_name(): 143 | self.combobox.set_active(i) 144 | if self.combobox.get_active() == -1: 145 | self.combobox.set_active(0) 146 | 147 | def combobox_changed(self): 148 | model = self.combobox.get_model() 149 | row = model[self.combobox.get_active()] 150 | padname, = row 151 | self.player.switch(padname) 152 | 153 | def create_ui(self): 154 | vbox = gtk.VBox() 155 | self.add(vbox) 156 | 157 | self.videowidget = VideoWidget() 158 | vbox.pack_start(self.videowidget) 159 | 160 | hbox = gtk.HBox() 161 | vbox.pack_start(hbox, fill=False, expand=False) 162 | 163 | self.combobox = combobox = gtk.combo_box_new_text() 164 | combobox.show() 165 | hbox.pack_start(combobox) 166 | 167 | self.combobox.connect('changed', 168 | lambda *x: self.combobox_changed()) 169 | 170 | self.videowidget.connect_after('realize', 171 | lambda *x: self.play()) 172 | 173 | def main(args): 174 | def usage(): 175 | sys.stderr.write("usage: %s\n" % args[0]) 176 | return 1 177 | 178 | # Need to register our derived widget types for implicit event 179 | # handlers to get called. 180 | gobject.type_register(SwitchWindow) 181 | gobject.type_register(VideoWidget) 182 | 183 | if len(args) != 1: 184 | return usage() 185 | 186 | w = SwitchWindow() 187 | w.show_all() 188 | gtk.main() 189 | return 0 190 | 191 | if __name__ == '__main__': 192 | sys.exit(main(sys.argv)) 193 | -------------------------------------------------------------------------------- /old_examples/tagsetter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # gst-python 6 | # Copyright (C) 2009 Stefan Kost 7 | # 8 | # This library is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Library General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2 of the License, or (at your option) any later version. 12 | # 13 | # This library is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Library General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Library General Public 19 | # License along with this library; if not, write to the 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | # Boston, MA 02110-1301, USA. 22 | # 23 | 24 | import sys 25 | 26 | import gobject 27 | gobject.threads_init() 28 | 29 | import pygst 30 | pygst.require('0.10') 31 | import gst 32 | 33 | 34 | mainloop = gobject.MainLoop() 35 | 36 | def on_eos(bus, msg): 37 | mainloop.quit() 38 | 39 | def main(args): 40 | "Tagsetter test, test result with:" 41 | "gst-launch -t playbin uri=file://$PWD/test.avi" 42 | 43 | # create a new bin to hold the elements 44 | bin = gst.parse_launch('audiotestsrc num-buffers=100 ! ' + 45 | 'lame ! ' + 46 | 'avimux name=mux ! ' + 47 | 'filesink location=test.avi') 48 | 49 | mux = bin.get_by_name('mux') 50 | 51 | bus = bin.get_bus() 52 | bus.add_signal_watch() 53 | bus.connect('message::eos', on_eos) 54 | 55 | # prepare 56 | bin.set_state(gst.STATE_READY) 57 | 58 | # send tags 59 | l = gst.TagList() 60 | l[gst.TAG_ARTIST] = "Unknown Genius" 61 | l[gst.TAG_TITLE] = "Unnamed Artwork" 62 | mux.merge_tags(l, gst.TAG_MERGE_APPEND) 63 | 64 | # start playing 65 | bin.set_state(gst.STATE_PLAYING) 66 | 67 | try: 68 | mainloop.run() 69 | except KeyboardInterrupt: 70 | pass 71 | 72 | # stop the bin 73 | bin.set_state(gst.STATE_NULL) 74 | 75 | if __name__ == '__main__': 76 | sys.exit(main(sys.argv)) 77 | 78 | -------------------------------------------------------------------------------- /old_examples/video-controller.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # videomixer-controller.py 6 | # (c) 2008 Stefan Kost 7 | # Test case for the GstController using videomixer and videotestsrc 8 | 9 | import pygst 10 | pygst.require('0.10') 11 | import gst 12 | import time 13 | 14 | def main(): 15 | pipeline = gst.Pipeline("videocontroller") 16 | src = gst.element_factory_make("videotestsrc", "src") 17 | mix = gst.element_factory_make("videomixer", "mix") 18 | conv = gst.element_factory_make("ffmpegcolorspace", "conv") 19 | sink = gst.element_factory_make("autovideosink", "sink") 20 | pipeline.add(src, mix, conv, sink) 21 | 22 | spad = src.get_static_pad('src') 23 | dpad = mix.get_request_pad('sink_%d') 24 | 25 | spad.link(dpad) 26 | mix.link(conv) 27 | conv.link(sink) 28 | 29 | control = gst.Controller(dpad, "xpos", "ypos") 30 | control.set_interpolation_mode("xpos", gst.INTERPOLATE_LINEAR) 31 | control.set_interpolation_mode("ypos", gst.INTERPOLATE_LINEAR) 32 | 33 | control.set("xpos", 0, 0) 34 | control.set("xpos", 5 * gst.SECOND, 200) 35 | 36 | control.set("ypos", 0, 0) 37 | control.set("ypos", 5 * gst.SECOND, 200) 38 | 39 | pipeline.set_state(gst.STATE_PLAYING) 40 | 41 | time.sleep(7) 42 | 43 | if __name__ == "__main__": 44 | main() 45 | -------------------------------------------------------------------------------- /old_examples/vumeter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # gst-python 6 | # Copyright (C) 2005 Andy Wingo 7 | # 8 | # This library is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU Library General Public 10 | # License as published by the Free Software Foundation; either 11 | # version 2 of the License, or (at your option) any later version. 12 | # 13 | # This library is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | # Library General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU Library General Public 19 | # License along with this library; if not, write to the 20 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 | # Boston, MA 02110-1301, USA. 22 | 23 | 24 | # A test more of gst-plugins than of gst-python. 25 | 26 | 27 | import pygtk 28 | pygtk.require('2.0') 29 | import gtk 30 | import gobject 31 | 32 | import pygst 33 | pygst.require('0.10') 34 | import gst 35 | 36 | import fvumeter 37 | 38 | 39 | def clamp(x, min, max): 40 | if x < min: 41 | return min 42 | elif x > max: 43 | return max 44 | return x 45 | 46 | 47 | class Window(gtk.Dialog): 48 | def __init__(self): 49 | gtk.Dialog.__init__(self, 'Volume Level') 50 | self.prepare_ui() 51 | 52 | def prepare_ui(self): 53 | self.set_default_size(200,60) 54 | self.set_title('Volume Level') 55 | self.connect('delete-event', lambda *x: gtk.main_quit()) 56 | self.vus = [] 57 | self.vus.append(fvumeter.FVUMeter()) 58 | self.vus.append(fvumeter.FVUMeter()) 59 | self.vbox.add(self.vus[0]) 60 | self.vbox.add(self.vus[1]) 61 | self.vus[0].show() 62 | self.vus[1].show() 63 | 64 | def error(self, message, secondary=None): 65 | m = gtk.MessageDialog(self, 66 | gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, 67 | gtk.MESSAGE_ERROR, 68 | gtk.BUTTONS_OK, 69 | message) 70 | if secondary: 71 | m.format_secondary_text(secondary) 72 | m.run() 73 | 74 | def on_message(self, bus, message): 75 | if message.structure.get_name() == 'level': 76 | s = message.structure 77 | for i in range(0, len(s['peak'])): 78 | self.vus[i].freeze_notify() 79 | decay = clamp(s['decay'][i], -90.0, 0.0) 80 | peak = clamp(s['peak'][i], -90.0, 0.0) 81 | if peak > decay: 82 | print "ERROR: peak bigger than decay!" 83 | 84 | self.vus[i].set_property('decay', decay) 85 | self.vus[i].set_property('peak', peak) 86 | return True 87 | 88 | def run(self): 89 | try: 90 | self.set_sensitive(False) 91 | s = 'alsasrc ! level message=true ! fakesink' 92 | pipeline = gst.parse_launch(s) 93 | self.set_sensitive(True) 94 | pipeline.get_bus().add_signal_watch() 95 | i = pipeline.get_bus().connect('message::element', self.on_message) 96 | pipeline.set_state(gst.STATE_PLAYING) 97 | gtk.Dialog.run(self) 98 | pipeline.get_bus().disconnect(i) 99 | pipeline.get_bus().remove_signal_watch() 100 | pipeline.set_state(gst.STATE_NULL) 101 | except gobject.GError, e: 102 | self.set_sensitive(True) 103 | self.error('Could not create pipeline', e.__str__) 104 | 105 | if __name__ == '__main__': 106 | w = Window() 107 | w.show_all() 108 | w.run() 109 | -------------------------------------------------------------------------------- /plugin/meson.build: -------------------------------------------------------------------------------- 1 | gstpython = library('gstpython', 2 | ['gstpythonplugin.c'], 3 | include_directories : [configinc], 4 | dependencies : [gst_dep, pygobject_dep, gstbase_dep, python_dep, gmodule_dep], 5 | install : true, 6 | install_dir : '@0@/gstreamer-1.0'.format(get_option('libdir')), 7 | ) 8 | pkgconfig.generate(gstpython, install_dir : plugins_pkgconfig_install_dir) 9 | plugins = [gstpython] 10 | -------------------------------------------------------------------------------- /testsuite/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GStreamer/gst-python/6580cad30e1adb247efcb89155087b6bcdaaf25c/testsuite/__init__.py -------------------------------------------------------------------------------- /testsuite/common.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python; py-indent-offset: 4 -*- 2 | # vim: tabstop=4 shiftwidth=4 expandtab 3 | # 4 | # Copyright (C) 2015 Thibault Saunier 5 | # 6 | # This program is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU Lesser General Public 8 | # License as published by the Free Software Foundation; either 9 | # version 2.1 of the License, or (at your option) any later version. 10 | # 11 | # This program 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 | # Lesser General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this program; if not, write to the 18 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 | # Boston, MA 02110-1301, USA. 20 | # This program is free software; you can redistribute it and/or modify 21 | # it under the terms of the GNU General Public License as published by 22 | # the Free Software Foundation; either version 3, or (at your option) 23 | # any later version. 24 | """ 25 | A collection of objects to use for testing 26 | 27 | Copyied from pitivi 28 | """ 29 | 30 | import os 31 | import gc 32 | import unittest 33 | import gi.overrides 34 | 35 | import gi 36 | gi.require_version("Gst", "1.0") 37 | from gi.repository import Gst 38 | 39 | 40 | detect_leaks = os.environ.get("TEST_DETECT_LEAKS", "1") not in ("0", "") 41 | 42 | 43 | class TestCase(unittest.TestCase): 44 | _tracked_types = (Gst.MiniObject, Gst.Element, Gst.Pad, Gst.Caps) 45 | 46 | def gctrack(self): 47 | self.gccollect() 48 | self._tracked = [] 49 | for obj in gc.get_objects(): 50 | if not isinstance(obj, self._tracked_types): 51 | continue 52 | 53 | self._tracked.append(obj) 54 | 55 | def gccollect(self): 56 | ret = 0 57 | while True: 58 | c = gc.collect() 59 | ret += c 60 | if c == 0: 61 | break 62 | return ret 63 | 64 | def gcverify(self): 65 | leaked = [] 66 | for obj in gc.get_objects(): 67 | if not isinstance(obj, self._tracked_types) or \ 68 | obj in self._tracked: 69 | continue 70 | 71 | leaked.append(obj) 72 | 73 | # we collect again here to get rid of temporary objects created in the 74 | # above loop 75 | self.gccollect() 76 | 77 | for elt in leaked: 78 | print(elt) 79 | for i in gc.get_referrers(elt): 80 | print(" ", i) 81 | 82 | self.assertFalse(leaked, leaked) 83 | del self._tracked 84 | 85 | def setUp(self): 86 | self._num_failures = len(getattr(self._result, 'failures', [])) 87 | self._num_errors = len(getattr(self._result, 'errors', [])) 88 | if detect_leaks: 89 | self.gctrack() 90 | 91 | def tearDown(self): 92 | # don't barf gc info all over the console if we have already failed a 93 | # test case 94 | if (self._num_failures < len(getattr(self._result, 'failures', [])) 95 | or self._num_errors < len(getattr(self._result, 'failures', []))): 96 | return 97 | if detect_leaks: 98 | self.gccollect() 99 | self.gcverify() 100 | 101 | # override run() to save a reference to the test result object 102 | def run(self, result=None): 103 | if not result: 104 | result = self.defaultTestResult() 105 | self._result = result 106 | unittest.TestCase.run(self, result) 107 | 108 | 109 | class SignalMonitor(object): 110 | 111 | def __init__(self, obj, *signals): 112 | self.signals = signals 113 | self.connectToObj(obj) 114 | 115 | def connectToObj(self, obj): 116 | self.obj = obj 117 | for signal in self.signals: 118 | obj.connect(signal, self._signalCb, signal) 119 | setattr(self, self._getSignalCounterName(signal), 0) 120 | setattr(self, self._getSignalCollectName(signal), []) 121 | 122 | def disconnectFromObj(self, obj): 123 | obj.disconnect_by_func(self._signalCb) 124 | del self.obj 125 | 126 | def _getSignalCounterName(self, signal): 127 | field = '%s_count' % signal.replace('-', '_') 128 | return field 129 | 130 | def _getSignalCollectName(self, signal): 131 | field = '%s_collect' % signal.replace('-', '_') 132 | return field 133 | 134 | def _signalCb(self, obj, *args): 135 | name = args[-1] 136 | field = self._getSignalCounterName(name) 137 | setattr(self, field, getattr(self, field, 0) + 1) 138 | field = self._getSignalCollectName(name) 139 | setattr(self, field, getattr(self, field, []) + [args[:-1]]) 140 | -------------------------------------------------------------------------------- /testsuite/gstpython.supp: -------------------------------------------------------------------------------- 1 | { 2 | pthread leak 3 | Memcheck:Leak 4 | fun:calloc 5 | fun:allocate_dtv 6 | fun:_dl_allocate_tls* 7 | } 8 | 9 | { 10 | pthread leak 2 11 | Memcheck:Leak 12 | fun:memalign 13 | fun:_dl_allocate_tls* 14 | } 15 | 16 | { 17 | popt leak 18 | Memcheck:Leak 19 | fun:malloc 20 | fun:nss_parse_service_list 21 | fun:__nss_database_lookup 22 | obj:* 23 | obj:* 24 | fun:getpwuid_r@@GLIBC_2.2.5 25 | fun:g_get_any_init_do 26 | fun:g_get_home_dir 27 | fun:init_post 28 | fun:init_popt_callback 29 | } 30 | 31 | { 32 | pygobject init leak 33 | Memcheck:Leak 34 | fun:calloc 35 | fun:g_malloc0 36 | fun:type_node_* 37 | fun:type_node_* 38 | fun:* 39 | fun:* 40 | fun:g_type_init* 41 | fun:initgobject 42 | } 43 | 44 | { 45 | borked pthread creation 46 | Memcheck:Param 47 | write(buf) 48 | fun:__pthread_initialize_manager 49 | fun:pthread_create@@GLIBC_2.2.5 50 | fun:g_thread_create* 51 | fun:g_thread_create* 52 | } 53 | 54 | { 55 | borked pthread creation 2 56 | Memcheck:Param 57 | write(buf) 58 | fun:pthread_create@@GLIBC_2.2.5 59 | fun:* 60 | fun:* 61 | fun:* 62 | fun:* 63 | fun:gst_task_start 64 | } 65 | 66 | { 67 | Syscall param clone(child_tidptr) contains uninitialised byte(s) 68 | Memcheck:Param 69 | clone(child_tidptr) 70 | fun:clone 71 | } 72 | 73 | { 74 | memory loss when creating thread 75 | Memcheck:Leak 76 | fun:malloc 77 | fun:__pthread_initialize_manager 78 | fun:pthread_create* 79 | } 80 | 81 | # pyg_enable_threads memleak 82 | 83 | { 84 | memleak in pyg_enable_threads 85 | Memcheck:Leak 86 | fun:malloc 87 | fun:* 88 | fun:* 89 | fun:* 90 | fun:* 91 | fun:* 92 | fun:pyg_enable_threads 93 | } 94 | 95 | 96 | { 97 | memleak in pyg_enable_threads 2 98 | Memcheck:Leak 99 | fun:malloc 100 | fun:* 101 | fun:* 102 | fun:* 103 | fun:* 104 | fun:pyg_enable_threads 105 | } 106 | 107 | { 108 | memleak in pyg_enable_threads 3 109 | Memcheck:Leak 110 | fun:malloc 111 | fun:* 112 | fun:* 113 | fun:* 114 | fun:pyg_enable_threads 115 | } 116 | 117 | #pygobject leaks 118 | 119 | { 120 | PyType_Ready leak 121 | Memcheck:Leak 122 | fun:malloc 123 | fun:PyObject_Malloc 124 | fun:_PyObject_GC_Malloc 125 | fun:PyType_GenericAlloc 126 | fun:* 127 | fun:* 128 | fun:PyType_Ready 129 | } 130 | 131 | #gst debug category new leak 132 | { 133 | gst debug category new leak 134 | Memcheck:Leak 135 | fun:malloc 136 | fun:g_malloc 137 | fun:g_strdup 138 | fun:_gst_debug_category_new 139 | } 140 | 141 | # memleak in gst_element_state_get_name that we can't get rid of 142 | { 143 | gst_element_state_get_name 144 | Memcheck:Leak 145 | fun:malloc 146 | fun:* 147 | fun:g_vasprintf 148 | fun:g_strdup* 149 | fun:g_strdup* 150 | fun:_wrap_gst_element_state_get_name 151 | } 152 | 153 | #memleak in pygobject_new_with_interfaces 154 | # weird, cos it seems to free the return value of g_type_interfaces 155 | { 156 | _gst_element_factory_make 157 | Memcheck:Leak 158 | fun:malloc 159 | fun:g_malloc 160 | fun:g_type_interfaces 161 | } 162 | 163 | #memleak in static_pad_template 164 | { 165 | gst_static_pad_template_get 166 | Memcheck:Leak 167 | fun:calloc 168 | fun:g_malloc0 169 | fun:g_type_create_instance 170 | fun:g_object_constructor 171 | fun:gst_object_constructor 172 | fun:* 173 | fun:* 174 | fun:* 175 | fun:gst_static_pad_template_get 176 | } 177 | 178 | #leak in libxml 179 | { 180 | xml_parse_memory leak 181 | Memcheck:Leak 182 | fun:malloc 183 | fun:* 184 | fun:xml* 185 | } 186 | 187 | # FIXME : This is an awful leak that has do to with the gst_pad_set_*_function wrappers 188 | { 189 | leak in gst_pad_set_*_function wrappers 190 | Memcheck:Leak 191 | fun:calloc 192 | fun:g_malloc0 193 | fun:pad_private 194 | } 195 | 196 | # python leak in runtime compiler 197 | { 198 | python leak in runtime compiler 199 | Memcheck:Leak 200 | fun:malloc 201 | fun:_PyObject_GC_Malloc 202 | fun:_PyObject_GC_New* 203 | fun:PyDict_New 204 | fun:PySymtableEntry_New 205 | fun:symtable_* 206 | fun:symtable_* 207 | fun:jcompile 208 | } 209 | 210 | #FIXME : These leaks are in core. See bug #344761 211 | { 212 | leak in init_gst, when creating the argv to give to gst_init_check() 213 | Memcheck:Leak 214 | fun:* 215 | fun:g_malloc 216 | fun:init_gst 217 | } 218 | 219 | { 220 | The GOption context is leaking in gst_init_check 221 | Memcheck:Leak 222 | fun:* 223 | fun:g_malloc0 224 | fun:g_option_context_new 225 | fun:gst_init_check 226 | fun:init_gst 227 | } 228 | 229 | { 230 | The GDir is leaked. 231 | Memcheck:Leak 232 | fun:* 233 | fun:g_malloc 234 | fun:g_dir_open 235 | fun:gst_registry_scan_path_level 236 | fun:gst_registry_scan_path 237 | fun:init_post 238 | fun:g_option_context_parse 239 | fun:gst_init_check 240 | fun:init_gst 241 | } 242 | -------------------------------------------------------------------------------- /testsuite/meson.build: -------------------------------------------------------------------------------- 1 | runtests = files('runtests.py') 2 | 3 | tests = [ 4 | ['Test gst', 'test_gst.py'], 5 | ['Test fundamentals', 'test_types.py'], 6 | ['Test plugins', 'test_plugin.py'], 7 | ] 8 | 9 | pluginsdirs = [] 10 | if not meson.is_subproject() 11 | pkgconfig = find_program('pkg-config') 12 | runcmd = run_command(pkgconfig, '--variable=pluginsdir', 13 | 'gstreamer-' + api_version) 14 | if runcmd.returncode() == 0 15 | pluginsdirs = runcmd.stdout().split() 16 | else 17 | error('Could not determine GStreamer core plugins directory for unit tests.') 18 | endif 19 | endif 20 | 21 | runcmd = run_command(python, '-c', '''with open("@0@/mesonconfig.py", "w") as f: 22 | f.write("path='@1@'")'''.format( 23 | join_paths(meson.current_build_dir()), join_paths(meson.current_build_dir(), '..'))) 24 | 25 | if runcmd.returncode() != 0 26 | error('Could not configure testsuite config file.' + runcmd.stderr()) 27 | endif 28 | 29 | pluginsdirs = [] 30 | if gst_dep.type_name() == 'pkgconfig' 31 | pbase = dependency('gstreamer-plugins-base-' + api_version, required : false) 32 | pluginsdirs = [gst_dep.get_pkgconfig_variable('pluginsdir'), 33 | pbase.get_pkgconfig_variable('pluginsdir')] 34 | endif 35 | 36 | pypluginsdir = [join_paths (meson.build_root(), 'plugin'), meson.current_source_dir()] 37 | 38 | foreach i: tests 39 | test_name = i.get(0) 40 | env = environment() 41 | env.set('GST_OVERRIDE_SRC_PATH', join_paths (meson.current_source_dir(), '..', 'gi', 'overrides')) 42 | env.set('GST_OVERRIDE_BUILD_PATH', join_paths (meson.current_build_dir(), '..', 'gi', 'overrides')) 43 | env.set('GST_PLUGIN_LOADING_WHITELIST', 'gstreamer', 44 | 'gst-plugins-base@' + meson.build_root(), 'gst-python@' + meson.build_root()) 45 | env.set('GST_PLUGIN_PATH_1_0', meson.build_root(), pluginsdirs + pypluginsdir) 46 | env.set('GST_REGISTRY', join_paths(meson.current_build_dir(), '@0@.registry'.format(test_name))) 47 | test(test_name, python, args: [runtests, i.get(1)], env: env) 48 | endforeach 49 | -------------------------------------------------------------------------------- /testsuite/old/test-object.c: -------------------------------------------------------------------------------- 1 | #include "test-object.h" 2 | 3 | enum 4 | { 5 | /* FILL ME */ 6 | SIGNAL_EVENT, 7 | LAST_SIGNAL 8 | }; 9 | 10 | 11 | static guint test_object_signals[LAST_SIGNAL] = { 0 }; 12 | 13 | G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT); 14 | 15 | static void 16 | test_object_init (TestObject * self) 17 | { 18 | } 19 | 20 | static void 21 | test_object_class_init (TestObjectClass * klass) 22 | { 23 | test_object_signals[SIGNAL_EVENT] = 24 | g_signal_new ("event", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 25 | G_STRUCT_OFFSET (TestObjectClass, event), NULL, NULL, 26 | g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_EVENT); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /testsuite/old/test-object.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* TestObject */ 5 | 6 | typedef struct { 7 | GObject parent; 8 | } TestObject; 9 | 10 | typedef struct { 11 | GObjectClass parent_class; 12 | /* signals */ 13 | void (*event) (TestObject *object, GstEvent *event); 14 | } TestObjectClass; 15 | 16 | #define TEST_TYPE_OBJECT (test_object_get_type()) 17 | #define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject)) 18 | #define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass)) 19 | #define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT)) 20 | #define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT)) 21 | #define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_OBJECT, TestObjectClass)) 22 | 23 | GType test_object_get_type (void); 24 | -------------------------------------------------------------------------------- /testsuite/old/test_adapter.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2009 Edward Hervey 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | from common import gobject, gst, unittest, TestCase 22 | 23 | class AdapterTest(TestCase): 24 | 25 | def setUp(self): 26 | TestCase.setUp(self) 27 | self.adapter = gst.Adapter() 28 | 29 | def tearDown(self): 30 | self.adapter = None 31 | TestCase.tearDown(self) 32 | 33 | def testAvailable(self): 34 | # starts empty 35 | self.assertEquals(self.adapter.available(), 0) 36 | self.assertEquals(self.adapter.available_fast(), 0) 37 | 38 | # let's give it 4 bytes 39 | self.adapter.push(gst.Buffer("1234")) 40 | self.assertEquals(self.adapter.available_fast(), 4) 41 | 42 | # let's give it another 5 bytes 43 | self.adapter.push(gst.Buffer("56789")) 44 | # we now have 9 bytes 45 | self.assertEquals(self.adapter.available(), 9) 46 | # but can only do a fast take of 4 bytes (the first buffer) 47 | self.assertEquals(self.adapter.available_fast(), 4) 48 | 49 | def testPeek(self): 50 | self.adapter.push(gst.Buffer("0123456789")) 51 | 52 | # let's peek at 5 bytes 53 | b = self.adapter.peek(5) 54 | # it can return more than 5 bytes 55 | self.assert_(len(b) >= 5) 56 | self.assertEquals(b, "01234") 57 | 58 | # it's still 10 bytes big 59 | self.assertEquals(self.adapter.available(), 10) 60 | 61 | # if we try to peek more than what's available, we'll have None 62 | self.assertEquals(self.adapter.peek(11), None) 63 | 64 | def testFlush(self): 65 | self.adapter.push(gst.Buffer("0123456789")) 66 | self.assertEquals(self.adapter.available(), 10) 67 | 68 | self.adapter.flush(5) 69 | self.assertEquals(self.adapter.available(), 5) 70 | 71 | # it flushed the first 5 bytes 72 | self.assertEquals(self.adapter.peek(5), "56789") 73 | 74 | self.adapter.flush(5) 75 | self.assertEquals(self.adapter.available(), 0) 76 | 77 | def testTake(self): 78 | self.adapter.push(gst.Buffer("0123456789")) 79 | self.assertEquals(self.adapter.available(), 10) 80 | 81 | s = self.adapter.take(5) 82 | self.assertEquals(s, "01234") 83 | self.assertEquals(self.adapter.available(), 5) 84 | -------------------------------------------------------------------------------- /testsuite/old/test_audio.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2009 Edward Hervey 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | from common import gobject, gst, unittest, TestCase 22 | 23 | class Audio(TestCase): 24 | 25 | def testBufferclip(self): 26 | assert hasattr(gst.audio, "buffer_clip") 27 | # create a segment 28 | segment = gst.Segment() 29 | gst.debug("Created the new segment") 30 | # we'll put a new segment of 500ms to 1000ms 31 | segment.set_newsegment(False, 1.0, gst.FORMAT_TIME, 0, -1, 0) 32 | gst.debug("Initialized the new segment") 33 | # create a new dummy buffer 34 | b = gst.Buffer("this is a really useless line") 35 | gst.debug("Created the buffer") 36 | # clip... which shouldn't do anything 37 | b2 = gst.audio.buffer_clip(b, segment, 44100, 8) 38 | gst.debug("DONE !") 39 | -------------------------------------------------------------------------------- /testsuite/old/test_bin.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # Copyright (C) 2005 Thomas Vander Stichele 9 | # 10 | # This library is free software; you can redistribute it and/or 11 | # modify it under the terms of the GNU Lesser General Public 12 | # License as published by the Free Software Foundation; either 13 | # version 2.1 of the License, or (at your option) any later version. 14 | # 15 | # This library is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | # Lesser General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU Lesser General Public 21 | # License along with this library; if not, write to the Free Software 22 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 | 24 | from common import gobject, gst, unittest, TestCase, pygobject_2_13 25 | 26 | import sys 27 | import time 28 | 29 | # see 30 | # http://www.sicem.biz/personal/lgs/docs/gobject-python/gobject-tutorial.html 31 | class MyBin(gst.Bin): 32 | _state_changed = False 33 | 34 | def __init__(self, name): 35 | # we need to call GObject's init to be able to do self.do_* 36 | gobject.GObject.__init__(self) 37 | # since we can't chain up to our parent's __init__, we set the 38 | # name manually 39 | self.set_property('name', name) 40 | 41 | def do_change_state(self, state_change): 42 | if state_change == gst.STATE_CHANGE_PAUSED_TO_PLAYING: 43 | self._state_changed = True 44 | # FIXME: it seems a vmethod increases the refcount without unreffing 45 | # print self.__gstrefcount__ 46 | # print self.__grefcount__ 47 | 48 | # chain up to parent 49 | return gst.Bin.do_change_state(self, state_change) 50 | 51 | # we need to register the type for PyGTK < 2.8 52 | gobject.type_register(MyBin) 53 | 54 | # FIXME: fix leak in vmethods before removing overriding fixture 55 | class BinSubclassTest(TestCase): 56 | def setUp(self): 57 | pass 58 | 59 | def tearDown(self): 60 | pass 61 | 62 | def testStateChange(self): 63 | bin = MyBin("mybin") 64 | self.assertEquals(bin.__gstrefcount__, 1) 65 | self.assertEquals(sys.getrefcount(bin), pygobject_2_13 and 2 or 3) 66 | 67 | self.assertEquals(bin.get_name(), "mybin") 68 | self.assertEquals(bin.__gstrefcount__, 1) 69 | 70 | # test get_state with no timeout 71 | (ret, state, pending) = bin.get_state() 72 | self.failIfEqual(ret, gst.STATE_CHANGE_FAILURE) 73 | self.assertEquals(bin.__gstrefcount__, 1) 74 | 75 | # set to playing 76 | bin.set_state(gst.STATE_PLAYING) 77 | self.failUnless(bin._state_changed) 78 | 79 | # test get_state with no timeout 80 | (ret, state, pending) = bin.get_state() 81 | self.failIfEqual(ret, gst.STATE_CHANGE_FAILURE) 82 | 83 | if ret == gst.STATE_CHANGE_SUCCESS: 84 | self.assertEquals(state, gst.STATE_PLAYING) 85 | self.assertEquals(pending, gst.STATE_VOID_PENDING) 86 | 87 | # test get_state with a timeout 88 | (ret, state, pending) = bin.get_state(1) 89 | self.failIfEqual(ret, gst.STATE_CHANGE_FAILURE) 90 | 91 | if ret == gst.STATE_CHANGE_SUCCESS: 92 | self.assertEquals(state, gst.STATE_PLAYING) 93 | self.assertEquals(pending, gst.STATE_VOID_PENDING) 94 | 95 | (ret, state, pending) = bin.get_state(timeout=gst.SECOND) 96 | 97 | # back to NULL 98 | bin.set_state(gst.STATE_NULL) 99 | 100 | class BinAddRemove(TestCase): 101 | def setUp(self): 102 | TestCase.setUp(self) 103 | self.bin = gst.Bin('bin') 104 | 105 | def tearDown(self): 106 | del self.bin 107 | TestCase.tearDown(self) 108 | 109 | def testError(self): 110 | gst.info("creating fakesrc") 111 | src = gst.element_factory_make('fakesrc', 'name') 112 | gst.info("creating fakesink") 113 | sink = gst.element_factory_make('fakesink', 'name') 114 | gst.info("adding src:%d to bin" % src.__gstrefcount__) 115 | self.assertEqual(src.__gstrefcount__, 1) 116 | self.bin.add(src) 117 | self.assertEqual(src.__gstrefcount__, 2) 118 | gst.info("added src:%d" % src.__gstrefcount__) 119 | self.assertRaises(gst.AddError, self.bin.add, sink) 120 | self.assertRaises(gst.AddError, self.bin.add, src) 121 | self.assertRaises(gst.RemoveError, self.bin.remove, sink) 122 | gst.info("removing src") 123 | self.bin.remove(src) 124 | gst.info("removed") 125 | self.assertRaises(gst.RemoveError, self.bin.remove, src) 126 | 127 | def testMany(self): 128 | src = gst.element_factory_make('fakesrc') 129 | sink = gst.element_factory_make('fakesink') 130 | self.bin.add(src, sink) 131 | self.assertRaises(gst.AddError, self.bin.add, src, sink) 132 | self.bin.remove(src, sink) 133 | self.assertRaises(gst.RemoveError, self.bin.remove, src, sink) 134 | 135 | class Preroll(TestCase): 136 | def setUp(self): 137 | TestCase.setUp(self) 138 | self.bin = gst.Bin('bin') 139 | 140 | def tearDown(self): 141 | # FIXME: wait for state change thread to settle down 142 | while self.bin.__gstrefcount__ > 1: 143 | time.sleep(0.1) 144 | self.assertEquals(self.bin.__gstrefcount__, 1) 145 | del self.bin 146 | TestCase.tearDown(self) 147 | 148 | def testFake(self): 149 | src = gst.element_factory_make('fakesrc') 150 | sink = gst.element_factory_make('fakesink') 151 | self.bin.add(src) 152 | 153 | # bin will go to paused, src pad task will start and error out 154 | self.bin.set_state(gst.STATE_PAUSED) 155 | ret = self.bin.get_state() 156 | self.assertEquals(ret[0], gst.STATE_CHANGE_SUCCESS) 157 | self.assertEquals(ret[1], gst.STATE_PAUSED) 158 | self.assertEquals(ret[2], gst.STATE_VOID_PENDING) 159 | 160 | # adding the sink will cause the bin to go in preroll mode 161 | gst.debug('adding sink and setting to PAUSED, should cause preroll') 162 | self.bin.add(sink) 163 | sink.set_state(gst.STATE_PAUSED) 164 | ret = self.bin.get_state(timeout=0) 165 | self.assertEquals(ret[0], gst.STATE_CHANGE_ASYNC) 166 | self.assertEquals(ret[1], gst.STATE_PAUSED) 167 | self.assertEquals(ret[2], gst.STATE_PAUSED) 168 | 169 | # to actually complete preroll, we need to link and re-enable fakesrc 170 | src.set_state(gst.STATE_READY) 171 | src.link(sink) 172 | src.set_state(gst.STATE_PAUSED) 173 | ret = self.bin.get_state() 174 | self.assertEquals(ret[0], gst.STATE_CHANGE_SUCCESS) 175 | self.assertEquals(ret[1], gst.STATE_PAUSED) 176 | self.assertEquals(ret[2], gst.STATE_VOID_PENDING) 177 | 178 | self.bin.set_state(gst.STATE_NULL) 179 | self.bin.get_state() 180 | 181 | class ConstructorTest(TestCase): 182 | def testGood(self): 183 | bin = gst.Bin() 184 | bin = gst.Bin(None) 185 | bin = gst.Bin('') 186 | bin = gst.Bin('myname') 187 | 188 | def testBad(self): 189 | # these are now valid. pygobject will take care of converting 190 | # the arguments to a string. 191 | #self.assertRaises(TypeError, gst.Bin, 0) 192 | #self.assertRaises(TypeError, gst.Bin, gst.Bin()) 193 | pass 194 | 195 | if __name__ == "__main__": 196 | unittest.main() 197 | -------------------------------------------------------------------------------- /testsuite/old/test_buffer.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Lesser General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2.1 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Lesser General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public 20 | # License along with this library; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | import sys 24 | import gc 25 | from common import gobject, gst, unittest, TestCase 26 | 27 | class BufferTest(TestCase): 28 | def testBufferBuffer(self): 29 | buf = gst.Buffer('test') 30 | assert str(buffer(buf)) == 'test' 31 | 32 | def testBufferStr(self): 33 | buffer = gst.Buffer('test') 34 | assert str(buffer) == 'test' 35 | 36 | def testBufferAlloc(self): 37 | bla = 'mooooooo' 38 | buffer = gst.Buffer(bla + '12345') 39 | gc.collect () 40 | assert str(buffer) == 'mooooooo12345' 41 | 42 | def testBufferBadConstructor(self): 43 | self.assertRaises(TypeError, gst.Buffer, 'test', 0) 44 | 45 | def testBufferStrNull(self): 46 | test_string = 't\0e\0s\0t\0' 47 | buffer = gst.Buffer(test_string) 48 | assert str(buffer) == test_string 49 | 50 | def testBufferSize(self): 51 | test_string = 'a little string' 52 | buffer = gst.Buffer(test_string) 53 | assert len(buffer) == len(test_string) 54 | assert hasattr(buffer, 'size') 55 | assert buffer.size == len(buffer) 56 | 57 | def testBufferCreateSub(self): 58 | s = '' 59 | for i in range(64): 60 | s += '%02d' % i 61 | 62 | buffer = gst.Buffer(s) 63 | self.assertEquals(len(buffer), 128) 64 | 65 | sub = buffer.create_sub(16, 16) 66 | self.assertEquals(sub.size, 16) 67 | self.assertEquals(sub.data, buffer.data[16:32]) 68 | self.assertEquals(sub.offset, gst.CLOCK_TIME_NONE) 69 | 70 | def testBufferMerge(self): 71 | buffer1 = gst.Buffer('foo') 72 | buffer2 = gst.Buffer('bar') 73 | 74 | merged_buffer = buffer1.merge(buffer2) 75 | assert str(merged_buffer) == 'foobar' 76 | 77 | def testBufferJoin(self): 78 | buffer1 = gst.Buffer('foo') 79 | buffer2 = gst.Buffer('bar') 80 | 81 | joined_buffer = buffer1.merge(buffer2) 82 | assert str(joined_buffer) == 'foobar' 83 | 84 | def testBufferSpan(self): 85 | buffer1 = gst.Buffer('foo') 86 | buffer2 = gst.Buffer('bar') 87 | 88 | spaned_buffer = buffer1.span(0L, buffer2, 6L) 89 | assert str(spaned_buffer) == 'foobar' 90 | def testBufferCopyOnWrite(self): 91 | s='test_vector' 92 | buffer = gst.Buffer(s) 93 | sub = buffer.create_sub(0, buffer.size) 94 | self.assertEquals(sub.size, buffer.size) 95 | out = sub.copy_on_write () 96 | self.assertEquals(out.size, sub.size) 97 | assert str(out) == str(buffer) 98 | out[5] = 'w' 99 | assert str(out) == 'test_wector' 100 | 101 | def testBufferFlagIsSet(self): 102 | buffer = gst.Buffer() 103 | # Off by default 104 | assert not buffer.flag_is_set(gst.BUFFER_FLAG_READONLY) 105 | 106 | # Try switching on and off 107 | buffer.flag_set(gst.BUFFER_FLAG_READONLY) 108 | assert buffer.flag_is_set(gst.BUFFER_FLAG_READONLY) 109 | buffer.flag_unset(gst.BUFFER_FLAG_READONLY) 110 | assert not buffer.flag_is_set(gst.BUFFER_FLAG_READONLY) 111 | 112 | # Try switching on and off 113 | buffer.flag_set(gst.BUFFER_FLAG_IN_CAPS) 114 | assert buffer.flag_is_set(gst.BUFFER_FLAG_IN_CAPS) 115 | buffer.flag_unset(gst.BUFFER_FLAG_IN_CAPS) 116 | assert not buffer.flag_is_set(gst.BUFFER_FLAG_IN_CAPS) 117 | 118 | def testAttrFlags(self): 119 | buffer = gst.Buffer() 120 | assert hasattr(buffer, "flags") 121 | assert isinstance(buffer.flags, int) 122 | 123 | def testAttrTimestamp(self): 124 | buffer = gst.Buffer() 125 | assert hasattr(buffer, "timestamp") 126 | assert isinstance(buffer.timestamp, long) 127 | 128 | assert buffer.timestamp == gst.CLOCK_TIME_NONE 129 | buffer.timestamp = 0 130 | assert buffer.timestamp == 0 131 | buffer.timestamp = 2**64 - 1 132 | assert buffer.timestamp == 2**64 - 1 133 | 134 | def testAttrDuration(self): 135 | buffer = gst.Buffer() 136 | assert hasattr(buffer, "duration") 137 | assert isinstance(buffer.duration, long) 138 | 139 | assert buffer.duration == gst.CLOCK_TIME_NONE 140 | buffer.duration = 0 141 | assert buffer.duration == 0 142 | buffer.duration = 2**64 - 1 143 | assert buffer.duration == 2**64 - 1 144 | 145 | def testAttrOffset(self): 146 | buffer = gst.Buffer() 147 | assert hasattr(buffer, "offset") 148 | assert isinstance(buffer.offset, long) 149 | 150 | assert buffer.offset == gst.CLOCK_TIME_NONE 151 | buffer.offset = 0 152 | assert buffer.offset == 0 153 | buffer.offset = 2**64 - 1 154 | assert buffer.offset == 2**64 - 1 155 | 156 | def testAttrOffset_end(self): 157 | buffer = gst.Buffer() 158 | assert hasattr(buffer, "offset_end") 159 | assert isinstance(buffer.offset_end, long) 160 | 161 | assert buffer.offset_end == gst.CLOCK_TIME_NONE 162 | buffer.offset_end = 0 163 | assert buffer.offset_end == 0 164 | buffer.offset_end = 2**64 - 1 165 | assert buffer.offset_end == 2**64 - 1 166 | 167 | def testBufferCaps(self): 168 | buffer = gst.Buffer() 169 | caps = gst.caps_from_string('foo/blah') 170 | gst.info("before settings caps") 171 | buffer.set_caps(caps) 172 | gst.info("after settings caps") 173 | c = buffer.get_caps() 174 | gst.info("after getting caps") 175 | self.assertEquals(caps, c) 176 | 177 | if __name__ == "__main__": 178 | unittest.main() 179 | -------------------------------------------------------------------------------- /testsuite/old/test_caps.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Lesser General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2.1 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Lesser General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public 20 | # License along with this library; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | import sys 24 | from common import gst, unittest, TestCase 25 | 26 | class CapsTest(TestCase): 27 | def setUp(self): 28 | TestCase.setUp(self) 29 | self.caps = gst.caps_from_string('video/x-raw-yuv,width=10,framerate=5/1;video/x-raw-rgb,width=15,framerate=10/1') 30 | self.assertEquals(self.caps.__refcount__, 1) 31 | self.structure = self.caps[0] 32 | self.any = gst.Caps("ANY") 33 | self.assertEquals(self.any.__refcount__, 1) 34 | self.empty = gst.Caps() 35 | self.assertEquals(self.empty.__refcount__, 1) 36 | 37 | def testCapsMime(self): 38 | mime = self.structure.get_name() 39 | assert mime == 'video/x-raw-yuv' 40 | 41 | def testCapsList(self): 42 | 'check if we can access Caps as a list' 43 | structure = self.caps[0] 44 | mime = structure.get_name() 45 | assert mime == 'video/x-raw-yuv' 46 | structure = self.caps[1] 47 | mime = structure.get_name() 48 | assert mime == 'video/x-raw-rgb' 49 | 50 | def testCapsContainingMiniObjects(self): 51 | # buffer contains hex encoding of ascii 'abcd' 52 | caps = gst.Caps("video/x-raw-yuv, buf=(buffer)61626364") 53 | buf = caps[0]['buf'] 54 | assert isinstance(buf, gst.Buffer) 55 | assert buf.data == "abcd" 56 | 57 | buf = gst.Buffer("1234") 58 | caps[0]['buf2'] = buf 59 | buf2 = caps[0]['buf2'] 60 | assert buf2 == buf 61 | 62 | def testCapsConstructEmpty(self): 63 | caps = gst.Caps() 64 | assert isinstance(caps, gst.Caps) 65 | 66 | def testCapsConstructFromString(self): 67 | caps = gst.Caps('video/x-raw-yuv,width=10') 68 | assert isinstance(caps, gst.Caps) 69 | assert len(caps) == 1 70 | assert isinstance(caps[0], gst.Structure) 71 | assert caps[0].get_name() == 'video/x-raw-yuv' 72 | assert isinstance(caps[0]['width'], int) 73 | assert caps[0]['width'] == 10 74 | 75 | def testCapsConstructFromStructure(self): 76 | struct = gst.structure_from_string('video/x-raw-yuv,width=10,framerate=[0/1, 25/3]') 77 | caps = gst.Caps(struct) 78 | assert isinstance(caps, gst.Caps) 79 | assert len(caps) == 1 80 | assert isinstance(caps[0], gst.Structure) 81 | assert caps[0].get_name() == 'video/x-raw-yuv' 82 | assert isinstance(caps[0]['width'], int) 83 | assert caps[0]['width'] == 10 84 | assert isinstance(caps[0]['framerate'], gst.FractionRange) 85 | 86 | def testCapsConstructFromStructures(self): 87 | struct1 = gst.structure_from_string('video/x-raw-yuv,width=10') 88 | struct2 = gst.structure_from_string('video/x-raw-rgb,height=20.0') 89 | caps = gst.Caps(struct1, struct2) 90 | assert isinstance(caps, gst.Caps) 91 | assert len(caps) == 2 92 | struct = caps[0] 93 | assert isinstance(struct, gst.Structure), struct 94 | assert struct.get_name() == 'video/x-raw-yuv', struct.get_name() 95 | assert struct.has_key('width') 96 | assert isinstance(struct['width'], int) 97 | assert struct['width'] == 10 98 | struct = caps[1] 99 | assert isinstance(struct, gst.Structure), struct 100 | assert struct.get_name() == 'video/x-raw-rgb', struct.get_name() 101 | assert struct.has_key('height') 102 | assert isinstance(struct['height'], float) 103 | assert struct['height'] == 20.0 104 | 105 | def testCapsReferenceStructs(self): 106 | 'test that shows why it\'s not a good idea to use structures by reference' 107 | caps = gst.Caps('hi/mom,width=0') 108 | structure = caps[0] 109 | del caps 110 | assert structure['width'] == 0 111 | 112 | 113 | def testCapsStructureChange(self): 114 | 'test if changing the structure of the caps works by reference' 115 | assert self.structure['width'] == 10 116 | self.structure['width'] = 5 117 | assert self.structure['width'] == 5.0 118 | # check if we changed the caps as well 119 | structure = self.caps[0] 120 | assert structure['width'] == 5.0 121 | 122 | def testCapsBadConstructor(self): 123 | struct = gst.structure_from_string('video/x-raw-yuv,width=10') 124 | self.assertRaises(TypeError, gst.Caps, None) 125 | self.assertRaises(TypeError, gst.Caps, 1) 126 | self.assertRaises(TypeError, gst.Caps, 2.0) 127 | self.assertRaises(TypeError, gst.Caps, object) 128 | self.assertRaises(TypeError, gst.Caps, 1, 2, 3) 129 | 130 | # This causes segfault! 131 | #self.assertRaises(TypeError, gst.Caps, struct, 10, None) 132 | 133 | def testTrueFalse(self): 134 | 'test that comparisons using caps work the intended way' 135 | assert self.any # not empty even though it has no structures 136 | assert not self.empty 137 | assert not gst.Caps('EMPTY') # also empty 138 | assert gst.Caps('your/mom') 139 | 140 | def testComparisons(self): 141 | assert self.empty < self.any 142 | assert self.empty < self.structure 143 | assert self.empty < self.caps 144 | assert self.caps < self.any 145 | assert self.empty <= self.empty 146 | assert self.caps <= self.caps 147 | assert self.caps <= self.any 148 | assert self.empty == "EMPTY" 149 | assert self.caps != self.any 150 | assert self.empty != self.any 151 | assert self.any > self.empty 152 | assert self.any >= self.empty 153 | 154 | def testFilters(self): 155 | name = 'video/x-raw-yuv' 156 | filtercaps = gst.Caps(*[struct for struct in self.caps if struct.get_name() == name]) 157 | intersection = self.caps & 'video/x-raw-yuv' 158 | assert filtercaps == intersection 159 | 160 | def doSubtract(self, set, subset): 161 | '''mimic the test in GStreamer core's testsuite/caps/subtract.c''' 162 | assert not set - set 163 | assert not subset - subset 164 | assert not subset - set 165 | test = set - subset 166 | assert test 167 | test2 = test | subset 168 | test = test2 - set 169 | assert not test 170 | #our own extensions foolow here 171 | assert subset == set & subset 172 | assert set == set | subset 173 | assert set - subset == set ^ subset 174 | 175 | def testSubtract(self): 176 | self.doSubtract( 177 | gst.Caps ("some/mime, _int = [ 1, 2 ], list = { \"A\", \"B\", \"C\" }"), 178 | gst.Caps ("some/mime, _int = 1, list = \"A\"")) 179 | self.doSubtract( 180 | gst.Caps ("some/mime, _double = (double) 1.0; other/mime, _int = { 1, 2 }"), 181 | gst.Caps ("some/mime, _double = (double) 1.0")) 182 | 183 | def testNoneValue(self): 184 | caps = gst.Caps("foo") 185 | 186 | def invalid_assignment(): 187 | caps[0]["bar"] = None 188 | self.assertRaises(TypeError, invalid_assignment) 189 | 190 | def invalid_set_value(): 191 | caps[0].set_value("bar", None) 192 | self.assertRaises(TypeError, invalid_set_value) 193 | 194 | 195 | if __name__ == "__main__": 196 | unittest.main() 197 | -------------------------------------------------------------------------------- /testsuite/old/test_event.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Lesser General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2.1 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Lesser General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public 20 | # License along with this library; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | import os 24 | import sys 25 | import time 26 | import tempfile 27 | 28 | from common import gst, unittest, testhelper, TestCase 29 | 30 | class EventTest(TestCase): 31 | def setUp(self): 32 | TestCase.setUp(self) 33 | self.pipeline = gst.parse_launch('fakesrc ! fakesink name=sink') 34 | self.sink = self.pipeline.get_by_name('sink') 35 | self.pipeline.set_state(gst.STATE_PLAYING) 36 | 37 | def tearDown(self): 38 | gst.debug('setting pipeline to NULL') 39 | self.pipeline.set_state(gst.STATE_NULL) 40 | gst.debug('set pipeline to NULL') 41 | # FIXME: wait for state change thread to die 42 | while self.pipeline.__gstrefcount__ > 1: 43 | gst.debug('waiting for self.pipeline G rc to drop to 1') 44 | time.sleep(0.1) 45 | self.assertEquals(self.pipeline.__gstrefcount__, 1) 46 | 47 | del self.sink 48 | del self.pipeline 49 | TestCase.tearDown(self) 50 | 51 | def testEventSeek(self): 52 | # this event only serves to change the rate of data transfer 53 | event = gst.event_new_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH, 54 | gst.SEEK_TYPE_NONE, 0, gst.SEEK_TYPE_NONE, 0) 55 | # FIXME: but basesrc goes into an mmap/munmap spree, needs to be fixed 56 | 57 | event = gst.event_new_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH, 58 | gst.SEEK_TYPE_SET, 0, gst.SEEK_TYPE_NONE, 0) 59 | assert event 60 | gst.debug('sending event') 61 | self.sink.send_event(event) 62 | gst.debug('sent event') 63 | 64 | self.assertEqual(event.parse_seek(), (1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH, 65 | gst.SEEK_TYPE_SET, 0, gst.SEEK_TYPE_NONE, 0)) 66 | 67 | def testWrongEvent(self): 68 | buffer = gst.Buffer() 69 | self.assertRaises(TypeError, self.sink.send_event, buffer) 70 | number = 1 71 | self.assertRaises(TypeError, self.sink.send_event, number) 72 | 73 | 74 | class EventFileSrcTest(TestCase): 75 | 76 | def setUp(self): 77 | TestCase.setUp(self) 78 | gst.info("start") 79 | self.filename = tempfile.mktemp() 80 | open(self.filename, 'w').write(''.join(map(str, range(10)))) 81 | 82 | self.pipeline = gst.parse_launch('filesrc name=source location=%s blocksize=1 ! fakesink signal-handoffs=1 name=sink' % self.filename) 83 | self.source = self.pipeline.get_by_name('source') 84 | self.sink = self.pipeline.get_by_name('sink') 85 | self.sigid = self.sink.connect('handoff', self.handoff_cb) 86 | self.bus = self.pipeline.get_bus() 87 | 88 | def tearDown(self): 89 | self.pipeline.set_state(gst.STATE_NULL) 90 | self.sink.disconnect(self.sigid) 91 | if os.path.exists(self.filename): 92 | os.remove(self.filename) 93 | del self.bus 94 | del self.pipeline 95 | del self.source 96 | del self.sink 97 | del self.handoffs 98 | TestCase.tearDown(self) 99 | 100 | def handoff_cb(self, element, buffer, pad): 101 | self.handoffs.append(str(buffer)) 102 | 103 | def playAndIter(self): 104 | self.handoffs = [] 105 | self.pipeline.set_state(gst.STATE_PLAYING) 106 | assert self.pipeline.set_state(gst.STATE_PLAYING) 107 | while 42: 108 | msg = self.bus.pop() 109 | if msg and msg.type == gst.MESSAGE_EOS: 110 | break 111 | assert self.pipeline.set_state(gst.STATE_PAUSED) 112 | handoffs = self.handoffs 113 | self.handoffs = [] 114 | return handoffs 115 | 116 | def sink_seek(self, offset, method=gst.SEEK_TYPE_SET): 117 | self.sink.seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_FLUSH, 118 | method, offset, 119 | gst.SEEK_TYPE_NONE, 0) 120 | 121 | def testSimple(self): 122 | handoffs = self.playAndIter() 123 | assert handoffs == map(str, range(10)) 124 | 125 | def testSeekCur(self): 126 | self.sink_seek(8) 127 | self.playAndIter() 128 | 129 | class TestEmit(TestCase): 130 | def testEmit(self): 131 | object = testhelper.get_object() 132 | object.connect('event', self._event_cb) 133 | 134 | # First emit from C 135 | testhelper.emit_event(object) 136 | 137 | # Then emit from Python 138 | object.emit('event', gst.event_new_eos()) 139 | 140 | def _event_cb(self, obj, event): 141 | assert isinstance(event, gst.Event) 142 | 143 | 144 | class TestDelayedEventProbe(TestCase): 145 | # this test: 146 | # starts a pipeline with only a source 147 | # adds an event probe to catch the (first) new-segment 148 | # adds a buffer probe to "autoplug" and send out this event 149 | def setUp(self): 150 | TestCase.setUp(self) 151 | self.pipeline = gst.Pipeline() 152 | self.src = gst.element_factory_make('fakesrc') 153 | self.src.set_property('num-buffers', 10) 154 | self.pipeline.add(self.src) 155 | self.srcpad = self.src.get_pad('src') 156 | 157 | def tearDown(self): 158 | gst.debug('setting pipeline to NULL') 159 | self.pipeline.set_state(gst.STATE_NULL) 160 | gst.debug('set pipeline to NULL') 161 | # FIXME: wait for state change thread to die 162 | while self.pipeline.__gstrefcount__ > 1: 163 | gst.debug('waiting for self.pipeline G rc to drop to 1') 164 | time.sleep(0.1) 165 | self.assertEquals(self.pipeline.__gstrefcount__, 1) 166 | 167 | def testProbe(self): 168 | self.srcpad.add_event_probe(self._event_probe_cb) 169 | self._buffer_probe_id = self.srcpad.add_buffer_probe( 170 | self._buffer_probe_cb) 171 | 172 | self._newsegment = None 173 | self._eos = None 174 | self._had_buffer = False 175 | 176 | self.pipeline.set_state(gst.STATE_PLAYING) 177 | 178 | while not self._eos: 179 | time.sleep(0.1) 180 | 181 | # verify if our newsegment event is still around and valid 182 | self.failUnless(self._newsegment) 183 | self.assertEquals(self._newsegment.type, gst.EVENT_NEWSEGMENT) 184 | self.assertEquals(self._newsegment.__grefcount__, 1) 185 | 186 | # verify if our eos event is still around and valid 187 | self.failUnless(self._eos) 188 | self.assertEquals(self._eos.type, gst.EVENT_EOS) 189 | self.assertEquals(self._eos.__grefcount__, 1) 190 | 191 | def _event_probe_cb(self, pad, event): 192 | if event.type == gst.EVENT_NEWSEGMENT: 193 | self._newsegment = event 194 | self.assertEquals(event.__grefcount__, 3) 195 | # drop the event, we're storing it for later sending 196 | return False 197 | 198 | if event.type == gst.EVENT_EOS: 199 | self._eos = event 200 | # we also want fakesink to get it 201 | return True 202 | 203 | # sinks now send Latency events upstream 204 | if event.type == gst.EVENT_LATENCY: 205 | return True 206 | 207 | self.fail("Got an unknown event %r" % event) 208 | 209 | def _buffer_probe_cb(self, pad, buffer): 210 | self.failUnless(self._newsegment) 211 | 212 | # fake autoplugging by now putting in a fakesink 213 | sink = gst.element_factory_make('fakesink') 214 | self.pipeline.add(sink) 215 | self.src.link(sink) 216 | sink.set_state(gst.STATE_PLAYING) 217 | 218 | pad = sink.get_pad('sink') 219 | pad.send_event(self._newsegment) 220 | 221 | # we don't want to be called again 222 | self.srcpad.remove_buffer_probe(self._buffer_probe_id) 223 | 224 | self._had_buffer = True 225 | # now let the buffer through 226 | return True 227 | 228 | class TestEventCreationParsing(TestCase): 229 | 230 | def testEventStep(self): 231 | if hasattr(gst.Event, "parse_step"): 232 | e = gst.event_new_step(gst.FORMAT_TIME, 42, 1.0, True, True) 233 | 234 | self.assertEquals(e.type, gst.EVENT_STEP) 235 | 236 | fmt, amount, rate, flush, intermediate = e.parse_step() 237 | self.assertEquals(fmt, gst.FORMAT_TIME) 238 | self.assertEquals(amount, 42) 239 | self.assertEquals(rate, 1.0) 240 | self.assertEquals(flush, True) 241 | self.assertEquals(intermediate, True) 242 | 243 | if __name__ == "__main__": 244 | unittest.main() 245 | -------------------------------------------------------------------------------- /testsuite/old/test_ghostpad.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Lesser General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2.1 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Lesser General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public 20 | # License along with this library; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | from common import gst, unittest, TestCase, pygobject_2_13 24 | 25 | import sys 26 | import gc 27 | import gobject 28 | 29 | class SrcBin(gst.Bin): 30 | def prepare(self): 31 | src = gst.element_factory_make('fakesrc') 32 | self.add(src) 33 | pad = src.get_pad("src") 34 | ghostpad = gst.GhostPad("src", pad) 35 | self.add_pad(ghostpad) 36 | gobject.type_register(SrcBin) 37 | 38 | class SinkBin(gst.Bin): 39 | def prepare(self): 40 | sink = gst.element_factory_make('fakesink') 41 | self.add(sink) 42 | pad = sink.get_pad("sink") 43 | ghostpad = gst.GhostPad("sink", pad) 44 | self.add_pad(ghostpad) 45 | self.sink = sink 46 | 47 | def connect_handoff(self, cb, *args, **kwargs): 48 | self.sink.set_property('signal-handoffs', True) 49 | self.sink.connect('handoff', cb, *args, **kwargs) 50 | 51 | gobject.type_register(SinkBin) 52 | 53 | 54 | class PipeTest(TestCase): 55 | def setUp(self): 56 | gst.info("setUp") 57 | TestCase.setUp(self) 58 | self.pipeline = gst.Pipeline() 59 | self.assertEquals(self.pipeline.__gstrefcount__, 1) 60 | self.assertEquals(sys.getrefcount(self.pipeline), pygobject_2_13 and 2 or 3) 61 | 62 | self.src = SrcBin() 63 | self.src.prepare() 64 | self.sink = SinkBin() 65 | self.sink.prepare() 66 | self.assertEquals(self.src.__gstrefcount__, 1) 67 | self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3) 68 | self.assertEquals(self.sink.__gstrefcount__, 1) 69 | self.assertEquals(sys.getrefcount(self.sink), pygobject_2_13 and 2 or 3) 70 | gst.info("end of SetUp") 71 | 72 | def tearDown(self): 73 | gst.info("tearDown") 74 | self.assertTrue (self.pipeline.__gstrefcount__ >= 1 and self.pipeline.__gstrefcount__ <= 2) 75 | self.assertEquals(sys.getrefcount(self.pipeline), pygobject_2_13 and 2 or 3) 76 | self.assertEquals(self.src.__gstrefcount__, 2) 77 | self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3) 78 | self.assertEquals(self.sink.__gstrefcount__, 2) 79 | self.assertEquals(sys.getrefcount(self.sink), 3) 80 | gst.debug('deleting pipeline') 81 | del self.pipeline 82 | self.gccollect() 83 | 84 | self.assertEquals(self.src.__gstrefcount__, 1) # parent gone 85 | self.assertEquals(self.sink.__gstrefcount__, 1) # parent gone 86 | self.assertEquals(sys.getrefcount(self.src), pygobject_2_13 and 2 or 3) 87 | self.assertEquals(sys.getrefcount(self.sink), pygobject_2_13 and 2 or 3) 88 | gst.debug('deleting src') 89 | del self.src 90 | self.gccollect() 91 | gst.debug('deleting sink') 92 | del self.sink 93 | self.gccollect() 94 | 95 | TestCase.tearDown(self) 96 | 97 | def testBinState(self): 98 | self.pipeline.add(self.src, self.sink) 99 | self.src.link(self.sink) 100 | self.sink.connect_handoff(self._sink_handoff_cb) 101 | self._handoffs = 0 102 | 103 | self.assertTrue(self.pipeline.set_state(gst.STATE_PLAYING) != gst.STATE_CHANGE_FAILURE) 104 | while True: 105 | (ret, cur, pen) = self.pipeline.get_state() 106 | if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_PLAYING: 107 | break 108 | 109 | while self._handoffs < 10: 110 | pass 111 | 112 | self.assertEquals(self.pipeline.set_state(gst.STATE_NULL), gst.STATE_CHANGE_SUCCESS) 113 | while True: 114 | (ret, cur, pen) = self.pipeline.get_state() 115 | if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_NULL: 116 | break 117 | 118 | ## def testProbedLink(self): 119 | ## self.pipeline.add(self.src) 120 | ## pad = self.src.get_pad("src") 121 | 122 | ## self.sink.connect_handoff(self._sink_handoff_cb) 123 | ## self._handoffs = 0 124 | 125 | ## # FIXME: adding a probe to the ghost pad does not work atm 126 | ## # id = pad.add_buffer_probe(self._src_buffer_probe_cb) 127 | ## realpad = pad.get_target() 128 | ## self._probe_id = realpad.add_buffer_probe(self._src_buffer_probe_cb) 129 | 130 | ## self._probed = False 131 | 132 | ## while True: 133 | ## (ret, cur, pen) = self.pipeline.get_state() 134 | ## if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_PLAYING: 135 | ## break 136 | 137 | ## while not self._probed: 138 | ## pass 139 | 140 | ## while self._handoffs < 10: 141 | ## pass 142 | 143 | ## self.pipeline.set_state(gst.STATE_NULL) 144 | ## while True: 145 | ## (ret, cur, pen) = self.pipeline.get_state() 146 | ## if ret == gst.STATE_CHANGE_SUCCESS and cur == gst.STATE_NULL: 147 | ## break 148 | 149 | def _src_buffer_probe_cb(self, pad, buffer): 150 | gst.debug("received probe on pad %r" % pad) 151 | self._probed = True 152 | gst.debug('adding sink bin') 153 | self.pipeline.add(self.sink) 154 | # this seems to get rid of the warnings about pushing on an unactivated 155 | # pad 156 | gst.debug('setting sink state') 157 | 158 | # FIXME: attempt one: sync to current pending state of bin 159 | (res, cur, pen) = self.pipeline.get_state(timeout=0) 160 | target = pen 161 | if target == gst.STATE_VOID_PENDING: 162 | target = cur 163 | gst.debug("setting sink state to %r" % target) 164 | # FIXME: the following print can cause a lock-up; why ? 165 | # print target 166 | # if we don't set async, it will possibly end up in PAUSED 167 | self.sink.set_state(target) 168 | 169 | gst.debug('linking') 170 | self.src.link(self.sink) 171 | gst.debug('removing buffer probe id %r' % self._probe_id) 172 | pad.remove_buffer_probe(self._probe_id) 173 | self._probe_id = None 174 | gst.debug('done') 175 | 176 | def _sink_handoff_cb(self, sink, buffer, pad): 177 | gst.debug('received handoff on pad %r' % pad) 178 | self._handoffs += 1 179 | 180 | class TargetTest(TestCase): 181 | def test_target(self): 182 | src = gst.Pad("src", gst.PAD_SRC) 183 | 184 | ghost = gst.GhostPad("ghost_src", src) 185 | self.failUnless(ghost.get_target() is src) 186 | 187 | ghost.set_target(None) 188 | self.failUnless(ghost.get_target() is None) 189 | 190 | ghost.set_target(src) 191 | self.failUnless(ghost.get_target() is src) 192 | 193 | if __name__ == "__main__": 194 | unittest.main() 195 | -------------------------------------------------------------------------------- /testsuite/old/test_interface.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Lesser General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2.1 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Lesser General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public 20 | # License along with this library; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | from common import gst, unittest, TestCase 24 | 25 | import gobject 26 | 27 | def find_mixer_element(): 28 | """ Searches for an element implementing the mixer interface """ 29 | allmix = [x for x in gst.registry_get_default().get_feature_list(gst.ElementFactory) 30 | if x.has_interface("GstMixer") and x.has_interface("GstPropertyProbe")] 31 | if allmix == []: 32 | return None 33 | return allmix[0] 34 | 35 | class Availability(TestCase): 36 | def testXOverlay(self): 37 | assert hasattr(gst.interfaces, 'XOverlay') 38 | assert issubclass(gst.interfaces.XOverlay, gobject.GInterface) 39 | 40 | def testMixer(self): 41 | assert hasattr(gst.interfaces, 'Mixer') 42 | assert issubclass(gst.interfaces.Mixer, gobject.GInterface) 43 | 44 | class FunctionCall(TestCase): 45 | def FIXME_testXOverlay(self): 46 | # obviously a testsuite is not allowed to instantiate this 47 | # since it needs a running X or will fail. find some way to 48 | # deal with that. 49 | element = gst.element_factory_make('xvimagesink') 50 | assert isinstance(element, gst.Element) 51 | assert isinstance(element, gst.interfaces.XOverlay) 52 | element.set_xwindow_id(0L) 53 | 54 | class MixerTest(TestCase): 55 | def setUp(self): 56 | TestCase.setUp(self) 57 | amix = find_mixer_element() 58 | if amix: 59 | self.mixer = amix.create() 60 | else: 61 | self.mixer = None 62 | 63 | def tearDown(self): 64 | del self.mixer 65 | TestCase.tearDown(self) 66 | 67 | def testGetProperty(self): 68 | if self.mixer == None: 69 | return 70 | self.failUnless(self.mixer.probe_get_property('device')) 71 | self.assertRaises(ValueError, 72 | self.mixer.probe_get_property, 'non-existent') 73 | 74 | def testGetProperties(self): 75 | if self.mixer == None: 76 | return 77 | properties = self.mixer.probe_get_properties() 78 | self.failUnless(properties) 79 | self.assertEqual(type(properties), list) 80 | prop = properties[0] 81 | self.assertEqual(prop.name, 'device') 82 | self.assertEqual(prop.value_type, gobject.TYPE_STRING) 83 | 84 | def testGetValuesName(self): 85 | if self.mixer == None: 86 | return 87 | values = self.mixer.probe_get_values_name('device') 88 | self.assertEqual(type(values), list) 89 | 90 | 91 | if __name__ == "__main__": 92 | unittest.main() 93 | -------------------------------------------------------------------------------- /testsuite/old/test_iterator.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # Copyright (C) 2005 Johan Dahlin 5 | # 6 | # This library is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU Lesser General Public 8 | # License as published by the Free Software Foundation; either 9 | # version 2.1 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 | # Lesser General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this library; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | import unittest 21 | from common import gst, TestCase 22 | 23 | class IteratorTest(TestCase): 24 | # XXX: Elements 25 | def testBinIterateElements(self): 26 | pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink") 27 | elements = list(pipeline.elements()) 28 | fakesrc = pipeline.get_by_name("src") 29 | fakesink = pipeline.get_by_name("sink") 30 | 31 | self.assertEqual(len(elements), 2) 32 | self.failUnless(fakesrc in elements) 33 | self.failUnless(fakesink in elements) 34 | 35 | pipeline.remove(fakesrc) 36 | elements = list(pipeline.elements()) 37 | 38 | self.assertEqual(len(elements), 1) 39 | self.failUnless(not fakesrc in pipeline) 40 | 41 | # XXX : There seems to be a problem about the GType 42 | # set in gst_bin_iterated_sorted 43 | 44 | def testBinIterateSorted(self): 45 | pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink") 46 | elements = list(pipeline.sorted()) 47 | fakesrc = pipeline.get_by_name("src") 48 | fakesink = pipeline.get_by_name("sink") 49 | 50 | self.assertEqual(elements[0], fakesink) 51 | self.assertEqual(elements[1], fakesrc) 52 | 53 | def testBinIterateRecurse(self): 54 | pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink") 55 | elements = list(pipeline.recurse()) 56 | fakesrc = pipeline.get_by_name("src") 57 | fakesink = pipeline.get_by_name("sink") 58 | 59 | self.assertEqual(elements[0], fakesink) 60 | self.assertEqual(elements[1], fakesrc) 61 | 62 | def testBinIterateSinks(self): 63 | pipeline = gst.parse_launch("fakesrc name=src ! fakesink name=sink") 64 | elements = list(pipeline.sinks()) 65 | fakesrc = pipeline.get_by_name("src") 66 | fakesink = pipeline.get_by_name("sink") 67 | 68 | self.assertEqual(len(elements), 1) 69 | self.failUnless(fakesink in elements) 70 | self.failUnless(not fakesrc in elements) 71 | 72 | 73 | def testIteratePadsFakeSrc(self): 74 | fakesrc = gst.element_factory_make('fakesrc') 75 | pads = list(fakesrc.pads()) 76 | srcpad = fakesrc.get_pad('src') 77 | self.assertEqual(len(pads), 1) 78 | self.assertEqual(pads[0], srcpad) 79 | srcpads = list(fakesrc.src_pads()) 80 | self.assertEqual(len(srcpads), 1) 81 | self.assertEqual(srcpads[0], srcpad) 82 | sinkpads = list(fakesrc.sink_pads()) 83 | self.assertEqual(sinkpads, []) 84 | 85 | self.assertEqual(len(list(fakesrc)), 1) 86 | for pad in fakesrc: 87 | self.assertEqual(pad, srcpad) 88 | break 89 | else: 90 | raise AssertionError 91 | 92 | def testIteratePadsFakeSink(self): 93 | fakesink = gst.element_factory_make('fakesink') 94 | pads = list(fakesink.pads()) 95 | sinkpad = fakesink.get_pad('sink') 96 | self.assertEqual(len(pads), 1) 97 | self.assertEqual(pads[0], sinkpad) 98 | srcpads = list(fakesink.src_pads()) 99 | self.assertEqual(srcpads, []) 100 | sinkpads = list(fakesink.sink_pads()) 101 | self.assertEqual(len(sinkpads), 1) 102 | self.assertEqual(sinkpads[0], sinkpad) 103 | 104 | self.assertEqual(len(list(fakesink)), 1) 105 | for pad in fakesink: 106 | self.assertEqual(pad, sinkpad) 107 | break 108 | else: 109 | raise AssertionError 110 | 111 | def testInvalidIterator(self): 112 | p = gst.Pad("p", gst.PAD_SRC) 113 | # The C function will return NULL, we should 114 | # therefore have an exception raised 115 | self.assertRaises(TypeError, p.iterate_internal_links) 116 | del p 117 | 118 | -------------------------------------------------------------------------------- /testsuite/old/test_libtag.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2010 Thiago Santos 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | from common import gst, TestCase 22 | from gst import tag 23 | 24 | class TesLibTag(TestCase): 25 | def testXmp(self): 26 | taglist = gst.TagList() 27 | taglist['title'] = 'my funny title' 28 | taglist['geo-location-latitude'] = 23.25 29 | 30 | xmp = tag.tag_list_to_xmp_buffer (taglist, True) 31 | self.assertNotEquals(xmp, None) 32 | taglist2 = tag.tag_list_from_xmp_buffer (xmp) 33 | 34 | self.assertEquals(len(taglist2), 2) 35 | self.assertEquals(taglist2['title'], 'my funny title') 36 | self.assertEquals(taglist2['geo-location-latitude'], 23.25) 37 | 38 | -------------------------------------------------------------------------------- /testsuite/old/test_message.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2005 Thomas Vander Stichele 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | import sys 22 | from common import gobject, gst, unittest, TestCase 23 | import gc 24 | 25 | class NewTest(TestCase): 26 | def testEOS(self): 27 | gst.info("creating new bin") 28 | b = gst.Bin() 29 | gst.info("creating new EOS message from that bin") 30 | m = gst.message_new_eos(b) 31 | gst.info("got message : %s" % m) 32 | 33 | def message_application_cb(self, bus, message): 34 | gst.info("got application message") 35 | self.got_message = True 36 | self.loop.quit() 37 | 38 | def testApplication(self): 39 | self.loop = gobject.MainLoop() 40 | gst.info("creating new pipeline") 41 | bin = gst.Pipeline() 42 | bus = bin.get_bus() 43 | bus.add_signal_watch() 44 | self.got_message = False 45 | bus.connect('message::application', self.message_application_cb) 46 | 47 | struc = gst.Structure("foo") 48 | msg = gst.message_new_application(bin, struc) 49 | # the bus is flushing in NULL, so we need to set the pipeline to READY 50 | bin.set_state(gst.STATE_READY) 51 | bus.post(msg) 52 | self.loop.run() 53 | bus.remove_signal_watch() 54 | bin.set_state(gst.STATE_NULL) 55 | self.failUnless(self.got_message == True) 56 | self.gccollect() 57 | 58 | class TestCreateMessages(TestCase): 59 | 60 | def setUp(self): 61 | TestCase.setUp(self) 62 | self.element = gst.Bin() 63 | 64 | def tearDown(self): 65 | del self.element 66 | 67 | def testCustomMessage(self): 68 | # create two custom messages using the same structure 69 | s = gst.Structure("something") 70 | assert s != None 71 | e1 = gst.message_new_custom(gst.MESSAGE_APPLICATION, self.element, s) 72 | assert e1 73 | e2 = gst.message_new_custom(gst.MESSAGE_APPLICATION, self.element, s) 74 | assert e2 75 | 76 | # make sure the two structures are equal 77 | self.assertEquals(e1.structure.to_string(), 78 | e2.structure.to_string()) 79 | 80 | def testTagMessage(self): 81 | # Create a taglist 82 | t = gst.TagList() 83 | t['something'] = "else" 84 | t['another'] = 42 85 | 86 | # Create two messages using that same taglist 87 | m1 = gst.message_new_tag(self.element, t) 88 | assert m1 89 | m2 = gst.message_new_tag(self.element, t) 90 | assert m2 91 | 92 | # make sure the two messages have the same taglist 93 | t1 = m1.parse_tag() 94 | assert t1 95 | keys = t1.keys() 96 | keys.sort() 97 | self.assertEquals(keys, ['another', 'something']) 98 | self.assertEquals(t1['something'], "else") 99 | self.assertEquals(t1['another'], 42) 100 | t2 = m2.parse_tag() 101 | assert t2 102 | keys = t2.keys() 103 | keys.sort() 104 | self.assertEquals(keys, ['another', 'something']) 105 | self.assertEquals(t2['something'], "else") 106 | self.assertEquals(t2['another'], 42) 107 | 108 | def testTagFullMessage(self): 109 | if hasattr(gst.Message, 'parse_tag_full'): 110 | p = gst.Pad("blahblah", gst.PAD_SRC) 111 | # Create a taglist 112 | t = gst.TagList() 113 | t['something'] = "else" 114 | t['another'] = 42 115 | 116 | # Create two messages using that same taglist 117 | m1 = gst.message_new_tag_full(self.element, p, t) 118 | assert m1 119 | m2 = gst.message_new_tag_full(self.element, p, t) 120 | assert m2 121 | 122 | # make sure the two messages have the same taglist 123 | p1, t1 = m1.parse_tag_full() 124 | assert t1 125 | keys = t1.keys() 126 | keys.sort() 127 | self.assertEquals(p1, p) 128 | self.assertEquals(keys, ['another', 'something']) 129 | self.assertEquals(t1['something'], "else") 130 | self.assertEquals(t1['another'], 42) 131 | p2, t2 = m2.parse_tag_full() 132 | assert t2 133 | keys = t2.keys() 134 | keys.sort() 135 | self.assertEquals(p2, p) 136 | self.assertEquals(keys, ['another', 'something']) 137 | self.assertEquals(t2['something'], "else") 138 | self.assertEquals(t2['another'], 42) 139 | 140 | def testStepStartMessage(self): 141 | if hasattr(gst, 'message_new_step_start'): 142 | m = gst.message_new_step_start(self.element, True, 143 | gst.FORMAT_TIME, 42, 1.0, 144 | True, True) 145 | self.assertEquals(m.type, gst.MESSAGE_STEP_START) 146 | active, format, amount, rate, flush, intermediate = m.parse_step_start() 147 | self.assertEquals(active, True) 148 | self.assertEquals(format, gst.FORMAT_TIME) 149 | self.assertEquals(amount, 42) 150 | self.assertEquals(rate, 1.0) 151 | self.assertEquals(flush, True) 152 | self.assertEquals(intermediate, True) 153 | 154 | def testStepDoneMessage(self): 155 | if hasattr(gst, 'message_new_step_done'): 156 | m = gst.message_new_step_done(self.element, gst.FORMAT_TIME, 42, 157 | 1.0, True, True, 54, True) 158 | self.assertEquals(m.type, gst.MESSAGE_STEP_DONE) 159 | 160 | fmt, am, rat, flu, inter, dur, eos = m.parse_step_done() 161 | self.assertEquals(fmt, gst.FORMAT_TIME) 162 | self.assertEquals(am, 42) 163 | self.assertEquals(rat, 1.0) 164 | self.assertEquals(flu, True) 165 | self.assertEquals(inter, True) 166 | self.assertEquals(dur, 54) 167 | self.assertEquals(eos, True) 168 | 169 | def testStructureChangeMessage(self): 170 | if hasattr(gst, 'message_new_structure_change'): 171 | p = gst.Pad("blah", gst.PAD_SINK) 172 | m = gst.message_new_structure_change(p, 173 | gst.STRUCTURE_CHANGE_TYPE_PAD_LINK, 174 | self.element, True) 175 | 176 | self.assertEquals(m.type, gst.MESSAGE_STRUCTURE_CHANGE) 177 | sct, owner, busy = m.parse_structure_change() 178 | self.assertEquals(sct, gst.STRUCTURE_CHANGE_TYPE_PAD_LINK) 179 | self.assertEquals(owner, self.element) 180 | self.assertEquals(busy, True) 181 | 182 | def testRequestStateMessage(self): 183 | if hasattr(gst, 'message_new_request_state'): 184 | m = gst.message_new_request_state(self.element, gst.STATE_NULL) 185 | self.assertEquals(m.type, gst.MESSAGE_REQUEST_STATE) 186 | self.assertEquals(m.parse_request_state(), gst.STATE_NULL) 187 | 188 | def testBufferingStatsMessage(self): 189 | if hasattr(gst.Message, 'set_buffering_stats'): 190 | gst.debug("Creating buffering message") 191 | m = gst.message_new_buffering(self.element, 50) 192 | gst.debug("Setting stats") 193 | m.set_buffering_stats(gst.BUFFERING_LIVE, 30, 1024, 123456) 194 | self.assertEquals(m.type, gst.MESSAGE_BUFFERING) 195 | mode, ain, aout, left = m.parse_buffering_stats() 196 | self.assertEquals(mode, gst.BUFFERING_LIVE) 197 | self.assertEquals(ain, 30) 198 | self.assertEquals(aout, 1024) 199 | self.assertEquals(left, 123456) 200 | 201 | if __name__ == "__main__": 202 | unittest.main() 203 | -------------------------------------------------------------------------------- /testsuite/old/test_pbutils.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2008 Edward Hervey 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | from common import gobject, gst, unittest, TestCase 22 | 23 | class Descriptions(TestCase): 24 | 25 | def testSourceDescription(self): 26 | assert hasattr(gst.pbutils, 'get_source_description') 27 | self.assertEquals(gst.pbutils.get_source_description("file"), 28 | "FILE protocol source") 29 | 30 | def testSinkDescription(self): 31 | assert hasattr(gst.pbutils, 'get_sink_description') 32 | self.assertEquals(gst.pbutils.get_sink_description("file"), 33 | "FILE protocol sink") 34 | 35 | def testDecoderDescription(self): 36 | assert hasattr(gst.pbutils, 'get_decoder_description') 37 | self.assertEquals(gst.pbutils.get_decoder_description(gst.caps_from_string("audio/mpeg,mpegversion=1,layer=3")), 38 | 'MPEG-1 Layer 3 (MP3) decoder') 39 | 40 | def testCodecDescription(self): 41 | assert hasattr(gst.pbutils, 'get_codec_description') 42 | self.assertEquals(gst.pbutils.get_codec_description(gst.caps_from_string("audio/mpeg,mpegversion=1,layer=3")), 43 | 'MPEG-1 Layer 3 (MP3)') 44 | 45 | def testEncoderDescription(self): 46 | assert hasattr(gst.pbutils, 'get_encoder_description') 47 | self.assertEquals(gst.pbutils.get_encoder_description(gst.caps_from_string("audio/mpeg,mpegversion=1,layer=3")), 48 | 'MPEG-1 Layer 3 (MP3) encoder') 49 | 50 | def testElementDescription(self): 51 | assert hasattr(gst.pbutils, 'get_element_description') 52 | self.assertEquals(gst.pbutils.get_element_description("something"), 53 | "GStreamer element something") 54 | 55 | def testAddCodecDescription(self): 56 | assert hasattr(gst.pbutils, 'add_codec_description_to_tag_list') 57 | 58 | # TODO 59 | # Add tests for the other parts of pbutils: 60 | # * missing-plugins 61 | # * install-plugins (and detect if there weren't compiled because of a version 62 | # of plugins-base too low) 63 | 64 | -------------------------------------------------------------------------------- /testsuite/old/test_registry.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Lesser General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2.1 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Lesser General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public 20 | # License along with this library; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | import sys 24 | import gc 25 | from common import gst, unittest, TestCase 26 | 27 | class RegistryTest(TestCase): 28 | def setUp(self): 29 | self.registry = gst.registry_get_default() 30 | self.plugins = self.registry.get_plugin_list() 31 | TestCase.setUp(self) 32 | 33 | def testGetDefault(self): 34 | assert(self.registry) 35 | 36 | def testPluginList(self): 37 | names = map(lambda p: p.get_name(), self.plugins) 38 | self.failUnless('staticelements' in names) 39 | 40 | def testGetPathList(self): 41 | # FIXME: this returns an empty list; probably due to core; 42 | # examine problem 43 | 44 | paths = self.registry.get_path_list() 45 | 46 | class RegistryFeatureTest(TestCase): 47 | def setUp(self): 48 | self.registry = gst.registry_get_default() 49 | self.plugins = self.registry.get_plugin_list() 50 | self.efeatures = self.registry.get_feature_list(gst.TYPE_ELEMENT_FACTORY) 51 | self.tfeatures = self.registry.get_feature_list(gst.TYPE_TYPE_FIND_FACTORY) 52 | self.ifeatures = self.registry.get_feature_list(gst.TYPE_INDEX_FACTORY) 53 | TestCase.setUp(self) 54 | 55 | def testFeatureList(self): 56 | self.assertRaises(TypeError, self.registry.get_feature_list, "kaka") 57 | 58 | elements = map(lambda f: f.get_name(), self.efeatures) 59 | self.failUnless('fakesink' in elements) 60 | 61 | typefinds = map(lambda f: f.get_name(), self.tfeatures) 62 | 63 | indexers = map(lambda f: f.get_name(), self.ifeatures) 64 | self.failUnless('memindex' in indexers) 65 | 66 | 67 | if __name__ == "__main__": 68 | unittest.main() 69 | -------------------------------------------------------------------------------- /testsuite/old/test_segment.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2006 Edward Hervey 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | from common import gst, unittest, TestCase 22 | 23 | class SegmentTest(TestCase): 24 | def testSeekNoSize(self): 25 | segment = gst.Segment() 26 | segment.init(gst.FORMAT_BYTES) 27 | 28 | # configure segment to start at 100 with no defined stop position 29 | update = segment.set_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_NONE, 30 | gst.SEEK_TYPE_SET, 100, 31 | gst.SEEK_TYPE_NONE, -1) 32 | self.assertEquals(update, True) 33 | self.assertEquals(segment.start, 100) 34 | self.assertEquals(segment.stop, -1) 35 | 36 | # configure segment to stop relative, should not do anything since 37 | # size is unknown 38 | update = segment.set_seek(1.0, gst.FORMAT_BYTES, gst.SEEK_FLAG_NONE, 39 | gst.SEEK_TYPE_NONE, 200, 40 | gst.SEEK_TYPE_CUR, -100) 41 | 42 | # the update flag is deprecated, we cannot check for proper behaviour. 43 | #self.assertEquals(update, False) 44 | self.assertEquals(segment.start, 100) 45 | self.assertEquals(segment.stop, -1) 46 | 47 | # clipping on outside range, always returns False 48 | res, cstart, cstop = segment.clip(gst.FORMAT_BYTES, 0, 50) 49 | self.assertEquals(res, False) 50 | 51 | # touching lower bound but outside 52 | res, cstart, cstop = segment.clip(gst.FORMAT_BYTES, 50, 100) 53 | self.assertEquals(res, False) 54 | 55 | # partially inside 56 | res, cstart, cstop = segment.clip(gst.FORMAT_BYTES, 50, 150) 57 | self.assertEquals(res, True) 58 | self.assertEquals(cstart, 100) 59 | self.assertEquals(cstop, 150) 60 | 61 | if __name__ == "__main__": 62 | unittest.main() 63 | -------------------------------------------------------------------------------- /testsuite/old/test_struct.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Lesser General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2.1 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Lesser General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public 20 | # License along with this library; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | import sys 24 | from common import gst, unittest, TestCase 25 | 26 | class StructureTest(TestCase): 27 | def setUp(self): 28 | TestCase.setUp(self) 29 | self.struct = gst.structure_from_string('video/x-raw-yuv,width=10,foo="bar",pixel-aspect-ratio=1/2,framerate=5/1,boolean=(boolean)true') 30 | 31 | def testName(self): 32 | assert self.struct.get_name() == 'video/x-raw-yuv' 33 | self.struct.set_name('foobar') 34 | assert self.struct.get_name() == 'foobar' 35 | 36 | def testInt(self): 37 | assert self.struct.has_key('width') 38 | assert isinstance(self.struct['width'], int) 39 | assert self.struct['width'] == 10, self.struct['width'] 40 | self.struct['width'] = 5 41 | assert self.struct.has_key('width') 42 | assert isinstance(self.struct['width'], int) 43 | assert self.struct['width'] == 5, self.struct['width'] 44 | 45 | def testString(self): 46 | assert self.struct.has_key('foo') 47 | assert isinstance(self.struct['foo'], unicode) 48 | assert self.struct['foo'] == 'bar', self.struct['foo'] 49 | self.struct['foo'] = 'baz' 50 | assert self.struct.has_key('foo') 51 | assert isinstance(self.struct['foo'], unicode) 52 | assert self.struct['foo'] == 'baz', self.struct['foo'] 53 | 54 | def testBoolean(self): 55 | assert self.struct.has_key('boolean') 56 | assert isinstance(self.struct['boolean'], bool) 57 | assert self.struct['boolean'] == True, self.struct['boolean'] 58 | self.struct['boolean'] = False 59 | assert self.struct.has_key('boolean') 60 | assert isinstance(self.struct['boolean'], bool) 61 | assert self.struct['boolean'] == False, self.struct['boolean'] 62 | 63 | def testCreateInt(self): 64 | self.struct['integer'] = 5 65 | assert self.struct.has_key('integer') 66 | assert isinstance(self.struct['integer'], int) 67 | assert self.struct['integer'] == 5, self.struct['integer'] 68 | 69 | def testGstValue(self): 70 | s = self.struct 71 | s['fourcc'] = gst.Fourcc('XVID') 72 | assert s['fourcc'].fourcc == 'XVID' 73 | s['frac'] = gst.Fraction(3,4) 74 | assert s['frac'].num == 3 75 | assert s['frac'].denom == 4 76 | s['fracrange'] = gst.FractionRange(gst.Fraction(0,1), 77 | gst.Fraction(25,3)) 78 | assert s['fracrange'].low.num == 0 79 | assert s['fracrange'].low.denom == 1 80 | assert s['fracrange'].high.num == 25 81 | assert s['fracrange'].high.denom == 3 82 | s['intrange'] = gst.IntRange(5,21) 83 | assert s['intrange'].low == 5 84 | assert s['intrange'].high == 21 85 | s['doublerange'] = gst.DoubleRange(6.,21.) 86 | assert s['doublerange'].low == 6. 87 | assert s['doublerange'].high == 21. 88 | s['fixedlist'] = (4, 5, 6) 89 | assert isinstance(s['fixedlist'], tuple) 90 | assert s['fixedlist'] == (4, 5, 6) 91 | s['list'] = [4, 5, 6] 92 | assert isinstance(s['list'], list) 93 | assert s['list'] == [4, 5, 6] 94 | s['boolean'] = True 95 | assert isinstance(s['boolean'], bool) 96 | assert s['boolean'] == True 97 | 98 | # finally, some recursive tests 99 | s['rflist'] = ([(['a', 'b'], ['c', 'd']),'e'], ['f', 'g']) 100 | assert s['rflist'] == ([(['a', 'b'], ['c', 'd']),'e'], ['f', 'g']) 101 | s['rlist'] = [([(['a', 'b'], ['c', 'd']),'e'], ['f', 'g']), 'h'] 102 | assert s['rlist'] == [([(['a', 'b'], ['c', 'd']),'e'], ['f', 'g']), 'h'] 103 | 104 | def testStructureChange(self): 105 | assert self.struct['framerate'] == gst.Fraction(5, 1) 106 | self.struct['framerate'] = gst.Fraction(10, 1) 107 | assert self.struct['framerate'] == gst.Fraction(10, 1) 108 | self.struct['pixel-aspect-ratio'] = gst.Fraction(4, 2) 109 | assert self.struct['pixel-aspect-ratio'].num == 2 110 | assert self.struct['pixel-aspect-ratio'].denom == 1 111 | 112 | def testKeys(self): 113 | k = self.struct.keys() 114 | self.failUnless(k) 115 | self.assertEquals(len(k), 5) 116 | self.failUnless("width" in k) 117 | self.failUnless("foo" in k) 118 | self.failUnless("framerate" in k) 119 | self.failUnless("pixel-aspect-ratio" in k) 120 | self.failUnless("boolean" in k) 121 | 122 | if __name__ == "__main__": 123 | unittest.main() 124 | -------------------------------------------------------------------------------- /testsuite/old/test_taglist.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2007 Johan Dahlin 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | from common import gst, TestCase 22 | 23 | 24 | class TestTagList(TestCase): 25 | def testContains(self): 26 | taglist = gst.TagList() 27 | self.failIf('key' in taglist) 28 | taglist['key'] = 'value' 29 | self.failUnless('key' in taglist) 30 | 31 | def testLength(self): 32 | taglist = gst.TagList() 33 | self.assertEqual(len(taglist), 0) 34 | taglist['key1'] = 'value' 35 | taglist['key2'] = 'value' 36 | self.assertEqual(len(taglist), 2) 37 | 38 | def testKeys(self): 39 | taglist = gst.TagList() 40 | self.assertEqual(taglist.keys(), []) 41 | taglist['key1'] = 'value' 42 | taglist['key2'] = 'value' 43 | keys = taglist.keys() 44 | keys.sort() 45 | self.assertEqual(keys, ['key1', 'key2']) 46 | 47 | def testUnicode(self): 48 | taglist = gst.TagList() 49 | 50 | # normal ASCII text 51 | taglist[gst.TAG_ARTIST] = 'Artist' 52 | self.failUnless(isinstance(taglist[gst.TAG_ARTIST], unicode)) 53 | self.assertEquals(taglist[gst.TAG_ARTIST], u'Artist') 54 | self.assertEquals(taglist[gst.TAG_ARTIST], 'Artist') 55 | 56 | # normal ASCII text as unicode 57 | taglist[gst.TAG_ARTIST] = u'Artist' 58 | self.failUnless(isinstance(taglist[gst.TAG_ARTIST], unicode)) 59 | self.assertEquals(taglist[gst.TAG_ARTIST], u'Artist') 60 | self.assertEquals(taglist[gst.TAG_ARTIST], 'Artist') 61 | 62 | # real unicode 63 | taglist[gst.TAG_ARTIST] = u'S\xc3\xadgur R\xc3\xb3s' 64 | self.failUnless(isinstance(taglist[gst.TAG_ARTIST], unicode)) 65 | self.assertEquals(taglist[gst.TAG_ARTIST], u'S\xc3\xadgur R\xc3\xb3s') 66 | 67 | def testUnsignedInt(self): 68 | taglist = gst.TagList() 69 | taglist[gst.TAG_TRACK_NUMBER] = 1 70 | vorbis = gst.tag.to_vorbis_comments(taglist, gst.TAG_TRACK_NUMBER) 71 | self.assertEquals(vorbis, ['TRACKNUMBER=1']) 72 | -------------------------------------------------------------------------------- /testsuite/old/test_typefind.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2008 Alessandro Decina 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | from common import gst, unittest, TestCase, pygobject_2_13 22 | 23 | import sys 24 | import time 25 | 26 | class TypeFindTest(TestCase): 27 | def testTypeFind(self): 28 | def application_awesome_type_find(typefind, arg1, arg2): 29 | self.failUnlessEqual(arg1, 'arg1') 30 | self.failUnlessEqual(arg2, 'arg2') 31 | 32 | data = typefind.peek(0, 5) 33 | self.failUnless(data == '', 'peek out of length??') 34 | 35 | data = typefind.peek(0, 0) 36 | self.failUnless(data == '', '0 peek??') 37 | 38 | data = typefind.peek(3, 1) 39 | self.failUnless(data == 'M') 40 | 41 | data = typefind.peek(0, 4) 42 | self.failUnless(data == 'AWSM') 43 | 44 | typefind.suggest(gst.TYPE_FIND_MAXIMUM, 45 | gst.Caps('application/awesome')) 46 | 47 | res = gst.type_find_register('application/awesome', gst.RANK_PRIMARY, 48 | application_awesome_type_find, ['.twi'], 49 | gst.Caps('application/awesome'), 'arg1', 'arg2') 50 | self.failUnless(res, 'type_find_register failed') 51 | 52 | factory = None 53 | factories = gst.type_find_factory_get_list() 54 | for typefind_factory in factories: 55 | if typefind_factory.get_name() == 'application/awesome': 56 | factory = typefind_factory 57 | break 58 | self.failUnless(factory is not None) 59 | 60 | obj = gst.Pad('src', gst.PAD_SRC) 61 | buffer = gst.Buffer('AWSM') 62 | caps, probability = gst.type_find_helper_for_buffer(obj, buffer) 63 | 64 | self.failUnlessEqual(str(caps), 'application/awesome') 65 | self.failUnlessEqual(probability, gst.TYPE_FIND_MAXIMUM) 66 | -------------------------------------------------------------------------------- /testsuite/old/test_xml.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2002 David I. Lehn 6 | # Copyright (C) 2004 Johan Dahlin 7 | # Copyright (C) 2005 Edward Hervey 8 | # 9 | # This library is free software; you can redistribute it and/or 10 | # modify it under the terms of the GNU Lesser General Public 11 | # License as published by the Free Software Foundation; either 12 | # version 2.1 of the License, or (at your option) any later version. 13 | # 14 | # This library is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | # Lesser General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU Lesser General Public 20 | # License along with this library; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | 23 | from common import gst, unittest, TestCase 24 | 25 | class PadTest(TestCase): 26 | 27 | def testQuery(self): 28 | # don't run this test if we don't have the libxml2 module 29 | try: 30 | import libxml2 31 | except: 32 | return 33 | xml = gst.XML() 34 | xml.parse_memory(""" 35 | 36 | 37 | test-pipeline 38 | pipeline 39 | 40 | name 41 | test-pipeline 42 | 43 | 44 | """) 45 | elements = xml.get_topelements() 46 | assert len(elements) == 1 47 | element = elements[0] 48 | assert isinstance(element, gst.Pipeline) 49 | assert element.get_name() == 'test-pipeline' 50 | 51 | if __name__ == "__main__": 52 | unittest.main() 53 | 54 | -------------------------------------------------------------------------------- /testsuite/old/testhelpermodule.c: -------------------------------------------------------------------------------- 1 | #include "pygobject.h" 2 | #include "test-object.h" 3 | 4 | #include 5 | #include 6 | 7 | static PyObject * 8 | _wrap_get_object (PyObject * self) 9 | { 10 | GObject *obj; 11 | obj = g_object_new (TEST_TYPE_OBJECT, NULL); 12 | if (!obj) { 13 | return NULL; 14 | } 15 | 16 | return pygobject_new (obj); 17 | } 18 | 19 | static PyObject * 20 | _wrap_emit_event (PyObject * self, PyObject * args) 21 | { 22 | PyGObject *obj; 23 | GstEventType event_type = GST_EVENT_UNKNOWN; 24 | GstEvent *event; 25 | 26 | if (!PyArg_ParseTuple (args, "O|i", &obj, &event_type)) 27 | return NULL; 28 | 29 | event = gst_event_new_custom (event_type, NULL); 30 | 31 | g_signal_emit_by_name (G_OBJECT (obj->obj), "event", event); 32 | 33 | gst_mini_object_unref (GST_MINI_OBJECT (event)); 34 | 35 | Py_INCREF (Py_None); 36 | return Py_None; 37 | } 38 | 39 | static PyMethodDef testhelper_methods[] = { 40 | {"get_object", (PyCFunction) _wrap_get_object, METH_NOARGS}, 41 | {"emit_event", (PyCFunction) _wrap_emit_event, METH_VARARGS}, 42 | {NULL, NULL} 43 | }; 44 | 45 | void 46 | inittesthelper () 47 | { 48 | PyObject *m, *d; 49 | 50 | init_pygobject (); 51 | gst_init (NULL, NULL); 52 | 53 | m = Py_InitModule ("testhelper", testhelper_methods); 54 | 55 | d = PyModule_GetDict (m); 56 | } 57 | -------------------------------------------------------------------------------- /testsuite/overrides_hack.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import imp 4 | 5 | class GstOverrideImport: 6 | def find_module(self, fullname, path=None): 7 | if fullname in ('gi.overrides.Gst', 'gi.overrides._gi_gst'): 8 | return self 9 | return None 10 | 11 | def load_module(self, name): 12 | if name in sys.modules: 13 | return sys.modules[name] 14 | 15 | fp, pathname, description = imp.find_module(name.split('.')[-1], [ 16 | os.environ.get('GST_OVERRIDE_SRC_PATH'), 17 | os.environ.get('GST_OVERRIDE_BUILD_PATH'), 18 | ]) 19 | 20 | try: 21 | module = imp.load_module(name, fp, pathname, description) 22 | finally: 23 | if fp: 24 | fp.close() 25 | sys.modules[name] = module 26 | return module 27 | 28 | if sys.version_info.major >= 3: 29 | sys.meta_path.insert(0, GstOverrideImport()) 30 | else: 31 | import gi.overrides 32 | 33 | gi.overrides.__path__.append(os.environ.get('GST_OVERRIDE_SRC_PATH')) 34 | gi.overrides.__path__.append(os.environ.get('GST_OVERRIDE_BUILD_PATH')) 35 | -------------------------------------------------------------------------------- /testsuite/python/identity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | 5 | # identity.py 6 | # 2016 Marianna S. Buschle 7 | # 8 | # Simple identity element in python 9 | # 10 | # You can run the example from the source doing from gst-python/: 11 | # 12 | # $ export GST_PLUGIN_PATH=$GST_PLUGIN_PATH:$PWD/plugin:$PWD/examples/plugins 13 | # $ GST_DEBUG=python:4 gst-launch-1.0 fakesrc num-buffers=10 ! identity_py ! fakesink 14 | 15 | import gi 16 | gi.require_version('Gst', '1.0') 17 | gi.require_version('GstBase', '1.0') 18 | 19 | from gi.repository import Gst, GObject, GstBase 20 | Gst.init(None) 21 | 22 | # 23 | # Simple Identity element created entirely in python 24 | # 25 | class Identity(GstBase.BaseTransform): 26 | __gstmetadata__ = ('Identity Python','Transform', \ 27 | 'Simple identity element written in python', 'Marianna S. Buschle') 28 | 29 | __gsttemplates__ = (Gst.PadTemplate.new("src", 30 | Gst.PadDirection.SRC, 31 | Gst.PadPresence.ALWAYS, 32 | Gst.Caps.new_any()), 33 | Gst.PadTemplate.new("sink", 34 | Gst.PadDirection.SINK, 35 | Gst.PadPresence.ALWAYS, 36 | Gst.Caps.new_any())) 37 | 38 | def __init__(self): 39 | self.transformed = False 40 | 41 | def do_transform_ip(self, buffer): 42 | self.transformed = True 43 | return Gst.FlowReturn.OK 44 | 45 | GObject.type_register(Identity) 46 | __gstelementfactory__ = ("test_identity_py", Gst.Rank.NONE, Identity) 47 | -------------------------------------------------------------------------------- /testsuite/runtests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- Mode: Python -*- 3 | # vi:si:et:sw=4:sts=4:ts=4 4 | # 5 | # gst-python - Python bindings for GStreamer 6 | # Copyright (C) 2002 David I. Lehn 7 | # Copyright (C) 2004 Johan Dahlin 8 | # Copyright (C) 2005 Edward Hervey 9 | # 10 | # This library is free software; you can redistribute it and/or 11 | # modify it under the terms of the GNU Lesser General Public 12 | # License as published by the Free Software Foundation; either 13 | # version 2.1 of the License, or (at your option) any later version. 14 | # 15 | # This library is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | # Lesser General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU Lesser General Public 21 | # License along with this library; if not, write to the Free Software 22 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 | 24 | import os 25 | import sys 26 | import unittest 27 | 28 | 29 | def _testcases(filenames): 30 | """Yield testcases out of filenames.""" 31 | for filename in filenames: 32 | if filename.endswith(".py"): 33 | yield filename[:-3] 34 | 35 | 36 | def _tests_suite(): 37 | """Pick which tests to run.""" 38 | testcase = os.getenv("TESTCASE") 39 | if testcase: 40 | testcases = [testcase] 41 | else: 42 | testcases = _testcases(sys.argv[1:]) 43 | loader = unittest.TestLoader() 44 | return loader.loadTestsFromNames(testcases) 45 | 46 | 47 | def setup(): 48 | return 49 | 50 | 51 | if __name__ == "__main__": 52 | setup() 53 | 54 | # Set verbosity. 55 | descriptions = 1 56 | verbosity = 1 57 | if 'VERBOSE' in os.environ: 58 | descriptions = 2 59 | verbosity = 2 60 | 61 | suite = _tests_suite() 62 | if not list(suite): 63 | raise Exception("No tests found") 64 | 65 | # Run the tests. 66 | testRunner = unittest.TextTestRunner(descriptions=descriptions, 67 | verbosity=verbosity) 68 | result = testRunner.run(suite) 69 | if result.failures or result.errors: 70 | sys.exit(1) 71 | -------------------------------------------------------------------------------- /testsuite/test_gst.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # Copyright (C) 2009 Thomas Vander Stichele 5 | # 6 | # This library is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU Lesser General Public 8 | # License as published by the Free Software Foundation; either 9 | # version 2.1 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 | # Lesser General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this library; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | import sys 21 | import overrides_hack 22 | overrides_hack 23 | from common import TestCase, unittest 24 | 25 | from gi.repository import Gst 26 | 27 | class TimeArgsTest(TestCase): 28 | def testNoneTime(self): 29 | self.assertRaises(TypeError, Gst.TIME_ARGS, None) 30 | 31 | def testStringTime(self): 32 | self.assertRaises(TypeError, Gst.TIME_ARGS, "String") 33 | 34 | def testClockTimeNone(self): 35 | self.assertEquals(Gst.TIME_ARGS(Gst.CLOCK_TIME_NONE), 'CLOCK_TIME_NONE') 36 | 37 | def testOneSecond(self): 38 | self.assertEquals(Gst.TIME_ARGS(Gst.SECOND), '0:00:01.000000000') 39 | 40 | class TestNotInitialized(TestCase): 41 | def testNotInitialized(self): 42 | if sys.version_info >= (3, 0): 43 | assert_type = Gst.NotInitialized 44 | else: 45 | assert_type = TypeError 46 | 47 | with self.assertRaises(assert_type): 48 | Gst.Caps.from_string("audio/x-raw") 49 | 50 | with self.assertRaises(assert_type): 51 | Gst.Structure.from_string("audio/x-raw") 52 | 53 | with self.assertRaises(assert_type): 54 | Gst.ElementFactory.make("identity", None) 55 | 56 | def testNotDeinitialized(self): 57 | Gst.init(None) 58 | 59 | assert(Gst.Caps.from_string("audio/x-raw")) 60 | assert(Gst.Structure.from_string("audio/x-raw")) 61 | assert(Gst.ElementFactory.make("identity", None)) 62 | 63 | Gst.deinit() 64 | if sys.version_info >= (3, 0): 65 | assert_type = Gst.NotInitialized 66 | else: 67 | assert_type = TypeError 68 | 69 | with self.assertRaises(assert_type): 70 | Gst.Caps.from_string("audio/x-raw") 71 | 72 | with self.assertRaises(assert_type): 73 | Gst.Structure.from_string("audio/x-raw") 74 | 75 | with self.assertRaises(assert_type): 76 | Gst.ElementFactory.make("identity", None) 77 | 78 | 79 | class TestStructure(TestCase): 80 | 81 | def test_new(self): 82 | Gst.init(None) 83 | test = Gst.Structure('test', test=1) 84 | self.assertEqual(test['test'], 1) 85 | 86 | test = Gst.Structure('test,test=1') 87 | self.assertEqual(test['test'], 1) 88 | 89 | 90 | class TestBin(TestCase): 91 | 92 | def test_add_pad(self): 93 | Gst.init(None) 94 | self.assertEqual(Gst.ElementFactory.make("bin", None).sinkpads, []) 95 | 96 | class TestBufferMap(TestCase): 97 | 98 | def test_map_unmap_manual(self): 99 | Gst.init(None) 100 | buf = Gst.Buffer.new_wrapped([42]) 101 | info = buf.map(Gst.MapFlags.READ | Gst.MapFlags.WRITE) 102 | self.assertEqual(info.data[0], 42) 103 | buf.unmap(info) 104 | with self.assertRaises(ValueError): 105 | info.data[0] 106 | 107 | def test_map_unmap_context(self): 108 | Gst.init(None) 109 | buf = Gst.Buffer.new_wrapped([42]) 110 | with buf.map(Gst.MapFlags.READ | Gst.MapFlags.WRITE) as info: 111 | self.assertEqual(info.data[0], 42) 112 | with self.assertRaises(ValueError): 113 | info.data[0] 114 | 115 | if __name__ == "__main__": 116 | unittest.main() 117 | -------------------------------------------------------------------------------- /testsuite/test_plugin.py: -------------------------------------------------------------------------------- 1 | # -*- Mode: Python -*- 2 | # vi:si:et:sw=4:sts=4:ts=4 3 | # 4 | # gst-python - Python bindings for GStreamer 5 | # Copyright (C) 2007 Johan Dahlin 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | import overrides_hack 22 | overrides_hack 23 | 24 | from common import TestCase, unittest 25 | 26 | import gi 27 | gi.require_version("Gst", "1.0") 28 | from gi.repository import Gst 29 | 30 | 31 | class TestPlugin(TestCase): 32 | def testLoad(self): 33 | Gst.init(None) 34 | p = Gst.parse_launch ("fakesrc ! test_identity_py name=id ! fakesink") 35 | assert p.get_by_name("id").transformed == False 36 | p.set_state(Gst.State.PLAYING) 37 | p.get_state(Gst.CLOCK_TIME_NONE) 38 | p.set_state(Gst.State.NULL) 39 | assert p.get_by_name("id").transformed == True 40 | 41 | if __name__ == "__main__": 42 | unittest.main() 43 | --------------------------------------------------------------------------------