diff options
author | Christian Pointner <equinox@spreadspace.org> | 2014-10-07 23:21:34 +0200 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2014-10-07 23:21:34 +0200 |
commit | 93097a178c6d0d50cbcfdf26a1a63fd571138484 (patch) | |
tree | 0919df4cbd5660b0ec32132cf0e4fad38aa62210 /src/pipelines.c | |
parent | prepared build system for multiple binaries (diff) |
cleanup for multiple binaries
Diffstat (limited to 'src/pipelines.c')
-rw-r--r-- | src/pipelines.c | 588 |
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; -} |