summaryrefslogtreecommitdiff
path: root/src/pipelines.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2014-10-02 00:24:31 +0200
committerChristian Pointner <equinox@spreadspace.org>2014-10-02 00:24:31 +0200
commit9f2b989e2dd9c8e50a8b3accb2f5afdee045b89e (patch)
treea909466325338948933a732c83d015b4ce13b337 /src/pipelines.c
parentsydra create bin now lets the caller control wheter to create ghost pads or not (diff)
source and sink are now same bin for video and audio
Diffstat (limited to 'src/pipelines.c')
-rw-r--r--src/pipelines.c106
1 files changed, 76 insertions, 30 deletions
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) ||