首页 > 解决方案 > g_signal_connect() 奇怪的行为

问题描述

我尝试为 Raspberry Pi 3 创建 gstreamer 应用程序,该应用程序从自定义 USB 设备捕获 mpeg2 数据流,并使用 appsrc 将此数据推送到管道。这是我的管道在 .dot 文件中的外观: 管道图像

我的问题:GstTSDemux 未链接到 GstH264Parse。

我用来g_singnal_connect()在回调函数中将解复用器和解析器链接在一起。但是应用程序启动时不会调用此函数。这是我使用 gstreamer 元素的结构:

struct CustomData {
CustomData():
    pipeline{nullptr},
    videosrc{nullptr},
    videoenc{nullptr},
    muxer{nullptr},
    sink{nullptr},
    parser{nullptr},
    converter{nullptr},
    numSamples{0},
    sourceId{0},
    mainLoop{nullptr},
    timer{nullptr}
{
}

GstElement *pipeline, *videosrc, *videoenc, *muxer, *sink, *parser, *converter;
guint64 numSamples;   /* Number of samples generated so far (for timestamp generation) */
guint sourceId;        /* To control the GSource */
GMainLoop *mainLoop;  /* GLib's Main Loop */
GTimer *timer;
};

我创建了静态 void 函数linkMuxerParser()来链接解复用器和解析器:

static void linkMuxerParser(GstElement* element, GstPad* sourcePad, gpointer sinkElement)
{
    GstPad* sinkPad = gst_element_get_static_pad((GstElement*)sinkElement, "sink");
    GstPadLinkReturn ret;

    ret = gst_pad_link(sourcePad, sinkPad);
    if ( ret != GST_PAD_LINK_OK) {
        g_print("link mux -> parser fail\n");
    }
    gst_object_unref(sinkPad);
    g_print("link mux -> parser\n");
}

这是我的初始化代码。

gst_init (NULL, NULL);
videoSource.videoData.mainLoop = g_main_loop_new (NULL, FALSE);
videoSource.videoData.pipeline = gst_pipeline_new ("video-player");
videoSource.videoData.videosrc = gst_element_factory_make ("appsrc", "video_source");
videoSource.videoData.muxer = gst_element_factory_make ("tsdemux", "mydemux");
videoSource.videoData.parser = gst_element_factory_make ("h264parse", "parser");
videoSource.videoData.videoenc = gst_element_factory_make ("omxh264dec", "videoenc");
videoSource.videoData.converter = gst_element_factory_make ("videoconvert", "convert");
videoSource.videoData.sink = gst_element_factory_make ("fbdevsink", "sink");

if (!videoSource.videoData.pipeline || !videoSource.videoData.videosrc || !videoSource.videoData.muxer ||
        !videoSource.videoData.parser || !videoSource.videoData.videoenc || !videoSource.videoData.converter || !videoSource.videoData.sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
}

g_print ("Elements are created\n");

bus = gst_pipeline_get_bus (GST_PIPELINE (videoSource.videoData.pipeline));
gst_bus_add_watch (bus, bus_call, videoSource.videoData.mainLoop);
gst_object_unref (bus);

gst_bin_add_many (GST_BIN (videoSource.videoData.pipeline), videoSource.videoData.videosrc, videoSource.videoData.muxer,
                  videoSource.videoData.parser, videoSource.videoData.videoenc, videoSource.videoData.converter, videoSource.videoData.sink, NULL);

g_print ("Added all the Elements into the pipeline\n");

/* we link the elements together */
if (!gst_element_link(videoSource.videoData.videosrc, videoSource.videoData.muxer)) {
    g_print("Failed src -> queue link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}

if (!gst_element_link(videoSource.videoData.parser, videoSource.videoData.videoenc)) {
    g_print("Failed parser -> enc link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}

if (!gst_element_link(videoSource.videoData.videoenc, videoSource.videoData.converter)) {
    g_print("Failed enc -> conv link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}

if (!gst_element_link(videoSource.videoData.converter, videoSource.videoData.sink)) {
    g_print("Failed conv -> sink link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}

result = g_signal_connect (videoSource.videoData.muxer, "pad-added", G_CALLBACK (linkMuxerParser), videoSource.videoData.parser);
if (result <= 0 ) {
    g_print("Failed mux -> parser link\n");
    gst_object_unref (GST_OBJECT (videoSource.videoData.pipeline));
    return -1;
}
g_signal_connect (videoSource.videoData.videosrc, "need-data", G_CALLBACK (VideoSource::startFeed), &videoSource.videoData);
g_signal_connect (videoSource.videoData.videosrc, "enough-data", G_CALLBACK (VideoSource::stopFeed), &videoSource.videoData);

videoSource.videoData.timer = g_timer_new();

g_print ("Linked all the Elements together\n");
/* Set the pipeline to "playing" state*/
g_print ("Playing the video\n");
gst_element_set_state (videoSource.videoData.pipeline, GST_STATE_PLAYING);
GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN (videoSource.videoData.pipeline),  GST_DEBUG_GRAPH_SHOW_ALL, "play");

/* Iterate */
g_print ("Running...\n");
g_main_loop_run (videoSource.videoData.mainLoop);

当我启动应用程序时,我在控制台中看到:

Elements are created
Added all the Elements into the pipeline
Linked all the Elements together
Playing the video
Running...

而且我的回调linkMuxerParser()没有被调用。也许有人可以检测到我错过了什么?先感谢您。

标签: c++raspberry-pigstreamer

解决方案


推荐阅读