2016-11-07 73 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