简体   繁体   中英

GStreamer error “assertion 'GST_IS_ELEMENT (src)' failed” when linking elements

I'm working on a GStreamer-based program using Python and the GObject introspection bindings. I'm trying to build this pipeline:

videomixer name=mix ! autovideosink \
uridecodebin uri=v4l2:///dev/video0 ! mix.

The pipeline works perfectly using gst-launch-1.0, but my Python program gives the errors:

(minimal.py:12168): GStreamer-CRITICAL **: gst_element_link_pads_full: assertion 'GST_IS_ELEMENT (src)' failed
on_error(): (GError('Internal data flow error.',), 'gstbasesrc.c(2865): gst_base_src_loop (): /GstPipeline:pipeline0/GstURIDecodeBin:uridecodebin0/GstV4l2Src:source:\nstreaming task paused, reason not-linked (-1)')

My code:

#!/usr/bin/python3
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst, Gtk, GdkX11, GstVideo
GObject.threads_init()
Gst.init(None)

class Source:
    def __init__(self, uri, pipeline, mixer):
        self.uri = uri
        self.pipeline = pipeline
        self.mixer = mixer

        self.src = Gst.ElementFactory.make('uridecodebin', None)
        self.pipeline.add(self.src)
        self.src.set_property('uri', uri)
        self.src.connect('pad-added', self.on_pad_added, self.src, self.mixer)

    def on_pad_added(self, element, pad, src, dest):
        name = pad.query_caps(None).to_string()
        print('on_pad_added:', name)
        if name.startswith('video/'):
            src.link(dest)

class Main:
    def __init__(self):
        self.window = Gtk.Window()
        self.window.connect('destroy', self.quit)
        self.window.set_default_size(1280, 720)

        self.drawingarea = Gtk.DrawingArea()
        self.window.add(self.drawingarea)

        self.pipeline = Gst.Pipeline()

        self.bus = self.pipeline.get_bus()
        self.bus.add_signal_watch()
        self.bus.connect('message::error', self.on_error)
        self.bus.enable_sync_message_emission()
        self.bus.connect('sync-message::element', self.on_sync_message)

        self.mixer = Gst.ElementFactory.make('videomixer', None)
        self.sink = Gst.ElementFactory.make('autovideosink', None)

        self.pipeline.add(self.mixer)
        self.pipeline.add(self.sink)

        self.mixer.link(self.sink)
        video = Source('v4l2:///dev/video0', self.pipeline, self.mixer)

    def run(self):
        self.window.show_all()
        # You need to get the XID after window.show_all().  You shouldn't get it
        # in the on_sync_message() handler because threading issues will cause
        # segfaults there.
        self.xid = self.drawingarea.get_property('window').get_xid()
        self.pipeline.set_state(Gst.State.PLAYING)
        Gtk.main()
    def quit(self, window):
        self.pipeline.set_state(Gst.State.NULL)
        Gtk.main_quit()
    def on_sync_message(self, bus, msg):
        if msg.get_structure().get_name() == 'prepare-window-handle': msg.src.set_window_handle(self.xid)
    def on_error(self, bus, msg):
        print('on_error():', msg.parse_error())

main = Main()
main.run()

I figured out the problem, I was linking the dynamically-created pad incorrectly:

src.link(dest)

Should have been:

pad.link(dest.get_compatible_pad(pad, None))

If the element is not added with the pipeline, then this error will occur. Ensure that the problematic element is added with the pipeline.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM