summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2014-09-27 20:13:56 +0200
committerChristian Pointner <equinox@spreadspace.org>2014-09-27 20:13:56 +0200
commite7ca89be606fc88c740d48b6cbdeff520a8d9ece (patch)
treed76566dfff7eeaa6169b881a38a7ab8988a51373 /src
parentidx vs. session (diff)
creating udp sources works now
Diffstat (limited to 'src')
-rw-r--r--src/options.c79
-rw-r--r--src/options.h8
-rw-r--r--src/pipelines.c60
3 files changed, 132 insertions, 15 deletions
diff --git a/src/options.c b/src/options.c
index 48a0f20..532039b 100644
--- a/src/options.c
+++ b/src/options.c
@@ -64,10 +64,18 @@ static void options_defaults(options_t* opt)
opt->video_src_ = g_strdup("v4l2src ! videoconvert ! videoscale ! video/x-raw,format=I420,width=864,height=480,framerate=25/1,pixel-aspect-ratio=1/1 ! identity");
opt->video_enc_ = g_strdup("vp8enc keyframe-max-dist=25 error-resilient=2 end-usage=1 target-bitrate=1200000 cpu-used=4 deadline=1000000 threads=2");
opt->video_payloader_ = g_strdup("rtpvp8pay");
+ opt->video_caps_ = g_strdup("application/x-rtp,media=video,clock-rate=90000,encoding-name=VP8-DRAFT-IETF-01,caps=\"video/x-vp8\"");
+ opt->video_depayloader_ = g_strdup("rtpvp8depay");
+ opt->video_dec_ = g_strdup("vp8dec");
+ opt->video_sink_ = g_strdup("videoconvert ! videoscale add-borders=true ! xvimagesink");
opt->audio_src_ = g_strdup("autoaudiosrc ! audio/x-raw,format=S16LE,channels=1,rate=48000 ! identity");
opt->audio_enc_ = g_strdup("opusenc bitrate=64000 cbr=true packet-loss-percentage=0 inband-fec=false");
opt->audio_payloader_ = g_strdup("rtpopuspay");
+ opt->audio_caps_ = g_strdup("application/x-rtp,media=audio,clock-rate=48000,payload=96,encoding-name=X-GST-OPUS-DRAFT-SPITTKA-00,caps=\"audio/x-opus\"");
+ opt->audio_depayloader_ = g_strdup("rtpopusdepay");
+ opt->audio_dec_ = g_strdup("opusdec");
+ opt->audio_sink_ = g_strdup("audioconvert ! autoaudiosink");
opt->rtp_host_ = NULL;
opt->rtp_port_base_ = 5000;
@@ -93,15 +101,17 @@ static GQuark options_error_quark()
return quark;
}
-static GOptionGroup* options_get_av_group(options_t* opt)
+static GOptionGroup* options_get_avsend_group(options_t* opt)
{
- GOptionEntry av_entries[] = {
+ GOptionEntry avsend_entries[] = {
{ "video-source", 0, 0, G_OPTION_ARG_STRING, &opt->video_src_,
"pipeline for raw video (i.e. videotestsrc)", "BIN DESCRIPTION" },
{ "video-encoder", 0, 0, G_OPTION_ARG_STRING, &opt->video_enc_,
"pipeline for video encoder (i.e. videoconvert ! vp8enc)", "BIN DESCRIPTION" },
{ "video-payloader", 0, 0, G_OPTION_ARG_STRING, &opt->video_payloader_,
"video RTP payloader element (i.e. rtpvp8pay)", "ELEMENT" },
+ { "previewsink", 0, 0, G_OPTION_ARG_STRING, &opt->preview_videosink_,
+ "video sink element for local preview (i.e. textoverlay text=\" preview \" ! xvimagesink) - leave empty to disable preview", "BIN DESCRIPTION" },
{ "audio-source", 0, 0, G_OPTION_ARG_STRING, &opt->audio_src_,
"pipeline for raw audio (i.e. audiotestsrc)", "BIN DESCRIPTION" },
{ "audio-encoder", 0, 0, G_OPTION_ARG_STRING, &opt->audio_enc_,
@@ -110,12 +120,41 @@ static GOptionGroup* options_get_av_group(options_t* opt)
"audio RTP payloader element (i.e. rtpopuspay)", "ELEMENT" },
{ NULL }
};
- GOptionGroup* av_group = g_option_group_new ("av", "Audio/Video Options",
- "Show Audio/Video Options", opt, NULL);
- if(!av_group) return NULL;
- g_option_group_add_entries(av_group, av_entries);
+ GOptionGroup* avsend_group = g_option_group_new ("avsend", "Audio/Video Sender Options",
+ "Show Audio/Video Sender Options", opt, NULL);
+ if(!avsend_group) return NULL;
+ g_option_group_add_entries(avsend_group, avsend_entries);
+
+ return avsend_group;
+}
+
+static GOptionGroup* options_get_avrecv_group(options_t* opt)
+{
+ GOptionEntry avrecv_entries[] = {
+ { "video-caps", 0, 0, G_OPTION_ARG_STRING, &opt->video_caps_,
+ "Caps for incoming Video RTP packets", "CAPS" },
+ { "video-depayloader", 0, 0, G_OPTION_ARG_STRING, &opt->video_depayloader_,
+ "video RTP depayloader element (i.e. rtpvp8depay)", "ELEMENT" },
+ { "video-decoder", 0, 0, G_OPTION_ARG_STRING, &opt->video_dec_,
+ "pipeline for video decoder (i.e. vp8dec)", "BIN DESCRIPTION" },
+ { "video-sink", 0, 0, G_OPTION_ARG_STRING, &opt->video_sink_,
+ "video sink element (i.e. videoconvert ! xvimagesink)", "BIN DESCRIPTION" },
+ { "audio-caps", 0, 0, G_OPTION_ARG_STRING, &opt->audio_caps_,
+ "Caps for incoming Audio RTP packets", "CAPS" },
+ { "audio-depayloader", 0, 0, G_OPTION_ARG_STRING, &opt->audio_depayloader_,
+ "audio RTP depayloader element (i.e. rtpopusdepay)", "ELEMENT" },
+ { "audio-decoder", 0, 0, G_OPTION_ARG_STRING, &opt->audio_dec_,
+ "pipeline for audio decoder (i.e. opusdnc)", "BIN DESCRIPTION" },
+ { "audio-sink", 0, 0, G_OPTION_ARG_STRING, &opt->audio_sink_,
+ "audio sink element (i.e. audioconvert ! autoaudiosink)", "BIN DESCRIPTION" },
+ { NULL }
+ };
+ GOptionGroup* avrecv_group = g_option_group_new ("avrecv", "Audio/Video Receiver Options",
+ "Show Audio/Video Receiver Options", opt, NULL);
+ if(!avrecv_group) return NULL;
+ g_option_group_add_entries(avrecv_group, avrecv_entries);
- return av_group;
+ return avrecv_group;
}
static GOptionGroup* options_get_rtp_group(options_t* opt)
@@ -216,8 +255,6 @@ int options_parse(options_t* opt, int argc, char* argv[])
"set the application name (will be used by xvimagesink for window title)", "NAME" },
{ "mode", 'm', 0, G_OPTION_ARG_CALLBACK, options_parse_mode,
"the main operation mode", "(sender|receiver)" },
- { "videosink", 'V', 0, G_OPTION_ARG_STRING, &opt->preview_videosink_,
- "video sink element for local preview (i.e. textoverlay text=\" preview \" ! xvimagesink) - leave empty to disable preview", "BIN DESCRIPTION" },
{ NULL }
};
GOptionContext *ctx = g_option_context_new("- spreadspace streaming hydra ");
@@ -226,16 +263,18 @@ int options_parse(options_t* opt, int argc, char* argv[])
if(main_group)
g_option_group_add_entries(main_group, main_entries);
- GOptionGroup* av_group = options_get_av_group(opt);
+ GOptionGroup* avsend_group = options_get_avsend_group(opt);
+ GOptionGroup* avrecv_group = options_get_avrecv_group(opt);
GOptionGroup* rtp_group = options_get_rtp_group(opt);
GOptionGroup* rec_group = options_get_rec_group(opt);
GOptionGroup* gst_group = gst_init_get_option_group();
- if(!main_group || !av_group || !rtp_group || !rec_group || !gst_group) {
+ if(!main_group || !avsend_group || !avrecv_group || !rtp_group || !rec_group || !gst_group) {
printf("Failed to initialize: memory error\n");
return -127;
}
g_option_context_set_main_group(ctx, main_group);
- g_option_context_add_group(ctx, av_group);
+ g_option_context_add_group(ctx, avsend_group);
+ g_option_context_add_group(ctx, avrecv_group);
g_option_context_add_group(ctx, rtp_group);
g_option_context_add_group(ctx, rec_group);
g_option_context_add_group(ctx, gst_group);
@@ -306,9 +345,17 @@ void options_clear(options_t* opt)
g_free(opt->video_src_);
g_free(opt->video_enc_);
g_free(opt->video_payloader_);
+ g_free(opt->video_caps_);
+ g_free(opt->video_depayloader_);
+ g_free(opt->video_dec_);
+ g_free(opt->video_sink_);
g_free(opt->audio_src_);
g_free(opt->audio_enc_);
g_free(opt->audio_payloader_);
+ g_free(opt->audio_caps_);
+ g_free(opt->audio_depayloader_);
+ g_free(opt->audio_dec_);
+ g_free(opt->audio_sink_);
g_free(opt->rtp_host_);
g_free(opt->rtp_addr_local_);
g_free(opt->preview_videosink_);
@@ -363,9 +410,17 @@ void options_print(options_t* opt)
printf(" video_src: >>%s<<\n", opt->video_src_);
printf(" video_enc: >>%s<<\n", opt->video_enc_);
printf(" video_payloader: >>%s<<\n", opt->video_payloader_);
+ printf(" video_caps: >>%s<<\n", opt->video_caps_);
+ printf(" video_depayloader: >>%s<<\n", opt->video_depayloader_);
+ printf(" video_dec: >>%s<<\n", opt->video_dec_);
+ printf(" video_sink: >>%s<<\n", opt->video_sink_);
printf(" audio_src: >>%s<<\n", opt->audio_src_);
printf(" audio_enc: >>%s<<\n", opt->audio_enc_);
printf(" audio_payloader: >>%s<<\n", opt->audio_payloader_);
+ printf(" audio_caps: >>%s<<\n", opt->audio_caps_);
+ printf(" audio_depayloader: >>%s<<\n", opt->audio_depayloader_);
+ printf(" audio_dec: >>%s<<\n", opt->audio_dec_);
+ printf(" audio_sink: >>%s<<\n", opt->audio_sink_);
printf(" rtp_host: >>%s<<\n", opt->rtp_host_);
printf(" rtp_port_base: %d\n", opt->rtp_port_base_);
printf(" rtp_addr_local: >>%s<<\n", opt->rtp_addr_local_);
diff --git a/src/options.h b/src/options.h
index 983964e..30d7433 100644
--- a/src/options.h
+++ b/src/options.h
@@ -54,10 +54,18 @@ struct options_struct {
gchar* video_src_;
gchar* video_enc_;
gchar* video_payloader_;
+ gchar* video_caps_;
+ gchar* video_depayloader_;
+ gchar* video_dec_;
+ gchar* video_sink_;
gchar* audio_src_;
gchar* audio_enc_;
gchar* audio_payloader_;
+ gchar* audio_caps_;
+ gchar* audio_depayloader_;
+ gchar* audio_dec_;
+ gchar* audio_sink_;
gchar* rtp_host_;
gint rtp_port_base_;
diff --git a/src/pipelines.c b/src/pipelines.c
index 54400a9..7478a7b 100644
--- a/src/pipelines.c
+++ b/src/pipelines.c
@@ -110,7 +110,7 @@ static gboolean create_udp_sinks(options_t* opt, GstElement* pipeline, GstElemen
if(!(sinks->rtp_video_.udp_) || !(sinks->rtcp_video_.udp_) || !(sinks->rtp_audio_.udp_) || !(sinks->rtcp_audio_.udp_))
return FALSE;
- log_printf(DEBUG, "udp elements created successfully!");
+ log_printf(DEBUG, "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);
@@ -132,7 +132,9 @@ static gboolean create_udp_sinks(options_t* opt, GstElement* pipeline, GstElemen
g_object_set(G_OBJECT(sinks->rtcp_audio_.udp_), "bind-address", opt->rtp_addr_local_, NULL);
}
- gst_bin_add_many(GST_BIN (pipeline), sinks->rtp_video_.udp_, sinks->rtcp_video_.udp_, sinks->rtp_audio_.udp_, sinks->rtcp_audio_.udp_, NULL);
+ log_printf(DEBUG, "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") ||
@@ -140,7 +142,55 @@ static gboolean create_udp_sinks(options_t* opt, GstElement* pipeline, GstElemen
!sydra_link_request_static(rtp, "send_rtcp_src_1", sinks->rtcp_audio_.udp_, "sink"))
return FALSE;
- log_printf(DEBUG, "udp elements linked successfully!");
+ log_printf(DEBUG, "udp sinks linked successfully!");
+
+ return TRUE;
+}
+
+static gboolean create_udp_sources(options_t* opt, GstElement* pipeline, GstElement* rtp, struct udp_sources *sources)
+{
+ sources->rtp_video_ = sydra_create_element("udpsrc", "udprtpv");
+ sources->rtcp_video_ = sydra_create_element("udpsrc", "udprtcpv");
+ sources->rtp_audio_ = sydra_create_element("udpsrc", "udprtpa");
+ sources->rtcp_audio_ = sydra_create_element("udpsrc", "udprtcpa");
+
+ if(!(sources->rtp_video_) || !(sources->rtcp_video_) || !(sources->rtp_audio_) || !(sources->rtcp_audio_))
+ return FALSE;
+
+ log_printf(DEBUG, "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(DEBUG, "udp sources configured successfully!");
+
+ gst_bin_add_many(GST_BIN(pipeline), sources->rtp_video_, sources->rtcp_video_, sources->rtp_audio_, sources->rtcp_audio_, NULL);
+
+ if(!sydra_link_static_request(sources->rtp_video_, "src", rtp, "recv_rtp_sink_0") ||
+ !sydra_link_static_request(sources->rtcp_video_, "src", rtp, "recv_rtcp_sink_0") ||
+ !sydra_link_static_request(sources->rtp_audio_, "src", rtp, "recv_rtp_sink_1") ||
+ !sydra_link_static_request(sources->rtcp_audio_, "src", rtp, "recv_rtcp_sink_1"))
+ return FALSE;
+
+ log_printf(DEBUG, "udp sources linked successfully!");
return TRUE;
}
@@ -301,6 +351,10 @@ GstElement* create_receiver_pipeline(options_t* opt, struct udp_sources *udp)
}
log_printf(DEBUG, "rtpbin created successfully!");
+ if(!create_udp_sources(opt, pipeline, rtp, udp)) {
+ return NULL;
+ }
+
log_printf(DEBUG, "receiver pipeline created successfully!");
return pipeline;
}