[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