summaryrefslogtreecommitdiff
path: root/src/pipelines.c
diff options
context:
space:
mode:
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) ||