У меня есть приложение 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;
}
Последовательность, которую я использую для запуска и мониторинга потока (прямая трансляция 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::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
:
Сообщение было размещено в автобусе. Этот сигнал испускается из
GSource добавлен в основной цикл. этот сигнал будет излучаться только тогда, когда
есть основной цикл работы.
signal::sync-message::state-changed
вместо:
Сообщение было размещено в автобусе. Этот сигнал испускается из
Тема, в которой размещено сообщение, поэтому нужно быть осторожным с блокировкой.
Таким образом, сообщение синхронизации отправляется также за пределы основного цикла.
документы для обоих сигналов.
Других решений пока нет …