From 33d8e1012e8306394f458064d85220c217c84e20 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 22 Sep 2014 04:38:45 +0200 Subject: added support for recording - for now only video works --- src/options.c | 4 +-- src/sydra.c | 88 +++++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 61 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/options.c b/src/options.c index 2d1ded4..7789456 100644 --- a/src/options.c +++ b/src/options.c @@ -271,8 +271,8 @@ void options_default(options_t* opt) opt->preview_videosink_ = NULL; - opt->rec_mux_ = strdup("oggmux"); - opt->rec_name_format_ = strdup("./recordings/%Y-%m-%d_%H-%M-%S.ogg"); + opt->rec_mux_ = strdup("matroskamux"); + opt->rec_name_format_ = strdup("./recordings/%Y-%m-%d_%H-%M-%S.mkv"); } void options_clear(options_t* opt) diff --git a/src/sydra.c b/src/sydra.c index 49951aa..0d9975f 100644 --- a/src/sydra.c +++ b/src/sydra.c @@ -221,6 +221,21 @@ static gboolean sydra_link_static_static(GstElement* src, const char* src_pad_na return sydra_link_pads(src, src_pad, src_pad_name, sink, sink_pad, sink_pad_name); } +static gboolean sydra_link_static_compatible(GstElement* src, const char* src_pad_name, GstElement* sink) +{ + GstPad *src_pad = gst_element_get_static_pad(src, src_pad_name); + if(!src_pad) return FALSE; + + GstPad *sink_pad = gst_element_get_compatible_pad(sink, src_pad, NULL); + if(!src_pad) return FALSE; + + gchar* sink_pad_name = gst_pad_get_name(sink_pad); + gboolean res = sydra_link_pads(src, src_pad, src_pad_name, sink, sink_pad, sink_pad_name); + g_free(sink_pad_name); + + return res; +} + struct media_elements { const char* name_; @@ -338,6 +353,45 @@ static gboolean create_preview_elements(const char* preview_bin_desc, GstElement return TRUE; } +static gboolean create_recorder_elements(const char* mux_str, const char* name_format, GstElement* pipeline, GstElement* tv, GstElement* ta) +{ + GstElement *qv = sydra_create_element("queue", NULL); + GstElement *qa = sydra_create_element("queue", NULL); + GstElement *mux = sydra_create_element(mux_str, NULL); + GstElement *sink = sydra_create_element("filesink", NULL); + + if(!qv || !qa || !mux || !sink) { + return FALSE; + } + + log_printf(DEBUG, "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]; //TODO: fix this hardcoded length + strftime(recfile, sizeof(recfile), 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); + + /* if(!sydra_link_request_static(tv, "src_%u", qv, "sink") || */ + /* !sydra_link_static_compatible(qv, "src", mux) || */ + /* !sydra_link_request_static(ta, "src_%u", qa, "sink") || */ + /* !sydra_link_static_compatible(qa, "src", mux)) { */ + /* return FALSE; */ + /* } */ + if(!sydra_link_request_static(tv, "src_%u", qv, "sink") || + !sydra_link_static_compatible(qv, "src", mux)) { + return FALSE; + } + + log_printf(DEBUG, "recorder path linked successfully!"); + return TRUE; +} + static GstElement* create_pipeline(options_t* opt) { GstElement *pipeline = gst_pipeline_new ("sydra"); @@ -349,7 +403,6 @@ static GstElement* create_pipeline(options_t* opt) if(!rtp || !gst_bin_add(GST_BIN(pipeline), rtp)) { return NULL; } - log_printf(DEBUG, "rtpbin created successfully!"); struct media_elements video = { "video", opt->video_src_, NULL, NULL, @@ -369,38 +422,15 @@ static GstElement* create_pipeline(options_t* opt) return NULL; } + if(opt->rec_mux_) { + if(!create_recorder_elements(opt->rec_mux_, opt->rec_name_format_, pipeline, video.tee_enc_, audio.tee_enc_)) + return NULL; + } + log_printf(DEBUG, "pipeline created successfully!"); return pipeline; } -/* static char* build_sender_pipeline_desc(options_t* opt) */ -/* { */ - /* struct timespec now; */ - /* clock_gettime(CLOCK_REALTIME, &now); */ - /* struct tm bd_time; */ - /* localtime_r(&(now.tv_sec), &bd_time); */ - /* char recfile[1024]; //TODO: fix this hardcoded length */ - /* strftime(recfile, sizeof(recfile), opt->rec_name_format_, &bd_time); */ - -/* char* sender_desc; */ -/* int slen = asprintf(&sender_desc, "rtpbin name=rtpbin \ */ -/* %s ! tee name=vt \ */ -/* vt. ! queue silent=true ! %s ! tee name=cvt \ */ -/* cvt. ! %s ! rtpbin.send_rtp_sink_0 \ */ -/* rtpbin.send_rtp_src_0 ! udpsink port=%d host=%s \ */ -/* rtpbin.send_rtcp_src_0 ! udpsink port=%d host=%s sync=false async=false \ */ -/* %s ! tee name=at \ */ -/* at. ! queue silent=true ! %s ! %s ! rtpbin.send_rtp_sink_1 \ */ -/* rtpbin.send_rtp_src_1 ! udpsink port=%d host=%s \ */ -/* rtpbin.send_rtcp_src_1 ! udpsink port=%d host=%s sync=false async=false \ */ -/* at. ! queue silent=true ! %s name=recmux ! filesink location=\"%s\" \ */ -/* vt. ! queue silent=true ! textoverlay text=\" local \" shaded-background=true halignment=center valignment=baseline font-desc=\"Sans 18\" ! %s", */ -/* opt->video_src_, opt->video_enc_, opt->video_payloader_, rtp_port_v, opt->rtp_host_, rtcp_port_v, opt->rtp_host_, */ -/* opt->audio_src_, opt->audio_enc_stream_, opt->audio_payloader_, rtp_port_a, opt->rtp_host_, rtcp_port_a, opt->rtp_host_, */ -/* opt->rec_mux_, recfile, opt->videosink_); */ - -/* return (slen < 0) ? NULL : sender_desc; */ -/* } */ int main_loop(options_t* opt) { -- cgit v1.2.3