[gst-devel] gst-python problem: refcount for gst.Buffer too big?
Артём Попов
artfwo at gmail.com
Mon Apr 24 02:00:06 CEST 2006
Hello again!
2006/4/22, Артём Попов <artfwo at gmail.com>:
> Hello,
>
> 21.04.06, Edward Hervey<bilboed at gmail.com> написал(а):
> > Hi,
> >
> > On 4/21/06, Артём Попов <artfwo at gmail.com> wrote:
> > > Hi all,
> > >
> > > I'm trying to write a gst element in python, based on
> > > GstBaseTransform. The core of such an element would be "transform" and
> > > "transform_ip" methods, with receive GstBuffer arguments. Both of
> > > these methods don't work for me, due to too large reference count of
> > > Buffers passed to them. By the way, the "transform" method requires
> > > "get_unit_size" virtual method to be implemented, the patch is here:
> > >
> > > http://bugzilla.gnome.org/show_bug.cgi?id=339248
> > >
> > > in "transform_ip", buffer refcount is 3, and that makes the buffer unwritable
> > > in "transform", both buffer refcounts are 2, what makes output buffer
> > > unwritable as well...
> > >
> > > def transform_ip (self, outbuf):
> > > print outbuf.__grefcount__ # always prints 3
> > > return gst.FLOW_OK
> > >
> > > def transform (self, inbuf, outbuf):
> > > print inbuf.__grefcount__ # always prints 2
> > > print outbuf.__grefcount__ # always prints 2
> > > return gst.FLOW_OK
> > >
> > > "gst_buffer_is_writable" checks, that the buffer refcount should be 1,
> > > and gst-python uses just that to enable or disable data writing to the
> > > buffer. So, how can I solve (or maybe workaround) this problem?
> > > Thanks. --Artem
> >
> > Would it be possible to see your code ? Seeing how you name your
> > methods, I doubt it'll work properly.
>
> Ah! Of course, they're "do_transform" and "do_transform_ip", and so
> they are called in my code. It does nothing useful except set_caps,
> get_unit_size and the transform test methods, that's why I didn't post
> the complete class :)
>
> >
> > Otherwise, we did refcount once too much, the bug and patch are
> > available here (I can't commit right now since cvs is frozen) :
> >
> > http://bugzilla.gnome.org/show_bug.cgi?id=339308
> >
> > Please comment on the bug if it doesn't solve your issues.
>
> Yeah, now the results are a bit different: here's what I get (full
> code also posted in comment for bug #339308, also posted here for
> convenience):
>
> def do_get_unit_size (self, caps):
> return 32 # buffer size (currently 2048) must be divisible by this number
>
> def do_transform_ip (self, outbuf):
> print "ip:", outbuf.size, outbuf.__grefcount__ # will print "2048 2"
> return gst.FLOW_OK
>
> def do_transform (self, inbuf, outbuf):
> print "noip:", inbuf.size, inbuf.__grefcount__ # will print "2048 1"
> print "noip:", outbuf.size, outbuf.__grefcount__ # will print "0 1"
> return gst.FLOW_OK
>
> So... do_transform_ip is still unusable, because refcount is now
> smaller but still more than 1. The do_transform method could actually
> work now if outbuf was not zero-sized. Right now do_transform only
> prints values _once_ and the program is freezed (I guess GStreamer is
> waiting for it to fill the output buffer or something like that?)
>
> Well, the patch fixed the bug at least partially, but it opens another
> issue: outbuf in do_transform is zeroed. What do you think can be done
> to solve this?
Well, I've managed (by an absolutely weird workaround) to make
outbuf.__grefcount__=1 in transform_ip:
I simply unref the buffer before calling python method and then ref it
back again (otherwise I get a segfault). Here's what I've added to the
proxy override:
gstbase.override:
...
%%
override GstBaseTransform__proxy_do_transform_ip
static GstFlowReturn
_wrap_GstBaseTransform__proxy_do_transform_ip(GstBaseTransform *self,
GstBuffer*buf)
{
...
gst_mini_object_unref ((GstMiniObject *) buf);
py_retval = PyObject_CallObject(py_method, py_args);
gst_mini_object_ref ((GstMiniObject *) buf);
...
}
I suppose, this completely weird and dirty way :( Could there be a
cleaner solution for the above workaround?
--Artem
More information about the gstreamer-devel
mailing list