GNOME Bugzilla – Bug 500258
Buffer is not writable in transform_ip in gstbasetransform with passthrough=False and in_place=True and different in/out caps
Last modified: 2008-08-05 11:23:38 UTC
When subclassing gst.BaseTransform with passthrough disabled and in_place enabled the buffer passed to do_transform_ip is not writtable. A code snippet is attached to show the bug: ------------- import gst, gobject, traceback class MyTransform(gst.BaseTransform): __gsttemplates__ = ( gst.PadTemplate("src", gst.PAD_SRC, gst.PAD_ALWAYS, gst.caps_new_any()), gst.PadTemplate("sink", gst.PAD_SINK, gst.PAD_ALWAYS, gst.caps_new_any()) ) def __init__(self, name): self.__gobject_init__() self.set_name(name) self.set_passthrough(False) self.set_in_place(True) def do_transform_ip(self, buffer): buffer[0]=1 #This should work return gst.FLOW_OK def set_property(self, key, value): if key == "name": self.set_name(name) else: print "Property %s does not exist" % key def get_property(self, key): if key == "name": return self.get_name() else: print "Property %s does not exist" % key gobject.type_register(MyTransform) gobject.threads_init() src = gst.element_factory_make("fakesrc", "src") sink = gst.element_factory_make("fakesink", "sink") trans = MyTransform("trans") pipe = gst.Pipeline("MyPipeline") pipe.add(src,trans, sink) gst.element_link_many(src, trans, sink) def bus_event(bus, message): t = message.type print message if t == gst.MESSAGE_EOS: loop.quit() return True pipe.get_bus().add_watch(bus_event) pipe.set_state(gst.STATE_PLAYING) loop = gobject.MainLoop() try: loop.run() except: traceback.print_exc() ------------------- The non-working line is marked with #This should work
Created attachment 103128 [details] [review] replace caps on input buffer instead of creating a subbuffer
Carlos and I tracked this bug down to gstbasetransform.c:gst_base_transform_prepare_output_buffer. For a writable input buffer with different caps, a new subbuffer is created (to replace the caps), rendering the buffer readonly. Changing the behaviour of subbuffers and making them writable is probably a pretty radical change, and we don't have the sufficient knowledge about gstreamer to change that, so I think we're left with two options: 1) Replace the caps directly on the in buffer and pass it on 2) Copy the in buffer, and repalce the caps on the copy If it's be possible I'd go with 1) as it'd be more efficient. In case anyone thinks/knows that this is not a good idea, and a copy should be made instead, let us know. I'll attach a proposed patch to the latest stable version.
This is not an issue with gst-python basetransform, but rather a bad usage of both. * You need to feed your basetransform buffers with fixed caps * Those buffers need to have valid sizes (fakesrc.set_property("sizetype", 2)) * buffers data are arrays of string, so you can't do = 1, but you can do = "1" Will attach my modified version so you can see how to properly use it
Created attachment 103135 [details] correct usage
After a deeper look into the problem the bug is more accurately defined. The patch 2008-01-18 10:00 UTC should be applicable in case that in-buffer caps are not used later in the code for other purposes.