Gstreamer 1.0 - 创建自定义 message/event/signal
Gstreamer 1.0 - Creating custom message/event/signal
我正在用 C 编写 gstreamer 1.0 的自定义插件。
该插件对帧执行一些处理,并应在满足某些条件时向应用程序发送事件。
它不应该阻塞管道而不是干扰它,只是一个信号,这样应用程序就可以触发与管道无关的动作。
处理工作正常,但是...我不知道下一步该做什么。
有很多已经存在的消息,例如 EOS 或 seek,但我如何创建自己的消息?
该消息应包含自定义数据,因此我必须自己创建一个我可以发送的数据。
通过发送事件或信号,我找不到任何关于如何处理来自插件的自定义事件的examples/documentations/explainations。
我什至没有示例代码可以开始。
如有任何见解,我们将不胜感激。
看看 fpsdisplaysink
元素:
https://github.com/GStreamer/gst-plugins-bad/blob/master/gst/debugutils/fpsdisplaysink.c
这个发出应用程序可以连接到的信号。最有趣的可能是信号创建:
g_signal_new ("fps-measurements", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 3, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
和所述信号的周期性触发:
g_signal_emit (G_OBJECT (self),
fpsdisplaysink_signals[SIGNAL_FPS_MEASUREMENTS], 0, rr, dr,
average_fps);
详细信息可在 GLib 信号文档中找到:
https://developer.gnome.org/gobject/stable/gobject-Signals.html
#
或者,您可以在总线上创建自己的 GstMessage
和 post。请参阅 GstMessage 文档:
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html
GstMessage *gst_message_new_application (GstObject *src,
GstStructure *structure);
然后您可以将数据包装在 GstStructure
中。然后 post 使用 gst_bus_post()
.
将消息发送到总线
谢谢 Florian 的见解,对我帮助很大。
我最终使用了 gst_message_new 和 gst_post_bus.
对于那些可能感兴趣的人,这里是 python 中的代码,我在其中实现了一个 运行 循环。
def connect(bus, name):
def _connect(f):
bus.connect(name, f)
return f
return _connect
....
bus = self.pipeline.get_bus()
bus.add_signal_watch()
ret = self.pipeline.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
logger.error("ERROR: Unable to set the pipeline to the playing state")
loop = GObject.MainLoop()
print()
@connect(bus, "message::"+Gst.MessageType.get_name(Gst.MessageType.ERROR))
def on_error(bus, message):
err, dbg = message.parse_error()
print("ERROR:", message.src.get_name().encode('utf-8'), ":", err.message.encode('utf-8'))
if dbg:
print("debugging info:", dbg)
loop.quit()
@connect(bus, "message::"+Gst.MessageType.get_name(Gst.MessageType.EOS))
def on_eos(bus, message):
logger.info("End-Of-Stream reached")
loop.quit()
.... other events
try:
loop.run()
except KeyboardInterrupt:
pass
print("START : Pipeline has stopped")
self.pipeline.set_state(Gst.State.NULL)
我正在用 C 编写 gstreamer 1.0 的自定义插件。
该插件对帧执行一些处理,并应在满足某些条件时向应用程序发送事件。
它不应该阻塞管道而不是干扰它,只是一个信号,这样应用程序就可以触发与管道无关的动作。
处理工作正常,但是...我不知道下一步该做什么。 有很多已经存在的消息,例如 EOS 或 seek,但我如何创建自己的消息? 该消息应包含自定义数据,因此我必须自己创建一个我可以发送的数据。
通过发送事件或信号,我找不到任何关于如何处理来自插件的自定义事件的examples/documentations/explainations。
我什至没有示例代码可以开始。
如有任何见解,我们将不胜感激。
看看 fpsdisplaysink
元素:
https://github.com/GStreamer/gst-plugins-bad/blob/master/gst/debugutils/fpsdisplaysink.c
这个发出应用程序可以连接到的信号。最有趣的可能是信号创建:
g_signal_new ("fps-measurements", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 3, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
和所述信号的周期性触发:
g_signal_emit (G_OBJECT (self),
fpsdisplaysink_signals[SIGNAL_FPS_MEASUREMENTS], 0, rr, dr,
average_fps);
详细信息可在 GLib 信号文档中找到:
https://developer.gnome.org/gobject/stable/gobject-Signals.html
#
或者,您可以在总线上创建自己的 GstMessage
和 post。请参阅 GstMessage 文档:
https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html
GstMessage *gst_message_new_application (GstObject *src,
GstStructure *structure);
然后您可以将数据包装在 GstStructure
中。然后 post 使用 gst_bus_post()
.
谢谢 Florian 的见解,对我帮助很大。
我最终使用了 gst_message_new 和 gst_post_bus.
对于那些可能感兴趣的人,这里是 python 中的代码,我在其中实现了一个 运行 循环。
def connect(bus, name):
def _connect(f):
bus.connect(name, f)
return f
return _connect
....
bus = self.pipeline.get_bus()
bus.add_signal_watch()
ret = self.pipeline.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
logger.error("ERROR: Unable to set the pipeline to the playing state")
loop = GObject.MainLoop()
print()
@connect(bus, "message::"+Gst.MessageType.get_name(Gst.MessageType.ERROR))
def on_error(bus, message):
err, dbg = message.parse_error()
print("ERROR:", message.src.get_name().encode('utf-8'), ":", err.message.encode('utf-8'))
if dbg:
print("debugging info:", dbg)
loop.quit()
@connect(bus, "message::"+Gst.MessageType.get_name(Gst.MessageType.EOS))
def on_eos(bus, message):
logger.info("End-Of-Stream reached")
loop.quit()
.... other events
try:
loop.run()
except KeyboardInterrupt:
pass
print("START : Pipeline has stopped")
self.pipeline.set_state(Gst.State.NULL)