Hi, I'm trying to create a function in python to find elements in a bin based
on their type (not name). I have such a function in C which works and I'm trying to convert it to python but I'm experiencing some issues. def compare_gtype(element, type): print(element) print(type) return 1 def gst_bin_get_by_gtype(bin, type_name): factory = Gst.ElementFactory.find(type_name) type = factory.get_element_type() print(type_name) print(type) print("[" + bin.get_name() + "]: looking up child element of type " + type.name) children = bin.iterate_recurse() if children: print(children) print(children.type) found, elem = children.find_custom(compare_gtype, type) else: print("Error") if found: print("Found") return elem else: print("Not Found") return None This is the output I get: filesink <GType GstFileSink (140449056935968)> [pipeline0]: looking up child element of type GstFileSink <Gst.Iterator object at 0x7fbcded2bdc0 (GstIterator at 0x7fbcd0009220)> <GType GstElement (140449054520272)> <GType GstFileSink (140449056935968)> 140448920294640 <GType GstFileSink (140449056935968)> 140448920294640 <GType GstFileSink (140449056935968)> 140448920294640 <GType GstFileSink (140449056935968)> 140448920294640 <GType GstFileSink (140449056935968)> 140448920294640 API Exception: {'type': 'TypeError', 'args': ('unknown type (null)',), 'message': 'unknown type (null)'} Traceback (most recent call last): File "/usr/lib/python3/dist-packages/jsonrpc/manager.py", line 113, in _get_responses result = method(*request.args, **request.kwargs) File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 248, in play gst_handler.play(index) File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 69, in play elem = gst_bin_get_by_gtype(self.pipeline[index], "filesink") File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 42, in gst_bin_get_by_gtype found, elem = children.find_custom(compare_gtype, type) TypeError: unknown type (null) So for me it seems like the find_custom() is not passing the GstElement from the iterator to the compare_gtype() function... And this is the pipeline it is searching (no filesink): filesrc name=replay location=/home/msb/test.ts ! decodebin ! videoconvert ! ximagesink sync=1 And just for reference the code in C: static gint compare_gtype(const GValue *velement, GType type) { gint eq = 1; GstElement *element = g_value_get_object(velement); GST_OBJECT_LOCK(element); if (G_OBJECT_TYPE(element) == type) eq = 0; GST_OBJECT_UNLOCK(element); return eq; } static GstElement * gst_bin_get_by_gtype(GstBin *bin, GType type) { GstIterator *children; GValue result = { 0, }; GstElement *element; gboolean found; g_return_val_if_fail(GST_IS_BIN(bin), NULL); QTEC_DEBUG("[%s]: looking up child element of type %s", GST_ELEMENT_NAME(bin), g_type_name(type)); children = gst_bin_iterate_recurse(bin); found = gst_iterator_find_custom(children, (GCompareFunc) compare_gtype, &result, (gpointer) type); gst_iterator_free(children); if (found) { element = g_value_dup_object(&result); g_value_unset(&result); } else { element = NULL; } return element; } GstElementFactory * proxysrc_factory = gst_element_factory_find("proxysrc"); if (!proxysrc_factory) return FALSE; GType proxysrc_type = gst_element_factory_get_element_type(proxysrc_factory); GstElement *psrc = gst_bin_get_by_gtype(GST_BIN(bin), proxysrc_type); -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Looks like a bug in pygobject, I tried to pinpoint it but that code base is
a bit of a maze :( And I think there's actually two bugs: one is the parameters passed back to the closure as you noticed, the other one is the final return value when no match was found, these are two separate issues. Note that the gst-python overrides let you iterate the GstIterator as a normal python iterator, why don't you simply loop over it to find your object? > Hi, I'm trying to create a function in python to find elements in a bin based > on their type (not name). On 5/21/21 9:24 AM, Marianna S. Buschle via gstreamer-devel wrote: > Hi, I'm trying to create a function in python to find elements in a bin based > on their type (not name). > > I have such a function in C which works and I'm trying to convert it to > python but I'm experiencing some issues. > > def compare_gtype(element, type): > print(element) > print(type) > > return 1 > > def gst_bin_get_by_gtype(bin, type_name): > factory = Gst.ElementFactory.find(type_name) > type = factory.get_element_type() > print(type_name) > print(type) > > print("[" + bin.get_name() + "]: looking up child element of type " + > type.name) > > children = bin.iterate_recurse() > if children: > print(children) > print(children.type) > found, elem = children.find_custom(compare_gtype, type) > else: > print("Error") > > if found: > print("Found") > return elem > else: > print("Not Found") > return None > > This is the output I get: > > filesink > <GType GstFileSink (140449056935968)> > [pipeline0]: looking up child element of type GstFileSink > <Gst.Iterator object at 0x7fbcded2bdc0 (GstIterator at 0x7fbcd0009220)> > <GType GstElement (140449054520272)> > <GType GstFileSink (140449056935968)> > 140448920294640 > <GType GstFileSink (140449056935968)> > 140448920294640 > <GType GstFileSink (140449056935968)> > 140448920294640 > <GType GstFileSink (140449056935968)> > 140448920294640 > <GType GstFileSink (140449056935968)> > 140448920294640 > API Exception: {'type': 'TypeError', 'args': ('unknown type (null)',), > 'message': 'unknown type (null)'} > Traceback (most recent call last): > File "/usr/lib/python3/dist-packages/jsonrpc/manager.py", line 113, in > _get_responses > result = method(*request.args, **request.kwargs) > File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 248, in play > gst_handler.play(index) > File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 69, in play > elem = gst_bin_get_by_gtype(self.pipeline[index], "filesink") > File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 42, in > gst_bin_get_by_gtype > found, elem = children.find_custom(compare_gtype, type) > TypeError: unknown type (null) > > So for me it seems like the find_custom() is not passing the GstElement from > the iterator to the compare_gtype() function... > > And this is the pipeline it is searching (no filesink): > filesrc name=replay location=/home/msb/test.ts ! decodebin ! videoconvert ! > ximagesink sync=1 > > And just for reference the code in C: > > static gint > compare_gtype(const GValue *velement, GType type) > { > gint eq = 1; > GstElement *element = g_value_get_object(velement); > > GST_OBJECT_LOCK(element); > if (G_OBJECT_TYPE(element) == type) > eq = 0; > GST_OBJECT_UNLOCK(element); > > return eq; > } > > static GstElement * > gst_bin_get_by_gtype(GstBin *bin, GType type) > { > GstIterator *children; > GValue result = { 0, }; > GstElement *element; > gboolean found; > > g_return_val_if_fail(GST_IS_BIN(bin), NULL); > > QTEC_DEBUG("[%s]: looking up child element of type %s", > GST_ELEMENT_NAME(bin), g_type_name(type)); > > children = gst_bin_iterate_recurse(bin); > found = gst_iterator_find_custom(children, > (GCompareFunc) compare_gtype, > &result, (gpointer) type); > gst_iterator_free(children); > > if (found) { > element = g_value_dup_object(&result); > g_value_unset(&result); > } else { > element = NULL; > } > > return element; > } > > GstElementFactory * proxysrc_factory = > gst_element_factory_find("proxysrc"); > > if (!proxysrc_factory) > return FALSE; > > GType proxysrc_type = > gst_element_factory_get_element_type(proxysrc_factory); > > GstElement *psrc = gst_bin_get_by_gtype(GST_BIN(bin), proxysrc_type); > > > > -- > Sent from: http://gstreamer-devel.966125.n4.nabble.com/ > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
eg:
def gst_bin_get_by_gtype(b, type_name): factory = Gst.ElementFactory.find(type_name) return None if factory is None else next(filter(lambda c: c.__gtype__ == factory.get_element_type(), b.iterate_recurse()), None) On 5/21/21 5:51 PM, Mathieu Duponchelle
via gstreamer-devel wrote:
Looks like a bug in pygobject, I tried to pinpoint it but that code base is a bit of a maze :( And I think there's actually two bugs: one is the parameters passed back to the closure as you noticed, the other one is the final return value when no match was found, these are two separate issues. Note that the gst-python overrides let you iterate the GstIterator as a normal python iterator, why don't you simply loop over it to find your object?Hi, I'm trying to create a function in python to find elements in a bin based on their type (not name).On 5/21/21 9:24 AM, Marianna S. Buschle via gstreamer-devel wrote:Hi, I'm trying to create a function in python to find elements in a bin based on their type (not name). I have such a function in C which works and I'm trying to convert it to python but I'm experiencing some issues. def compare_gtype(element, type): print(element) print(type) return 1 def gst_bin_get_by_gtype(bin, type_name): factory = Gst.ElementFactory.find(type_name) type = factory.get_element_type() print(type_name) print(type) print("[" + bin.get_name() + "]: looking up child element of type " + type.name) children = bin.iterate_recurse() if children: print(children) print(children.type) found, elem = children.find_custom(compare_gtype, type) else: print("Error") if found: print("Found") return elem else: print("Not Found") return None This is the output I get: filesink <GType GstFileSink (140449056935968)> [pipeline0]: looking up child element of type GstFileSink <Gst.Iterator object at 0x7fbcded2bdc0 (GstIterator at 0x7fbcd0009220)> <GType GstElement (140449054520272)> <GType GstFileSink (140449056935968)> 140448920294640 <GType GstFileSink (140449056935968)> 140448920294640 <GType GstFileSink (140449056935968)> 140448920294640 <GType GstFileSink (140449056935968)> 140448920294640 <GType GstFileSink (140449056935968)> 140448920294640 API Exception: {'type': 'TypeError', 'args': ('unknown type (null)',), 'message': 'unknown type (null)'} Traceback (most recent call last): File "/usr/lib/python3/dist-packages/jsonrpc/manager.py", line 113, in _get_responses result = method(*request.args, **request.kwargs) File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 248, in play gst_handler.play(index) File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 69, in play elem = gst_bin_get_by_gtype(self.pipeline[index], "filesink") File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 42, in gst_bin_get_by_gtype found, elem = children.find_custom(compare_gtype, type) TypeError: unknown type (null) So for me it seems like the find_custom() is not passing the GstElement from the iterator to the compare_gtype() function... And this is the pipeline it is searching (no filesink): filesrc name=replay location=/home/msb/test.ts ! decodebin ! videoconvert ! ximagesink sync=1 And just for reference the code in C: static gint compare_gtype(const GValue *velement, GType type) { gint eq = 1; GstElement *element = g_value_get_object(velement); GST_OBJECT_LOCK(element); if (G_OBJECT_TYPE(element) == type) eq = 0; GST_OBJECT_UNLOCK(element); return eq; } static GstElement * gst_bin_get_by_gtype(GstBin *bin, GType type) { GstIterator *children; GValue result = { 0, }; GstElement *element; gboolean found; g_return_val_if_fail(GST_IS_BIN(bin), NULL); QTEC_DEBUG("[%s]: looking up child element of type %s", GST_ELEMENT_NAME(bin), g_type_name(type)); children = gst_bin_iterate_recurse(bin); found = gst_iterator_find_custom(children, (GCompareFunc) compare_gtype, &result, (gpointer) type); gst_iterator_free(children); if (found) { element = g_value_dup_object(&result); g_value_unset(&result); } else { element = NULL; } return element; } GstElementFactory * proxysrc_factory = gst_element_factory_find("proxysrc"); if (!proxysrc_factory) return FALSE; GType proxysrc_type = gst_element_factory_get_element_type(proxysrc_factory); GstElement *psrc = gst_bin_get_by_gtype(GST_BIN(bin), proxysrc_type); -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel_______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hi, thanks for the help
I had tried using the iterator directly previously, but couldn't get it to work either. So I though that maybe it was me not knowing how to use it. But with your code I'm getting similar errors: API Exception: {'type': 'TypeError', 'args': ("'Iterator' object is not iterable",), 'message': "'Iterator' object is not iterable"} Traceback (most recent call last): File "/usr/lib/python3/dist-packages/jsonrpc/manager.py", line 113, in _get_responses result = method(*request.args, **request.kwargs) File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 283, in play gst_handler.play(index) File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 79, in play elem = gst_bin_get_by_gtype(self.pipeline[index], "filesink") File "/home/msb/QtecGit/python-tests/gst_ctrl.py", line 61, in gst_bin_get_by_gtype return None if factory is None else next(filter(lambda c: c.__gtype__ == factory.get_element_type(), bin.iterate_recurse()), None) TypeError: 'Iterator' object is not iterable -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
I did manage to make it work like this:
def gst_bin_get_by_gtype(bin, type_name): factory = Gst.ElementFactory.find(type_name) if factory is None: print("No factory found for " + type_name) return None type = factory.get_element_type() print("[" + bin.get_name() + "]: looking up child element of type " + type.name) children = bin.iterate_recurse() if children is None: print("Iterate Error") return None elem = children.next().elem while elem: #print(elem.name) #print(elem.__gtype__) if elem.__gtype__ == type: return elem elem = children.next().elem return None And found out that since gstreamer 1.18 I can also use: #from gst 1.18 children = bin.iterate_all_by_element_factory_name(type_name) if children is None: print("Iterate Error") return None res = [] elem = children.next().elem while elem: print(elem.name) #print(elem.__gtype__) res.append(elem) elem = children.next().elem return res -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Hey, it looks like you're missing the gst-python overrides:
https://gitlab.freedesktop.org/gstreamer/gst-python/-/blob/master/gi/overrides/Gst.py#L233-246 On 5/25/21 2:09 PM, Marianna S. Buschle via gstreamer-devel wrote: > I did manage to make it work like this: > > def gst_bin_get_by_gtype(bin, type_name): > factory = Gst.ElementFactory.find(type_name) > if factory is None: > print("No factory found for " + type_name) > return None > type = factory.get_element_type() > print("[" + bin.get_name() + "]: looking up child element of type " + > type.name) > > children = bin.iterate_recurse() > if children is None: > print("Iterate Error") > return None > > elem = children.next().elem > while elem: > #print(elem.name) > #print(elem.__gtype__) > if elem.__gtype__ == type: > return elem > elem = children.next().elem > > return None > > And found out that since gstreamer 1.18 I can also use: > > #from gst 1.18 > children = bin.iterate_all_by_element_factory_name(type_name) > if children is None: > print("Iterate Error") > return None > res = [] > elem = children.next().elem > while elem: > print(elem.name) > #print(elem.__gtype__) > res.append(elem) > elem = children.next().elem > return res > > > > -- > Sent from: http://gstreamer-devel.966125.n4.nabble.com/ > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Thanks,
Your code does work after installing: python3-gst-1.0 -- Sent from: http://gstreamer-devel.966125.n4.nabble.com/ _______________________________________________ gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Cool :)
On 5/26/21 9:21 AM, Marianna S. Buschle via gstreamer-devel wrote: > Thanks, > > Your code does work after installing: python3-gst-1.0 > > > > -- > Sent from: http://gstreamer-devel.966125.n4.nabble.com/ > _______________________________________________ > gstreamer-devel mailing list > [hidden email] > https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel gstreamer-devel mailing list [hidden email] https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel |
Free forum by Nabble | Edit this page |