diff options
author | Jan Schmidt <thaytan@mad.scientist.com> | 2008-06-27 08:39:37 +0000 |
---|---|---|
committer | Jan Schmidt <thaytan@mad.scientist.com> | 2008-06-27 08:39:37 +0000 |
commit | 468cb05597958290ed0eb30432dde4af07eaa12b (patch) | |
tree | 9f4a0a4b87f54ea19e421c603d5be1435fdc35cf | |
parent | 103e13fa6655fa3ff01a3d55ddbc4d593f238ffc (diff) |
gst/gstbuffer.override: the GstBuffer overrides seem to be confused about whether they're mini-objects or a GBoxed, a...
Original commit message from CVS:
* gst/gstbuffer.override:
the GstBuffer overrides seem to be confused about whether they're
mini-objects or a GBoxed, and it makes copy_on_write no actually
return a usable gst.Buffer. Fix up places where GstBuffers are
treated as GBoxed to use pygstminiobject functions.
Makes gst.Buffer('blah').copy_on_write() work.
* testsuite/test_buffer.py:
Add test for copy-on-write writability
* examples/buffer-draw.py:
Add an example of drawing on a GStreamer buffer with cairo
* gst/gstpad.override:
Make function static
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | examples/buffer-draw.py | 138 | ||||
-rw-r--r-- | gst/gstbuffer.override | 21 | ||||
-rw-r--r-- | gst/gstpad.override | 2 | ||||
-rw-r--r-- | testsuite/test_buffer.py | 10 |
5 files changed, 179 insertions, 11 deletions
@@ -1,3 +1,22 @@ +2008-06-27 Jan Schmidt <jan.schmidt@sun.com> + + * gst/gstbuffer.override: + the GstBuffer overrides seem to be confused about whether they're + mini-objects or a GBoxed, and it makes copy_on_write no actually + return a usable gst.Buffer. Fix up places where GstBuffers are + treated as GBoxed to use pygstminiobject functions. + + Makes gst.Buffer('blah').copy_on_write() work. + + * testsuite/test_buffer.py: + Add test for copy-on-write writability + + * examples/buffer-draw.py: + Add an example of drawing on a GStreamer buffer with cairo + + * gst/gstpad.override: + Make function static + 2008-06-26 Edward Hervey <edward.hervey@collabora.co.uk> * gst/common.h: diff --git a/examples/buffer-draw.py b/examples/buffer-draw.py new file mode 100644 index 0000000..7058382 --- /dev/null +++ b/examples/buffer-draw.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python + +import sys +import traceback +from math import pi + +import pygtk +pygtk.require ("2.0") +import gobject +gobject.threads_init() + +import pygst +pygst.require('0.10') +import gst + +import cairo + +WIDTH, HEIGHT = 640, 480 +FRAMES = 300 +FRAMERATE = 15 + +class PyGstBufferDraw(gst.Element): + _sinkpadtemplate = gst.PadTemplate ("sink", + gst.PAD_SINK, + gst.PAD_ALWAYS, + 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 ]")) + _srcpadtemplate = gst.PadTemplate ("src", + gst.PAD_SRC, + gst.PAD_ALWAYS, + 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 ]")) + + def __init__(self): + gst.Element.__init__(self) + + self.sinkpad = gst.Pad(self._sinkpadtemplate, "sink") + self.sinkpad.set_chain_function(self.chainfunc) + self.sinkpad.set_event_function(self.eventfunc) + self.sinkpad.set_getcaps_function(gst.Pad.proxy_getcaps) + self.sinkpad.set_setcaps_function(gst.Pad.proxy_setcaps) + self.add_pad (self.sinkpad) + + self.srcpad = gst.Pad(self._srcpadtemplate, "src") + + self.srcpad.set_event_function(self.srceventfunc) + self.srcpad.set_query_function(self.srcqueryfunc) + self.srcpad.set_getcaps_function(gst.Pad.proxy_getcaps) + self.srcpad.set_setcaps_function(gst.Pad.proxy_setcaps) + self.add_pad (self.srcpad) + + def chainfunc(self, pad, buffer): + try: + outbuf = buffer.copy_on_write () + self.draw_on (outbuf) + return self.srcpad.push (outbuf) + except: + return GST_FLOW_ERROR + + def eventfunc(self, pad, event): + return self.srcpad.push_event (event) + + def srcqueryfunc (self, pad, query): + return self.sinkpad.query (query) + def srceventfunc (self, pad, event): + return self.sinkpad.push_event (event) + + def draw_on (self, buf): + try: + caps = buf.get_caps() + width = caps[0]['width'] + height = caps[0]['height'] + framerate = caps[0]['framerate'] + surface = cairo.ImageSurface.create_for_data (buf, cairo.FORMAT_ARGB32, width, height, 4 * width) + ctx = cairo.Context(surface) + except: + print "Failed to create cairo surface for buffer" + traceback.print_exc() + return + + try: + center_x = width/4 + center_y = 3*height/4 + + # draw a circle + radius = float (min (width, height)) * 0.25 + ctx.set_source_rgba (0.0, 0.0, 0.0, 0.9) + ctx.move_to (center_x, center_y) + ctx.arc (center_x, center_y, radius, 0, 2.0*pi) + ctx.close_path() + ctx.fill() + ctx.set_source_rgba (1.0, 1.0, 1.0, 1.0) + ctx.set_font_size(0.3 * radius) + txt = "Hello World" + extents = ctx.text_extents (txt) + ctx.move_to(center_x - extents[2]/2, center_y + extents[3]/2) + ctx.text_path(txt) + ctx.fill() + + except: + print "Failed cairo render" + traceback.print_exc() + +gobject.type_register(PyGstBufferDraw) + +pipe = gst.Pipeline() +vt = gst.element_factory_make ("videotestsrc") +cf = gst.element_factory_make ("capsfilter") +c1 = PyGstBufferDraw() +color = gst.element_factory_make ("ffmpegcolorspace") +scale = gst.element_factory_make ("videoscale") +q1 = gst.element_factory_make ("queue") +sink = gst.element_factory_make ("autovideosink") + +caps = gst.caps_from_string ("video/x-raw-rgb,width=%d,height=%d,framerate=%d/1" % (WIDTH, HEIGHT, FRAMERATE)) +cf.set_property ("caps", caps) + +vt.set_property ("num-buffers", FRAMES) + +pipe.add (vt, cf, c1, q1, color, scale, sink) +gst.element_link_many (vt, cf, c1, q1, color, scale, sink) + +def on_eos (bus, msg): + mainloop.quit() + +bus = pipe.get_bus() +bus.add_signal_watch() +bus.connect('message::eos', on_eos) + +pipe.set_state (gst.STATE_PLAYING) + +mainloop = gobject.MainLoop() +try: + mainloop.run() +except: + pass + +pipe.set_state (gst.STATE_NULL) +pipe.get_state (gst.CLOCK_TIME_NONE) + diff --git a/gst/gstbuffer.override b/gst/gstbuffer.override index 161bea3..7a9eb94 100644 --- a/gst/gstbuffer.override +++ b/gst/gstbuffer.override @@ -89,7 +89,7 @@ _wrap_gst_buffer_tp_str (PyGstMiniObject *self) GstBuffer *buf; g_assert (self); - buf = pyg_boxed_get (self, GstBuffer); + buf = GST_BUFFER(pygstminiobject_get(self)); g_assert (buf); return PyString_FromStringAndSize((const gchar*) GST_BUFFER_DATA(buf), @@ -143,7 +143,7 @@ static Py_ssize_t gst_buffer_getreadbuffer(PyObject *self, Py_ssize_t index, void **ptr) { - GstBuffer *buf = pyg_boxed_get(self, GstBuffer); + GstBuffer *buf = GST_BUFFER(pygstminiobject_get(self)); if ( index != 0 ) { PyErr_SetString(PyExc_SystemError, @@ -158,7 +158,7 @@ gst_buffer_getreadbuffer(PyObject *self, Py_ssize_t index, static Py_ssize_t gst_buffer_getsegcount(PyObject *self, Py_ssize_t *lenp) { - GstBuffer *buf = pyg_boxed_get(self, GstBuffer); + GstBuffer *buf = GST_BUFFER(pygstminiobject_get(self)); if (lenp) *lenp = GST_BUFFER_SIZE(buf); @@ -180,7 +180,7 @@ static Py_ssize_t gst_buffer_getcharbuf (PyObject *self, static Py_ssize_t gst_buffer_getwritebuf(PyObject *self, Py_ssize_t index, void **ptr) { - GstBuffer *buf = pyg_boxed_get(self, GstBuffer); + GstBuffer *buf = GST_BUFFER(pygstminiobject_get(self)); if ( index != 0 ) { PyErr_SetString(PyExc_SystemError, @@ -299,7 +299,7 @@ define GstBuffer.copy_on_write static PyObject * _wrap_gst_buffer_copy_on_write (PyObject *self) { - GstBuffer *buf = pyg_boxed_get(self, GstBuffer); + GstBuffer *buf = GST_BUFFER(pygstminiobject_get(self)); GST_INFO("INCREF"); if (gst_buffer_is_writable (buf)) { @@ -307,7 +307,8 @@ _wrap_gst_buffer_copy_on_write (PyObject *self) return self; } buf = gst_buffer_copy (buf); - self = pyg_boxed_new (GST_TYPE_BUFFER, buf, FALSE, TRUE); + self = pygstminiobject_new ((GstMiniObject *)(buf)); + gst_buffer_unref (buf); return self; } %% @@ -322,7 +323,7 @@ _wrap_gst_buffer_flag_is_set(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:GstBuffer.flag_is_set", &flag)) return NULL; - buf = pyg_boxed_get(self, GstBuffer); + buf = GST_BUFFER(pygstminiobject_get(self)); g_assert(GST_IS_BUFFER(buf)); retval = GST_BUFFER_FLAG_IS_SET(buf, flag) ? Py_True : Py_False; @@ -340,7 +341,7 @@ _wrap_gst_buffer_flag_set(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:GstBuffer.set", &flag)) return NULL; - buf = pyg_boxed_get(self, GstBuffer); + buf = GST_BUFFER(pygstminiobject_get(self)); g_assert(GST_IS_BUFFER(buf)); GST_BUFFER_FLAG_SET(buf, flag); @@ -358,7 +359,7 @@ _wrap_gst_buffer_flag_unset(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:GstBuffer.unset", &flag)) return NULL; - buf = pyg_boxed_get(self, GstBuffer); + buf = GST_BUFFER(pygstminiobject_get(self)); g_assert(GST_IS_BUFFER(buf)); GST_BUFFER_FLAG_UNSET(buf, flag); @@ -374,7 +375,7 @@ _wrap_gst_buffer__get_data(PyObject *self, void *closure) GstBuffer *buf; g_assert (self); - buf = pyg_boxed_get (self, GstBuffer); + buf = GST_BUFFER(pygstminiobject_get(self)); g_assert (buf); return PyString_FromStringAndSize((const gchar*) GST_BUFFER_DATA(buf), diff --git a/gst/gstpad.override b/gst/gstpad.override index 8b32124..3ddb665 100644 --- a/gst/gstpad.override +++ b/gst/gstpad.override @@ -1006,7 +1006,7 @@ _wrap_gst_pad_add_buffer_probe(PyGObject *self, PyObject *args) %% override-slot GstPadTemplate.tp_getattr #define IS_ATTR(name) (strcmp (name, attr) == 0) -PyObject * +static PyObject * _wrap_gst_pad_template_tp_getattr(PyObject *self, char *attr) { GstPadTemplate *templ = GST_PAD_TEMPLATE (pygobject_get (self)); diff --git a/testsuite/test_buffer.py b/testsuite/test_buffer.py index bce6d1a..b4a5fb2 100644 --- a/testsuite/test_buffer.py +++ b/testsuite/test_buffer.py @@ -87,6 +87,16 @@ class BufferTest(TestCase): spaned_buffer = buffer1.span(0L, buffer2, 6L) assert str(spaned_buffer) == 'foobar' + def testBufferCopyOnWrite(self): + s='test_vector' + buffer = gst.Buffer(s) + sub = buffer.create_sub(0, buffer.size) + self.assertEquals(sub.size, buffer.size) + out = sub.copy_on_write () + self.assertEquals(out.size, sub.size) + assert str(out) == str(buffer) + out[5] = 'w' + assert str(out) == 'test_wector' def testBufferFlagIsSet(self): buffer = gst.Buffer() |