summaryrefslogtreecommitdiff
path: root/src/pipelines.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2014-10-07 23:21:34 +0200
committerChristian Pointner <equinox@spreadspace.org>2014-10-07 23:21:34 +0200
commit93097a178c6d0d50cbcfdf26a1a63fd571138484 (patch)
tree0919df4cbd5660b0ec32132cf0e4fad38aa62210 /src/pipelines.c
parentprepared build system for multiple binaries (diff)
cleanup for multiple binaries
Diffstat (limited to 'src/pipelines.c')
-rw-r--r--src/pipelines.c588
1 files changed, 0 insertions, 588 deletions
diff --git a/src/pipelines.c b/src/pipelines.c
deleted file mode 100644
index 440f183..0000000
--- a/src/pipelines.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * sydra
- *
- * sydra is a toolbox which allows you to set up multiple bidirectional
- * Video/Audio streams from external locations.
- * sydra has been written to be used for the Elevate Festival in Graz
- * Austria in order to involve external locations to present themselves
- * at the festival.
- *
- *
- * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
- *
- * This file is part of sydra.
- *
- * sydra is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * sydra is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with sydra. If not, see <http://www.gnu.org/licenses/>.
- *
- * In addition, as a special exception, the copyright holders hereby
- * grant permission for non-GPL-compatible GStreamer plugins to be used
- * and distributed together with GStreamer and sydra.
- * This permission goes above and beyond the permissions granted by the
- * GPL license sydra is covered by.
- */
-
-#include "datatypes.h"
-
-#include <gst/gst.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "options.h"
-#include "utils.h"
-#include "log.h"
-
-struct av_elements {
- const char* name_;
-
- GstElement* srcsink_;
- GstElement* tee_raw_;
-
- const char* encdec_str_;
- GstElement* encdec_;
-
- GstElement* tee_enc_;
-
- const char* payloader_str_;
- GstElement* payloader_;
-};
-
-static GstElement* create_avsend_src(const char* desc, GstElement* pipeline)
-{
- GstElement* src = sydra_create_bin_from_desc("AV source bin", desc, FALSE);
- if(!src) return NULL;
- gst_bin_add(GST_BIN(pipeline), src);
-
- GstElement* element = gst_bin_get_by_name(GST_BIN(src), "videosrc");
- if(!element) {
- log_printf(ERROR, "can't find an element 'videosrc' inside source bin");
- return NULL;
- }
- GstPad* pad = gst_element_get_static_pad(element, "src");
- if(!gst_element_add_pad(src, gst_ghost_pad_new("video", pad))) {
- log_printf(ERROR, "can't create video ghost pad for source bin");
- return NULL;
- }
- gst_object_unref(GST_OBJECT(pad));
- gst_object_unref(GST_OBJECT(element));
-
- element = gst_bin_get_by_name(GST_BIN(src), "audiosrc");
- if(!element) {
- log_printf(ERROR, "can't find an element 'audiosrc' inside source bin");
- return NULL;
- }
- pad = gst_element_get_static_pad(element, "src");
- if(!gst_element_add_pad(src, gst_ghost_pad_new("audio", pad))) {
- log_printf(ERROR, "can't create audio ghost pad for source bin");
- return NULL;
- }
- gst_object_unref(GST_OBJECT(pad));
- gst_object_unref(GST_OBJECT(element));
-
- return src;
-}
-
-static gboolean create_avsend_elements(struct av_elements *ave, GstElement* pipeline, GstElement *rtp, uint32_t session)
-{
- ave->tee_raw_ = sydra_create_element("tee", NULL);
- GstElement *qr = sydra_create_element("queue", NULL);
-
- char bin_name[32];
- snprintf(bin_name, sizeof(bin_name), "%s encoder bin", ave->name_);
- ave->encdec_ = sydra_create_bin_from_desc(bin_name, ave->encdec_str_, TRUE);
- ave->tee_enc_ = sydra_create_element("tee", NULL);
- GstElement *qe = sydra_create_element("queue", NULL);
- ave->payloader_ = sydra_create_element(ave->payloader_str_, NULL);
-
- if(!ave->tee_raw_ || !qr || !ave->encdec_ || !ave->tee_enc_ || !qe || !ave->payloader_) {
- return FALSE;
- }
-
- log_printf(INFO, "%s path created successfully!", ave->name_);
-
- gst_bin_add_many(GST_BIN(pipeline), ave->tee_raw_, qr, ave->encdec_, ave->tee_enc_, qe, ave->payloader_, NULL);
- if(!sydra_link_static_static(ave->srcsink_, ave->name_, ave->tee_raw_, "sink")) return FALSE;
- gst_element_link_many(qr, ave->encdec_, ave->tee_enc_, NULL);
- gst_element_link(qe, ave->payloader_);
-
- char pad_name[32];
- snprintf(pad_name, sizeof(pad_name), "send_rtp_sink_%u", session);
- if(!sydra_link_request_static(ave->tee_raw_, "src_%u", qr, "sink") ||
- !sydra_link_request_static(ave->tee_enc_, "src_%u", qe, "sink") ||
- !sydra_link_static_request(ave->payloader_, "src", rtp, pad_name)) {
- return FALSE;
- }
-
- log_printf(INFO, "%s path linked successfully!", ave->name_);
- return TRUE;
-}
-
-static GstElement* create_avrecv_sink(const char* desc, GstElement* pipeline)
-{
- GstElement* sink = sydra_create_bin_from_desc("AV sink bin", desc, FALSE);
- if(!sink) return NULL;
- gst_bin_add(GST_BIN(pipeline), sink);
-
- GstElement* element = gst_bin_get_by_name(GST_BIN(sink), "videosink");
- if(!element) {
- log_printf(ERROR, "can't find an element 'videosink' inside sink bin");
- return NULL;
- }
- GstPad* pad = gst_element_get_static_pad(element, "sink");
- if(!gst_element_add_pad(sink, gst_ghost_pad_new("video", pad))) {
- log_printf(ERROR, "can't create video ghost pad for source bin");
- return NULL;
- }
- gst_object_unref(GST_OBJECT(pad));
- gst_object_unref(GST_OBJECT(element));
-
- element = gst_bin_get_by_name(GST_BIN(sink), "audiosink");
- if(!element) {
- log_printf(ERROR, "can't find an element 'audiosink' inside sink bin");
- return NULL;
- }
- pad = gst_element_get_static_pad(element, "sink");
- if(!gst_element_add_pad(sink, gst_ghost_pad_new("audio", pad))) {
- log_printf(ERROR, "can't create audio ghost pad for source bin");
- return NULL;
- }
- gst_object_unref(GST_OBJECT(pad));
- gst_object_unref(GST_OBJECT(element));
-
- return sink;
-}
-
-static gboolean create_avrecv_elements(struct av_elements *ave, GstElement* pipeline)
-{
- ave->tee_raw_ = sydra_create_element("tee", NULL);
- GstElement *qr = sydra_create_element("queue", NULL);
-
- char bin_name[32];
- snprintf(bin_name, sizeof(bin_name), "%s decoder bin", ave->name_);
- ave->encdec_ = sydra_create_bin_from_desc(bin_name, ave->encdec_str_, TRUE);
- ave->tee_enc_ = sydra_create_element("tee", NULL);
- GstElement *qe = sydra_create_element("queue", NULL);
- ave->payloader_ = sydra_create_element(ave->payloader_str_, NULL);
-
- if(!ave->tee_raw_ || !qr || !ave->encdec_ || !ave->tee_enc_ || !qe || !ave->payloader_) {
- return FALSE;
- }
-
- log_printf(INFO, "%s path created successfully!", ave->name_);
-
- gst_bin_add_many (GST_BIN(pipeline), ave->tee_raw_, qr, ave->encdec_, ave->tee_enc_, qe, ave->payloader_, NULL);
- gst_element_link_many(ave->payloader_, ave->tee_enc_, qe, ave->encdec_, ave->tee_raw_, qr, NULL);
- if(!sydra_link_static_static(qr, "src", ave->srcsink_, ave->name_)) return FALSE;
-
- log_printf(INFO, "%s path linked successfully!", ave->name_);
- return TRUE;
-}
-
-static gboolean create_udp_sinks(options_t* opt, GstElement* pipeline, GstElement* rtp, struct udp_sinks *sinks)
-{
- sinks->rtp_video_.udp_ = sydra_create_element("multiudpsink", "udprtpv");
- sinks->rtcp_video_.udp_ = sydra_create_element("multiudpsink", "udprtcpv");
- sinks->rtp_audio_.udp_ = sydra_create_element("multiudpsink", "udprtpa");
- sinks->rtcp_audio_.udp_ = sydra_create_element("multiudpsink", "udprtcpa");
-
- if(!(sinks->rtp_video_.udp_) || !(sinks->rtcp_video_.udp_) || !(sinks->rtp_audio_.udp_) || !(sinks->rtcp_audio_.udp_))
- return FALSE;
-
- log_printf(INFO, "udp sinks created successfully!");
-
- int rtp_port_local = opt->rtp_port_base_local_;
- g_object_set(G_OBJECT(sinks->rtp_video_.udp_), "bind-port", rtp_port_local++, NULL);
- g_object_set(G_OBJECT(sinks->rtcp_video_.udp_), "bind-port", rtp_port_local++, "sync", FALSE, "async", FALSE, NULL);
- g_object_set(G_OBJECT(sinks->rtp_audio_.udp_), "bind-port", rtp_port_local++, NULL);
- g_object_set(G_OBJECT(sinks->rtcp_audio_.udp_), "bind-port", rtp_port_local++, "sync", FALSE, "async", FALSE, NULL);
-
- if(opt->rtp_host_) {
- int rtp_port = opt->rtp_port_base_;
- g_signal_emit_by_name(G_OBJECT(sinks->rtp_video_.udp_), "add", opt->rtp_host_, rtp_port++, NULL);
- g_signal_emit_by_name(G_OBJECT(sinks->rtcp_video_.udp_), "add", opt->rtp_host_, rtp_port++, NULL);
- g_signal_emit_by_name(G_OBJECT(sinks->rtp_audio_.udp_), "add", opt->rtp_host_, rtp_port++, NULL);
- g_signal_emit_by_name(G_OBJECT(sinks->rtcp_audio_.udp_), "add", opt->rtp_host_, rtp_port++, NULL);
- }
- if(opt->rtp_addr_local_) {
- g_object_set(G_OBJECT(sinks->rtp_video_.udp_), "bind-address", opt->rtp_addr_local_, NULL);
- g_object_set(G_OBJECT(sinks->rtcp_video_.udp_), "bind-address", opt->rtp_addr_local_, NULL);
- g_object_set(G_OBJECT(sinks->rtp_audio_.udp_), "bind-address", opt->rtp_addr_local_, NULL);
- g_object_set(G_OBJECT(sinks->rtcp_audio_.udp_), "bind-address", opt->rtp_addr_local_, NULL);
- }
-
- log_printf(INFO, "udp sinks configured successfully!");
-
- gst_bin_add_many(GST_BIN(pipeline), sinks->rtp_video_.udp_, sinks->rtcp_video_.udp_, sinks->rtp_audio_.udp_, sinks->rtcp_audio_.udp_, NULL);
-
- if(!sydra_link_static_static(rtp, "send_rtp_src_0", sinks->rtp_video_.udp_, "sink") ||
- !sydra_link_request_static(rtp, "send_rtcp_src_0", sinks->rtcp_video_.udp_, "sink") ||
- !sydra_link_static_static(rtp, "send_rtp_src_1", sinks->rtp_audio_.udp_, "sink") ||
- !sydra_link_request_static(rtp, "send_rtcp_src_1", sinks->rtcp_audio_.udp_, "sink"))
- return FALSE;
-
- log_printf(INFO, "udp sinks linked successfully!");
-
- return TRUE;
-}
-
-struct udpsrc_tees {
- GstElement* rtpv_;
- GstElement* rtcpv_;
- GstElement* rtpa_;
- GstElement* rtcpa_;
-};
-
-static gboolean create_rtp_reflector(options_t* opt, GstElement* pipeline, struct udpsrc_tees *tees)
-{
- GstElement* rtp_video = sydra_create_element("udpsink", "udprtpvref");
- GstElement* qrtpv = sydra_create_element("queue", NULL);
- GstElement* rtcp_video = sydra_create_element("udpsink", "udprtcpvref");
- GstElement* qrtcpv = sydra_create_element("queue", NULL);
- GstElement* rtp_audio = sydra_create_element("udpsink", "udprtparef");
- GstElement* qrtpa = sydra_create_element("queue", NULL);
- GstElement* rtcp_audio = sydra_create_element("udpsink", "udprtcparef");
- GstElement* qrtcpa = sydra_create_element("queue", NULL);
-
- if(!rtp_video || !rtcp_video || !rtp_audio || !rtcp_audio || !qrtpv || !qrtcpv || !qrtpa || !qrtcpa)
- return FALSE;
-
- log_printf(INFO, "udp reflector sinks created successfully!");
-
- int rtp_port_reflector = opt->rtp_port_base_reflector_;
- g_object_set(G_OBJECT(rtp_video), "host", opt->rtp_host_reflector_, "port", rtp_port_reflector++,
- "sync", FALSE, "async", FALSE, NULL);
- g_object_set(G_OBJECT(rtcp_video), "host", opt->rtp_host_reflector_, "port", rtp_port_reflector++,
- "sync", FALSE, "async", FALSE, NULL);
- g_object_set(G_OBJECT(rtp_audio), "host", opt->rtp_host_reflector_, "port", rtp_port_reflector++,
- "sync", FALSE, "async", FALSE, NULL);
- g_object_set(G_OBJECT(rtcp_audio), "host", opt->rtp_host_reflector_, "port", rtp_port_reflector++,
- "sync", FALSE, "async", FALSE, NULL);
-
- log_printf(INFO, "udp reflector sinks configured successfully!");
-
- gst_bin_add_many(GST_BIN(pipeline), rtp_video, rtcp_video, rtp_audio, rtcp_audio, NULL);
- gst_bin_add_many(GST_BIN(pipeline), qrtpv, qrtcpv, qrtpa, qrtcpa, NULL);
-
- gst_element_link(qrtpv, rtp_video);
- gst_element_link(qrtcpv, rtcp_video);
- gst_element_link(qrtpa, rtp_audio);
- gst_element_link(qrtcpa, rtcp_audio);
-
- if(!sydra_link_request_static(tees->rtpv_, "src_%u", qrtpv, "sink") ||
- !sydra_link_request_static(tees->rtcpv_, "src_%u", qrtcpv, "sink") ||
- !sydra_link_request_static(tees->rtpa_, "src_%u", qrtpa, "sink") ||
- !sydra_link_request_static(tees->rtcpa_, "src_%u", qrtcpa, "sink"))
- return FALSE;
-
- log_printf(INFO, "udp reflector sinks linked successfully!");
-
- return TRUE;
-}
-
-static gboolean create_udp_sources(options_t* opt, GstElement* pipeline, GstElement* rtp, struct udp_sources *sources)
-{
- struct udpsrc_tees tees;
-
- sources->rtp_video_ = sydra_create_element("udpsrc", "udprtpv");
- tees.rtpv_ = sydra_create_element("tee", "rtpvt");
- sources->rtcp_video_ = sydra_create_element("udpsrc", "udprtcpv");
- tees.rtcpv_ = sydra_create_element("tee", "rtcpvt");
- sources->rtp_audio_ = sydra_create_element("udpsrc", "udprtpa");
- tees.rtpa_ = sydra_create_element("tee", "rtpat");
- sources->rtcp_audio_ = sydra_create_element("udpsrc", "udprtcpa");
- tees.rtcpa_ = sydra_create_element("tee", "rtcpat");
-
- if(!(sources->rtp_video_) || !(sources->rtcp_video_) || !(sources->rtp_audio_) || !(sources->rtcp_audio_) ||
- !(tees.rtpv_) || !(tees.rtcpv_) || !(tees.rtpa_) || !(tees.rtcpa_))
- return FALSE;
-
- log_printf(INFO, "udp sources created successfully!");
-
- GstCaps *video_caps = gst_caps_from_string(opt->video_caps_);
- GstCaps *audio_caps = gst_caps_from_string(opt->audio_caps_);
- if(!video_caps || !audio_caps) {
- log_printf(ERROR, "parsing video or audio caps failed!");
- return FALSE;
- }
- int rtp_port_local = opt->rtp_port_base_local_;
- g_object_set(G_OBJECT(sources->rtp_video_), "port", rtp_port_local++, "caps", video_caps, NULL);
- g_object_set(G_OBJECT(sources->rtcp_video_), "port", rtp_port_local++, NULL);
- g_object_set(G_OBJECT(sources->rtp_audio_), "port", rtp_port_local++, "caps", audio_caps, NULL);
- g_object_set(G_OBJECT(sources->rtcp_audio_), "port", rtp_port_local++, NULL);
- gst_caps_unref(video_caps);
- gst_caps_unref(audio_caps);
-
- if(opt->rtp_addr_local_) {
- g_object_set(G_OBJECT(sources->rtp_video_), "address", opt->rtp_addr_local_, NULL);
- g_object_set(G_OBJECT(sources->rtcp_video_), "address", opt->rtp_addr_local_, NULL);
- g_object_set(G_OBJECT(sources->rtp_audio_), "address", opt->rtp_addr_local_, NULL);
- g_object_set(G_OBJECT(sources->rtcp_audio_), "address", opt->rtp_addr_local_, NULL);
- }
-
- log_printf(INFO, "udp sources configured successfully!");
-
- gst_bin_add_many(GST_BIN(pipeline), sources->rtp_video_, sources->rtcp_video_, sources->rtp_audio_, sources->rtcp_audio_, NULL);
- gst_bin_add_many(GST_BIN(pipeline), tees.rtpv_, tees.rtcpv_, tees.rtpa_, tees.rtcpa_, NULL);
-
- gst_element_link(sources->rtp_video_, tees.rtpv_);
- gst_element_link(sources->rtcp_video_, tees.rtcpv_);
- gst_element_link(sources->rtp_audio_, tees.rtpa_);
- gst_element_link(sources->rtcp_audio_, tees.rtcpa_);
-
- if(!sydra_link_request_request(tees.rtpv_, "src_%u", rtp, "recv_rtp_sink_0") ||
- !sydra_link_request_request(tees.rtcpv_, "src_%u", rtp, "recv_rtcp_sink_0") ||
- !sydra_link_request_request(tees.rtpa_, "src_%u", rtp, "recv_rtp_sink_1") ||
- !sydra_link_request_request(tees.rtcpa_, "src_%u", rtp, "recv_rtcp_sink_1"))
- return FALSE;
-
- log_printf(INFO, "udp sources linked successfully!");
-
- if(opt->rtp_host_reflector_)
- return create_rtp_reflector(opt, pipeline, &tees);
-
- return TRUE;
-}
-
-static gboolean create_preview_elements(const char* preview_bin_desc, GstElement* pipeline, GstElement* tee)
-{
- GstElement *qr = sydra_create_element("queue", NULL);
- GstElement *preview_bin = sydra_create_bin_from_desc("preview sink bin", preview_bin_desc, TRUE);
-
- if(!qr || !preview_bin) {
- return FALSE;
- }
-
- log_printf(INFO, "preview path created successfully!");
-
- gst_bin_add_many (GST_BIN(pipeline), qr, preview_bin, NULL);
- gst_element_link(qr, preview_bin);
-
- if(!sydra_link_request_static(tee, "src_%u", qr, "sink")) {
- return FALSE;
- }
-
- log_printf(INFO, "preview path linked successfully!");
- return TRUE;
-}
-
-static gboolean create_recorder_elements(options_t* opt, GstElement* pipeline, struct av_elements *ve, struct av_elements *ae)
-{
- GstElement *qv = sydra_create_element("queue", NULL);
- GstElement *qa = sydra_create_element("queue", NULL);
- GstElement *mux = sydra_create_element(opt->rec_mux_, NULL);
- GstElement *sink = sydra_create_element("filesink", NULL);
-
- if(!qv || !qa || !mux || !sink) {
- return FALSE;
- }
-
- GstElement *ev = NULL, *tv = ve->tee_enc_;
- if(opt->video_enc_rec_) {
- ev = sydra_create_bin_from_desc("record video encoder bin", opt->video_enc_rec_, TRUE);
- if(!ev) return FALSE;
- tv = ve->tee_raw_;
- }
- GstElement *ea = NULL, *ta = ae->tee_enc_;
- if(opt->audio_enc_rec_) {
- ea = sydra_create_bin_from_desc("record audio encoder bin", opt->audio_enc_rec_, TRUE);
- if(!ea) return FALSE;
- ta = ae->tee_raw_;
- }
-
- log_printf(INFO, "recorder path created successfully!");
-
- struct timespec now;
- clock_gettime(CLOCK_REALTIME, &now);
- struct tm bd_time;
- localtime_r(&(now.tv_sec), &bd_time);
- char recfile[1024];
- recfile[0] = 0;
- strftime(recfile, sizeof(recfile), opt->rec_name_format_, &bd_time);
- g_object_set(G_OBJECT(sink), "location", recfile, NULL);
-
- gst_bin_add_many(GST_BIN(pipeline), qv, qa, mux, sink, NULL);
- gst_element_link(mux, sink);
- GstElement* sv = qv;
- if(ev) {
- gst_bin_add(GST_BIN(pipeline), ev);
- gst_element_link(qv, ev);
- sv = ev;
- }
- GstElement* sa = qa;
- if(ev) {
- gst_bin_add(GST_BIN(pipeline), ea);
- gst_element_link(qa, ea);
- sa = ea;
- }
-
- if(!sydra_link_request_static(tv, "src_%u", qv, "sink") ||
- !sydra_link_static_compatible(sv, "src", mux) ||
- !sydra_link_request_static(ta, "src_%u", qa, "sink") ||
- !sydra_link_static_compatible(sa, "src", mux)) {
- return FALSE;
- }
-
- log_printf(INFO, "recorder path linked successfully!");
- return TRUE;
-}
-
-GstElement* create_sender_pipeline(options_t* opt, struct udp_sinks *udp)
-{
- GstElement *pipeline = gst_pipeline_new ("sydra-rtp-sender");
- if(!pipeline) {
- log_printf(ERROR, "Creating pipeline failed!");
- return NULL;
- }
- GstElement *rtp = sydra_create_element("rtpbin", "rtpbin");
- if(!rtp || !gst_bin_add(GST_BIN(pipeline), rtp)) return NULL;
- log_printf(INFO, "rtpbin created successfully!");
-
- GstElement* src = create_avsend_src(opt->source_, pipeline);
- if(!src) return NULL;
- log_printf(INFO, "source bin created successfully!");
-
- struct av_elements video = { "video", src, NULL, opt->video_enc_, NULL, NULL,
- opt->video_payloader_, NULL };
- struct av_elements audio = { "audio", src, NULL, opt->audio_enc_, NULL, NULL,
- opt->audio_payloader_, NULL };
- if(!create_avsend_elements(&video, pipeline, rtp, 0) ||
- !create_avsend_elements(&audio, pipeline, rtp, 1) ||
- !create_udp_sinks(opt, pipeline, rtp, udp)) {
- return NULL;
- }
-
- if(opt->preview_videosink_) {
- if(!create_preview_elements(opt->preview_videosink_, pipeline, video.tee_raw_))
- return NULL;
- }
-
- if(opt->rec_mux_) {
- if(!create_recorder_elements(opt, pipeline, &video, &audio))
- return NULL;
- }
-
- log_printf(INFO, "sender pipeline created successfully!");
- return pipeline;
-}
-
-static void rtpbin_pad_added(GstElement* rtp, GstPad* pad, gpointer user_data)
-{
- GstElement **depays = (GstElement**)user_data;
-
- GstPadTemplate *pad_template = gst_pad_get_pad_template(pad);
- if(pad_template == NULL) return;
- if(strcmp("recv_rtp_src_%u_%u_%u", GST_PAD_TEMPLATE_NAME_TEMPLATE(pad_template))) {
- gst_object_unref(GST_OBJECT(pad_template));
- return;
- }
- gst_object_unref(GST_OBJECT(pad_template));
-
- gchar* src_pad_name = gst_element_get_name(pad);
- log_printf(INFO, "rtpbin: new pad created %s", src_pad_name);
-
- guint i;
- for(i = 0; i < 2; i++) {
- GstPad *sink_pad = gst_element_get_static_pad(depays[i], "sink");
- if(gst_pad_is_linked(sink_pad) || !gst_pad_can_link(pad, sink_pad)) {
- gst_object_unref(GST_OBJECT(sink_pad));
- continue;
- }
- GstPadLinkReturn ret = gst_pad_link(pad, sink_pad);
- gst_object_unref(GST_OBJECT(sink_pad));
-
- if(GST_PAD_LINK_FAILED(ret)) {
- gchar* src_name = gst_element_get_name(rtp);
- gchar* sink_name = gst_element_get_name(depays[i]);
- log_printf(ERROR, "Error linking pad '%s' of '%s' with pad '%s' of '%s'",
- src_pad_name, src_name, "sink", sink_name);
- g_free(src_name);
- g_free(sink_name);
- continue;
- }
- break;
- }
- if(!gst_pad_is_linked(pad)) {
- log_printf(ERROR, "rtpbin: no compatible depayloader found for pad %s (or all depayloader already connected)", src_pad_name);
- GstStructure* ms = gst_structure_new("sydra-rtp", "quit", G_TYPE_BOOLEAN, TRUE, "reason",
- G_TYPE_STRING, "New RTP Session but all depayloader are already connected or none compatible found", NULL);
- GstMessage* msg = gst_message_new_application(GST_OBJECT(rtp), ms);
- if(!ms || ! msg)
- log_printf(ERROR, "rtpbin: message creation failed!");
- else {
- if(!gst_element_post_message(rtp, msg))
- log_printf(ERROR, "rtpbin: sending message to the application failed: no bus");
- }
- }
- g_free(src_pad_name);
-}
-
-static void rtp_new_ssrc(GstElement *rtp, guint session, guint ssrc, gpointer user_data)
-{
- log_printf(INFO, "rtpbin: new SSRC %u for session %u", ssrc, session);
-}
-
-static void rtp_ssrc_timeout(GstElement *rtp, guint session, guint ssrc, gpointer user_data)
-{
- log_printf(INFO, "rtpbin: SSRC %u of session %u timed out", ssrc, session);
- GstStructure* ms = gst_structure_new("sydra-rtp", "quit", G_TYPE_BOOLEAN, TRUE, "reason",
- G_TYPE_STRING, "RTP session timed out", NULL);
- GstMessage* msg = gst_message_new_application(GST_OBJECT(rtp), ms);
- if(!ms || ! msg)
- log_printf(ERROR, "rtpbin: message creation failed!");
- else {
- if(!gst_element_post_message(rtp, msg))
- log_printf(ERROR, "rtpbin: sending message to the application failed: no bus");
- }
-}
-
-GstElement* create_receiver_pipeline(options_t* opt, struct udp_sources *udp)
-{
- GstElement *pipeline = gst_pipeline_new ("sydra-rtp-receiver");
- if(!pipeline) {
- log_printf(ERROR, "Creating pipeline failed!");
- return NULL;
- }
- GstElement *rtp = sydra_create_element("rtpbin", "rtpbin");
- if(!rtp || !gst_bin_add(GST_BIN(pipeline), rtp)) {
- return NULL;
- }
- log_printf(INFO, "rtpbin created successfully!");
-
- GstElement* sink = create_avrecv_sink(opt->sink_, pipeline);
- if(!sink) return NULL;
- log_printf(INFO, "sink bin created successfully!");
-
- struct av_elements video = { "video", sink, NULL, opt->video_dec_, NULL, NULL,
- opt->video_depayloader_, NULL };
- struct av_elements audio = { "audio", sink, NULL, opt->audio_dec_, NULL, NULL,
- opt->audio_depayloader_, NULL };
- if(!create_udp_sources(opt, pipeline, rtp, udp) ||
- !create_avrecv_elements(&video, pipeline) ||
- !create_avrecv_elements(&audio, pipeline)) {
- return NULL;
- }
- GstElement **depays = g_new(GstElement*, 2);
- depays[0] = video.payloader_;
- depays[1] = audio.payloader_;
- g_signal_connect_closure(rtp, "pad-added", g_cclosure_new(G_CALLBACK(rtpbin_pad_added), depays, NULL), FALSE);
- g_signal_connect(rtp, "on-new-ssrc", G_CALLBACK(rtp_new_ssrc), NULL);
- g_signal_connect(rtp, "on-timeout", G_CALLBACK(rtp_ssrc_timeout), NULL);
-
- if(opt->rec_mux_) {
- if(!create_recorder_elements(opt, pipeline, &video, &audio))
- return NULL;
- }
-
- log_printf(INFO, "receiver pipeline created successfully!");
- return pipeline;
-}