使用 parse_launch 创建管道时,相同的 Gstreamer 管道会导致显示网络摄像头提要的窗口,但手动创建时则不会显示

问题描述 投票:0回答:1

我正在尝试用 python 创建一个简单的 Gstreamer 管道,它将从网络摄像头获取输入并将其显示在视频窗口上。

以下代码按预期工作:

import gi
gi.require_version("Gst", "1.0") 
from gi.repository import Gst, GLib
from threading import Thread
Gst.init()

main_loop = GLib.MainLoop()
pipeline = Gst.parse_launch("v4l2src ! decodebin ! videoconvert ! autovideosink")
main_loop_tread = Thread(target=main_loop.run)
main_loop_tread.start()

pipeline.set_state(Gst.State.PLAYING)

但是,当我尝试使用手动创建的管道执行相同的操作时,管道不会显示任何窗口。我的相机灯仍然亮着,但没有弹出视频窗口。另外,如果我用 appsink 重新设置自动视频接收器,我得到的每个缓冲区都是 None。

import gi
gi.require_version("Gst", "1.0") 
from gi.repository import Gst, GLib
from threading import Thread
Gst.init()

main_loop = GLib.MainLoop()
pipeline = Gst.Pipeline()
main_loop_tread = Thread(target=main_loop.run)
main_loop_tread.start()

src = Gst.ElementFactory.make("v4l2src")
decode = Gst.ElementFactory.make("decodebin")
convert = Gst.ElementFactory.make("videoconvert")
sink = Gst.ElementFactory.make("autovideosink")

pipeline.add(src)
pipeline.add(decode)
pipeline.add(convert)
pipeline.add(sink)

src.link(decode)
decode.link(convert)
convert.link(sink)

pipeline.set_state(Gst.State.PLAYING)

第二个代码示例有什么问题?

python gstreamer
1个回答
0
投票

我用

GST_DEBUG=3
标志运行你的代码并看到警告

$ GST_DEBUG=3 python3 python_gstreamer.py
0:00:00.010488893 2604612 0x55d4f997cc00 FIXME                default gstutils.c:4025:gst_pad_create_stream_id_internal:<videotestsrc0:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id
0:00:00.011231276 2604612 0x55d4f997cc00 WARN                 basesrc gstbasesrc.c:3127:gst_base_src_loop:<videotestsrc0> error: Internal data stream error.
0:00:00.011236130 2604612 0x55d4f997cc00 WARN                 basesrc gstbasesrc.c:3127:gst_base_src_loop:<videotestsrc0> error: streaming stopped, reason not-linked (-1)

然后我用

GST_DEBUG=4
运行它以查找更多详细信息,我注意到
decodebin
元素没有正确链接到
videoconvert
元素。

$ GST_DEBUG=4 python3 python_gstreamer.py
...
0:00:00.008857654 2606874 0x564edfcf68a0 INFO        GST_ELEMENT_PADS gstutils.c:1816:gst_element_link_pads_full: trying to link element decodebin0:(any) to element videoconvert0:(any)
0:00:00.008860541 2606874 0x564edfcf68a0 INFO                GST_PADS gstpad.c:4357:gst_pad_peer_query:<videoconvert0:src> pad has no peer
0:00:00.008934791 2606874 0x564edfcf68a0 INFO        GST_ELEMENT_PADS gstelement.c:1013:gst_element_get_static_pad: no such pad 'src_%u' in element "decodebin0"
0:00:00.008941910 2606874 0x564edfcf68a0 INFO        GST_ELEMENT_PADS gstutils.c:1270:gst_element_get_compatible_pad:<decodebin0> Could not find a compatible pad to link to videoconvert0:sink
...

显然,您必须处理由decodebin发出的“pad-added”信号,然后将新的pad链接到下一个接收器元素。

import gi
gi.require_version("Gst", "1.0") 
from gi.repository import Gst, GLib
from threading import Thread
Gst.init()

def pad_added_handler(src, new_pad, convert):
    sink_pad = convert.get_static_pad("sink")
    if sink_pad.is_linked():
        return

    new_pad.link(sink_pad)

main_loop = GLib.MainLoop()
pipeline = Gst.Pipeline()
main_loop_tread = Thread(target=main_loop.run)
main_loop_tread.start()

src = Gst.ElementFactory.make("v4l2src")
decode = Gst.ElementFactory.make("decodebin")
convert = Gst.ElementFactory.make("videoconvert")
sink = Gst.ElementFactory.make("autovideosink")

pipeline.add(src)
pipeline.add(decode)
pipeline.add(convert)
pipeline.add(sink)

src.link(decode)
convert.link(sink)

decode.connect("pad-added", pad_added_handler, convert)

pipeline.set_state(Gst.State.PLAYING)
© www.soinside.com 2019 - 2024. All rights reserved.