LINUX.ORG.RU

Как в GStreamer выполнить старт / стоп ?

 


0

1

Сразу скажу что я только начинаю знакомиться с GStreamer. И еще не разобрался в нем как надо бы, но ... По образу приложения «Hello world» с сайта с документацией на GSTreamer создал своё приложение для трансляции аудиопотока с одного хоста на другой со сжатием voip кодеком. И даже сделал паралельную запись потока в файл. Все заработало прекрасно.
Но вот как перевести конвейер в другое состояние, например поставить на паузу - не пойму.

После выполнения в программе методов

gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Итерация */
g_print ("STARTING ...\n");
g_main_loop_run (loop);

программа уходит в бесконечный цикл.
Есть метод для остановки конвейера с передачей ему EOS,

gst_element_set_state (pipeline, GST_STATE_NULL);
но вот как его выполнить и прервать цикл я никак не соображу.
Из этой же программы ? Или допустим послать команду на остановку потока в паузу из другого процесса -тоже не понятно.
Хочу сделать чтоб запись начиналась/останавливалась не с запуском всего конвейера, а по моей команде , например при изменении значения кокой-нибудь переменной, например. Что-то прям застрял на этом и все - и не туды и не сюды :)
Подскажите, люди добрые.


gst_element_set_state (pipeline, GST_STATE_NULL);
но вот как его выполнить и прервать цикл я никак не соображу.

У тебя интерфейс-то какой?

Если Gtk3, то при нажатии кнопки возникает событие, обрабатываешь его в main_loop - запускаешь команду управления конвейером: play, pause или stop.

Для паузы так:

gst_element_set_state (pipeline, GST_STATE_PAUSED)

В этих двух мануалах ищи по слову «PAUSE».

Novator ★★★★★
()
Последнее исправление: Novator (всего исправлений: 1)
Ответ на: комментарий от Novator

Я горю желанием поставить на паузу нажатием клавиши на клаве, либо GPIO кнопки(что еще лучше).
Как отловить изменение переменной по нажатию кнопки я знаю, как далее послать сигнал в запущенный программой конвейер не понимаю.
В рамках самой программы запускающей конвейер в PLAY, я так думаю, это не получится, так как выполнение программы останавливается в main_loop.
Почитал указанные разделы манула и например, подобные форумы супостатов - эффект понимания тот же.
Видать саму логику пока «не прорубил».
Найти бы какой-нибудь пример c «человеческим лицом» по этому поводу.

edu08
() автор топика
Ответ на: комментарий от edu08

А что не прорубил-то? Я же тебе дал ссылки, как нужно с пайпами работать. Там живые примеры приведены.

Например, по второй ссылке ищи по слову «cb_message» - там пример, как прицепить «сигнал» к пайпу.

Ты вобще Gtk программировал? Знаешь, что такое сигналы? Я ведь тебя не просто так спросил, а ты проигнорил.

Обработчик сигнала можно прицепить к пайпу, а можно - к главному окну.

Тебе по нажатию кнопки или по GPIO-событию нужно посылать сигнал либо пайпу, либо главному окну, а там уже (внутри gtk или gstreamer цикла) должен сработать твой обработчик сигнала.

На, курни про сигналы, может что-то проясниться.

Novator ★★★★★
()
Последнее исправление: Novator (всего исправлений: 2)
Ответ на: комментарий от Novator

Покурил...

Я не программер и ранее дальше кроме как bash-скриптов и прикладных программ на си, выполняющихся в режиме командной строки, не ходил. Графикой не занимался. Этого по жизни хватало, поэтому с GTK дела не имел.
Покурил это и стало понятнее.
Потом почитал про вызовы pipe и хотелось бы спросить:
«Правильной ли дорогой иду, товарищи ?».
Не пойму как процесс с обработчиком (как в примере на сайте) запускающий конвейер в PLAY цикл поймет что я именно к нему обращаюсь? Как приять этот пайп с другого процесса в процесс с запущенным PLAY циклом?
ЗЫ. Возможно я по неопытности тут всякий бред написал, не судите строго. Просто это новое для меня и хочу разобраться. В любом случае буду «курить» дальше ...
Пример я так понимаю обработчика:

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 ("1- Окончание потока\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 ("2- Ошибка: %s\n", error->message);
      g_error_free (error);

      g_main_loop_quit (loop);
      break;
    }
    default:
      break;
  }

  return TRUE;
}

edu08
() автор топика
Ответ на: Покурил... от edu08

Я Gtk и Г-Стрёмер на Си не программировал - только на Ruby, и только версии Gtk2 и Gstreamer0.1, с ними было всё гораздо проще.

Может тебе тоже сначала на чём-нибудь без компиляции пописать (на Python или Ruby), а потом уже на Си переписывать?

ГСтрёмер - сам по себе замороченный движок, а вы ещё пытаетесь его на Си раскочегарить.

Лично я в нём разочаровался, особенно после выхода Gtk3 - Gstreamer1.0 у меня в Ruby перестал работать, и я его забросил.

Сейчас вот ищу что-то более простое. FFMpeg - тоже дерьмо. Ощущение, что библиотеки мультимедиа в линуксе пишут только моральные уроды. Даже не знаю, что тебе посоветовать.

P.S. Попробуй на тостере спросить, может там что подскажут.

Novator ★★★★★
()
Последнее исправление: Novator (всего исправлений: 2)
Ответ на: комментарий от Novator

Я по GTK почитал мануалы и мне понравилось, появились новые идеи, но с ними позже ... Спасибо за совет!

Ну, вот! Таки научился управлять потоком. Из родительского процесса по нажатии кнопки на клаве посылаю сигнал в дочерний процесс реализующий сам поток, где обработчик выполняет нужные мне действия над ним. Только вот по самому Г-стрёмеру не совсем понимаю когда надо запускать цикл, а когда нет.

gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);

В варианте и с ним и в варианте без него у меня работает.

Где то в инете я даже читал что можно и без главного цикла обойтись, а где то и циклом GTK обойтись. Можете в двух словах (как говорится - на пальцах :-) ) объяснить когда необходимо выполнять g_main_loop_run (loop);, а когда нет ?

edu08
() автор топика
Ответ на: комментарий от edu08

Я использовал только в Gtk2 и только на высоких языках - на Ruby и Python. У тебя Си, там всё замороченно - так что не подскажу.

Novator ★★★★★
()
Ответ на: комментарий от edu08

Если ты используешь Gtk, то нет не обходимости в отдельном main loop в коде, т.к. он уже есть в Gtk, нужно только инициализировать gstreamer gst_init (&argc, &argv). Если Gtk не используется, то только тогда нужно озаботиться g_main_loop_run (loop), чтобы полнеценно обрабатывать события.

anonymous
()
Ответ на: комментарий от anonymous

В том то весь и вопрос, что GTK не использую. Образец для примера взял здесь https://gstreamer.freedesktop.org/documentation/tutorials/basic/multithreadin...

Только подправил его под себя (мультилинки, запись и т.д.), но сути это не меняет. В примере нет g_main_loop_run (loop);, а оно работает. GTK здесь я тоже не вижу. Вот я и не понял, а в чем фишка то ?

edu08
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.