GStreamer 似乎没有调用我的回调
GStreamer appears to be not calling my callbacks
我有一个 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::eos
、message::error
和 message::element
信号,我也没有输出。
我不确定这是否会成为问题,但为了以防万一,上面的代码略有简化。实际上有 两个 流正在播放,所以上面的第一个代码片段发生了两次,每个 playbin 一次(每个播放器的顺序都是准确的,我只是认为没有必要使代码不必要地复杂化) .
然后创建主循环并运行。
如前所述,我没有看到回调函数的输出,那么我的消息去哪儿了?
附录:为了它的价值,我也尝试了 gst_bus_add_watch
方法来捕获 所有 消息而不是特定信号,但仍然没有显示。我还应该提到,作为一个 Qt 应用程序,我的代码中没有 gtk_init
- 我只是从主线程调用 gst_init
。
我对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 message has been posted on the bus. This signal is emitted from a
GSource added to the mainloop. this signal will only be emitted when
there is a mainloop running.
signal::sync-message::state-changed
改为:
A message has been posted on the bus. This signal is emitted from the
thread that posted the message so one has to be careful with locking.
因此同步消息也在主循环之外发出。
两个信号的docs。
我有一个 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::eos
、message::error
和 message::element
信号,我也没有输出。
我不确定这是否会成为问题,但为了以防万一,上面的代码略有简化。实际上有 两个 流正在播放,所以上面的第一个代码片段发生了两次,每个 playbin 一次(每个播放器的顺序都是准确的,我只是认为没有必要使代码不必要地复杂化) .
然后创建主循环并运行。
如前所述,我没有看到回调函数的输出,那么我的消息去哪儿了?
附录:为了它的价值,我也尝试了 gst_bus_add_watch
方法来捕获 所有 消息而不是特定信号,但仍然没有显示。我还应该提到,作为一个 Qt 应用程序,我的代码中没有 gtk_init
- 我只是从主线程调用 gst_init
。
我对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 message has been posted on the bus. This signal is emitted from a GSource added to the mainloop. this signal will only be emitted when there is a mainloop running.
signal::sync-message::state-changed
改为:
A message has been posted on the bus. This signal is emitted from the thread that posted the message so one has to be careful with locking.
因此同步消息也在主循环之外发出。
两个信号的docs。