GStreamer. Как управлять потоком? (Техгология посылки команд управления в поток GStreamer)

Модератор: Модераторы разделов

edu081
Сообщения: 3

GStreamer. Как управлять потоком?

Сообщение edu081 » 10.01.2019 23:01

В моей программе процесс родитель по нажатию кнопки 1 на клавиатуре посылает команду в виде строки дочернему процессу через не именованный pipe .
В свою очередь дочерний процесс выполняет конвейер gstreamer который проигрывает музыку.

Кто-нибудь знает как написать для этого дочернего процесса обработчик команды присланной из родителя?
Например для постановки конвейера на паузу. Пример на Си был бы в тему ...
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 14937
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: GStreamer. Как управлять потоком?

Сообщение Bizdelnick » 11.01.2019 00:32

А в чём, собственно, проблема? Прочитать команду?
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

edu081
Сообщения: 3

Re: GStreamer. Как управлять потоком?

Сообщение edu081 » 11.01.2019 10:58

Команду в потомке то читаю. Все ОК.
Не понятно как заставить 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);

    } 
   
А далее не понятно как запускаемый процесс test-gstream1 должен её принять и обработать чтобы поставить конвейер на паузу.
Т.е. чтобы выполнить 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
Модератор
Сообщения: 14937
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: GStreamer. Как управлять потоком?

Сообщение Bizdelnick » 11.01.2019 11:50

Ну как минимум надо читать строку в test-gstream1, а не до его запуска. Или я по-прежнему не понимаю, в чём проблема? Если не знаете, как заставить GStreamer работать асинхронно, посмотрите тут: https://stackoverflow.com/questions/34325201/g-main-loop-run-blocks-the-qthread-and-does-not-allow-to-stop-video
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

edu081
Сообщения: 3

Re: GStreamer. Как управлять потоком?

Сообщение edu081 » 11.01.2019 12:36

Я только начал разбираться с GSreamer и пока многое не понимаю. Во всех подобных примерах применяют Qt или GTK и с помощью этих инструментов посылают сигналы на обработку в gstreamer.
Я же не хочу использовать эти инструменты. Я с ними не имею опыта работы. Мне тем более не нужны графические интерфейсы.
Хочу просто нажатием 1 на клавиатуре посылать команду в виде строки на запущенный конвейер.
Как заставить конвейер слушать присылаемые команды ? Или это не возможно ?
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 14937
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: GStreamer. Как управлять потоком?

Сообщение Bizdelnick » 11.01.2019 16:24

edu081 писал(а):
11.01.2019 12:36
Во всех подобных примерах применяют Qt или GTK и с помощью этих инструментов посылают сигналы на обработку в gstreamer.
В ответе на вопрос, ссылку на который я дал выше, нет привязки к Qt или GTK (она есть в вопросе, но пусть Вас это не смущает).
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Спасибо сказали: