2016-07-01 59 views
1

Я следующий очень простой код с помощью библиотеки GStreamer (GStreamer V1.8.1 на Xubuntu 16.04, если это важно)GStreamer трубопровод висит на gst_element_get_state

#include <gst/gst.h> 

int main(int argc, char *argv[]) 
{ 
    gst_init(&argc, &argv); 

    const gchar* pd = 
     "filesrc location=some.mp4 ! qtdemux name=d " 
     "d.video_0 ! fakesink " 
     "d.audio_0 ! fakesink "; 

    GError* error = nullptr; 
    GstElement *pipeline = gst_parse_launch(pd, &error); 

    GstState state; GstState pending; 
    switch(gst_element_set_state(pipeline, GST_STATE_PAUSED)) { 
     case GST_STATE_CHANGE_FAILURE: 
     case GST_STATE_CHANGE_NO_PREROLL: 
      return -1; 
     case GST_STATE_CHANGE_ASYNC: { 
      gst_element_get_state(pipeline, &state, &pending, GST_CLOCK_TIME_NONE); 
     } 
     case GST_STATE_CHANGE_SUCCESS: 
      break; 
    } 

    GMainLoop* loop = g_main_loop_new(nullptr, false); 
    g_main_loop_run(loop); 

    gst_object_unref(pipeline); 

    return 0; 
} 

Проблема заключается в том, когда я пытаюсь запустить этот код он висит на

gst_element_get_state(pipeline, &state, &pending, GST_CLOCK_TIME_NONE); 

Вопрос в том, почему он висит? Особенно если учесть, если я удалю d.audio_0 ! fakesink из описания контура, он не виснет.

+0

кстати, вам не хватает перерыва .. и код не зависал для меня: P, но у вас уже есть ответ. – nayana

+0

@otopolsky, нет, я не пропустил перерыв. Он просто делится одним перерывом на два случая. Какую версию GStreamer вы используете? – RSATom

+0

ах ок я подумал, что, возможно, это дело .. 1.6.4 – nayana

ответ

2

Хорошая практика всегда добавлять очереди (или многоточие) после элементов, которые создают несколько выходных ветвей в конвейере, например. демультиплексирования.

Причина в том, что раковины будут блокировать ожидание приема других приемников для получения первого буфера (preeroll). С помощью одного потока, как вашего кода, он блокирует единственный поток, доступный для ввода данных в приемники. Один поток идет от демультиплексоров к обеим раковинам, как только 1 блокирует, что данные не поступают на второй приемник.

Использование очередей будет создавать новые потоки, и каждая раковина будет иметь выделенный.