Gstreamer в C — утверждении не удалось : конвейер не распознается как bin при хранении в массиве?

#pointers #types #streaming #gstreamer #pipeline

Вопрос:

Ладно, длинный вопрос, потому что он нуждается в контексте. Я пытаюсь построить сервер, содержащий несколько конвейеров в Gstreamer, используя C. В основном, есть клиенты, которые отправляют видеопоток на центральный сервер, который перераспределяет его среди других присутствующих клиентов, как при вызове видеоконференции. Поэтому у меня есть файл server.c, который должен это делать, и я использую rtpbins для приема и отправки видеопотоков с помощью RTP.

У меня максимальное количество клиентов, поэтому я объявляю массив struct Client clients[MAX_CLIENTS] для хранения каждого из них. Чтобы хранить информацию о каждом клиенте, я создал клиент структуры, в котором я разместил конвейер, начинающийся с rtpbin, который получает видеопоток, поступающий от клиента. Затем этот конвейер содержит тройник, который разбивает поток на несколько ветвей, которые заканчиваются rtpbin для отправки потока другим клиентам.

 struct Client{
  gint id;
  gchar *ip;
  gint baseport;
  GstElement *pipeline;
  struct Rtpbin_out rtpbins_out[MAX_CLIENTS];
};
 

Поскольку мне нужно знать, какая ветвь после тройника направлена на каких клиентов, я помещаю элементы этой ветви в структуру под названием Rtpbin_out :

 struct Rtpbin_out{
  GstPad *tee_out_pad;
  GstElement *queue;
  GstElement *rtpbin_out;
  GstElement *udpsink_rtp;
  GstElement *udpsink_rtcp;
  GstElement *udpsrc_rtcp;
};
 

В каждом client[i] я таким образом ставлю a rtpbins_out[MAX_CLIENTS] , чтобы каждую ветвь можно было найти снова.

Эти структуры и массив объявлены глобально, над основным.

Теперь, когда я запускаю код и появляется первый клиент (Client0), конвейер clients[0] строится до тройника с помощью функции create_new_pipeline(clients[0]) , которая выполняет обычные функции построения конвейера Gstreamer : gst_element_factory_make, newclient.pipeline = gst_pipeline_new(name0) , gst_bin_add_many(GST_BIN(newclient.pipeline),...) , запросы на rtpbin, обратный вызов для добавления pad и т. Д. Я также добавляю поддельную ссылку на тройник, чтобы конвейер можно было настроить на ВОСПРОИЗВЕДЕНИЕ в этой функции. Здесь нет проблем.

Проблема возникает, когда приходит второй клиент. В этот момент мне нужно вернуться clients[0].pipeline и добавить к нему элементы внутри rtpbins_out[*number mapped to the 2nd client*] . Таким образом, у нас есть конвейер, который начинается с получения rtpbin от Client0 и заканчивается отправкой rtpbin 2-му клиенту. Для этого я вызываю функцию : add_client_to_pipeline(clients[0], ...) . В этой функции я сначала создаю элементы, хранящиеся в rtpbins_out, с помощью factory_make, что работает.

Ошибка возникает, когда я это делаю gst_bin_add_many(GST_BIN(clients[0].pipeline), clients[0].rtpbins_out[*2nd client*].queue, ..., NULL) . Я получаю :

 (SERVER:8625): GStreamer-CRITICAL **: 15:29:14.970: gst_bin_add_many: assertion 'GST_IS_BIN (bin)' failed
 

Позже та же ошибка возникает, когда я звоню gst_bin_get_by_name(GST_BIN(clients[0].pipeline), "tee") , чтобы получить тройник в конвейере, чтобы связать его с новой очередью.

Я не понимаю. Поэтому , когда я впервые вызываю gst_bin_add_many этот конвейер при создании конвейера create_new_pipeline , ошибки нет. Но если я вернусь позже и вызову ту же функцию add_client_to_pipeline , тип конвейера больше не распознается. Связано ли это с тем, как конвейер хранится в массиве структур ? Это потому, что конвейер-это указатель, и поэтому я больше ничего не могу к нему добавить ? Это потому, что трубопровод находится в ИГРОВОМ состоянии ? (Этого не должно быть, так как у меня есть поддельный канал, подключенный к тройнику)

I hope you can understand with the info I gave you here, thanks in advance.