0

To start with, I KNOW the standard answer to this in non-gstreamer python. The trouble is that that leads to an infinite recursion.

I am using the gi repository to write a python-gstreamer element which is a child of Gst.Bin. gi hides the virtual methods of parent classes, but lets you automagically override them by defining a do_... method. So I can override GstBin's handle_message method by defining a do_handle_message method in the child. However if that child method calls the parent's do_handle_message, it calls back into the child, and you get an infinite recursion. ie, this doesn't work:

class MyBin(Gst.Bin):
"New Gst.Bin based Element"

  def __init__(self):
    Gst.Bin.__init__(self) # works
    ...

  def do_handle_message(self, message):
    if message.type != Gst.MessageType.ERROR:
      Gst.Bin.do_handle_error(self, message)  # infinite recursion
      super().do_handle_error(self, message)  # same thing
    else:
      ...

I only want to change the Gst.Bin's behaviour for ERRORs, and leave the other processing intact. Any suggestions?

swestrup
  • 4,079
  • 3
  • 22
  • 33
  • I just noticed that this very same element calls Gst.Bin.do_change_state() inside MyBin.do_change_state() and it works fine. So, is this just a bug in the GstPython implementation that I should be reporting? – swestrup Apr 11 '23 at 19:36

1 Answers1

0

Okay, I found something that is a workaround, even if its not a direct answer to my question. In the case of do_handle_messages, I could find no way to define it without ending up in a recursive loop, but I found I could intercept the messages early, and then send them to the parent if I didn't want them:

class MyBin(Gst.Bin):
"New Gst.Bin based Element"

  def __init__(self):
    Gst.Bin.__init__(self)
    self.child_bus.set_sync_handler(self._sync_handler)
    ...

  def _sync_handler(self, bus, message):
    message.mini_object.refcount += 1
    handled = (message.type == Gst.MessageType.Error)
    if handled:
      (err, debug) = message.parse_error()
      handled = self._resolve_error(err, debug)
    if handled:
      message.mini_object.refcount -= 1
    else:
      Gst.Bin.do_handle_message(self,message)
    return Gst.BusSyncReplay.DROP 
swestrup
  • 4,079
  • 3
  • 22
  • 33