2016-11-07 70 views
8

我有一个Qt应用程序,它在一个单独的线程中执行GStreamer相关的东西。虽然我认为我遵循了设置信号回调的规则,但我指定的回调函数似乎没有被调用。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; 
} 

我使用的启动和监控的视频流(实况RTSP/H.264饲料序列从IP摄像机)是:

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

我假设你正在检查所有被调用的函数(特别是g_signal_connect)在真实代码中的返回值? – Silicomancer

+0

由于某种原因,stdout可能被重定向。你有没有尝试在'Cb()'函数中放置一个断点? – MrEricSir

回答

1

我对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

的消息已经发布在总线上。这个信号是从 GSource添加到主循环中发出的。此信号只会在 有主循环运行时发出。

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

报文已被发表在总线上。该信号是从发布消息的 线程发出的,因此必须注意锁定。

因此,同步消息也在主循环之外发射。

这两个信号的docs

+0

我不确定这个答案对OP有帮助,但是因为没有其他评论提到,所以我给你的答案奖励奖金。感谢您的巨大努力。 – user2728397