В моей программе процесс родитель по нажатию кнопки 1 на клавиатуре посылает команду в виде строки дочернему процессу через не именованный pipe .
В свою очередь дочерний процесс выполняет конвейер gstreamer который проигрывает музыку.
Кто-нибудь знает как написать для этого дочернего процесса обработчик команды присланной из родителя?
Например для постановки конвейера на паузу. Пример на Си был бы в тему ...
GStreamer. Как управлять потоком? (Техгология посылки команд управления в поток GStreamer)
Модератор: Модераторы разделов
- Bizdelnick
- Модератор
- Сообщения: 20792
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: GStreamer. Как управлять потоком?
А в чём, собственно, проблема? Прочитать команду?
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: GStreamer. Как управлять потоком?
Команду в потомке то читаю. Все ОК.
Не понятно как заставить gstreamer отработать её.
Приведу кусочек кода (после fork()) первоначально запускаемой в терминале программы для ясности.
Если раскомментировать в нем строки, то можно вывести полученную от родителя строку на терминал и убедится, что строка доходит по pipe до потомка.
Кусок стартовой программы, делающей fork() с запуском конвейера gstreamer
А далее не понятно как запускаемый процесс test-gstream1 должен её принять и обработать чтобы поставить конвейер на паузу.
Т.е. чтобы выполнить gst_element_set_state(pipeline, GST_STATE_PAUSED);
Ниже код запускающий сам GStreamer-ский ковейер
Программа запускаемая в потомке test-gstream1 :
Не понятно как заставить gstreamer отработать её.
Приведу кусочек кода (после fork()) первоначально запускаемой в терминале программы для ясности.
Если раскомментировать в нем строки, то можно вывести полученную от родителя строку на терминал и убедится, что строка доходит по pipe до потомка.
Кусок стартовой программы, делающей fork() с запуском конвейера gstreamer
Код: Выделить всё
// Child process
} else {
printf ("This is child process ! \n");
// Read a string using pipe
// char concat_str[100];
// read(fd1[0], concat_str, 100);
// printf("Recieved string ---> %s\n", concat_str);
// Здесь передаю полученную от родителя строку на stdin запускаемой программы с конвейером gstreamer
close(fd1[1]); // Close writing end of pipe
dup2(fd1[0], 0);
execlp("/home/edu/test-gstream1", "/home/edu/test-gstream1", NULL);
}
Т.е. чтобы выполнить gst_element_set_state(pipeline, GST_STATE_PAUSED);
Ниже код запускающий сам GStreamer-ский ковейер
Программа запускаемая в потомке test-gstream1 :
Код: Выделить всё
#include <gst/gst.h>
#include <glib.h>
static gboolean
bus_call (GstBus *bus,
GstMessage *msg,
gpointer data)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("Окончание потока\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR: {
gchar *debug;
GError *error;
gst_message_parse_error (msg, &error, &debug);
g_free (debug);
g_printerr ("Ошибка: %s\n", error->message);
g_error_free (error);
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
static void
on_pad_added (GstElement *element,
GstPad *pad,
gpointer data)
{
GstPad *sinkpad;
GstElement *coder = (GstElement *) data;
/* Теперь мы можем связать эту точку соединения с входной точкой соединения элемента декодирования аудиопотока */
g_print ("Динамическая точка соединения создана \n");
sinkpad = gst_element_get_static_pad (coder, "sink");
gst_pad_link (pad, sinkpad);
gst_object_unref (sinkpad);
}
int
main (int argc,
char *argv[])
{
GMainLoop *loop;
GstElement *pipeline, *source, *coder, *conv, *udpsink;
GstBus *bus;
guint bus_watch_id;
/* Инициализация */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/*
Проверка входных аргументов
if (argc != 2) {
g_printerr ("Использование: %s <имя файла формата >\n", argv[0]);
return -1;
}
*/
/* Создание элементов из состава фреймворка GStreamer */
pipeline = gst_pipeline_new ("audio-player");
source = gst_element_factory_make ("alsasrc", "alsasrc");
coder = gst_element_factory_make ("mulawenc", "mulawenc");
conv = gst_element_factory_make ("rtppcmupay", "rtppcmupay");
udpsink = gst_element_factory_make ("udpsink", "udpsink");
if (!pipeline || !source || !coder || !conv || !udpsink) {
g_printerr ("Не удалось создать один из элементов конвейера. Работа приложения завершена.\n");
return -1;
}
/* Настройка конвейера */
/* Передаем заданное имя аудиофайла элементу для ввода данных */
g_object_set (G_OBJECT (udpsink), "host","192.168.0.77", "port", 5111, NULL);
/* Устанавливаем обработчик сообщений */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
bus_watch_id = gst_bus_add_watch (bus, bus_call, loop);
// gst_bus_add_signal_watch(bus);
gst_object_unref (bus);
/* Добавляем все элементы в конвейер */
gst_bin_add_many (GST_BIN (pipeline), source, coder, conv, udpsink, NULL);
/* Связываем элементы друг с другом */
gst_element_link_many (source, coder, conv, udpsink, NULL);
g_signal_connect (coder, "pad-added", G_CALLBACK (on_pad_added), conv);
/* Перевод конвейера в состояние "проигрывается"*/
g_print ("Plaing - GST_STATE_PLAYING \n");
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Итерация */
g_print ("Starting...\n");
g_main_loop_run (loop);
/* Выход из главного цикла обработки событий, аккуратное освобождение ресурсов */
g_print ("End plaing\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Disable conveer\n");
gst_object_unref (GST_OBJECT (pipeline));
g_source_remove (bus_watch_id);
g_main_loop_unref (loop);
return 0;
}
- Bizdelnick
- Модератор
- Сообщения: 20792
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: GStreamer. Как управлять потоком?
Ну как минимум надо читать строку в test-gstream1, а не до его запуска. Или я по-прежнему не понимаю, в чём проблема? Если не знаете, как заставить GStreamer работать асинхронно, посмотрите тут: https://stackoverflow.com/questions/34325201/g-main-loop-run-blocks-the-qthread-and-does-not-allow-to-stop-video
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Re: GStreamer. Как управлять потоком?
Я только начал разбираться с GSreamer и пока многое не понимаю. Во всех подобных примерах применяют Qt или GTK и с помощью этих инструментов посылают сигналы на обработку в gstreamer.
Я же не хочу использовать эти инструменты. Я с ними не имею опыта работы. Мне тем более не нужны графические интерфейсы.
Хочу просто нажатием 1 на клавиатуре посылать команду в виде строки на запущенный конвейер.
Как заставить конвейер слушать присылаемые команды ? Или это не возможно ?
Я же не хочу использовать эти инструменты. Я с ними не имею опыта работы. Мне тем более не нужны графические интерфейсы.
Хочу просто нажатием 1 на клавиатуре посылать команду в виде строки на запущенный конвейер.
Как заставить конвейер слушать присылаемые команды ? Или это не возможно ?
- Bizdelnick
- Модератор
- Сообщения: 20792
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: GStreamer. Как управлять потоком?
В ответе на вопрос, ссылку на который я дал выше, нет привязки к Qt или GTK (она есть в вопросе, но пусть Вас это не смущает).
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |