GStreamer似乎没有调用我的回调

时间:2016-11-07 07:55:27

标签: c++ qt callback gstreamer-1.0

我有一个Qt应用程序,它在一个单独的线程中执行与GStreamer相关的东西。虽然我认为我已遵循设置信号回调的规则,但我指定的回调函数似乎没有被调用。

接下来是回调函数,它尝试做的就是将某些内容记录到控制台进行调试:

static gboolean Cb(GstBus *bus, GstMessage *msg, gpointer data)
{
    std::cout << "g_sig, bus = " << (void*)bus
              << ", msg = "      << (void*)msg
              << ", data = "     << (void*)data
              << std::endl;
    return TRUE;
}

我用来启动和监控流的序列(来自IP摄像机的实时RTSP / H.264馈送)是:

GstElement *playBin = gst_parse_launch("<gstreamer pipeline>");
GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(playBin));
gst_bus_add_signal_watch(bus);
g_signal_connect(bus, "message::state-changed", (GCallback)Cb, NULL);
gst_element_set_state(playBin, GST_STATE_PLAYING);

GMainLoop *mainLoop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainLoop);

现在 实际正在播放(视频出现),所以我假设那里没有问题。但是,我希望在管道开始播放时应该发布状态更改消息。这似乎不会发生,因为我没有看到Cb()的输出。

即使我也抓住了message::eosmessage::errormessage::element信号,我也没有输出。

我不确定这是一个问题但是,以防万一,上面的代码略有简化。实际上有两个流正在播放,所以上面第一段代码发生两次,每个playbin一次(序列对每个都是准确的,我只是看到不需要不必要地使代码复杂化)。

然后创建并运行主循环。

如上所述,我没有看到回调函数的输出,所以我的消息在哪里?

附录:对于它的价值,我还尝试使用gst_bus_add_watch方法捕获所有消息而不是特定信号,但仍然没有显示任何消息。我还要提一下,作为一个Qt应用程序,我在代码中没有gtk_init - 我只是从主线程中调用gst_init

1 个答案:

答案 0 :(得分:3)

我对gstreamer的了解有限,很久以前我就搞砸了。

我做了一点测试,这似乎有效:

#include <stdio.h>
#include <gstreamer-1.0/gst/gst.h>

static gboolean Cb(GstBus *bus, GstMessage *msg, gpointer data)
{
        printf("g_sig, bus = %x, msg = %s, data = %x\n",
          bus,
          gst_message_type_get_name(GST_MESSAGE_TYPE(msg)),
          data);

        return TRUE;
}

int main(int argc, char *argv[]) {
        GstElement *pipeline;
        GstBus *bus;
        GstMessage *msg;

        /* Initialize GStreamer */
        gst_init (&argc, &argv);

        /* Build the pipeline */
        pipeline = gst_parse_launch ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);

        /* Wait until error or EOS */
        bus = gst_element_get_bus (pipeline);

        /* use the sync signal handler to link elements while the pipeline is still
         * doing the state change */
        gst_bus_set_sync_handler (bus, gst_bus_sync_signal_handler, pipeline, NULL);
        g_object_connect (bus, "signal::sync-message::state-changed", G_CALLBACK (Cb), pipeline, NULL);

        /* Start playing */
        gst_element_set_state (pipeline, GST_STATE_PLAYING);

        msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

        /* Free resources */
        if (msg != NULL)
                gst_message_unref (msg);

        gst_object_unref (bus);
        gst_element_set_state (pipeline, GST_STATE_NULL);
        gst_object_unref (pipeline);

        return 0;
}

message::state-changed

  

已在公交车上发布消息。该信号从a发出   GSource添加到mainloop。这个信号只会在发出时发出   有一个主循环运行。

signal::sync-message::state-changed代替:

  

已在公交车上发布消息。这个信号是从   发布消息的线程,因此必须小心锁定。

因此同步消息也会在主循环之外发出。

两个信号的docs