#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.