Gstreamer 1.0 - Создание собственного сообщения / события / сигнала

Я пишу пользовательский плагин для gstreamer 1.0 в C.
Этот плагин выполняет некоторую обработку кадров и должен посылать событие приложению, когда выполняются некоторые условия. Он не должен блокировать конвейер, не мешать ему, просто сигнал, чтобы приложение могло инициировать действие, не связанное с конвейером на стороне.

Обработка работает хорошо, но... я не знаю, что делать дальше. Существует много уже существующих сообщений, таких как EOS или search, но как мне создать свое собственное? Сообщение должно содержать пользовательские данные, и поэтому я должен сам создать их, которые я мог бы отправить.

Отправляя события или сигнал, я не смог найти никаких примеров / документов / объяснений о том, как обрабатывать пользовательские события из плагина.

У меня даже нет примера кода для начала.

Любое понимание будет оценено.

2 ответа

Посмотрите на 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 и отправьте это в автобус. Смотрите документацию GstMessage:

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstMessage.html

GstMessage *gst_message_new_application (GstObject *src,
    GstStructure *structure);

Затем вы можете обернуть ваши данные внутри GstStructure, А затем отправьте сообщение в автобус с gst_bus_post(),

Спасибо, Флориан, за понимание, которое мне очень помогло.
В итоге я использовал 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)
Другие вопросы по тегам