From 9f2b989e2dd9c8e50a8b3accb2f5afdee045b89e Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 2 Oct 2014 00:24:31 +0200 Subject: source and sink are now same bin for video and audio --- src/pipelines.c | 106 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 30 deletions(-) (limited to 'src/pipelines.c') diff --git a/src/pipelines.c b/src/pipelines.c index abe6fca..c291549 100644 --- a/src/pipelines.c +++ b/src/pipelines.c @@ -43,14 +43,10 @@ #include "utils.h" #include "log.h" - - struct av_elements { const char* name_; - const char* srcsink_str_; GstElement* srcsink_; - GstElement* tee_raw_; const char* encdec_str_; @@ -62,34 +58,58 @@ struct av_elements { GstElement* payloader_; }; -static gboolean create_avsend_elements(struct av_elements *ave, GstElement* pipeline, GstElement *rtp, uint32_t session) +static GstElement* create_avsend_src(const char* desc, GstElement* pipeline) { - char bin_name[32]; + GstElement* src = sydra_create_bin_from_desc("AV source", desc, FALSE); + if(!src) return NULL; + gst_bin_add(GST_BIN(pipeline), src); + + GstElement* element = gst_bin_get_by_name(GST_BIN(src), "videosrc"); + 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"); + 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 video ghost pad for source bin"); + return NULL; + } + gst_object_unref(GST_OBJECT(pad)); + gst_object_unref(GST_OBJECT(element)); + + return src; +} - snprintf(bin_name, sizeof(bin_name), "%s source", ave->name_); - ave->srcsink_ = sydra_create_bin_from_desc(bin_name, ave->srcsink_str_, TRUE); +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", 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->srcsink_ || !ave->tee_raw_ || !qr || !ave->encdec_ || !ave->tee_enc_ || !qe || !ave->payloader_) { + if(!ave->tee_raw_ || !qr || !ave->encdec_ || !ave->tee_enc_ || !qe || !ave->payloader_) { return FALSE; } log_printf(DEBUG, "%s path created successfully!", ave->name_); - gst_bin_add_many (GST_BIN(pipeline), ave->srcsink_, ave->tee_raw_, qr, ave->encdec_, ave->tee_enc_, qe, ave->payloader_, NULL); - gst_element_link(ave->srcsink_, ave->tee_raw_); + 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(bin_name), "send_rtp_sink_%u", session); + 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)) { @@ -100,29 +120,54 @@ static gboolean create_avsend_elements(struct av_elements *ave, GstElement* pipe return TRUE; } -static gboolean create_avrecv_elements(struct av_elements *ave, GstElement* pipeline) +static GstElement* create_avrecv_sink(const char* desc, GstElement* pipeline) { - char bin_name[32]; + GstElement* sink = sydra_create_bin_from_desc("AV sink", desc, FALSE); + if(!sink) return NULL; + gst_bin_add(GST_BIN(pipeline), sink); + + GstElement* element = gst_bin_get_by_name(GST_BIN(sink), "videosink"); + 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"); + 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 video ghost pad for source bin"); + return NULL; + } + gst_object_unref(GST_OBJECT(pad)); + gst_object_unref(GST_OBJECT(element)); + + return sink; +} - snprintf(bin_name, sizeof(bin_name), "%s sink", ave->name_); - ave->srcsink_ = sydra_create_bin_from_desc(bin_name, ave->srcsink_str_, TRUE); +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", 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->srcsink_ || !ave->tee_raw_ || !qr || !ave->encdec_ || !ave->tee_enc_ || !qe || !ave->payloader_) { + if(!ave->tee_raw_ || !qr || !ave->encdec_ || !ave->tee_enc_ || !qe || !ave->payloader_) { return FALSE; } log_printf(DEBUG, "%s path created successfully!", ave->name_); - gst_bin_add_many (GST_BIN(pipeline), ave->srcsink_, 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, ave->srcsink_, NULL); + 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, "sink", ave->srcsink_, ave->name_)) return FALSE; log_printf(DEBUG, "%s path linked successfully!", ave->name_); return TRUE; @@ -314,16 +359,16 @@ GstElement* create_sender_pipeline(options_t* opt, struct udp_sinks *udp) return NULL; } GstElement *rtp = sydra_create_element("rtpbin", "rtpbin"); - if(!rtp || !gst_bin_add(GST_BIN(pipeline), rtp)) { - return NULL; - } + if(!rtp || !gst_bin_add(GST_BIN(pipeline), rtp)) return NULL; log_printf(DEBUG, "rtpbin created successfully!"); - struct av_elements video = { "video", opt->video_src_, NULL, NULL, - opt->video_enc_, NULL, NULL, + GstElement* src = create_avsend_src(opt->source_, pipeline); + if(!src) return NULL; + log_printf(DEBUG, "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", opt->audio_src_, NULL, NULL, - opt->audio_enc_, NULL, 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) || @@ -400,12 +445,13 @@ GstElement* create_receiver_pipeline(options_t* opt, struct udp_sources *udp) } log_printf(DEBUG, "rtpbin created successfully!"); + GstElement* sink = create_avrecv_sink(opt->sink_, pipeline); + if(!sink) return NULL; + log_printf(DEBUG, "sink bin created successfully!"); - struct av_elements video = { "video", opt->video_sink_, NULL, NULL, - opt->video_dec_, NULL, NULL, + struct av_elements video = { "video", sink, NULL, opt->video_dec_, NULL, NULL, opt->video_depayloader_, NULL }; - struct av_elements audio = { "audio", opt->audio_sink_, NULL, NULL, - opt->audio_dec_, NULL, 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) || -- cgit v1.2.3