GStreamer: изменение состояния части pipeline

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

IMB
Сообщения: 2567
ОС: Debian

GStreamer: изменение состояния части pipeline

Сообщение IMB »

Доброго дня!
Железка на ARM захватывает видео, кодирует и передаёт в сеть, работа с видео ведётся средствами GStreamer 0.10.28.
Необходи по приходу команды снять один в кадр в максимальном разрешение и сохранить его локально, важно - снять кадр необходимо без остановки основного потока.
Пока мне это видется в виде такой схемы:

Код: Выделить всё

                кодирование snapshot - локальное сохранение (поток snapshot)
              /
захват - tee
              \
                кодирование основного потока в меньшем разрешение - отправка в сеть (поток video)

Кодирование основного потока с отправкой в сеть в первом приближении сделано. Как сделать подобное разделение тоже вроде понятно. Не совсем понятно как управлять этой "гидрой".
Имеющиеся вопросы:
- как включить поток video оставив выключенным поток snapshot, насколько я понял gst_element_set_state(pipeline, GST_STATE_PLAYING) влияет на все элементы
- как остановить поток snapshot после сохранения одного кадра, предполагаю, что для этого можно отслеживать состояние одного из его элементов через GstMessage и по приходу некоего сообщения выключать поток, в этом пукте возвращаемся к первому вопросу
- если выборочное управление состояниями отдельных потоков невозможно, то насколько незаметно для потока video может быть подсоединение/отсоединение потока snapshot и насколько это будет быстро
Спасибо.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: GStreamer: изменение состояния части pipeline

Сообщение IMB »

На данный момент пошёл по пути наименьшего сопротивления:
- добавил в модуль multifilesink опцию позволяющую выставить количество сохранённых файлов
- при получении сигнала SIGHUP в модуле multifilesink выставляю сохранение одного файла и ставлю флаг
- при наличии флага проверяю значения в модуле multifilesink и если выставленный лимит равен нулю а количество сохранённых файлов больше нуля модифицирую парамтеры multifilesink

Код: Выделить всё

guint limit = 0;
gint index = 0;
.................
while (!env->is_stop) {
    if (env->is_snapshot) {
        g_object_get(G_OBJECT(filesink), "limit", &limit, "index", &index, NULL);

    if (!limit && !index) {
        g_object_set(G_OBJECT(filesink), "limit", 1, NULL);
    }
    if (!limit && index) {
        g_object_set(G_OBJECT(filesink), "limit", 0, "index", 0, NULL);
        env->is_snapshot = FALSE;
    }
    }

}
..........

Собственно сам patch


Чем плох метод - параллельно работает два модуля кодирования, что при использовании максимального пазрешения скажется на быстродействии.
Надо сделать включение/отключение кодирования в потоке создания snapshot.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: GStreamer: изменение состояния части pipeline

Сообщение IMB »

Переделал на динамическое подсоединение/отсоединение.
Для подсоединения:
- установить основной pipeline в GST_STATE_PAUSED
- слинковать основной pipeline и bin
- перевести pipeline в GST_STATE_PLAYING
Для отсодения:
- установить pipeline в GST_STATE_NULL
- разлинковать bin и основной pipeline
- перевести pipeline в GST_STATE_PLAYING
Спасибо сказали: