在 GStreamer 中发送 EOS 信号并使用 C 接收它的正确方法

Proper way to send an EOS signal in GStreamer and receive it using C

我正在开发一个 C 程序,它逐块地从文件中获取数据并将其发送到 appsrc 对象中。这部分代码效果很好,但我想使用 EOS 信号。所以,我尝试了不同的方法,但我还是抓不到EOS。

首先我们需要配置GstBus来获取不同的消息

_bus = gst_pipeline_get_bus (GST_PIPELINE (_pipeline));
_bus_watch_id = gst_bus_add_watch (_bus, bus_call, this);
gst_object_unref(_bus);

处理函数:

gboolean bus_call (GstBus *bus, GstMessage *msg, Session* user_data) {
    switch (GST_MESSAGE_TYPE (msg)) {

        case GST_MESSAGE_EOS:
            g_print ("End of stream\n");
            break;

        case GST_MESSAGE_ERROR: {
            gchar  *debug;
            GError *error;

            gst_message_parse_error (msg, &error, &debug);
            g_free (debug);
            g_printerr ("Error: %s\n", error->message);
            g_error_free (error);
            break;
        }
        default:
            g_print("got message %s\n", gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
            break;
    }

    return TRUE;
}

处理程序接受除 EOS 之外的所有消息类型。有什么建议吗?

之后我尝试发送EOS消息

有两种不同的方法:从 appsrc 和使用 gst_element_send_event 函数。

第一个

gboolean push_data(Session *) {
    if(!_stream_alive) {
        GstFlowReturn ret;
        g_signal_emit_by_name(_appsrc, "end-of-stream", &ret);

        if (GST_FLOW_OK != ret) {
            g_print("Error occurred! EOS signal cannot be sent!\n\r");
        }

        return FALSE;
    }

    push_data_all();

    return TRUE;
}

第二个

if (_pipeline != nullptr) {
        gboolean res = gst_element_send_event(_pipeline, gst_event_new_eos());
        if(!res) {
            g_print("Error occurred! EOS signal cannot be sent!\n\r");
        }
    }

所以,无论如何,我没有在我的处理程序函数中获取 EOS。有什么建议吗?

管道

appsrc name=appsrc do-timestamp=true ! identity silent=false ! video/x-vp8 ! rtpvp8pay mtu=1400 ! application/x-rtp, encoding-name=VP8 ! webrtcbin

appsrc 带有它自己的 API。检查 gst_app_src_end_of_stream().

的文档

另外请记住,只有在 所有 接收器都是 EOS 之后,总线才会收到 EOS。因为你没有透露你的管道,我们不能说这是否是一个问题..