From 25222b1a41d74fac81c3b968856e486991e044ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Kreith?= Date: Tue, 15 Sep 2015 17:43:26 +0300 Subject: [PATCH 01/18] add mprtp scheduler --- transport/owr_transport_agent.c | 67 +++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index b429df72..2e75d4c0 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -112,6 +112,7 @@ typedef struct { } DataChannel; typedef struct { + GstElement *mprtp_sch; GstElement *dtls_srtp_bin_rtp; GstElement *dtls_srtp_bin_rtcp; GstElement *send_output_bin; @@ -1198,6 +1199,29 @@ static GstElement *add_dtls_srtp_bin(OwrTransportAgent *transport_agent, guint s return dtls_srtp_bin; } +static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agent, guint stream_id, + GstElement *bin) +{ + GstElement *mprtp_sch = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_sch_%s", stream_id); + + mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); + + g_object_set(mprtp_sch, "subflow-riports-enabled", FALSE, NULL); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_sch; +} + static GstPad *ghost_pad_and_add_to_bin(GstPad *pad, GstElement *bin, const gchar *pad_name) { GstPad *ghost_pad; @@ -1233,11 +1257,12 @@ static void on_rtcp_mux_changed(OwrMediaSession *media_session, GParamSpec *pspe static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, guint stream_id, gboolean rtp, gboolean rtcp) { - gchar *rtpbin_pad_name, *dtls_srtp_pad_name; + gchar *rtpbin_pad_name, *sink_pad_name; gchar *output_selector_name; gboolean linked_ok; GstPad *sink_pad, *src_pad; GstElement *output_selector; + GstElement* mprtp_sch; GstElement *dtls_srtp_bin_rtp; GstElement *dtls_srtp_bin_rtcp; GstElement *send_output_bin; @@ -1248,7 +1273,7 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g send_bin_info = g_hash_table_lookup(transport_agent->priv->send_bins, GINT_TO_POINTER(stream_id)); g_return_if_fail(send_bin_info); - + mprtp_sch = send_bin_info->mprtp_sch; dtls_srtp_bin_rtp = send_bin_info->dtls_srtp_bin_rtp; dtls_srtp_bin_rtcp = send_bin_info->dtls_srtp_bin_rtcp; send_output_bin = send_bin_info->send_output_bin; @@ -1259,19 +1284,18 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g /* RTP */ if (rtp) { rtpbin_pad_name = g_strdup_printf("send_rtp_src_%u", stream_id); - dtls_srtp_pad_name = g_strdup_printf("rtp_sink_%u", stream_id); - - sink_pad = gst_element_get_request_pad(dtls_srtp_bin_rtp, dtls_srtp_pad_name); + sink_pad_name = g_strdup_printf("rtp_sink_%u", stream_id); + sink_pad = gst_element_get_static_pad(mprtp_sch, "rtp_sink"); g_assert(GST_IS_PAD(sink_pad)); - ghost_pad_and_add_to_bin(sink_pad, send_output_bin, dtls_srtp_pad_name); + ghost_pad_and_add_to_bin(sink_pad, send_output_bin, sink_pad_name); gst_object_unref(sink_pad); linked_ok = gst_element_link_pads(transport_agent->priv->rtpbin, rtpbin_pad_name, - send_output_bin, dtls_srtp_pad_name); + send_output_bin, sink_pad_name); g_warn_if_fail(linked_ok); g_free(rtpbin_pad_name); - g_free(dtls_srtp_pad_name); + g_free(sink_pad_name); } /* RTCP */ @@ -1284,10 +1308,10 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g gst_element_sync_state_with_parent(output_selector); rtpbin_pad_name = g_strdup_printf("send_rtcp_src_%u", stream_id); - dtls_srtp_pad_name = g_strdup_printf("rtcp_sink_%u", stream_id); + sink_pad_name = g_strdup_printf("rtcp_sink_%u", stream_id); /* RTCP muxing */ - sink_pad = gst_element_get_request_pad(dtls_srtp_bin_rtp, dtls_srtp_pad_name); + sink_pad = gst_element_get_request_pad(dtls_srtp_bin_rtp, sink_pad_name); g_assert(GST_IS_PAD(sink_pad)); src_pad = gst_element_get_request_pad(output_selector, "src_%u"); g_assert(GST_IS_PAD(src_pad)); @@ -1299,7 +1323,7 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g if (dtls_srtp_bin_rtcp) { /* RTCP standalone */ - sink_pad = gst_element_get_request_pad(dtls_srtp_bin_rtcp, dtls_srtp_pad_name); + sink_pad = gst_element_get_request_pad(dtls_srtp_bin_rtcp, sink_pad_name); g_assert(GST_IS_PAD(sink_pad)); src_pad = gst_element_get_request_pad(output_selector, "src_%u"); g_assert(GST_IS_PAD(src_pad)); @@ -1316,15 +1340,15 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g } sink_pad = gst_element_get_static_pad(output_selector, "sink"); - ghost_pad_and_add_to_bin(sink_pad, send_output_bin, dtls_srtp_pad_name); + ghost_pad_and_add_to_bin(sink_pad, send_output_bin, sink_pad_name); gst_object_unref(sink_pad); linked_ok = gst_element_link_pads(transport_agent->priv->rtpbin, rtpbin_pad_name, - send_output_bin, dtls_srtp_pad_name); + send_output_bin, sink_pad_name); g_warn_if_fail(linked_ok); g_free(rtpbin_pad_name); - g_free(dtls_srtp_pad_name); + g_free(sink_pad_name); send_bin_info->linked_rtcp = TRUE; } @@ -1336,8 +1360,10 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age GstElement *nice_element, *dtls_srtp_bin_rtp, *dtls_srtp_bin_rtcp = NULL; gboolean linked_ok, synced_ok; GstElement *send_output_bin; + GstElement *mprtp_sch; SendBinInfo *send_bin_info; - gchar *bin_name; + gchar *bin_name, *dtls_srtp_pad_name; + GstPad *sink_pad; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); @@ -1356,6 +1382,14 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); dtls_srtp_bin_rtp = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); + mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, send_output_bin); + dtls_srtp_pad_name = g_strdup_printf("rtp_sink_%u", stream_id); + + linked_ok = gst_element_link_pads(mprtp_sch, "mprtp_src", + dtls_srtp_bin_rtp, dtls_srtp_pad_name); + g_free(dtls_srtp_pad_name); + + g_warn_if_fail(linked_ok); linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); g_warn_if_fail(linked_ok); synced_ok = gst_element_sync_state_with_parent(nice_element); @@ -1375,6 +1409,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age } send_bin_info = g_new(SendBinInfo, 1); + send_bin_info->mprtp_sch = mprtp_sch; send_bin_info->dtls_srtp_bin_rtp = dtls_srtp_bin_rtp; send_bin_info->dtls_srtp_bin_rtcp = dtls_srtp_bin_rtcp; send_bin_info->send_output_bin = send_output_bin; @@ -1458,7 +1493,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ rtcp_src_pad = gst_element_get_static_pad(funnel, "src"); ghost_pad_and_add_to_bin(rtcp_src_pad, receive_input_bin, "rtcp_src"); gst_object_unref(rtcp_src_pad); - +//mprtpplayouter rtpbin_pad_name = g_strdup_printf("recv_rtcp_sink_%u", stream_id); linked_ok = gst_element_link_pads(receive_input_bin, "rtcp_src", transport_agent->priv->rtpbin, rtpbin_pad_name); From 84c7504cd0c0cc44a275063e2013d67ae3fc4563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Kreith?= Date: Tue, 15 Sep 2015 18:03:36 +0300 Subject: [PATCH 02/18] add mprtp scheduler --- transport/owr_transport_agent.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index 2e75d4c0..f071b281 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -1208,7 +1208,7 @@ static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agen g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - element_name = g_strdup_printf("mprtp_sch_%s", stream_id); + element_name = g_strdup_printf("mprtp_sch_%d", stream_id); mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); @@ -1363,7 +1363,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age GstElement *mprtp_sch; SendBinInfo *send_bin_info; gchar *bin_name, *dtls_srtp_pad_name; - GstPad *sink_pad; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); From 376491879e7a51a5d9fb09b01c6c69e3287b00be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Kreith?= Date: Tue, 15 Sep 2015 18:26:40 +0300 Subject: [PATCH 03/18] crash probe. Damn, I must figure out compile it on local --- transport/owr_transport_agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index f071b281..1282fbf8 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -1389,7 +1389,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age g_free(dtls_srtp_pad_name); g_warn_if_fail(linked_ok); - linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); + //linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); g_warn_if_fail(linked_ok); synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); From fecad9990171216480f14af653f4d73e1c3c4991 Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Thu, 17 Sep 2015 17:43:23 +0300 Subject: [PATCH 04/18] change back --- transport/owr_transport_agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index 1282fbf8..f071b281 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -1389,7 +1389,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age g_free(dtls_srtp_pad_name); g_warn_if_fail(linked_ok); - //linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); + linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); g_warn_if_fail(linked_ok); synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); From aed1976dbba5f87a12a9d8045b3f2d665816851d Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Fri, 18 Sep 2015 09:41:47 +0300 Subject: [PATCH 05/18] join subflow try --- transport/owr_transport_agent.c | 1 + 1 file changed, 1 insertion(+) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index f071b281..fab44877 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -1213,6 +1213,7 @@ static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agen mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); g_object_set(mprtp_sch, "subflow-riports-enabled", FALSE, NULL); + g_object_set(mprtp_sch, "join-subflow=1", FALSE, NULL); added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); g_warn_if_fail(added_ok); From c85b826908df411f62aaa053ef81a6d00181551b Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Fri, 18 Sep 2015 09:45:34 +0300 Subject: [PATCH 06/18] join subflow try --- transport/owr_transport_agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index fab44877..c421fceb 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -1213,7 +1213,7 @@ static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agen mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); g_object_set(mprtp_sch, "subflow-riports-enabled", FALSE, NULL); - g_object_set(mprtp_sch, "join-subflow=1", FALSE, NULL); + g_object_set(mprtp_sch, "join-subflow", 1, NULL); added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); g_warn_if_fail(added_ok); From 478ddae6381688f2f23cf532660c52895d7f4a0b Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Fri, 18 Sep 2015 19:38:02 +0300 Subject: [PATCH 07/18] try --- transport/owr_transport_agent.c | 35 ++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index c421fceb..e473e85e 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -1223,6 +1223,32 @@ static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agen return mprtp_sch; } + +static GstElement *add_mprtp_plaoyouter_element(OwrTransportAgent *transport_agent, guint stream_id, + GstElement *bin) +{ + GstElement *mprtp_sch = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_ply_%d", stream_id); + + mprtp_sch = gst_element_factory_make("mprtpplayouter", element_name); + + g_object_set(mprtp_sch, "subflow-riports-enabled", FALSE, NULL); + g_object_set(mprtp_sch, "join-subflow", 1, NULL); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_sch; +} + + static GstPad *ghost_pad_and_add_to_bin(GstPad *pad, GstElement *bin, const gchar *pad_name) { GstPad *ghost_pad; @@ -1423,6 +1449,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ guint stream_id, gboolean rtcp_mux) { GstElement *nice_element, *dtls_srtp_bin, *funnel; + GstElement *mprtp_ply; GstPad *rtp_src_pad, *rtcp_src_pad; gchar *rtpbin_pad_name; gboolean linked_ok, synced_ok; @@ -1449,8 +1476,11 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); + mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, receive_input_bin); - rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); + //rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); + gst_element_link_pads(dtls_srtp_bin, "rtp_src", mprtp_ply, "mprtp_sink"); + rtp_src_pad = gst_element_get_static_pad(mprtp_ply, "mprtp_src"); ghost_pad_and_add_to_bin(rtp_src_pad, receive_input_bin, "rtp_src"); gst_object_unref(rtp_src_pad); @@ -1525,6 +1555,7 @@ static void prepare_transport_bin_data_receive_elements(OwrTransportAgent *trans { OwrTransportAgentPrivate *priv; GstElement *nice_element, *dtls_srtp_bin, *sctpdec; + //GstElement *mprtp_ply; GstElement *receive_input_bin; gchar *name; OwrDataSession *data_session; @@ -1552,6 +1583,8 @@ static void prepare_transport_bin_data_receive_elements(OwrTransportAgent *trans nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); + //mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, receive_input_bin); + sctpdec = _owr_data_session_create_decoder(data_session); g_return_if_fail(nice_element && dtls_srtp_bin && sctpdec); From f628f235ae5af9759b557efaacc13164e743a580 Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Sun, 20 Sep 2015 16:48:22 +0300 Subject: [PATCH 08/18] changes for mprtp --- tests/test_send_receive.c | 8 + transport/owr_transport_agent.c | 285 +++++++++++++++++++++++++++++++- transport/owr_transport_agent.h | 1 + 3 files changed, 288 insertions(+), 6 deletions(-) diff --git a/tests/test_send_receive.c b/tests/test_send_receive.c index 90c51466..dbdb8255 100644 --- a/tests/test_send_receive.c +++ b/tests/test_send_receive.c @@ -182,10 +182,16 @@ static void got_sources(GList *sources, gpointer user_data) } } +static gboolean added = FALSE; static gboolean dump_cb(gpointer *user_data) { g_print("Dumping send transport agent pipeline!\n"); + if(!added){ + owr_transport_agent_join_subflow(recv_transport_agent, 2, "127.0.0.2"); + owr_transport_agent_join_subflow(send_transport_agent, 2, "127.0.0.2"); + added = TRUE; + } if (video_source) write_dot_file("test_send-got_source-video-source", owr_media_source_get_dot_data(video_source), TRUE); if (video_renderer) @@ -294,6 +300,7 @@ int main(int argc, char **argv) owr_transport_agent_set_local_port_range(send_transport_agent, 5000, 5999); owr_transport_agent_add_local_address(send_transport_agent, "127.0.0.1"); + if (!disable_video) { recv_session_video = owr_media_session_new(FALSE); owr_bus_add_message_origin(bus, OWR_MESSAGE_ORIGIN(recv_session_video)); @@ -345,6 +352,7 @@ int main(int argc, char **argv) g_timeout_add_seconds(10, (GSourceFunc)dump_cb, NULL); + owr_run(); return 0; diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index e473e85e..0b6001d2 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -112,7 +112,6 @@ typedef struct { } DataChannel; typedef struct { - GstElement *mprtp_sch; GstElement *dtls_srtp_bin_rtp; GstElement *dtls_srtp_bin_rtcp; GstElement *send_output_bin; @@ -120,6 +119,22 @@ typedef struct { gboolean linked_rtcp; } SendBinInfo; +typedef struct{ + guint8 id; + NiceAgent *sink_agent; + NiceAgent *src_agent; + GstElement *nicesink; + GstElement *nicesrc; + GstElement *bin; + guint sink_stream; + guint src_stream; + NiceComponentState src_state; + NiceComponentState sink_state; + guint component_id; + + OwrTransportAgent *parent; +}MpRTPSubflow; + struct _OwrTransportAgentPrivate { NiceAgent *nice_agent; gboolean ice_controlling_mode; @@ -134,6 +149,15 @@ struct _OwrTransportAgentPrivate { /* session_id -> struct SendBinInfo */ GHashTable *send_bins; + GstElement *mprtp_sch; + GstElement *mprtp_snd; + GstElement *mprtp_rcv; + GstElement *mprtp_ply; + GHashTable *mprtp_subflows; + + /* session_id -> struct MPRtpElements */ + //GHashTable *mprtp_elements; + gboolean local_address_added; guint local_min_port; guint local_max_port; @@ -451,6 +475,7 @@ static void owr_transport_agent_init(OwrTransportAgent *transport_agent) priv->data_session_established = FALSE; priv->send_bins = g_hash_table_new_full(NULL, NULL, NULL, g_free); + priv->mprtp_subflows = g_hash_table_new_full(NULL, NULL, NULL, g_free); priv->message_origin_bus_set = owr_message_origin_bus_set_new(); } @@ -542,6 +567,156 @@ void owr_transport_agent_add_helper_server(OwrTransportAgent *transport_agent, g_object_unref(resolver); } + + +static void +subflow_cb_candidate_gathering_done (NiceAgent * agent, guint stream_id, gpointer data) +{ + GSList *candidates; + + GST_INFO ("Candidates gathered on agent %" GST_PTR_FORMAT ", stream: %d", + agent, stream_id); + + candidates = nice_agent_get_local_candidates (agent, stream_id, 1); + + nice_agent_set_remote_candidates (NICE_AGENT (data), stream_id, 1, + candidates); + + g_slist_free_full (candidates, (GDestroyNotify) nice_candidate_free); +} + +static void +credentials_negotiation (NiceAgent * a_agent, NiceAgent * b_agent, + guint a_stream, guint b_stream) +{ + gchar *user = NULL; + gchar *passwd = NULL; + + nice_agent_get_local_credentials (a_agent, a_stream, &user, &passwd); + nice_agent_set_remote_credentials (b_agent, b_stream, user, passwd); + + g_free (user); + g_free (passwd); +} + +static void +subflow_cb_component_state_changed (NiceAgent * agent, guint stream_id, + guint component_id, guint state, gpointer user_data) +{ + MpRTPSubflow *subflow = (MpRTPSubflow *)user_data; + NiceComponentState *stateptr; + + g_return_if_fail(subflow); + stateptr = (subflow->src_stream == stream_id) ? &subflow->src_state : &subflow->sink_state; + *stateptr = state; + subflow->component_id = component_id; + g_print("unused parameters at " + "subflow_cb_component_state_changed: %p\n", agent); +} + +void owr_transport_agent_join_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id, + const gchar *local_address) +{ + NiceAddress addr; + NiceAgent *sink_agent; + NiceAgent *src_agent; + MpRTPSubflow *subflow; + GstElement *nicesink; + GstElement *nicesrc; + GstElement *subflow_bin; + gchar *bin_name; + gchar *padname; + gchar *element_name; + gboolean synced_ok; + guint sink_stream; + guint src_stream; + OwrTransportAgentPrivate *priv; + + g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); + g_return_if_fail(local_address); + g_return_if_fail(transport_agent->priv->local_address_added); + g_return_if_fail(nice_address_set_from_string(&addr, local_address)); + + priv = transport_agent->priv; + + subflow = g_malloc0(sizeof(MpRTPSubflow)); + subflow->sink_agent = sink_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); + subflow->src_agent = src_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); + + nice_agent_add_local_address (sink_agent, &addr); + nice_agent_add_local_address (src_agent, &addr); + + subflow->sink_stream = sink_stream = nice_agent_add_stream (sink_agent, 1); + subflow->src_stream = src_stream = nice_agent_add_stream (src_agent, 1); + + bin_name = g_strdup_printf("subflow-bin-%hu", subflow_id); + subflow->bin = subflow_bin = gst_bin_new(bin_name); + g_free(bin_name); + + + g_signal_connect (G_OBJECT (sink_agent), "candidate-gathering-done", + G_CALLBACK (subflow_cb_candidate_gathering_done), src_agent); + g_signal_connect (G_OBJECT (src_agent), "candidate-gathering-done", + G_CALLBACK (subflow_cb_candidate_gathering_done), sink_agent); + + g_signal_connect (G_OBJECT (sink_agent), "component-state-changed", + G_CALLBACK (subflow_cb_component_state_changed), subflow); + g_signal_connect (G_OBJECT (src_agent), "component-state-changed", + G_CALLBACK (subflow_cb_component_state_changed), subflow); + + credentials_negotiation (sink_agent, src_agent, sink_stream, src_stream); + credentials_negotiation (src_agent, sink_agent, src_stream, src_stream); + + nice_agent_gather_candidates (sink_agent, sink_stream); + nice_agent_gather_candidates (src_agent, src_stream); + + element_name = g_strdup_printf("subflow-nicesink-%hhu", subflow_id); + subflow->nicesink = nicesink = gst_element_factory_make("nicesink", element_name); + g_free(element_name); + element_name = g_strdup_printf("subflow-nicesrc-%hhu", subflow_id); + subflow->nicesrc = nicesrc = gst_element_factory_make("nicesrc", element_name); + g_free(element_name); + + if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), subflow_bin)) { + GST_ERROR("Failed to add subflow_bin-%hhu to parent bin", subflow_id); + return; + } + if (!gst_element_sync_state_with_parent(subflow_bin)) { + GST_ERROR("Failed to sync subflow_bin-%hhu to parent bin", subflow_id); + return; + } + gst_bin_add_many(GST_BIN(subflow_bin), nicesrc, nicesink, NULL); + + g_object_set (nicesink, "agent", sink_agent, "stream", sink_stream, + "component", NICE_COMPONENT_TYPE_RTP, NULL); + g_object_set (nicesrc, "agent", src_agent, "stream", src_stream, + "component", NICE_COMPONENT_TYPE_RTP, NULL); + + g_object_set(nicesink, "enable-last-sample", FALSE, "async", FALSE, NULL); + + synced_ok = gst_element_sync_state_with_parent(nicesink); + g_warn_if_fail(synced_ok); + synced_ok = gst_element_sync_state_with_parent(nicesrc); + g_warn_if_fail(synced_ok); + + padname = g_strdup_printf("sink_%hhu", subflow_id); + gst_element_link_pads(nicesrc, "src", priv->mprtp_rcv, padname); + g_free(padname); + padname = g_strdup_printf("src_%hhu", subflow_id); + gst_element_link_pads(priv->mprtp_snd, padname, nicesink, "sink"); + g_free(padname); + + g_object_set(priv->mprtp_sch, "join-subflow", subflow_id, NULL); + g_object_set(priv->mprtp_ply, "join-subflow", subflow_id, NULL); + + g_hash_table_insert(transport_agent->priv->mprtp_subflows, + GINT_TO_POINTER(subflow_id), subflow); + +} + + + void owr_transport_agent_add_local_address(OwrTransportAgent *transport_agent, const gchar *local_address) { NiceAddress addr; @@ -1075,6 +1250,35 @@ static GstElement *add_nice_element(OwrTransportAgent *transport_agent, guint st return nice_element; } +// +//static GstElement *add_external_nice_element(OwrTransportAgent *transport_agent, guint stream_id, +// gboolean is_sink, GstElement *bin, NiceAgent *agent, gint external_id) +//{ +// GstElement *nice_element = NULL; +// gchar *element_name; +// gboolean added_ok; +// +// g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); +// +// element_name = g_strdup_printf("nice-rtp-%s-%u", is_sink +// ? "sink" : "src", stream_id + external_id); +// nice_element = gst_element_factory_make(is_sink ? "nicesink" : "nicesrc", element_name); +// g_free(element_name); +// +// g_object_set(nice_element, "agent", agent, +// "stream", stream_id + external_id, +// "component", NICE_COMPONENT_TYPE_RTP, NULL); +// +// if (is_sink) { +// g_object_set(nice_element, "enable-last-sample", FALSE, "async", FALSE, NULL); +// } +// +// added_ok = gst_bin_add(GST_BIN(bin), nice_element); +// g_warn_if_fail(added_ok); +// +// return nice_element; +//} + static void set_srtp_key(OwrMediaSession *media_session, GParamSpec *pspec, GstElement *dtls_srtp_bin) { @@ -1249,6 +1453,53 @@ static GstElement *add_mprtp_plaoyouter_element(OwrTransportAgent *transport_age } +static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent, guint stream_id, + GstElement *bin) +{ + GstElement *mprtp_rcv = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_rcv_%d", stream_id); + + mprtp_rcv = gst_element_factory_make("mprtpreceiver", element_name); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_rcv); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_rcv; +} + + + +static GstElement *add_mprtp_sender_element(OwrTransportAgent *transport_agent, guint stream_id, + GstElement *bin) +{ + GstElement *mprtp_snd = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_snd_%d", stream_id); + + mprtp_snd = gst_element_factory_make("mprtpsender", element_name); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_snd); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_snd; +} + + + + static GstPad *ghost_pad_and_add_to_bin(GstPad *pad, GstElement *bin, const gchar *pad_name) { GstPad *ghost_pad; @@ -1300,7 +1551,7 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g send_bin_info = g_hash_table_lookup(transport_agent->priv->send_bins, GINT_TO_POINTER(stream_id)); g_return_if_fail(send_bin_info); - mprtp_sch = send_bin_info->mprtp_sch; + mprtp_sch = transport_agent->priv->mprtp_sch; dtls_srtp_bin_rtp = send_bin_info->dtls_srtp_bin_rtp; dtls_srtp_bin_rtcp = send_bin_info->dtls_srtp_bin_rtcp; send_output_bin = send_bin_info->send_output_bin; @@ -1388,6 +1639,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age gboolean linked_ok, synced_ok; GstElement *send_output_bin; GstElement *mprtp_sch; + GstElement *mprtp_snd; SendBinInfo *send_bin_info; gchar *bin_name, *dtls_srtp_pad_name; @@ -1395,6 +1647,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age bin_name = g_strdup_printf("send-output-bin-%u", stream_id); send_output_bin = gst_bin_new(bin_name); + g_free(bin_name); if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), send_output_bin)) { @@ -1406,7 +1659,9 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age return; } + nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); + mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, send_output_bin); dtls_srtp_bin_rtp = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, send_output_bin); dtls_srtp_pad_name = g_strdup_printf("rtp_sink_%u", stream_id); @@ -1416,8 +1671,15 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age g_free(dtls_srtp_pad_name); g_warn_if_fail(linked_ok); - linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); + //linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); + linked_ok = gst_element_link_pads(dtls_srtp_bin_rtp, "src", mprtp_snd, "mprtp_sink"); + g_warn_if_fail(linked_ok); + linked_ok = gst_element_link_pads(mprtp_snd, "src_1", nice_element, "sink"); g_warn_if_fail(linked_ok); + synced_ok = gst_element_sync_state_with_parent(mprtp_snd); + g_warn_if_fail(synced_ok); + synced_ok = gst_element_sync_state_with_parent(mprtp_sch); + g_warn_if_fail(synced_ok); synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); synced_ok = gst_element_sync_state_with_parent(dtls_srtp_bin_rtp); @@ -1435,13 +1697,16 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age } send_bin_info = g_new(SendBinInfo, 1); - send_bin_info->mprtp_sch = mprtp_sch; send_bin_info->dtls_srtp_bin_rtp = dtls_srtp_bin_rtp; send_bin_info->dtls_srtp_bin_rtcp = dtls_srtp_bin_rtcp; send_bin_info->send_output_bin = send_output_bin; send_bin_info->linked_rtcp = FALSE; + transport_agent->priv->mprtp_sch = mprtp_sch; + transport_agent->priv->mprtp_snd = mprtp_snd; + g_hash_table_insert(transport_agent->priv->send_bins, GINT_TO_POINTER(stream_id), send_bin_info); + } /* #define TEST_RTX 1 */ @@ -1450,10 +1715,12 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ { GstElement *nice_element, *dtls_srtp_bin, *funnel; GstElement *mprtp_ply; + GstElement *mprtp_rcv; GstPad *rtp_src_pad, *rtcp_src_pad; gchar *rtpbin_pad_name; gboolean linked_ok, synced_ok; GstElement *receive_input_bin; + #ifdef TEST_RTX GstElement *identity; #endif @@ -1474,10 +1741,13 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ return; } + mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, receive_input_bin); nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, receive_input_bin); + transport_agent->priv->mprtp_rcv = mprtp_rcv; + transport_agent->priv->mprtp_ply = mprtp_ply; //rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); gst_element_link_pads(dtls_srtp_bin, "rtp_src", mprtp_ply, "mprtp_sink"); rtp_src_pad = gst_element_get_static_pad(mprtp_ply, "mprtp_src"); @@ -1502,7 +1772,10 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ synced_ok = gst_element_sync_state_with_parent(dtls_srtp_bin); g_warn_if_fail(synced_ok); - linked_ok = gst_element_link(nice_element, dtls_srtp_bin); +// linked_ok = gst_element_link(nice_element, dtls_srtp_bin); + linked_ok = gst_element_link_pads(nice_element, "src", mprtp_rcv, "sink_1"); + g_warn_if_fail(linked_ok); + linked_ok = gst_element_link_pads(mprtp_rcv, "mprtp_src", dtls_srtp_bin, "sink"); g_warn_if_fail(linked_ok); synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); @@ -1523,7 +1796,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ rtcp_src_pad = gst_element_get_static_pad(funnel, "src"); ghost_pad_and_add_to_bin(rtcp_src_pad, receive_input_bin, "rtcp_src"); gst_object_unref(rtcp_src_pad); -//mprtpplayouter + rtpbin_pad_name = g_strdup_printf("recv_rtcp_sink_%u", stream_id); linked_ok = gst_element_link_pads(receive_input_bin, "rtcp_src", transport_agent->priv->rtpbin, rtpbin_pad_name); diff --git a/transport/owr_transport_agent.h b/transport/owr_transport_agent.h index 950e4b4b..fd55af40 100644 --- a/transport/owr_transport_agent.h +++ b/transport/owr_transport_agent.h @@ -73,6 +73,7 @@ OwrTransportAgent * owr_transport_agent_new(gboolean ice_controlling_mode); void owr_transport_agent_add_helper_server(OwrTransportAgent *transport_agent, OwrHelperServerType type, const gchar *address, guint port, const gchar *username, const gchar *password); void owr_transport_agent_add_local_address(OwrTransportAgent *transport_agent, const gchar *local_address); +void owr_transport_agent_join_subflow(OwrTransportAgent *transport_agent, guint8 subflow_id, const gchar *local_address); void owr_transport_agent_set_local_port_range(OwrTransportAgent *transport_agent, guint min_port, guint max_port); void owr_transport_agent_add_session(OwrTransportAgent *agent, OwrSession *session); gchar * owr_transport_agent_get_dot_data(OwrTransportAgent *transport_agent); From 7af34668821546b97e383c3bec4dcbc81d7adcf1 Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Fri, 2 Oct 2015 10:07:08 +0300 Subject: [PATCH 09/18] udpsink and source for subflow join --- tests/test_send_receive.c | 6 +- transport/owr_transport_agent.c | 345 ++++++++++++++++++++++---------- transport/owr_transport_agent.h | 13 +- 3 files changed, 257 insertions(+), 107 deletions(-) diff --git a/tests/test_send_receive.c b/tests/test_send_receive.c index dbdb8255..a1a9ddc2 100644 --- a/tests/test_send_receive.c +++ b/tests/test_send_receive.c @@ -188,8 +188,10 @@ static gboolean dump_cb(gpointer *user_data) g_print("Dumping send transport agent pipeline!\n"); if(!added){ - owr_transport_agent_join_subflow(recv_transport_agent, 2, "127.0.0.2"); - owr_transport_agent_join_subflow(send_transport_agent, 2, "127.0.0.2"); + //owr_transport_agent_join_subflow(recv_transport_agent, 2, "127.1.0.2", 56780, 56790); + //owr_transport_agent_join_subflow(send_transport_agent, 2, "127.1.0.2", 56790, 56780); + owr_transport_agent_join_snd_subflow(send_transport_agent, 2, "127.2.1.1", 5565); + owr_transport_agent_join_rcv_subflow(recv_transport_agent, 2, 5565); added = TRUE; } if (video_source) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index 0b6001d2..c79ebc24 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -154,7 +154,7 @@ struct _OwrTransportAgentPrivate { GstElement *mprtp_rcv; GstElement *mprtp_ply; GHashTable *mprtp_subflows; - +// GstCaps *mprtp_caps; /* session_id -> struct MPRtpElements */ //GHashTable *mprtp_elements; @@ -256,6 +256,9 @@ static void complete_data_channel_and_ack(OwrTransportAgent *transport_agent, static void on_datachannel_send(OwrTransportAgent *transport_agent, guint8 *data, guint len, gboolean is_binary, OwrDataChannel *data_channel); static void maybe_close_data_channel(OwrTransportAgent *transport_agent, DataChannel *data_channel_info); +static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agent, guint stream_id, + GstElement *bin); + static void owr_transport_agent_finalize(GObject *object) { @@ -305,6 +308,10 @@ static void owr_transport_agent_finalize(GObject *object) owr_message_origin_bus_set_free(priv->message_origin_bus_set); priv->message_origin_bus_set = NULL; +// if(priv->mprtp_caps != NULL){ +// gst_buffer_unref(priv->mprtp_caps); +// } + G_OBJECT_CLASS(owr_transport_agent_parent_class)->finalize(object); } @@ -476,7 +483,7 @@ static void owr_transport_agent_init(OwrTransportAgent *transport_agent) priv->send_bins = g_hash_table_new_full(NULL, NULL, NULL, g_free); priv->mprtp_subflows = g_hash_table_new_full(NULL, NULL, NULL, g_free); - +// priv->mprtp_caps = NULL; priv->message_origin_bus_set = owr_message_origin_bus_set_new(); } @@ -567,156 +574,280 @@ void owr_transport_agent_add_helper_server(OwrTransportAgent *transport_agent, g_object_unref(resolver); } +// +// +//static void +//subflow_cb_candidate_gathering_done (NiceAgent * agent, guint stream_id, gpointer data) +//{ +// GSList *candidates; +// +// GST_INFO ("Candidates gathered on agent %" GST_PTR_FORMAT ", stream: %d", +// agent, stream_id); +// +// candidates = nice_agent_get_local_candidates (agent, stream_id, 1); +// +// nice_agent_set_remote_candidates (NICE_AGENT (data), stream_id, 1, +// candidates); +// +// g_slist_free_full (candidates, (GDestroyNotify) nice_candidate_free); +//} +// +//static void +//credentials_negotiation (NiceAgent * a_agent, NiceAgent * b_agent, +// guint a_stream, guint b_stream) +//{ +// gchar *user = NULL; +// gchar *passwd = NULL; +// +// nice_agent_get_local_credentials (a_agent, a_stream, &user, &passwd); +// nice_agent_set_remote_credentials (b_agent, b_stream, user, passwd); +// +// g_free (user); +// g_free (passwd); +//} +// +//static void +//subflow_cb_component_state_changed (NiceAgent * agent, guint stream_id, +// guint component_id, guint state, gpointer user_data) +//{ +// MpRTPSubflow *subflow = (MpRTPSubflow *)user_data; +// NiceComponentState *stateptr; +// +// g_return_if_fail(subflow); +// stateptr = (subflow->src_stream == stream_id) ? &subflow->src_state : &subflow->sink_state; +// *stateptr = state; +// subflow->component_id = component_id; +// g_print("unused parameters at " +// "subflow_cb_component_state_changed: %p\n", agent); +//} + + +// +//void owr_transport_agent_join_subflow(OwrTransportAgent *transport_agent, +// guint8 subflow_id, +// const gchar *local_address) +//{ +// NiceAddress addr; +// NiceAgent *sink_agent; +// NiceAgent *src_agent; +// MpRTPSubflow *subflow; +// GstElement *nicesink; +// GstElement *nicesrc; +// GstElement *subflow_bin; +// gchar *bin_name; +// gchar *padname; +// gchar *element_name; +// gboolean synced_ok; +// guint sink_stream; +// guint src_stream; +// OwrTransportAgentPrivate *priv; +// +// g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); +// g_return_if_fail(local_address); +// g_return_if_fail(transport_agent->priv->local_address_added); +// g_return_if_fail(nice_address_set_from_string(&addr, local_address)); +// +// priv = transport_agent->priv; +// +// subflow = g_malloc0(sizeof(MpRTPSubflow)); +// subflow->sink_agent = sink_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); +// subflow->src_agent = src_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); +// +// nice_agent_add_local_address (sink_agent, &addr); +// nice_agent_add_local_address (src_agent, &addr); +// +// subflow->sink_stream = sink_stream = nice_agent_add_stream (sink_agent, 1); +// subflow->src_stream = src_stream = nice_agent_add_stream (src_agent, 1); +// +// bin_name = g_strdup_printf("subflow-bin-%hu", subflow_id); +// subflow->bin = subflow_bin = gst_bin_new(bin_name); +// g_free(bin_name); +// +// +// g_signal_connect (G_OBJECT (sink_agent), "candidate-gathering-done", +// G_CALLBACK (subflow_cb_candidate_gathering_done), src_agent); +// g_signal_connect (G_OBJECT (src_agent), "candidate-gathering-done", +// G_CALLBACK (subflow_cb_candidate_gathering_done), sink_agent); +// +// g_signal_connect (G_OBJECT (sink_agent), "component-state-changed", +// G_CALLBACK (subflow_cb_component_state_changed), subflow); +// g_signal_connect (G_OBJECT (src_agent), "component-state-changed", +// G_CALLBACK (subflow_cb_component_state_changed), subflow); +// +// credentials_negotiation (sink_agent, src_agent, sink_stream, src_stream); +// credentials_negotiation (src_agent, sink_agent, src_stream, src_stream); +// +// nice_agent_gather_candidates (sink_agent, sink_stream); +// nice_agent_gather_candidates (src_agent, src_stream); +// +// element_name = g_strdup_printf("subflow-nicesink-%hhu", subflow_id); +// subflow->nicesink = nicesink = gst_element_factory_make("nicesink", element_name); +// g_free(element_name); +// element_name = g_strdup_printf("subflow-nicesrc-%hhu", subflow_id); +// subflow->nicesrc = nicesrc = gst_element_factory_make("nicesrc", element_name); +// g_free(element_name); +// +// if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), subflow_bin)) { +// GST_ERROR("Failed to add subflow_bin-%hhu to parent bin", subflow_id); +// return; +// } +// if (!gst_element_sync_state_with_parent(subflow_bin)) { +// GST_ERROR("Failed to sync subflow_bin-%hhu to parent bin", subflow_id); +// return; +// } +// gst_bin_add_many(GST_BIN(subflow_bin), nicesrc, nicesink, NULL); +// +// g_object_set (nicesink, "agent", sink_agent, "stream", sink_stream, +// "component", NICE_COMPONENT_TYPE_RTP, NULL); +// g_object_set (nicesrc, "agent", src_agent, "stream", src_stream, +// "component", NICE_COMPONENT_TYPE_RTP, NULL); +// +// g_object_set(nicesink, "enable-last-sample", FALSE, "async", FALSE, NULL); +// +// synced_ok = gst_element_sync_state_with_parent(nicesink); +// g_warn_if_fail(synced_ok); +// synced_ok = gst_element_sync_state_with_parent(nicesrc); +// g_warn_if_fail(synced_ok); +// +// padname = g_strdup_printf("sink_%hhu", subflow_id); +// gst_element_link_pads(nicesrc, "src", priv->mprtp_rcv, padname); +// g_free(padname); +// padname = g_strdup_printf("src_%hhu", subflow_id); +// gst_element_link_pads(priv->mprtp_snd, padname, nicesink, "sink"); +// g_free(padname); +// +// g_object_set(priv->mprtp_sch, "join-subflow", subflow_id, NULL); +// g_object_set(priv->mprtp_ply, "join-subflow", subflow_id, NULL); +// +// g_hash_table_insert(transport_agent->priv->mprtp_subflows, +// GINT_TO_POINTER(subflow_id), subflow); +// +//} + -static void -subflow_cb_candidate_gathering_done (NiceAgent * agent, guint stream_id, gpointer data) +void owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id, + const gchar *remote_address, + guint port) { - GSList *candidates; - GST_INFO ("Candidates gathered on agent %" GST_PTR_FORMAT ", stream: %d", - agent, stream_id); + MpRTPSubflow *subflow; + GstElement *udpsink; + GstElement *subflow_bin; + gchar *bin_name; + gchar *padname; + gchar *element_name; + gboolean synced_ok; + OwrTransportAgentPrivate *priv; - candidates = nice_agent_get_local_candidates (agent, stream_id, 1); + g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); + g_return_if_fail(remote_address); - nice_agent_set_remote_candidates (NICE_AGENT (data), stream_id, 1, - candidates); + priv = transport_agent->priv; - g_slist_free_full (candidates, (GDestroyNotify) nice_candidate_free); -} -static void -credentials_negotiation (NiceAgent * a_agent, NiceAgent * b_agent, - guint a_stream, guint b_stream) -{ - gchar *user = NULL; - gchar *passwd = NULL; + subflow = (MpRTPSubflow*) g_hash_table_lookup(priv->mprtp_subflows, GUINT_TO_POINTER(subflow_id)); + if(subflow == NULL){ + subflow = g_malloc0(sizeof(MpRTPSubflow)); + g_hash_table_insert(transport_agent->priv->mprtp_subflows, + GINT_TO_POINTER(subflow_id), subflow); + bin_name = g_strdup_printf("subflow-bin-%hu", subflow_id); + subflow->bin = subflow_bin = gst_bin_new(bin_name); + g_free(bin_name); + }else{ + subflow_bin = subflow->bin; + } - nice_agent_get_local_credentials (a_agent, a_stream, &user, &passwd); - nice_agent_set_remote_credentials (b_agent, b_stream, user, passwd); + element_name = g_strdup_printf("subflow-nicesink-%hhu", subflow_id); + subflow->nicesink = udpsink = gst_element_factory_make("udpsink", element_name); + g_free(element_name); - g_free (user); - g_free (passwd); -} + if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), subflow_bin)) { + GST_WARNING("Failed to add subflow_bin-%hhu to parent bin", subflow_id); + return; + } + if (!gst_element_sync_state_with_parent(subflow_bin)) { + GST_WARNING("Failed to sync subflow_bin-%hhu to parent bin", subflow_id); + return; + } + gst_bin_add_many(GST_BIN(subflow_bin), udpsink, NULL); -static void -subflow_cb_component_state_changed (NiceAgent * agent, guint stream_id, - guint component_id, guint state, gpointer user_data) -{ - MpRTPSubflow *subflow = (MpRTPSubflow *)user_data; - NiceComponentState *stateptr; + g_object_set (udpsink, "port", port, "host", remote_address, "sync", + FALSE, "async", FALSE, NULL); + + synced_ok = gst_element_sync_state_with_parent(udpsink); + g_warn_if_fail(synced_ok); + + padname = g_strdup_printf("src_%hhu", subflow_id); + gst_element_link_pads(priv->mprtp_snd, padname, udpsink, "sink"); + g_free(padname); + + g_object_set(priv->mprtp_sch, "join-subflow", subflow_id, NULL); - g_return_if_fail(subflow); - stateptr = (subflow->src_stream == stream_id) ? &subflow->src_state : &subflow->sink_state; - *stateptr = state; - subflow->component_id = component_id; - g_print("unused parameters at " - "subflow_cb_component_state_changed: %p\n", agent); } -void owr_transport_agent_join_subflow(OwrTransportAgent *transport_agent, + + +void owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, guint8 subflow_id, - const gchar *local_address) + guint port) { - NiceAddress addr; - NiceAgent *sink_agent; - NiceAgent *src_agent; + MpRTPSubflow *subflow; - GstElement *nicesink; - GstElement *nicesrc; + GstElement *udpsrc; GstElement *subflow_bin; gchar *bin_name; gchar *padname; gchar *element_name; gboolean synced_ok; - guint sink_stream; - guint src_stream; OwrTransportAgentPrivate *priv; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); - g_return_if_fail(local_address); - g_return_if_fail(transport_agent->priv->local_address_added); - g_return_if_fail(nice_address_set_from_string(&addr, local_address)); priv = transport_agent->priv; - subflow = g_malloc0(sizeof(MpRTPSubflow)); - subflow->sink_agent = sink_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); - subflow->src_agent = src_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); - - nice_agent_add_local_address (sink_agent, &addr); - nice_agent_add_local_address (src_agent, &addr); - - subflow->sink_stream = sink_stream = nice_agent_add_stream (sink_agent, 1); - subflow->src_stream = src_stream = nice_agent_add_stream (src_agent, 1); - - bin_name = g_strdup_printf("subflow-bin-%hu", subflow_id); - subflow->bin = subflow_bin = gst_bin_new(bin_name); - g_free(bin_name); - - - g_signal_connect (G_OBJECT (sink_agent), "candidate-gathering-done", - G_CALLBACK (subflow_cb_candidate_gathering_done), src_agent); - g_signal_connect (G_OBJECT (src_agent), "candidate-gathering-done", - G_CALLBACK (subflow_cb_candidate_gathering_done), sink_agent); - - g_signal_connect (G_OBJECT (sink_agent), "component-state-changed", - G_CALLBACK (subflow_cb_component_state_changed), subflow); - g_signal_connect (G_OBJECT (src_agent), "component-state-changed", - G_CALLBACK (subflow_cb_component_state_changed), subflow); - - credentials_negotiation (sink_agent, src_agent, sink_stream, src_stream); - credentials_negotiation (src_agent, sink_agent, src_stream, src_stream); + subflow = (MpRTPSubflow*) g_hash_table_lookup(priv->mprtp_subflows, GUINT_TO_POINTER(subflow_id)); + if(subflow == NULL){ + subflow = g_malloc0(sizeof(MpRTPSubflow)); + g_hash_table_insert(transport_agent->priv->mprtp_subflows, + GINT_TO_POINTER(subflow_id), subflow); + bin_name = g_strdup_printf("subflow-bin-%hu", subflow_id); + subflow->bin = subflow_bin = gst_bin_new(bin_name); + g_free(bin_name); + }else{ + subflow_bin = subflow->bin; + } - nice_agent_gather_candidates (sink_agent, sink_stream); - nice_agent_gather_candidates (src_agent, src_stream); - element_name = g_strdup_printf("subflow-nicesink-%hhu", subflow_id); - subflow->nicesink = nicesink = gst_element_factory_make("nicesink", element_name); - g_free(element_name); element_name = g_strdup_printf("subflow-nicesrc-%hhu", subflow_id); - subflow->nicesrc = nicesrc = gst_element_factory_make("nicesrc", element_name); + subflow->nicesrc = udpsrc = gst_element_factory_make("udpsrc", element_name); g_free(element_name); if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), subflow_bin)) { - GST_ERROR("Failed to add subflow_bin-%hhu to parent bin", subflow_id); + GST_WARNING("Failed to add subflow_bin-%hhu to parent bin", subflow_id); return; } if (!gst_element_sync_state_with_parent(subflow_bin)) { - GST_ERROR("Failed to sync subflow_bin-%hhu to parent bin", subflow_id); + GST_WARNING("Failed to sync subflow_bin-%hhu to parent bin", subflow_id); return; } - gst_bin_add_many(GST_BIN(subflow_bin), nicesrc, nicesink, NULL); - - g_object_set (nicesink, "agent", sink_agent, "stream", sink_stream, - "component", NICE_COMPONENT_TYPE_RTP, NULL); - g_object_set (nicesrc, "agent", src_agent, "stream", src_stream, - "component", NICE_COMPONENT_TYPE_RTP, NULL); + gst_bin_add_many(GST_BIN(subflow_bin), udpsrc, NULL); - g_object_set(nicesink, "enable-last-sample", FALSE, "async", FALSE, NULL); + g_object_set (udpsrc, "port", port, NULL); - synced_ok = gst_element_sync_state_with_parent(nicesink); - g_warn_if_fail(synced_ok); - synced_ok = gst_element_sync_state_with_parent(nicesrc); + synced_ok = gst_element_sync_state_with_parent(udpsrc); g_warn_if_fail(synced_ok); - padname = g_strdup_printf("sink_%hhu", subflow_id); - gst_element_link_pads(nicesrc, "src", priv->mprtp_rcv, padname); - g_free(padname); padname = g_strdup_printf("src_%hhu", subflow_id); - gst_element_link_pads(priv->mprtp_snd, padname, nicesink, "sink"); + gst_element_link_pads(priv->mprtp_snd, padname, udpsrc, "sink"); g_free(padname); - g_object_set(priv->mprtp_sch, "join-subflow", subflow_id, NULL); g_object_set(priv->mprtp_ply, "join-subflow", subflow_id, NULL); - g_hash_table_insert(transport_agent->priv->mprtp_subflows, - GINT_TO_POINTER(subflow_id), subflow); - } - void owr_transport_agent_add_local_address(OwrTransportAgent *transport_agent, const gchar *local_address) { NiceAddress addr; @@ -938,8 +1069,16 @@ static void handle_new_send_source(OwrTransportAgent *transport_agent, * and if one is reusable, use it, else raw? g_object_get(send_payload, "codec-type", &codec_type, NULL); */ - caps = _owr_payload_create_raw_caps(send_payload); +// if(transport_agent->priv->mprtp_caps == NULL){ +// g_print("Halleluja!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); +// transport_agent->priv->mprtp_caps = caps; +// gst_buffer_ref(transport_agent->priv->mprtp_caps); +// }else{ +// gst_buffer_unref(transport_agent->priv->mprtp_caps); +// transport_agent->priv->mprtp_caps = caps; +// gst_buffer_ref(transport_agent->priv->mprtp_caps); +// } src = _owr_media_source_request_source(send_source, caps); g_assert(src); gst_caps_unref(caps); @@ -1416,7 +1555,6 @@ static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agen mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); - g_object_set(mprtp_sch, "subflow-riports-enabled", FALSE, NULL); g_object_set(mprtp_sch, "join-subflow", 1, NULL); added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); @@ -1441,7 +1579,6 @@ static GstElement *add_mprtp_plaoyouter_element(OwrTransportAgent *transport_age mprtp_sch = gst_element_factory_make("mprtpplayouter", element_name); - g_object_set(mprtp_sch, "subflow-riports-enabled", FALSE, NULL); g_object_set(mprtp_sch, "join-subflow", 1, NULL); added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); diff --git a/transport/owr_transport_agent.h b/transport/owr_transport_agent.h index fd55af40..f0d1182b 100644 --- a/transport/owr_transport_agent.h +++ b/transport/owr_transport_agent.h @@ -73,7 +73,18 @@ OwrTransportAgent * owr_transport_agent_new(gboolean ice_controlling_mode); void owr_transport_agent_add_helper_server(OwrTransportAgent *transport_agent, OwrHelperServerType type, const gchar *address, guint port, const gchar *username, const gchar *password); void owr_transport_agent_add_local_address(OwrTransportAgent *transport_agent, const gchar *local_address); -void owr_transport_agent_join_subflow(OwrTransportAgent *transport_agent, guint8 subflow_id, const gchar *local_address); +//void owr_transport_agent_join_subflow(OwrTransportAgent *transport_agent, +// guint8 subflow_id, +// const gchar *local_address, +// guint snd_port, +// guint rcv_port); +void owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id, + guint port); +void owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id, + const gchar *remote_address, + guint port); void owr_transport_agent_set_local_port_range(OwrTransportAgent *transport_agent, guint min_port, guint max_port); void owr_transport_agent_add_session(OwrTransportAgent *agent, OwrSession *session); gchar * owr_transport_agent_get_dot_data(OwrTransportAgent *transport_agent); From 6d070e26f5d8e9b08ac18f175c4bfb60ab53cfee Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Fri, 2 Oct 2015 10:39:04 +0300 Subject: [PATCH 10/18] udpsink and source for subflow join --- transport/owr_transport_agent.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index c79ebc24..86e64c42 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -776,15 +776,14 @@ void owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, g_object_set (udpsink, "port", port, "host", remote_address, "sync", FALSE, "async", FALSE, NULL); - synced_ok = gst_element_sync_state_with_parent(udpsink); - g_warn_if_fail(synced_ok); - padname = g_strdup_printf("src_%hhu", subflow_id); gst_element_link_pads(priv->mprtp_snd, padname, udpsink, "sink"); g_free(padname); g_object_set(priv->mprtp_sch, "join-subflow", subflow_id, NULL); + synced_ok = gst_element_sync_state_with_parent(udpsink); + g_warn_if_fail(synced_ok); } @@ -802,7 +801,7 @@ void owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, gchar *element_name; gboolean synced_ok; OwrTransportAgentPrivate *priv; - + g_print("!!!!!!!!!!!!!BAZD MEG MAGAD!!!!!!!!!!!!!\n"); g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); priv = transport_agent->priv; @@ -836,15 +835,14 @@ void owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, g_object_set (udpsrc, "port", port, NULL); - synced_ok = gst_element_sync_state_with_parent(udpsrc); - g_warn_if_fail(synced_ok); - - padname = g_strdup_printf("src_%hhu", subflow_id); - gst_element_link_pads(priv->mprtp_snd, padname, udpsrc, "sink"); + padname = g_strdup_printf("sink_%hhu", subflow_id); + gst_element_link_pads(udpsrc, "src", priv->mprtp_rcv, padname); g_free(padname); g_object_set(priv->mprtp_ply, "join-subflow", subflow_id, NULL); + synced_ok = gst_element_sync_state_with_parent(udpsrc); + g_warn_if_fail(synced_ok); } From 90a14506448bcc7361e644d66124aa2c67f2d6bc Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Tue, 6 Oct 2015 14:54:52 +0300 Subject: [PATCH 11/18] multipath rtp changes --- tests/test_send_receive.c | 55 +++- transport/owr_transport_agent.c | 491 ++++++++++++++++---------------- transport/owr_transport_agent.h | 21 +- 3 files changed, 309 insertions(+), 258 deletions(-) diff --git a/tests/test_send_receive.c b/tests/test_send_receive.c index a1a9ddc2..83e278e5 100644 --- a/tests/test_send_receive.c +++ b/tests/test_send_receive.c @@ -182,18 +182,54 @@ static void got_sources(GList *sources, gpointer user_data) } } -static gboolean added = FALSE; +static guint8 subflow_snd_id; +static guint8 subflow_rcv_id; + +static gboolean join_subflows(gpointer *user_data) +{ + const GstStructure *s = NULL; + g_print( + "-----------------------------------------------------------------\n" + "---------------- JOIN SUBFLOW BEGIN -----------------------------\n" + "-----------------------------------------------------------------\n" + ); + subflow_snd_id = owr_transport_agent_join_snd_subflow(send_transport_agent, "127.2.1.1", 5565); + subflow_rcv_id = owr_transport_agent_join_rcv_subflow(recv_transport_agent, 5565); + g_print( + "-----------------------------------------------------------------\n" + "---------------- JOIN SUBFLOW END -> snd:%d, rcv:%d <------------\n" + "-----------------------------------------------------------------\n", + subflow_snd_id, subflow_rcv_id + ); +// s = owr_transport_agent_get_rcv_subflow_stats(recv_transport_agent); +// g_print("%s", gst_structure_to_string(s)); + s = owr_transport_agent_get_snd_subflow_stats(recv_transport_agent); + g_print("%s", gst_structure_to_string(s)); + return G_SOURCE_REMOVE; +} + +static gboolean detach_subflows(gpointer *user_data) +{ + g_print( + "-----------------------------------------------------------------\n" + "---------------- DETACH SUBFLOW BEGIN -> snd:%d, rcv:%d <--------\n" + "-----------------------------------------------------------------\n", + subflow_snd_id, subflow_rcv_id + ); + owr_transport_agent_detach_snd_subflow(send_transport_agent, subflow_snd_id); + owr_transport_agent_detach_rcv_subflow(recv_transport_agent, subflow_rcv_id); + g_print( + "-----------------------------------------------------------------\n" + "------------------ DETACH SUBFLOW END ---------------------------\n" + "-----------------------------------------------------------------\n" + ); + return G_SOURCE_REMOVE; +} + static gboolean dump_cb(gpointer *user_data) { g_print("Dumping send transport agent pipeline!\n"); - if(!added){ - //owr_transport_agent_join_subflow(recv_transport_agent, 2, "127.1.0.2", 56780, 56790); - //owr_transport_agent_join_subflow(send_transport_agent, 2, "127.1.0.2", 56790, 56780); - owr_transport_agent_join_snd_subflow(send_transport_agent, 2, "127.2.1.1", 5565); - owr_transport_agent_join_rcv_subflow(recv_transport_agent, 2, 5565); - added = TRUE; - } if (video_source) write_dot_file("test_send-got_source-video-source", owr_media_source_get_dot_data(video_source), TRUE); if (video_renderer) @@ -353,7 +389,8 @@ int main(int argc, char **argv) got_sources, NULL); g_timeout_add_seconds(10, (GSourceFunc)dump_cb, NULL); - + g_timeout_add_seconds(2, (GSourceFunc)join_subflows, NULL); + g_timeout_add_seconds(20, (GSourceFunc)detach_subflows, NULL); owr_run(); diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index 86e64c42..b4978176 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -121,19 +121,15 @@ typedef struct { typedef struct{ guint8 id; - NiceAgent *sink_agent; - NiceAgent *src_agent; - GstElement *nicesink; - GstElement *nicesrc; - GstElement *bin; - guint sink_stream; - guint src_stream; - NiceComponentState src_state; - NiceComponentState sink_state; + NiceAgent *agent; + NiceComponentState state; guint component_id; - + GstElement *sink; + GstElement *src; + guint agent_id; + guint stream_id; OwrTransportAgent *parent; -}MpRTPSubflow; +}Subflow; struct _OwrTransportAgentPrivate { NiceAgent *nice_agent; @@ -149,14 +145,14 @@ struct _OwrTransportAgentPrivate { /* session_id -> struct SendBinInfo */ GHashTable *send_bins; + /* mprtp stuff */ GstElement *mprtp_sch; GstElement *mprtp_snd; GstElement *mprtp_rcv; GstElement *mprtp_ply; - GHashTable *mprtp_subflows; -// GstCaps *mprtp_caps; - /* session_id -> struct MPRtpElements */ - //GHashTable *mprtp_elements; + GHashTable *subflows; + guint mprtp_actual_subflow_id_index; + gboolean mprtp_subflow_id_overflow_detected; gboolean local_address_added; guint local_min_port; @@ -256,9 +252,6 @@ static void complete_data_channel_and_ack(OwrTransportAgent *transport_agent, static void on_datachannel_send(OwrTransportAgent *transport_agent, guint8 *data, guint len, gboolean is_binary, OwrDataChannel *data_channel); static void maybe_close_data_channel(OwrTransportAgent *transport_agent, DataChannel *data_channel_info); -static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agent, guint stream_id, - GstElement *bin); - static void owr_transport_agent_finalize(GObject *object) { @@ -482,7 +475,9 @@ static void owr_transport_agent_init(OwrTransportAgent *transport_agent) priv->data_session_established = FALSE; priv->send_bins = g_hash_table_new_full(NULL, NULL, NULL, g_free); - priv->mprtp_subflows = g_hash_table_new_full(NULL, NULL, NULL, g_free); + priv->subflows = g_hash_table_new_full(NULL, NULL, NULL, g_free); + priv->mprtp_actual_subflow_id_index = 0; + priv->mprtp_subflow_id_overflow_detected = FALSE; // priv->mprtp_caps = NULL; priv->message_origin_bus_set = owr_message_origin_bus_set_new(); } @@ -574,204 +569,85 @@ void owr_transport_agent_add_helper_server(OwrTransportAgent *transport_agent, g_object_unref(resolver); } -// -// -//static void -//subflow_cb_candidate_gathering_done (NiceAgent * agent, guint stream_id, gpointer data) -//{ -// GSList *candidates; -// -// GST_INFO ("Candidates gathered on agent %" GST_PTR_FORMAT ", stream: %d", -// agent, stream_id); -// -// candidates = nice_agent_get_local_candidates (agent, stream_id, 1); -// -// nice_agent_set_remote_candidates (NICE_AGENT (data), stream_id, 1, -// candidates); -// -// g_slist_free_full (candidates, (GDestroyNotify) nice_candidate_free); -//} -// -//static void -//credentials_negotiation (NiceAgent * a_agent, NiceAgent * b_agent, -// guint a_stream, guint b_stream) -//{ -// gchar *user = NULL; -// gchar *passwd = NULL; -// -// nice_agent_get_local_credentials (a_agent, a_stream, &user, &passwd); -// nice_agent_set_remote_credentials (b_agent, b_stream, user, passwd); -// -// g_free (user); -// g_free (passwd); -//} -// -//static void -//subflow_cb_component_state_changed (NiceAgent * agent, guint stream_id, -// guint component_id, guint state, gpointer user_data) -//{ -// MpRTPSubflow *subflow = (MpRTPSubflow *)user_data; -// NiceComponentState *stateptr; -// -// g_return_if_fail(subflow); -// stateptr = (subflow->src_stream == stream_id) ? &subflow->src_state : &subflow->sink_state; -// *stateptr = state; -// subflow->component_id = component_id; -// g_print("unused parameters at " -// "subflow_cb_component_state_changed: %p\n", agent); -//} - -// -//void owr_transport_agent_join_subflow(OwrTransportAgent *transport_agent, -// guint8 subflow_id, -// const gchar *local_address) -//{ -// NiceAddress addr; -// NiceAgent *sink_agent; -// NiceAgent *src_agent; -// MpRTPSubflow *subflow; -// GstElement *nicesink; -// GstElement *nicesrc; -// GstElement *subflow_bin; -// gchar *bin_name; -// gchar *padname; -// gchar *element_name; -// gboolean synced_ok; -// guint sink_stream; -// guint src_stream; -// OwrTransportAgentPrivate *priv; -// -// g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); -// g_return_if_fail(local_address); -// g_return_if_fail(transport_agent->priv->local_address_added); -// g_return_if_fail(nice_address_set_from_string(&addr, local_address)); -// -// priv = transport_agent->priv; -// -// subflow = g_malloc0(sizeof(MpRTPSubflow)); -// subflow->sink_agent = sink_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); -// subflow->src_agent = src_agent = nice_agent_new (NULL, NICE_COMPATIBILITY_RFC5245); -// -// nice_agent_add_local_address (sink_agent, &addr); -// nice_agent_add_local_address (src_agent, &addr); -// -// subflow->sink_stream = sink_stream = nice_agent_add_stream (sink_agent, 1); -// subflow->src_stream = src_stream = nice_agent_add_stream (src_agent, 1); -// -// bin_name = g_strdup_printf("subflow-bin-%hu", subflow_id); -// subflow->bin = subflow_bin = gst_bin_new(bin_name); -// g_free(bin_name); -// -// -// g_signal_connect (G_OBJECT (sink_agent), "candidate-gathering-done", -// G_CALLBACK (subflow_cb_candidate_gathering_done), src_agent); -// g_signal_connect (G_OBJECT (src_agent), "candidate-gathering-done", -// G_CALLBACK (subflow_cb_candidate_gathering_done), sink_agent); -// -// g_signal_connect (G_OBJECT (sink_agent), "component-state-changed", -// G_CALLBACK (subflow_cb_component_state_changed), subflow); -// g_signal_connect (G_OBJECT (src_agent), "component-state-changed", -// G_CALLBACK (subflow_cb_component_state_changed), subflow); -// -// credentials_negotiation (sink_agent, src_agent, sink_stream, src_stream); -// credentials_negotiation (src_agent, sink_agent, src_stream, src_stream); -// -// nice_agent_gather_candidates (sink_agent, sink_stream); -// nice_agent_gather_candidates (src_agent, src_stream); -// -// element_name = g_strdup_printf("subflow-nicesink-%hhu", subflow_id); -// subflow->nicesink = nicesink = gst_element_factory_make("nicesink", element_name); -// g_free(element_name); -// element_name = g_strdup_printf("subflow-nicesrc-%hhu", subflow_id); -// subflow->nicesrc = nicesrc = gst_element_factory_make("nicesrc", element_name); -// g_free(element_name); -// -// if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), subflow_bin)) { -// GST_ERROR("Failed to add subflow_bin-%hhu to parent bin", subflow_id); -// return; -// } -// if (!gst_element_sync_state_with_parent(subflow_bin)) { -// GST_ERROR("Failed to sync subflow_bin-%hhu to parent bin", subflow_id); -// return; -// } -// gst_bin_add_many(GST_BIN(subflow_bin), nicesrc, nicesink, NULL); -// -// g_object_set (nicesink, "agent", sink_agent, "stream", sink_stream, -// "component", NICE_COMPONENT_TYPE_RTP, NULL); -// g_object_set (nicesrc, "agent", src_agent, "stream", src_stream, -// "component", NICE_COMPONENT_TYPE_RTP, NULL); -// -// g_object_set(nicesink, "enable-last-sample", FALSE, "async", FALSE, NULL); -// -// synced_ok = gst_element_sync_state_with_parent(nicesink); -// g_warn_if_fail(synced_ok); -// synced_ok = gst_element_sync_state_with_parent(nicesrc); -// g_warn_if_fail(synced_ok); -// -// padname = g_strdup_printf("sink_%hhu", subflow_id); -// gst_element_link_pads(nicesrc, "src", priv->mprtp_rcv, padname); -// g_free(padname); -// padname = g_strdup_printf("src_%hhu", subflow_id); -// gst_element_link_pads(priv->mprtp_snd, padname, nicesink, "sink"); -// g_free(padname); -// -// g_object_set(priv->mprtp_sch, "join-subflow", subflow_id, NULL); -// g_object_set(priv->mprtp_ply, "join-subflow", subflow_id, NULL); -// -// g_hash_table_insert(transport_agent->priv->mprtp_subflows, -// GINT_TO_POINTER(subflow_id), subflow); -// -//} +static guint8 get_new_subflow_id(OwrTransportAgent *transport_agent) +{ + Subflow *subflow; + gpointer val,key; + gboolean reserved[255]; + guint result,i; + GHashTableIter iter; + + if(transport_agent->priv->mprtp_actual_subflow_id_index == 255){ + transport_agent->priv->mprtp_subflow_id_overflow_detected = TRUE; + } + + if(!transport_agent->priv->mprtp_subflow_id_overflow_detected){ + if(transport_agent->priv->mprtp_actual_subflow_id_index == 0){ + transport_agent->priv->mprtp_actual_subflow_id_index = 2; + } + result = transport_agent->priv->mprtp_actual_subflow_id_index++; + goto done; + } + + g_hash_table_iter_init (&iter, transport_agent->priv->subflows); + while (g_hash_table_iter_next (&iter, (gpointer) & key, (gpointer) & val)) { + subflow = (Subflow *) val; + reserved[subflow->id] = TRUE; + } + + for(i=2; i<255; ++i){ + if(reserved[i] == FALSE){ + result = i; + goto done; + } + } + result = 0; +done: + return result; +} -void owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, - guint8 subflow_id, +guint8 owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, const gchar *remote_address, guint port) { - MpRTPSubflow *subflow; + Subflow *subflow; GstElement *udpsink; - GstElement *subflow_bin; - gchar *bin_name; gchar *padname; gchar *element_name; gboolean synced_ok; OwrTransportAgentPrivate *priv; + guint8 subflow_id = 0; - g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); - g_return_if_fail(remote_address); + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), 0); + g_return_val_if_fail(remote_address, 0); + + subflow_id = get_new_subflow_id(transport_agent); + g_return_val_if_fail(subflow_id > 0, 0); priv = transport_agent->priv; - subflow = (MpRTPSubflow*) g_hash_table_lookup(priv->mprtp_subflows, GUINT_TO_POINTER(subflow_id)); + subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); if(subflow == NULL){ - subflow = g_malloc0(sizeof(MpRTPSubflow)); - g_hash_table_insert(transport_agent->priv->mprtp_subflows, + subflow = g_malloc0(sizeof(Subflow)); + g_hash_table_insert(transport_agent->priv->subflows, GINT_TO_POINTER(subflow_id), subflow); - bin_name = g_strdup_printf("subflow-bin-%hu", subflow_id); - subflow->bin = subflow_bin = gst_bin_new(bin_name); - g_free(bin_name); - }else{ - subflow_bin = subflow->bin; + } - element_name = g_strdup_printf("subflow-nicesink-%hhu", subflow_id); - subflow->nicesink = udpsink = gst_element_factory_make("udpsink", element_name); + element_name = g_strdup_printf("subflow-rtc-udpsink-%hhu", subflow_id); + subflow->sink = udpsink = gst_element_factory_make("udpsink", element_name); g_free(element_name); - if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), subflow_bin)) { - GST_WARNING("Failed to add subflow_bin-%hhu to parent bin", subflow_id); - return; + if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), + udpsink)) { + GST_WARNING("Failed to add udpsrc-rtc to parent bin"); + return subflow_id; } - if (!gst_element_sync_state_with_parent(subflow_bin)) { - GST_WARNING("Failed to sync subflow_bin-%hhu to parent bin", subflow_id); - return; - } - gst_bin_add_many(GST_BIN(subflow_bin), udpsink, NULL); g_object_set (udpsink, "port", port, "host", remote_address, "sync", FALSE, "async", FALSE, NULL); @@ -784,54 +660,72 @@ void owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, synced_ok = gst_element_sync_state_with_parent(udpsink); g_warn_if_fail(synced_ok); + + return subflow_id; } +void owr_transport_agent_detach_snd_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id) +{ + + Subflow *subflow; + OwrTransportAgentPrivate *priv; + + g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); + + priv = transport_agent->priv; + + subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); + if(subflow == NULL){ + GST_WARNING("Not existed subflow (%d) requested to detach at sending part", subflow_id); + return; + } + + g_object_set(priv->mprtp_sch, "detach-subflow", subflow_id, NULL); + gst_element_set_state(subflow->sink, GST_STATE_NULL); + if (!gst_bin_remove(GST_BIN(transport_agent->priv->transport_bin), subflow->sink)) { + GST_WARNING("Failed to remove sink for subflow %d", subflow_id); + } + subflow->sink = NULL; + if(subflow->src == NULL){ + g_hash_table_remove(priv->subflows, GUINT_TO_POINTER(subflow_id)); + } +} -void owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, - guint8 subflow_id, +guint8 owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, guint port) { - - MpRTPSubflow *subflow; + Subflow *subflow; GstElement *udpsrc; - GstElement *subflow_bin; - gchar *bin_name; gchar *padname; gchar *element_name; gboolean synced_ok; OwrTransportAgentPrivate *priv; - g_print("!!!!!!!!!!!!!BAZD MEG MAGAD!!!!!!!!!!!!!\n"); - g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); + guint8 subflow_id = 0; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), 0); + subflow_id = get_new_subflow_id(transport_agent); + g_return_val_if_fail(subflow_id > 0, 0); priv = transport_agent->priv; - subflow = (MpRTPSubflow*) g_hash_table_lookup(priv->mprtp_subflows, GUINT_TO_POINTER(subflow_id)); + subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); if(subflow == NULL){ - subflow = g_malloc0(sizeof(MpRTPSubflow)); - g_hash_table_insert(transport_agent->priv->mprtp_subflows, + subflow = g_malloc0(sizeof(Subflow)); + g_hash_table_insert(transport_agent->priv->subflows, GINT_TO_POINTER(subflow_id), subflow); - bin_name = g_strdup_printf("subflow-bin-%hu", subflow_id); - subflow->bin = subflow_bin = gst_bin_new(bin_name); - g_free(bin_name); - }else{ - subflow_bin = subflow->bin; } - - element_name = g_strdup_printf("subflow-nicesrc-%hhu", subflow_id); - subflow->nicesrc = udpsrc = gst_element_factory_make("udpsrc", element_name); + element_name = g_strdup_printf("subflow-udpsrc-%hhu", subflow_id); + subflow->src = udpsrc = gst_element_factory_make("udpsrc", element_name); g_free(element_name); - if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), subflow_bin)) { - GST_WARNING("Failed to add subflow_bin-%hhu to parent bin", subflow_id); - return; - } - if (!gst_element_sync_state_with_parent(subflow_bin)) { - GST_WARNING("Failed to sync subflow_bin-%hhu to parent bin", subflow_id); - return; + if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), + udpsrc)) { + GST_WARNING("Failed to add udpsrc-rtc to parent bin"); + return subflow_id; } - gst_bin_add_many(GST_BIN(subflow_bin), udpsrc, NULL); g_object_set (udpsrc, "port", port, NULL); @@ -843,8 +737,57 @@ void owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, synced_ok = gst_element_sync_state_with_parent(udpsrc); g_warn_if_fail(synced_ok); + + return subflow_id; +} + + +void owr_transport_agent_detach_rcv_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id) +{ + + Subflow *subflow; + OwrTransportAgentPrivate *priv; + + g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); + + priv = transport_agent->priv; + + subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); + if(subflow == NULL){ + GST_WARNING("Not existed subflow (%d) requested to detach at sending part", subflow_id); + return; + } + + g_object_set(priv->mprtp_ply, "detach-subflow", subflow_id, NULL); + gst_element_set_state(subflow->src, GST_STATE_NULL); + if (!gst_bin_remove(GST_BIN(transport_agent->priv->transport_bin), subflow->src)) { + GST_WARNING("Failed to remove src for subflow %d", subflow_id); + } + + subflow->src = NULL; + if(subflow->sink == NULL){ + g_hash_table_remove(priv->subflows, GUINT_TO_POINTER(subflow_id)); + } +} + +GstStructure* owr_transport_agent_get_rcv_subflow_stats(OwrTransportAgent *transport_agent) +{ + GstStructure *result = NULL; + gchar* value; + g_object_get(transport_agent->priv->mprtp_ply, "subflow-stats", &value, NULL); + result = gst_structure_from_string(value, NULL); + return result; } +GstStructure* owr_transport_agent_get_snd_subflow_stats(OwrTransportAgent *transport_agent) +{ + GstStructure *result = NULL; + gchar* value; + g_object_get(transport_agent->priv->mprtp_sch, "subflow-stats", &value, NULL); + result = gst_structure_from_string(value, NULL); + return result; +} void owr_transport_agent_add_local_address(OwrTransportAgent *transport_agent, const gchar *local_address) { @@ -1540,7 +1483,10 @@ static GstElement *add_dtls_srtp_bin(OwrTransportAgent *transport_agent, guint s return dtls_srtp_bin; } -static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agent, guint stream_id, +static GstElement *add_mprtp_scheduler_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, GstElement *bin) { GstElement *mprtp_sch = NULL; @@ -1549,7 +1495,9 @@ static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agen g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - element_name = g_strdup_printf("mprtp_sch_%d", stream_id); + element_name = g_strdup_printf("mprtp_sch_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); @@ -1564,7 +1512,10 @@ static GstElement *add_mprtp_scheduler_element(OwrTransportAgent *transport_agen } -static GstElement *add_mprtp_plaoyouter_element(OwrTransportAgent *transport_agent, guint stream_id, +static GstElement *add_mprtp_plaoyouter_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, GstElement *bin) { GstElement *mprtp_sch = NULL; @@ -1573,7 +1524,9 @@ static GstElement *add_mprtp_plaoyouter_element(OwrTransportAgent *transport_age g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - element_name = g_strdup_printf("mprtp_ply_%d", stream_id); + element_name = g_strdup_printf("mprtp_ply_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); mprtp_sch = gst_element_factory_make("mprtpplayouter", element_name); @@ -1588,8 +1541,10 @@ static GstElement *add_mprtp_plaoyouter_element(OwrTransportAgent *transport_age } -static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent, guint stream_id, - GstElement *bin) +static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) { GstElement *mprtp_rcv = NULL; gchar *element_name; @@ -1597,7 +1552,9 @@ static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - element_name = g_strdup_printf("mprtp_rcv_%d", stream_id); + element_name = g_strdup_printf("mprtp_rcv_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); mprtp_rcv = gst_element_factory_make("mprtpreceiver", element_name); @@ -1611,7 +1568,10 @@ static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent -static GstElement *add_mprtp_sender_element(OwrTransportAgent *transport_agent, guint stream_id, +static GstElement *add_mprtp_sender_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, GstElement *bin) { GstElement *mprtp_snd = NULL; @@ -1620,7 +1580,9 @@ static GstElement *add_mprtp_sender_element(OwrTransportAgent *transport_agent, g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - element_name = g_strdup_printf("mprtp_snd_%d", stream_id); + element_name = g_strdup_printf("mprtp_snd_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); mprtp_snd = gst_element_factory_make("mprtpsender", element_name); @@ -1796,9 +1758,9 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); - mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, send_output_bin); + mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, FALSE, send_output_bin); dtls_srtp_bin_rtp = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); - mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, send_output_bin); + mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, FALSE, send_output_bin); dtls_srtp_pad_name = g_strdup_printf("rtp_sink_%u", stream_id); linked_ok = gst_element_link_pads(mprtp_sch, "mprtp_src", @@ -1876,10 +1838,10 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ return; } - mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, receive_input_bin); + mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, FALSE, receive_input_bin); nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); - mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, receive_input_bin); + mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, FALSE, receive_input_bin); transport_agent->priv->mprtp_rcv = mprtp_rcv; transport_agent->priv->mprtp_ply = mprtp_ply; @@ -1963,7 +1925,8 @@ static void prepare_transport_bin_data_receive_elements(OwrTransportAgent *trans { OwrTransportAgentPrivate *priv; GstElement *nice_element, *dtls_srtp_bin, *sctpdec; - //GstElement *mprtp_ply; + GstElement *mprtp_rcv; + GstElement *mprtp_ply; GstElement *receive_input_bin; gchar *name; OwrDataSession *data_session; @@ -1990,8 +1953,9 @@ static void prepare_transport_bin_data_receive_elements(OwrTransportAgent *trans } nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); + mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, TRUE, receive_input_bin); dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); - //mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, receive_input_bin); + mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, TRUE, receive_input_bin); sctpdec = _owr_data_session_create_decoder(data_session); g_return_if_fail(nice_element && dtls_srtp_bin && sctpdec); @@ -2001,14 +1965,26 @@ static void prepare_transport_bin_data_receive_elements(OwrTransportAgent *trans g_signal_connect(sctpdec, "pad-added", (GCallback)sctpdec_pad_added, transport_agent); g_signal_connect(sctpdec, "pad-removed", (GCallback)sctpdec_pad_removed, transport_agent); - link_ok = gst_element_link_pads(dtls_srtp_bin, "data_src", sctpdec, "sink"); - link_ok &= gst_element_link(nice_element, dtls_srtp_bin); +// link_ok = gst_element_link_pads(dtls_srtp_bin, "data_src", sctpdec, "sink"); +// link_ok &= gst_element_link(nice_element, dtls_srtp_bin); + link_ok = gst_element_link_pads(mprtp_ply, "mprtp_src", sctpdec, "sink"); + g_warn_if_fail(link_ok); + link_ok = gst_element_link_pads(dtls_srtp_bin, "data_src", mprtp_ply, "mprtp_sink"); + g_warn_if_fail(link_ok); + link_ok = gst_element_link_pads(mprtp_rcv, "mprtp_src", dtls_srtp_bin, "sink"); + g_warn_if_fail(link_ok); + link_ok = gst_element_link_pads(nice_element, "src", mprtp_rcv, "sink_1"); g_warn_if_fail(link_ok); sync_ok = gst_element_sync_state_with_parent(sctpdec); + sync_ok &= gst_element_sync_state_with_parent(mprtp_ply); sync_ok &= gst_element_sync_state_with_parent(dtls_srtp_bin); + sync_ok &= gst_element_sync_state_with_parent(mprtp_rcv); sync_ok &= gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(sync_ok); + + transport_agent->priv->mprtp_ply = mprtp_ply; + transport_agent->priv->mprtp_rcv = mprtp_rcv; } static void prepare_transport_bin_data_send_elements(OwrTransportAgent *transport_agent, @@ -2019,6 +1995,8 @@ static void prepare_transport_bin_data_send_elements(OwrTransportAgent *transpor OwrDataSession *data_session; gboolean linked_ok, sync_ok; gchar *name; + GstElement *mprtp_sch; + GstElement *mprtp_snd; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); priv = transport_agent->priv; @@ -2038,8 +2016,10 @@ static void prepare_transport_bin_data_send_elements(OwrTransportAgent *transpor } nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); + mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, TRUE, send_output_bin); dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); sctpenc = _owr_data_session_create_encoder(data_session); + mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, TRUE, send_output_bin); g_warn_if_fail(sctpenc); g_object_set_data(G_OBJECT(sctpenc), "session-id", GUINT_TO_POINTER(stream_id)); @@ -2047,14 +2027,26 @@ static void prepare_transport_bin_data_send_elements(OwrTransportAgent *transpor g_signal_connect(sctpenc, "sctp-association-established", G_CALLBACK(on_sctp_association_established), transport_agent); - linked_ok = gst_element_link(dtls_srtp_bin, nice_element); - linked_ok &= gst_element_link_pads(sctpenc, "src", dtls_srtp_bin, "data_sink"); +// linked_ok = gst_element_link(dtls_srtp_bin, nice_element); +// linked_ok &= gst_element_link_pads(sctpenc, "src", dtls_srtp_bin, "data_sink"); +// g_warn_if_fail(linked_ok); + + linked_ok = gst_element_link_pads(mprtp_snd, "src_1", nice_element, "sink"); + g_warn_if_fail(linked_ok); + linked_ok = gst_element_link_pads(dtls_srtp_bin, "src", mprtp_snd, "mprtp_sink"); + g_warn_if_fail(linked_ok); + linked_ok = gst_element_link_pads(mprtp_sch, "mprtp_src", dtls_srtp_bin, "data_sink"); + g_warn_if_fail(linked_ok); + linked_ok = gst_element_link_pads(sctpenc, "src", mprtp_sch, "mprtp_sink"); g_warn_if_fail(linked_ok); sync_ok = gst_element_sync_state_with_parent(nice_element); sync_ok &= gst_element_sync_state_with_parent(dtls_srtp_bin); sync_ok &= gst_element_sync_state_with_parent(sctpenc); g_warn_if_fail(sync_ok); + + transport_agent->priv->mprtp_sch = mprtp_sch; + transport_agent->priv->mprtp_snd = mprtp_snd; } static void set_send_ssrc_and_cname(OwrTransportAgent *transport_agent, OwrMediaSession *media_session) @@ -2473,12 +2465,14 @@ static void on_new_remote_candidate(OwrTransportAgent *transport_agent, gboolean gchar *username = NULL, *password = NULL; gboolean forced_ok; gint cands_added; + //NiceAgent *nice_agent; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); g_return_if_fail(OWR_IS_SESSION(session)); stream_id = get_stream_id(transport_agent, session); g_return_if_fail(stream_id); + //nice_agent = transport_agent->priv->nice_agent; item = forced ? _owr_session_get_forced_remote_candidates(session) : _owr_session_get_remote_candidates(session); @@ -2502,8 +2496,27 @@ static void on_new_remote_candidate(OwrTransportAgent *transport_agent, gboolean forced_ok = nice_agent_set_selected_remote_candidate(transport_agent->priv->nice_agent, stream_id, nice_candidate->component_id, nice_candidate); g_warn_if_fail(forced_ok); - } else if (nice_candidate->component_id == NICE_COMPONENT_TYPE_RTP) + } else if (nice_candidate->component_id == NICE_COMPONENT_TYPE_RTP){ + gchar addr[255]; + gchar base_addr[255]; + nice_address_to_string(&nice_candidate->addr, addr); + nice_address_to_string(&nice_candidate->addr, base_addr); + + g_print("-------------------------------------\n" + "-----------RTP CANDIDATE-------------\n" + "-------------------------------------\n" + "foundation: %s\n" + "priority: %d\n" + "base address: %s\n" + "address: %s\n" + "stream_id: %d\n", + nice_candidate->foundation, + nice_candidate->priority, + base_addr, + addr, + stream_id); nice_cands_rtp = g_slist_append(nice_cands_rtp, nice_candidate); + } else nice_cands_rtcp = g_slist_append(nice_cands_rtcp, nice_candidate); } diff --git a/transport/owr_transport_agent.h b/transport/owr_transport_agent.h index f0d1182b..17318e86 100644 --- a/transport/owr_transport_agent.h +++ b/transport/owr_transport_agent.h @@ -35,6 +35,7 @@ #include "owr_session.h" #include +#include G_BEGIN_DECLS @@ -73,18 +74,18 @@ OwrTransportAgent * owr_transport_agent_new(gboolean ice_controlling_mode); void owr_transport_agent_add_helper_server(OwrTransportAgent *transport_agent, OwrHelperServerType type, const gchar *address, guint port, const gchar *username, const gchar *password); void owr_transport_agent_add_local_address(OwrTransportAgent *transport_agent, const gchar *local_address); -//void owr_transport_agent_join_subflow(OwrTransportAgent *transport_agent, -// guint8 subflow_id, -// const gchar *local_address, -// guint snd_port, -// guint rcv_port); -void owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, - guint8 subflow_id, - guint port); -void owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, - guint8 subflow_id, +guint8 owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, guint port); +guint8 owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, const gchar *remote_address, guint port); +void owr_transport_agent_detach_snd_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id); +void owr_transport_agent_detach_rcv_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id); + +GstStructure* owr_transport_agent_get_rcv_subflow_stats(OwrTransportAgent *transport_agent); +GstStructure* owr_transport_agent_get_snd_subflow_stats(OwrTransportAgent *transport_agent); + void owr_transport_agent_set_local_port_range(OwrTransportAgent *transport_agent, guint min_port, guint max_port); void owr_transport_agent_add_session(OwrTransportAgent *agent, OwrSession *session); gchar * owr_transport_agent_get_dot_data(OwrTransportAgent *transport_agent); From 8ed2029d1df3fa8457f8c0fe39b565cd251dabfc Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Wed, 21 Oct 2015 11:36:59 +0300 Subject: [PATCH 12/18] sink sync false --- local/owr_video_renderer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/local/owr_video_renderer.c b/local/owr_video_renderer.c index 171fef75..5a66ec2b 100644 --- a/local/owr_video_renderer.c +++ b/local/owr_video_renderer.c @@ -387,7 +387,10 @@ static GstCaps *owr_video_renderer_get_caps(OwrMediaRenderer *renderer) static GstElement *owr_video_renderer_get_sink(OwrMediaRenderer *renderer) { OWR_UNUSED(renderer); - return gst_element_factory_make(VIDEO_SINK, "video-renderer-sink"); + GstElement *result; + result = gst_element_factory_make(VIDEO_SINK, "video-renderer-sink"); + g_object_set(result, "sync", FALSE, NULL); + return result; } void _owr_video_renderer_notify_tag_changed(OwrVideoRenderer *video_renderer, const gchar *tag, gboolean have_handle, guintptr new_handle) From bb72edf0b092f5272312c58aff276d6cfce03442 Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Wed, 21 Oct 2015 11:55:38 +0300 Subject: [PATCH 13/18] test changed to 60s --- tests/test_send_receive.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_send_receive.c b/tests/test_send_receive.c index 83e278e5..af8c288a 100644 --- a/tests/test_send_receive.c +++ b/tests/test_send_receive.c @@ -388,9 +388,9 @@ int main(int argc, char **argv) owr_get_capture_sources((!disable_video ? OWR_MEDIA_TYPE_VIDEO : 0) | (!disable_audio ? OWR_MEDIA_TYPE_AUDIO : 0), got_sources, NULL); - g_timeout_add_seconds(10, (GSourceFunc)dump_cb, NULL); + g_timeout_add_seconds(5, (GSourceFunc)dump_cb, NULL); g_timeout_add_seconds(2, (GSourceFunc)join_subflows, NULL); - g_timeout_add_seconds(20, (GSourceFunc)detach_subflows, NULL); + g_timeout_add_seconds(60, (GSourceFunc)detach_subflows, NULL); owr_run(); From 091a074b8fcebc8181b4a22ad6903797aa937902 Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Thu, 22 Oct 2015 18:52:42 +0300 Subject: [PATCH 14/18] refresh --- transport/owr_transport_agent.c | 495 +------------------------------- transport/owr_transport_agent.h | 13 - 2 files changed, 15 insertions(+), 493 deletions(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index 83394e15..238d4b50 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -130,24 +130,13 @@ typedef struct { GstElement *nice_sink_rtcp, *dtls_enc_rtcp; } PendingSessionInfo; -typedef struct{ - guint8 id; - NiceAgent *agent; - NiceComponentState state; - guint component_id; - GstElement *sink; - GstElement *src; - guint agent_id; - guint stream_id; - OwrTransportAgent *parent; -}Subflow; - struct _OwrTransportAgentPrivate { NiceAgent *nice_agent; gboolean ice_controlling_mode; GMutex sessions_lock; GHashTable *sessions; + GHashTable *pending_sessions; guint agent_id; gchar *transport_bin_name; GstElement *pipeline, *transport_bin; @@ -156,15 +145,6 @@ struct _OwrTransportAgentPrivate { /* session_id -> struct SendBinInfo */ GHashTable *send_bins; - /* mprtp stuff */ - GstElement *mprtp_sch; - GstElement *mprtp_snd; - GstElement *mprtp_rcv; - GstElement *mprtp_ply; - GHashTable *subflows; - guint mprtp_actual_subflow_id_index; - gboolean mprtp_subflow_id_overflow_detected; - gboolean local_address_added; guint local_min_port; guint local_max_port; @@ -318,10 +298,6 @@ static void owr_transport_agent_finalize(GObject *object) owr_message_origin_bus_set_free(priv->message_origin_bus_set); priv->message_origin_bus_set = NULL; -// if(priv->mprtp_caps != NULL){ -// gst_buffer_unref(priv->mprtp_caps); -// } - G_OBJECT_CLASS(owr_transport_agent_parent_class)->finalize(object); } @@ -446,6 +422,8 @@ static void owr_transport_agent_init(OwrTransportAgent *transport_agent) G_CALLBACK(on_candidate_gathering_done), transport_agent); g_signal_connect(G_OBJECT(priv->nice_agent), "component-state-changed", G_CALLBACK(on_component_state_changed), transport_agent); + g_signal_connect(G_OBJECT(priv->nice_agent), "new-selected-pair-full", + G_CALLBACK(on_new_selected_pair), transport_agent); pipeline_name = g_strdup_printf("transport-agent-%u", priv->agent_id); priv->pipeline = gst_pipeline_new(pipeline_name); @@ -493,10 +471,7 @@ static void owr_transport_agent_init(OwrTransportAgent *transport_agent) priv->data_session_established = FALSE; priv->send_bins = g_hash_table_new_full(NULL, NULL, NULL, g_free); - priv->subflows = g_hash_table_new_full(NULL, NULL, NULL, g_free); - priv->mprtp_actual_subflow_id_index = 0; - priv->mprtp_subflow_id_overflow_detected = FALSE; -// priv->mprtp_caps = NULL; + priv->message_origin_bus_set = owr_message_origin_bus_set_new(); } @@ -587,226 +562,6 @@ void owr_transport_agent_add_helper_server(OwrTransportAgent *transport_agent, g_object_unref(resolver); } - - -static guint8 get_new_subflow_id(OwrTransportAgent *transport_agent) -{ - Subflow *subflow; - gpointer val,key; - gboolean reserved[255]; - guint result,i; - GHashTableIter iter; - - if(transport_agent->priv->mprtp_actual_subflow_id_index == 255){ - transport_agent->priv->mprtp_subflow_id_overflow_detected = TRUE; - } - - if(!transport_agent->priv->mprtp_subflow_id_overflow_detected){ - if(transport_agent->priv->mprtp_actual_subflow_id_index == 0){ - transport_agent->priv->mprtp_actual_subflow_id_index = 2; - } - result = transport_agent->priv->mprtp_actual_subflow_id_index++; - goto done; - } - - g_hash_table_iter_init (&iter, transport_agent->priv->subflows); - while (g_hash_table_iter_next (&iter, (gpointer) & key, (gpointer) & val)) { - subflow = (Subflow *) val; - reserved[subflow->id] = TRUE; - } - - for(i=2; i<255; ++i){ - if(reserved[i] == FALSE){ - result = i; - goto done; - } - } - result = 0; -done: - return result; -} - - -guint8 owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, - const gchar *remote_address, - guint port) -{ - - Subflow *subflow; - GstElement *udpsink; - gchar *padname; - gchar *element_name; - gboolean synced_ok; - OwrTransportAgentPrivate *priv; - guint8 subflow_id = 0; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), 0); - g_return_val_if_fail(remote_address, 0); - - subflow_id = get_new_subflow_id(transport_agent); - g_return_val_if_fail(subflow_id > 0, 0); - - priv = transport_agent->priv; - - - subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); - if(subflow == NULL){ - subflow = g_malloc0(sizeof(Subflow)); - g_hash_table_insert(transport_agent->priv->subflows, - GINT_TO_POINTER(subflow_id), subflow); - - } - - element_name = g_strdup_printf("subflow-rtc-udpsink-%hhu", subflow_id); - subflow->sink = udpsink = gst_element_factory_make("udpsink", element_name); - g_free(element_name); - - if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), - udpsink)) { - GST_WARNING("Failed to add udpsrc-rtc to parent bin"); - return subflow_id; - } - - g_object_set (udpsink, "port", port, "host", remote_address, "sync", - FALSE, "async", FALSE, NULL); - - padname = g_strdup_printf("src_%hhu", subflow_id); - gst_element_link_pads(priv->mprtp_snd, padname, udpsink, "sink"); - g_free(padname); - - g_object_set(priv->mprtp_sch, "join-subflow", subflow_id, NULL); - - synced_ok = gst_element_sync_state_with_parent(udpsink); - g_warn_if_fail(synced_ok); - - return subflow_id; -} - - -void owr_transport_agent_detach_snd_subflow(OwrTransportAgent *transport_agent, - guint8 subflow_id) -{ - - Subflow *subflow; - OwrTransportAgentPrivate *priv; - - g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); - - priv = transport_agent->priv; - - subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); - if(subflow == NULL){ - GST_WARNING("Not existed subflow (%d) requested to detach at sending part", subflow_id); - return; - } - - g_object_set(priv->mprtp_sch, "detach-subflow", subflow_id, NULL); - gst_element_set_state(subflow->sink, GST_STATE_NULL); - if (!gst_bin_remove(GST_BIN(transport_agent->priv->transport_bin), subflow->sink)) { - GST_WARNING("Failed to remove sink for subflow %d", subflow_id); - } - subflow->sink = NULL; - if(subflow->src == NULL){ - g_hash_table_remove(priv->subflows, GUINT_TO_POINTER(subflow_id)); - } -} - -guint8 owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, - guint port) -{ - Subflow *subflow; - GstElement *udpsrc; - gchar *padname; - gchar *element_name; - gboolean synced_ok; - OwrTransportAgentPrivate *priv; - guint8 subflow_id = 0; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), 0); - subflow_id = get_new_subflow_id(transport_agent); - g_return_val_if_fail(subflow_id > 0, 0); - - priv = transport_agent->priv; - - subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); - if(subflow == NULL){ - subflow = g_malloc0(sizeof(Subflow)); - g_hash_table_insert(transport_agent->priv->subflows, - GINT_TO_POINTER(subflow_id), subflow); - } - - element_name = g_strdup_printf("subflow-udpsrc-%hhu", subflow_id); - subflow->src = udpsrc = gst_element_factory_make("udpsrc", element_name); - g_free(element_name); - - if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), - udpsrc)) { - GST_WARNING("Failed to add udpsrc-rtc to parent bin"); - return subflow_id; - } - - g_object_set (udpsrc, "port", port, NULL); - - padname = g_strdup_printf("sink_%hhu", subflow_id); - gst_element_link_pads(udpsrc, "src", priv->mprtp_rcv, padname); - g_free(padname); - - g_object_set(priv->mprtp_ply, "join-subflow", subflow_id, NULL); - - synced_ok = gst_element_sync_state_with_parent(udpsrc); - g_warn_if_fail(synced_ok); - - return subflow_id; -} - - -void owr_transport_agent_detach_rcv_subflow(OwrTransportAgent *transport_agent, - guint8 subflow_id) -{ - - Subflow *subflow; - OwrTransportAgentPrivate *priv; - - g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); - - priv = transport_agent->priv; - - subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); - if(subflow == NULL){ - GST_WARNING("Not existed subflow (%d) requested to detach at sending part", subflow_id); - return; - } - - g_object_set(priv->mprtp_ply, "detach-subflow", subflow_id, NULL); - gst_element_set_state(subflow->src, GST_STATE_NULL); - if (!gst_bin_remove(GST_BIN(transport_agent->priv->transport_bin), subflow->src)) { - GST_WARNING("Failed to remove src for subflow %d", subflow_id); - } - - subflow->src = NULL; - if(subflow->sink == NULL){ - g_hash_table_remove(priv->subflows, GUINT_TO_POINTER(subflow_id)); - } -} - -GstStructure* owr_transport_agent_get_rcv_subflow_stats(OwrTransportAgent *transport_agent) -{ - GstStructure *result = NULL; - gchar* value; - g_object_get(transport_agent->priv->mprtp_ply, "subflow-stats", &value, NULL); - result = gst_structure_from_string(value, NULL); - return result; -} - -GstStructure* owr_transport_agent_get_snd_subflow_stats(OwrTransportAgent *transport_agent) -{ - GstStructure *result = NULL; - gchar* value; - g_object_get(transport_agent->priv->mprtp_sch, "subflow-stats", &value, NULL); - result = gst_structure_from_string(value, NULL); - return result; -} - void owr_transport_agent_add_local_address(OwrTransportAgent *transport_agent, const gchar *local_address) { NiceAddress addr; @@ -1030,15 +785,6 @@ static void handle_new_send_source(OwrTransportAgent *transport_agent, */ caps = _owr_payload_create_raw_caps(send_payload); -// if(transport_agent->priv->mprtp_caps == NULL){ -// g_print("Halleluja!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); -// transport_agent->priv->mprtp_caps = caps; -// gst_buffer_ref(transport_agent->priv->mprtp_caps); -// }else{ -// gst_buffer_unref(transport_agent->priv->mprtp_caps); -// transport_agent->priv->mprtp_caps = caps; -// gst_buffer_ref(transport_agent->priv->mprtp_caps); -// } src = _owr_media_source_request_source(send_source, caps); g_assert(src); gst_caps_unref(caps); @@ -1367,35 +1113,6 @@ static GstElement *add_nice_element(OwrTransportAgent *transport_agent, guint st return nice_element; } -// -//static GstElement *add_external_nice_element(OwrTransportAgent *transport_agent, guint stream_id, -// gboolean is_sink, GstElement *bin, NiceAgent *agent, gint external_id) -//{ -// GstElement *nice_element = NULL; -// gchar *element_name; -// gboolean added_ok; -// -// g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); -// -// element_name = g_strdup_printf("nice-rtp-%s-%u", is_sink -// ? "sink" : "src", stream_id + external_id); -// nice_element = gst_element_factory_make(is_sink ? "nicesink" : "nicesrc", element_name); -// g_free(element_name); -// -// g_object_set(nice_element, "agent", agent, -// "stream", stream_id + external_id, -// "component", NICE_COMPONENT_TYPE_RTP, NULL); -// -// if (is_sink) { -// g_object_set(nice_element, "enable-last-sample", FALSE, "async", FALSE, NULL); -// } -// -// added_ok = gst_bin_add(GST_BIN(bin), nice_element); -// g_warn_if_fail(added_ok); -// -// return nice_element; -//} - static void set_srtp_key(OwrMediaSession *media_session, GParamSpec *pspec, GstElement *dtls_srtp_bin) { @@ -1528,120 +1245,6 @@ static GstElement *add_dtls_srtp_bin(OwrTransportAgent *transport_agent, guint s return dtls_srtp_bin; } -static GstElement *add_mprtp_scheduler_element( - OwrTransportAgent *transport_agent, - guint stream_id, - gboolean for_datastream, - GstElement *bin) -{ - GstElement *mprtp_sch = NULL; - gchar *element_name; - gboolean added_ok; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - - element_name = g_strdup_printf("mprtp_sch_%s_%d", - for_datastream ? "datastr" : "rtcstr", - stream_id); - - mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); - - g_object_set(mprtp_sch, "join-subflow", 1, NULL); - - added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); - g_warn_if_fail(added_ok); - - g_free(element_name); - - return mprtp_sch; -} - - -static GstElement *add_mprtp_plaoyouter_element( - OwrTransportAgent *transport_agent, - guint stream_id, - gboolean for_datastream, - GstElement *bin) -{ - GstElement *mprtp_sch = NULL; - gchar *element_name; - gboolean added_ok; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - - element_name = g_strdup_printf("mprtp_ply_%s_%d", - for_datastream ? "datastr" : "rtcstr", - stream_id); - - mprtp_sch = gst_element_factory_make("mprtpplayouter", element_name); - - g_object_set(mprtp_sch, "join-subflow", 1, NULL); - - added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); - g_warn_if_fail(added_ok); - - g_free(element_name); - - return mprtp_sch; -} - - -static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent, - guint stream_id, - gboolean for_datastream, - GstElement *bin) -{ - GstElement *mprtp_rcv = NULL; - gchar *element_name; - gboolean added_ok; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - - element_name = g_strdup_printf("mprtp_rcv_%s_%d", - for_datastream ? "datastr" : "rtcstr", - stream_id); - - mprtp_rcv = gst_element_factory_make("mprtpreceiver", element_name); - - added_ok = gst_bin_add(GST_BIN(bin), mprtp_rcv); - g_warn_if_fail(added_ok); - - g_free(element_name); - - return mprtp_rcv; -} - - - -static GstElement *add_mprtp_sender_element( - OwrTransportAgent *transport_agent, - guint stream_id, - gboolean for_datastream, - GstElement *bin) -{ - GstElement *mprtp_snd = NULL; - gchar *element_name; - gboolean added_ok; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - - element_name = g_strdup_printf("mprtp_snd_%s_%d", - for_datastream ? "datastr" : "rtcstr", - stream_id); - - mprtp_snd = gst_element_factory_make("mprtpsender", element_name); - - added_ok = gst_bin_add(GST_BIN(bin), mprtp_snd); - g_warn_if_fail(added_ok); - - g_free(element_name); - - return mprtp_snd; -} - - - - static GstPad *ghost_pad_and_add_to_bin(GstPad *pad, GstElement *bin, const gchar *pad_name) { GstPad *ghost_pad; @@ -1682,7 +1285,6 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g gboolean linked_ok; GstPad *sink_pad, *src_pad; GstElement *output_selector; - GstElement* mprtp_sch; GstElement *dtls_srtp_bin_rtp; GstElement *dtls_srtp_bin_rtcp; GstElement *send_output_bin; @@ -1693,7 +1295,7 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g send_bin_info = g_hash_table_lookup(transport_agent->priv->send_bins, GINT_TO_POINTER(stream_id)); g_return_if_fail(send_bin_info); - mprtp_sch = transport_agent->priv->mprtp_sch; + dtls_srtp_bin_rtp = send_bin_info->dtls_srtp_bin_rtp; dtls_srtp_bin_rtcp = send_bin_info->dtls_srtp_bin_rtcp; send_output_bin = send_bin_info->send_output_bin; @@ -1783,8 +1385,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age GstElement *nice_element, *dtls_srtp_bin_rtp, *dtls_srtp_bin_rtcp = NULL; gboolean linked_ok, synced_ok; GstElement *send_output_bin; - GstElement *mprtp_sch; - GstElement *mprtp_snd; SendBinInfo *send_bin_info; gchar *bin_name; AgentAndSessionIdPair *agent_and_session_id_pair; @@ -1793,7 +1393,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age bin_name = g_strdup_printf("send-output-bin-%u", stream_id); send_output_bin = gst_bin_new(bin_name); - g_free(bin_name); if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), send_output_bin)) { @@ -1808,12 +1407,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age pending_session_info->nice_sink_rtp = nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); pending_session_info->dtls_enc_rtp = dtls_srtp_bin_rtp = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); - linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); - mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, FALSE, send_output_bin); - - linked_ok = gst_element_link_pads(mprtp_sch, "mprtp_src", - dtls_srtp_bin_rtp, dtls_srtp_pad_name); - + linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); g_warn_if_fail(linked_ok); agent_and_session_id_pair = g_new0(AgentAndSessionIdPair, 1); @@ -1823,8 +1417,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); - synced_ok = gst_element_sync_state_with_parent(dtls_srtp_bin_rtp); - g_warn_if_fail(synced_ok); if (!rtcp_mux) { pending_session_info->nice_sink_rtcp = nice_element = add_nice_element(transport_agent, stream_id, TRUE, TRUE, send_output_bin); @@ -1839,8 +1431,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); - synced_ok = gst_element_sync_state_with_parent(dtls_srtp_bin_rtcp); - g_warn_if_fail(synced_ok); } send_bin_info = g_new(SendBinInfo, 1); @@ -1849,11 +1439,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age send_bin_info->send_output_bin = send_output_bin; send_bin_info->linked_rtcp = FALSE; - transport_agent->priv->mprtp_sch = mprtp_sch; - transport_agent->priv->mprtp_snd = mprtp_snd; - g_hash_table_insert(transport_agent->priv->send_bins, GINT_TO_POINTER(stream_id), send_bin_info); - } static GstPadProbeReturn nice_src_pad_block(GstPad *pad, GstPadProbeInfo *info, AgentAndSessionIdPair *data) @@ -1869,14 +1455,11 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ guint stream_id, gboolean rtcp_mux, PendingSessionInfo *pending_session_info) { GstElement *nice_element, *dtls_srtp_bin, *funnel; - GstElement *mprtp_ply; - GstElement *mprtp_rcv; GstPad *rtp_src_pad, *rtcp_src_pad; GstPad *nice_src_pad; gchar *rtpbin_pad_name; gboolean linked_ok, synced_ok; GstElement *receive_input_bin; - #ifdef TEST_RTX GstElement *identity; #endif @@ -1898,10 +1481,9 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ GST_ERROR("Failed to sync receive-input-bin-%u state with parent bin", stream_id); return; } - mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, FALSE, receive_input_bin); + pending_session_info->nice_src_rtp = nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); pending_session_info->dtls_dec_rtp = dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); - mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, FALSE, receive_input_bin); agent_and_session_id_pair = g_new0(AgentAndSessionIdPair, 1); agent_and_session_id_pair->transport_agent = transport_agent; @@ -1910,11 +1492,10 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ pending_session_info->nice_src_block_rtp = gst_pad_add_probe(nice_src_pad, GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST, (GstPadProbeCallback)nice_src_pad_block, agent_and_session_id_pair, (GDestroyNotify) g_free); gst_object_unref(nice_src_pad); - transport_agent->priv->mprtp_rcv = mprtp_rcv; - transport_agent->priv->mprtp_ply = mprtp_ply; - //rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); - gst_element_link_pads(dtls_srtp_bin, "rtp_src", mprtp_ply, "mprtp_sink"); - rtp_src_pad = gst_element_get_static_pad(mprtp_ply, "mprtp_src"); + synced_ok = gst_element_sync_state_with_parent(nice_element); + g_warn_if_fail(synced_ok); + + rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); ghost_pad_and_add_to_bin(rtp_src_pad, receive_input_bin, "rtp_src"); gst_object_unref(rtp_src_pad); @@ -1934,13 +1515,6 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ g_warn_if_fail(linked_ok); g_free(rtpbin_pad_name); - synced_ok = gst_element_sync_state_with_parent(dtls_srtp_bin); - g_warn_if_fail(synced_ok); - linked_ok = gst_element_link(nice_element, dtls_srtp_bin); - g_warn_if_fail(linked_ok); - synced_ok = gst_element_sync_state_with_parent(nice_element); - g_warn_if_fail(synced_ok); - if (!rtcp_mux) { funnel = gst_element_factory_make("funnel", NULL); gst_bin_add(GST_BIN(receive_input_bin), funnel); @@ -1972,12 +1546,6 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ g_free(rtpbin_pad_name); synced_ok = gst_element_sync_state_with_parent(funnel); g_warn_if_fail(synced_ok); - synced_ok = gst_element_sync_state_with_parent(dtls_srtp_bin); - g_warn_if_fail(synced_ok); - linked_ok = gst_element_link(nice_element, dtls_srtp_bin); - g_warn_if_fail(linked_ok); - synced_ok = gst_element_sync_state_with_parent(nice_element); - g_warn_if_fail(synced_ok); } else { rtcp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtcp_src"); ghost_pad_and_add_to_bin(rtcp_src_pad, receive_input_bin, "rtcp_src"); @@ -1996,8 +1564,6 @@ static void prepare_transport_bin_data_receive_elements(OwrTransportAgent *trans { OwrTransportAgentPrivate *priv; GstElement *nice_element, *dtls_srtp_bin, *sctpdec; - GstElement *mprtp_rcv; - GstElement *mprtp_ply; GstElement *receive_input_bin; gchar *name; OwrDataSession *data_session; @@ -2024,10 +1590,7 @@ static void prepare_transport_bin_data_receive_elements(OwrTransportAgent *trans } nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); - mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, TRUE, receive_input_bin); dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); - mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, TRUE, receive_input_bin); - sctpdec = _owr_data_session_create_decoder(data_session); g_return_if_fail(nice_element && dtls_srtp_bin && sctpdec); @@ -2036,26 +1599,14 @@ static void prepare_transport_bin_data_receive_elements(OwrTransportAgent *trans g_signal_connect(sctpdec, "pad-added", (GCallback)sctpdec_pad_added, transport_agent); g_signal_connect(sctpdec, "pad-removed", (GCallback)sctpdec_pad_removed, transport_agent); -// link_ok = gst_element_link_pads(dtls_srtp_bin, "data_src", sctpdec, "sink"); -// link_ok &= gst_element_link(nice_element, dtls_srtp_bin); - link_ok = gst_element_link_pads(mprtp_ply, "mprtp_src", sctpdec, "sink"); - g_warn_if_fail(link_ok); - link_ok = gst_element_link_pads(dtls_srtp_bin, "data_src", mprtp_ply, "mprtp_sink"); - g_warn_if_fail(link_ok); - link_ok = gst_element_link_pads(mprtp_rcv, "mprtp_src", dtls_srtp_bin, "sink"); - g_warn_if_fail(link_ok); - link_ok = gst_element_link_pads(nice_element, "src", mprtp_rcv, "sink_1"); + link_ok = gst_element_link_pads(dtls_srtp_bin, "data_src", sctpdec, "sink"); + link_ok &= gst_element_link(nice_element, dtls_srtp_bin); g_warn_if_fail(link_ok); sync_ok = gst_element_sync_state_with_parent(sctpdec); - sync_ok &= gst_element_sync_state_with_parent(mprtp_ply); sync_ok &= gst_element_sync_state_with_parent(dtls_srtp_bin); - sync_ok &= gst_element_sync_state_with_parent(mprtp_rcv); sync_ok &= gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(sync_ok); - - transport_agent->priv->mprtp_ply = mprtp_ply; - transport_agent->priv->mprtp_rcv = mprtp_rcv; } static void prepare_transport_bin_data_send_elements(OwrTransportAgent *transport_agent, @@ -2066,8 +1617,6 @@ static void prepare_transport_bin_data_send_elements(OwrTransportAgent *transpor OwrDataSession *data_session; gboolean linked_ok, sync_ok; gchar *name; - GstElement *mprtp_sch; - GstElement *mprtp_snd; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); priv = transport_agent->priv; @@ -2087,10 +1636,8 @@ static void prepare_transport_bin_data_send_elements(OwrTransportAgent *transpor } nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); - mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, TRUE, send_output_bin); dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); sctpenc = _owr_data_session_create_encoder(data_session); - mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, TRUE, send_output_bin); g_warn_if_fail(sctpenc); g_object_set_data(G_OBJECT(sctpenc), "session-id", GUINT_TO_POINTER(stream_id)); @@ -2098,26 +1645,14 @@ static void prepare_transport_bin_data_send_elements(OwrTransportAgent *transpor g_signal_connect(sctpenc, "sctp-association-established", G_CALLBACK(on_sctp_association_established), transport_agent); -// linked_ok = gst_element_link(dtls_srtp_bin, nice_element); -// linked_ok &= gst_element_link_pads(sctpenc, "src", dtls_srtp_bin, "data_sink"); -// g_warn_if_fail(linked_ok); - - linked_ok = gst_element_link_pads(mprtp_snd, "src_1", nice_element, "sink"); - g_warn_if_fail(linked_ok); - linked_ok = gst_element_link_pads(dtls_srtp_bin, "src", mprtp_snd, "mprtp_sink"); - g_warn_if_fail(linked_ok); - linked_ok = gst_element_link_pads(mprtp_sch, "mprtp_src", dtls_srtp_bin, "data_sink"); - g_warn_if_fail(linked_ok); - linked_ok = gst_element_link_pads(sctpenc, "src", mprtp_sch, "mprtp_sink"); + linked_ok = gst_element_link(dtls_srtp_bin, nice_element); + linked_ok &= gst_element_link_pads(sctpenc, "src", dtls_srtp_bin, "data_sink"); g_warn_if_fail(linked_ok); sync_ok = gst_element_sync_state_with_parent(nice_element); sync_ok &= gst_element_sync_state_with_parent(dtls_srtp_bin); sync_ok &= gst_element_sync_state_with_parent(sctpenc); g_warn_if_fail(sync_ok); - - transport_agent->priv->mprtp_sch = mprtp_sch; - transport_agent->priv->mprtp_snd = mprtp_snd; } static void set_send_ssrc_and_cname(OwrTransportAgent *transport_agent, OwrMediaSession *media_session) diff --git a/transport/owr_transport_agent.h b/transport/owr_transport_agent.h index 17318e86..950e4b4b 100644 --- a/transport/owr_transport_agent.h +++ b/transport/owr_transport_agent.h @@ -35,7 +35,6 @@ #include "owr_session.h" #include -#include G_BEGIN_DECLS @@ -74,18 +73,6 @@ OwrTransportAgent * owr_transport_agent_new(gboolean ice_controlling_mode); void owr_transport_agent_add_helper_server(OwrTransportAgent *transport_agent, OwrHelperServerType type, const gchar *address, guint port, const gchar *username, const gchar *password); void owr_transport_agent_add_local_address(OwrTransportAgent *transport_agent, const gchar *local_address); -guint8 owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, guint port); -guint8 owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, - const gchar *remote_address, - guint port); -void owr_transport_agent_detach_snd_subflow(OwrTransportAgent *transport_agent, - guint8 subflow_id); -void owr_transport_agent_detach_rcv_subflow(OwrTransportAgent *transport_agent, - guint8 subflow_id); - -GstStructure* owr_transport_agent_get_rcv_subflow_stats(OwrTransportAgent *transport_agent); -GstStructure* owr_transport_agent_get_snd_subflow_stats(OwrTransportAgent *transport_agent); - void owr_transport_agent_set_local_port_range(OwrTransportAgent *transport_agent, guint min_port, guint max_port); void owr_transport_agent_add_session(OwrTransportAgent *agent, OwrSession *session); gchar * owr_transport_agent_get_dot_data(OwrTransportAgent *transport_agent); From 96a06e421bb2ace77cadea8531eebe222f7b4acf Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Thu, 22 Oct 2015 19:59:12 +0300 Subject: [PATCH 15/18] refresh --- tests/test_send_receive.c | 49 +-------------------------------------- 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/tests/test_send_receive.c b/tests/test_send_receive.c index af8c288a..90c51466 100644 --- a/tests/test_send_receive.c +++ b/tests/test_send_receive.c @@ -182,50 +182,6 @@ static void got_sources(GList *sources, gpointer user_data) } } -static guint8 subflow_snd_id; -static guint8 subflow_rcv_id; - -static gboolean join_subflows(gpointer *user_data) -{ - const GstStructure *s = NULL; - g_print( - "-----------------------------------------------------------------\n" - "---------------- JOIN SUBFLOW BEGIN -----------------------------\n" - "-----------------------------------------------------------------\n" - ); - subflow_snd_id = owr_transport_agent_join_snd_subflow(send_transport_agent, "127.2.1.1", 5565); - subflow_rcv_id = owr_transport_agent_join_rcv_subflow(recv_transport_agent, 5565); - g_print( - "-----------------------------------------------------------------\n" - "---------------- JOIN SUBFLOW END -> snd:%d, rcv:%d <------------\n" - "-----------------------------------------------------------------\n", - subflow_snd_id, subflow_rcv_id - ); -// s = owr_transport_agent_get_rcv_subflow_stats(recv_transport_agent); -// g_print("%s", gst_structure_to_string(s)); - s = owr_transport_agent_get_snd_subflow_stats(recv_transport_agent); - g_print("%s", gst_structure_to_string(s)); - return G_SOURCE_REMOVE; -} - -static gboolean detach_subflows(gpointer *user_data) -{ - g_print( - "-----------------------------------------------------------------\n" - "---------------- DETACH SUBFLOW BEGIN -> snd:%d, rcv:%d <--------\n" - "-----------------------------------------------------------------\n", - subflow_snd_id, subflow_rcv_id - ); - owr_transport_agent_detach_snd_subflow(send_transport_agent, subflow_snd_id); - owr_transport_agent_detach_rcv_subflow(recv_transport_agent, subflow_rcv_id); - g_print( - "-----------------------------------------------------------------\n" - "------------------ DETACH SUBFLOW END ---------------------------\n" - "-----------------------------------------------------------------\n" - ); - return G_SOURCE_REMOVE; -} - static gboolean dump_cb(gpointer *user_data) { g_print("Dumping send transport agent pipeline!\n"); @@ -338,7 +294,6 @@ int main(int argc, char **argv) owr_transport_agent_set_local_port_range(send_transport_agent, 5000, 5999); owr_transport_agent_add_local_address(send_transport_agent, "127.0.0.1"); - if (!disable_video) { recv_session_video = owr_media_session_new(FALSE); owr_bus_add_message_origin(bus, OWR_MESSAGE_ORIGIN(recv_session_video)); @@ -388,9 +343,7 @@ int main(int argc, char **argv) owr_get_capture_sources((!disable_video ? OWR_MEDIA_TYPE_VIDEO : 0) | (!disable_audio ? OWR_MEDIA_TYPE_AUDIO : 0), got_sources, NULL); - g_timeout_add_seconds(5, (GSourceFunc)dump_cb, NULL); - g_timeout_add_seconds(2, (GSourceFunc)join_subflows, NULL); - g_timeout_add_seconds(60, (GSourceFunc)detach_subflows, NULL); + g_timeout_add_seconds(10, (GSourceFunc)dump_cb, NULL); owr_run(); From 97fa6ec3b70c64296ca40115ef2a012898a6a466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Kreith?= Date: Thu, 11 Feb 2016 12:00:20 +0100 Subject: [PATCH 16/18] update --- transport/owr_transport_agent.c | 168 +++++++++++++++++++++++++++++--- transport/owr_transport_agent.h | 3 + 2 files changed, 157 insertions(+), 14 deletions(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index 21e88cc6..07598cc7 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -97,6 +97,10 @@ static void owr_message_origin_interface_init(OwrMessageOriginInterface *interfa G_DEFINE_TYPE_WITH_CODE(OwrTransportAgent, owr_transport_agent, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(OWR_TYPE_MESSAGE_ORIGIN, owr_message_origin_interface_init)) +typedef struct{ + GstElement *scheduler, *receiver, *sender, *playouter; +}MPRTPPlugin; + typedef struct { OwrDataChannelState state; GstElement *data_sink, *data_src; @@ -144,6 +148,7 @@ struct _OwrTransportAgentPrivate { GstElement *pipeline, *transport_bin; GstElement *rtpbin; + MPRTPPlugin mprtp; /* session_id -> struct SendBinInfo */ GHashTable *send_bins; @@ -360,7 +365,7 @@ static void owr_message_origin_interface_init(OwrMessageOriginInterface *interfa interface->get_bus_set = owr_transport_agent_get_bus_set; } -/* FIXME: Copy from owr/orw.c without any error handling whatsoever */ +/* _FIXME: Copy from owr/orw.c without any error handling whatsoever */ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer user_data) { gboolean ret, is_warning = FALSE; @@ -816,7 +821,7 @@ static void handle_new_send_source(OwrTransportAgent *transport_agent, return; } - /* FIXME - communicate what codec types are supported by the source + /* _FIXME - communicate what codec types are supported by the source * and if one is reusable, use it, else raw? g_object_get(send_payload, "codec-type", &codec_type, NULL); */ @@ -1413,7 +1418,7 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g g_assert(scream_queue); g_signal_connect_object(scream_queue, "on-bitrate-change", G_CALLBACK(on_bitrate_change), media_session, 0); - /* TODO: Move connect to prepare_transport_bin_send_elements */ + /* _TODO: Move connect to prepare_transport_bin_send_elements */ /* RTP */ if (rtp) { @@ -1489,6 +1494,118 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g } } +static GstElement *add_mprtp_scheduler_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) +{ + GstElement *mprtp_sch = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_sch_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); + + mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); + + g_object_set(mprtp_sch, "join-subflow", 1, NULL); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_sch; +} + + +static GstElement *add_mprtp_plaoyouter_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) +{ + GstElement *mprtp_sch = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_ply_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); + + mprtp_sch = gst_element_factory_make("mprtpplayouter", element_name); + + g_object_set(mprtp_sch, "join-subflow", 1, NULL); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_sch; +} + + +static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) +{ + GstElement *mprtp_rcv = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_rcv_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); + + mprtp_rcv = gst_element_factory_make("mprtpreceiver", element_name); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_rcv); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_rcv; +} + + + +static GstElement *add_mprtp_sender_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) +{ + GstElement *mprtp_snd = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_snd_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); + + mprtp_snd = gst_element_factory_make("mprtpsender", element_name); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_snd); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_snd; +} + + static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_agent, guint stream_id, gboolean rtcp_mux, PendingSessionInfo *pending_session_info) { @@ -1496,6 +1613,8 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age GstElement *scream_queue = NULL; gboolean linked_ok, synced_ok; GstElement *send_output_bin; + GstElement *mprtp_sch; + GstElement *mprtp_snd; SendBinInfo *send_bin_info; gchar *bin_name, *dtls_srtp_pad_name; OwrMediaSession *media_session; @@ -1503,6 +1622,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); + //ToDO: MPRTP Sender elements added here bin_name = g_strdup_printf("send-output-bin-%u", stream_id); send_output_bin = gst_bin_new(bin_name); g_free(bin_name); @@ -1519,6 +1639,9 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age media_session = OWR_MEDIA_SESSION(get_session(transport_agent, stream_id)); scream_queue = gst_element_factory_make("screamqueue", "screamqueue"); + mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, FALSE, send_output_bin); + mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, FALSE, send_output_bin); + g_assert(scream_queue); g_object_set(scream_queue, "scream-controller-id", transport_agent->priv->agent_id, NULL); g_signal_connect(scream_queue, "on-payload-adaptation-request", @@ -1527,7 +1650,9 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age pending_session_info->nice_sink_rtp = nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); pending_session_info->dtls_enc_rtp = dtls_srtp_bin_rtp = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); - linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); + linked_ok = gst_element_link_pads(dtls_srtp_bin_rtp, "src", mprtp_snd, "mprtp_sink"); + g_warn_if_fail(linked_ok); + linked_ok = gst_element_link_pads(mprtp_snd, "src_1", nice_element, "sink"); g_warn_if_fail(linked_ok); agent_and_session_id_pair = g_new0(AgentAndSessionIdPair, 1); @@ -1536,10 +1661,16 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age g_signal_connect_data(dtls_srtp_bin_rtp, "on-key-set", G_CALLBACK(on_dtls_enc_key_set), agent_and_session_id_pair, (GClosureNotify) g_free, 0); dtls_srtp_pad_name = g_strdup_printf("rtp_sink_%u", stream_id); - linked_ok = gst_element_link_pads(scream_queue, "src", dtls_srtp_bin_rtp, dtls_srtp_pad_name); + linked_ok = gst_element_link_pads(scream_queue, "src", mprtp_sch, "mprtp_sink"); + g_warn_if_fail(linked_ok); + linked_ok = gst_element_link_pads(mprtp_sch, "mprtp_sink", dtls_srtp_bin_rtp, dtls_srtp_pad_name); g_free(dtls_srtp_pad_name); g_warn_if_fail(linked_ok); + synced_ok = gst_element_sync_state_with_parent(mprtp_sch); + g_warn_if_fail(synced_ok); + synced_ok = gst_element_sync_state_with_parent(mprtp_snd); + g_warn_if_fail(synced_ok); synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); synced_ok = gst_element_sync_state_with_parent(scream_queue); @@ -1566,6 +1697,9 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age send_bin_info->send_output_bin = send_output_bin; send_bin_info->linked_rtcp = FALSE; + transport_agent->priv->mprtp.scheduler = mprtp_sch; + transport_agent->priv->mprtp.sender = mprtp_snd; + g_hash_table_insert(transport_agent->priv->send_bins, GINT_TO_POINTER(stream_id), send_bin_info); } @@ -1582,6 +1716,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ guint stream_id, gboolean rtcp_mux, PendingSessionInfo *pending_session_info) { GstElement *nice_element, *dtls_srtp_bin, *funnel; + GstElement *mprtp_ply, *mprtp_rcv; GstPad *rtp_src_pad, *rtcp_src_pad, *rtp_sink_pad; GstPad *nice_src_pad; gchar *rtpbin_pad_name; @@ -1595,7 +1730,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ AgentAndSessionIdPair *agent_and_session_id_pair; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); - + //ToDO: MPRTP Receiver elements added here bin_name = g_strdup_printf("receive-input-bin-%u", stream_id); receive_input_bin = gst_bin_new(bin_name); g_free(bin_name); @@ -1610,7 +1745,9 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ return; } - pending_session_info->nice_src_rtp = nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); + transport_agent->priv->mprtp.receiver = mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, FALSE, receive_input_bin); + transport_agent->priv->mprtp.playouter = mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, FALSE, receive_input_bin); + pending_session_info->nice_src_rtp = nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); pending_session_info->dtls_dec_rtp = dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); agent_and_session_id_pair = g_new0(AgentAndSessionIdPair, 1); @@ -1623,7 +1760,8 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); - rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); + gst_element_link_pads(dtls_srtp_bin, "rtp_src", mprtp_ply, "mprtp_sink"); + rtp_src_pad = gst_element_get_static_pad(mprtp_ply, "mprtp_src"); ghost_pad_and_add_to_bin(rtp_src_pad, receive_input_bin, "rtp_src"); gst_object_unref(rtp_src_pad); @@ -2011,7 +2149,9 @@ static void on_new_selected_pair(NiceAgent *nice_agent, GstPad *pad; gboolean sync_ok, link_ok; - link_ok = gst_element_link(pending_session_info->nice_src_rtp, pending_session_info->dtls_dec_rtp); + link_ok = gst_element_link_pads(pending_session_info->nice_src_rtp, "src", transport_agent->priv->mprtp.receiver, "sink_1"); + g_warn_if_fail(link_ok); + link_ok = gst_element_link_pads(transport_agent->priv->mprtp.receiver, "mprtp_src", pending_session_info->dtls_dec_rtp, "sink"); g_warn_if_fail(link_ok); gst_element_set_locked_state(pending_session_info->dtls_dec_rtp, FALSE); @@ -2089,7 +2229,7 @@ on_dtls_enc_key_set(GstElement *dtls_srtp_enc, AgentAndSessionIdPair *data) */ g_mutex_lock(&transport_agent->priv->sessions_lock); pending_session_info = g_hash_table_lookup(transport_agent->priv->pending_sessions, GUINT_TO_POINTER(stream_id)); - /* FIXME: What to do about RTCP? It's not guaranteed to ever be enabled if + /* _FIXME: What to do about RTCP? It's not guaranteed to ever be enabled if * RTCP muxing is used but the usage wasn't known beforehand */ if (pending_session_info && dtls_srtp_enc == pending_session_info->dtls_enc_rtp) { @@ -2829,7 +2969,7 @@ static GstElement * on_rtpbin_request_aux_receiver(G_GNUC_UNUSED GstElement *rtp g_object_set(rtxrecv, "payload-type-map", pt_map, NULL); gst_structure_free(pt_map); - /* FIXME: how do we get rtx-time? */ + /* _FIXME: how do we get rtx-time? */ return create_aux_bin("rtprtxrecv", rtxrecv, session_id); @@ -3488,7 +3628,7 @@ static GstFlowReturn new_data_callback(GstAppSink *appsink, OwrTransportAgent *t break; case OWR_DATA_CHANNEL_PPID_BINARY_PARTIAL: g_warning("PPID: DATA_CHANNEL_PPID_BINARY_PARTIAL - Deprecated - Not supported"); - /* TODO: Seems like chrome is using this.. maybe it should be supported to at least receive + /* _TODO: Seems like chrome is using this.. maybe it should be supported to at least receive * this kind of messages even if it is deprecated?. */ break; case OWR_DATA_CHANNEL_PPID_BINARY: @@ -3496,7 +3636,7 @@ static GstFlowReturn new_data_callback(GstAppSink *appsink, OwrTransportAgent *t break; case OWR_DATA_CHANNEL_PPID_STRING_PARTIAL: g_warning("PPID: DATA_CHANNEL_PPID_STRING_PARTIAL - Deprecated - Not supported"); - /* TODO: Seems like chrome is using this.. maybe it should be supported to at least receive + /* _TODO: Seems like chrome is using this.. maybe it should be supported to at least receive * this kind of messages even if it is deprecated? */ break; default: @@ -4199,7 +4339,7 @@ static void on_feedback_rtcp(GObject *session, guint type, guint fbtype, guint s n_loss = GST_READ_UINT8(fci_buf + 2); n_ecn = GST_READ_UINT8(fci_buf + 3); timestamp = GST_READ_UINT32_BE(fci_buf + 4); - /* TODO: Fix qbit */ + /* _TODO: Fix qbit */ gst_buffer_unmap(fci, &info); g_signal_emit_by_name(scream_queue, "incoming-feedback", media_ssrc, timestamp, highest_seq, n_loss, n_ecn, qbit); diff --git a/transport/owr_transport_agent.h b/transport/owr_transport_agent.h index 950e4b4b..06b8e616 100644 --- a/transport/owr_transport_agent.h +++ b/transport/owr_transport_agent.h @@ -77,6 +77,9 @@ void owr_transport_agent_set_local_port_range(OwrTransportAgent *transport_agent void owr_transport_agent_add_session(OwrTransportAgent *agent, OwrSession *session); gchar * owr_transport_agent_get_dot_data(OwrTransportAgent *transport_agent); +//void owr_transport_join_subflow(OwrTransportAgent *transport_agent, guint subflow_id, const gchar *remote_address, guint port); +//void owr_transport_detach_subflow(OwrTransportAgent *transport_agent, guint subflow_id); + G_END_DECLS #endif /* __OWR_TRANSPORT_AGENT_H__ */ From e9ddad7cb990b460aaad6edae46082883369f425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Kreith?= Date: Thu, 11 Feb 2016 14:05:53 +0100 Subject: [PATCH 17/18] update --- transport/owr_transport_agent.c | 168 +++----------------------------- 1 file changed, 14 insertions(+), 154 deletions(-) diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index 07598cc7..21e88cc6 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -97,10 +97,6 @@ static void owr_message_origin_interface_init(OwrMessageOriginInterface *interfa G_DEFINE_TYPE_WITH_CODE(OwrTransportAgent, owr_transport_agent, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(OWR_TYPE_MESSAGE_ORIGIN, owr_message_origin_interface_init)) -typedef struct{ - GstElement *scheduler, *receiver, *sender, *playouter; -}MPRTPPlugin; - typedef struct { OwrDataChannelState state; GstElement *data_sink, *data_src; @@ -148,7 +144,6 @@ struct _OwrTransportAgentPrivate { GstElement *pipeline, *transport_bin; GstElement *rtpbin; - MPRTPPlugin mprtp; /* session_id -> struct SendBinInfo */ GHashTable *send_bins; @@ -365,7 +360,7 @@ static void owr_message_origin_interface_init(OwrMessageOriginInterface *interfa interface->get_bus_set = owr_transport_agent_get_bus_set; } -/* _FIXME: Copy from owr/orw.c without any error handling whatsoever */ +/* FIXME: Copy from owr/orw.c without any error handling whatsoever */ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer user_data) { gboolean ret, is_warning = FALSE; @@ -821,7 +816,7 @@ static void handle_new_send_source(OwrTransportAgent *transport_agent, return; } - /* _FIXME - communicate what codec types are supported by the source + /* FIXME - communicate what codec types are supported by the source * and if one is reusable, use it, else raw? g_object_get(send_payload, "codec-type", &codec_type, NULL); */ @@ -1418,7 +1413,7 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g g_assert(scream_queue); g_signal_connect_object(scream_queue, "on-bitrate-change", G_CALLBACK(on_bitrate_change), media_session, 0); - /* _TODO: Move connect to prepare_transport_bin_send_elements */ + /* TODO: Move connect to prepare_transport_bin_send_elements */ /* RTP */ if (rtp) { @@ -1494,118 +1489,6 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g } } -static GstElement *add_mprtp_scheduler_element( - OwrTransportAgent *transport_agent, - guint stream_id, - gboolean for_datastream, - GstElement *bin) -{ - GstElement *mprtp_sch = NULL; - gchar *element_name; - gboolean added_ok; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - - element_name = g_strdup_printf("mprtp_sch_%s_%d", - for_datastream ? "datastr" : "rtcstr", - stream_id); - - mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); - - g_object_set(mprtp_sch, "join-subflow", 1, NULL); - - added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); - g_warn_if_fail(added_ok); - - g_free(element_name); - - return mprtp_sch; -} - - -static GstElement *add_mprtp_plaoyouter_element( - OwrTransportAgent *transport_agent, - guint stream_id, - gboolean for_datastream, - GstElement *bin) -{ - GstElement *mprtp_sch = NULL; - gchar *element_name; - gboolean added_ok; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - - element_name = g_strdup_printf("mprtp_ply_%s_%d", - for_datastream ? "datastr" : "rtcstr", - stream_id); - - mprtp_sch = gst_element_factory_make("mprtpplayouter", element_name); - - g_object_set(mprtp_sch, "join-subflow", 1, NULL); - - added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); - g_warn_if_fail(added_ok); - - g_free(element_name); - - return mprtp_sch; -} - - -static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent, - guint stream_id, - gboolean for_datastream, - GstElement *bin) -{ - GstElement *mprtp_rcv = NULL; - gchar *element_name; - gboolean added_ok; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - - element_name = g_strdup_printf("mprtp_rcv_%s_%d", - for_datastream ? "datastr" : "rtcstr", - stream_id); - - mprtp_rcv = gst_element_factory_make("mprtpreceiver", element_name); - - added_ok = gst_bin_add(GST_BIN(bin), mprtp_rcv); - g_warn_if_fail(added_ok); - - g_free(element_name); - - return mprtp_rcv; -} - - - -static GstElement *add_mprtp_sender_element( - OwrTransportAgent *transport_agent, - guint stream_id, - gboolean for_datastream, - GstElement *bin) -{ - GstElement *mprtp_snd = NULL; - gchar *element_name; - gboolean added_ok; - - g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); - - element_name = g_strdup_printf("mprtp_snd_%s_%d", - for_datastream ? "datastr" : "rtcstr", - stream_id); - - mprtp_snd = gst_element_factory_make("mprtpsender", element_name); - - added_ok = gst_bin_add(GST_BIN(bin), mprtp_snd); - g_warn_if_fail(added_ok); - - g_free(element_name); - - return mprtp_snd; -} - - static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_agent, guint stream_id, gboolean rtcp_mux, PendingSessionInfo *pending_session_info) { @@ -1613,8 +1496,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age GstElement *scream_queue = NULL; gboolean linked_ok, synced_ok; GstElement *send_output_bin; - GstElement *mprtp_sch; - GstElement *mprtp_snd; SendBinInfo *send_bin_info; gchar *bin_name, *dtls_srtp_pad_name; OwrMediaSession *media_session; @@ -1622,7 +1503,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); - //ToDO: MPRTP Sender elements added here bin_name = g_strdup_printf("send-output-bin-%u", stream_id); send_output_bin = gst_bin_new(bin_name); g_free(bin_name); @@ -1639,9 +1519,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age media_session = OWR_MEDIA_SESSION(get_session(transport_agent, stream_id)); scream_queue = gst_element_factory_make("screamqueue", "screamqueue"); - mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, FALSE, send_output_bin); - mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, FALSE, send_output_bin); - g_assert(scream_queue); g_object_set(scream_queue, "scream-controller-id", transport_agent->priv->agent_id, NULL); g_signal_connect(scream_queue, "on-payload-adaptation-request", @@ -1650,9 +1527,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age pending_session_info->nice_sink_rtp = nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); pending_session_info->dtls_enc_rtp = dtls_srtp_bin_rtp = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); - linked_ok = gst_element_link_pads(dtls_srtp_bin_rtp, "src", mprtp_snd, "mprtp_sink"); - g_warn_if_fail(linked_ok); - linked_ok = gst_element_link_pads(mprtp_snd, "src_1", nice_element, "sink"); + linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); g_warn_if_fail(linked_ok); agent_and_session_id_pair = g_new0(AgentAndSessionIdPair, 1); @@ -1661,16 +1536,10 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age g_signal_connect_data(dtls_srtp_bin_rtp, "on-key-set", G_CALLBACK(on_dtls_enc_key_set), agent_and_session_id_pair, (GClosureNotify) g_free, 0); dtls_srtp_pad_name = g_strdup_printf("rtp_sink_%u", stream_id); - linked_ok = gst_element_link_pads(scream_queue, "src", mprtp_sch, "mprtp_sink"); - g_warn_if_fail(linked_ok); - linked_ok = gst_element_link_pads(mprtp_sch, "mprtp_sink", dtls_srtp_bin_rtp, dtls_srtp_pad_name); + linked_ok = gst_element_link_pads(scream_queue, "src", dtls_srtp_bin_rtp, dtls_srtp_pad_name); g_free(dtls_srtp_pad_name); g_warn_if_fail(linked_ok); - synced_ok = gst_element_sync_state_with_parent(mprtp_sch); - g_warn_if_fail(synced_ok); - synced_ok = gst_element_sync_state_with_parent(mprtp_snd); - g_warn_if_fail(synced_ok); synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); synced_ok = gst_element_sync_state_with_parent(scream_queue); @@ -1697,9 +1566,6 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age send_bin_info->send_output_bin = send_output_bin; send_bin_info->linked_rtcp = FALSE; - transport_agent->priv->mprtp.scheduler = mprtp_sch; - transport_agent->priv->mprtp.sender = mprtp_snd; - g_hash_table_insert(transport_agent->priv->send_bins, GINT_TO_POINTER(stream_id), send_bin_info); } @@ -1716,7 +1582,6 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ guint stream_id, gboolean rtcp_mux, PendingSessionInfo *pending_session_info) { GstElement *nice_element, *dtls_srtp_bin, *funnel; - GstElement *mprtp_ply, *mprtp_rcv; GstPad *rtp_src_pad, *rtcp_src_pad, *rtp_sink_pad; GstPad *nice_src_pad; gchar *rtpbin_pad_name; @@ -1730,7 +1595,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ AgentAndSessionIdPair *agent_and_session_id_pair; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); - //ToDO: MPRTP Receiver elements added here + bin_name = g_strdup_printf("receive-input-bin-%u", stream_id); receive_input_bin = gst_bin_new(bin_name); g_free(bin_name); @@ -1745,9 +1610,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ return; } - transport_agent->priv->mprtp.receiver = mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, FALSE, receive_input_bin); - transport_agent->priv->mprtp.playouter = mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, FALSE, receive_input_bin); - pending_session_info->nice_src_rtp = nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); + pending_session_info->nice_src_rtp = nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); pending_session_info->dtls_dec_rtp = dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); agent_and_session_id_pair = g_new0(AgentAndSessionIdPair, 1); @@ -1760,8 +1623,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); - gst_element_link_pads(dtls_srtp_bin, "rtp_src", mprtp_ply, "mprtp_sink"); - rtp_src_pad = gst_element_get_static_pad(mprtp_ply, "mprtp_src"); + rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); ghost_pad_and_add_to_bin(rtp_src_pad, receive_input_bin, "rtp_src"); gst_object_unref(rtp_src_pad); @@ -2149,9 +2011,7 @@ static void on_new_selected_pair(NiceAgent *nice_agent, GstPad *pad; gboolean sync_ok, link_ok; - link_ok = gst_element_link_pads(pending_session_info->nice_src_rtp, "src", transport_agent->priv->mprtp.receiver, "sink_1"); - g_warn_if_fail(link_ok); - link_ok = gst_element_link_pads(transport_agent->priv->mprtp.receiver, "mprtp_src", pending_session_info->dtls_dec_rtp, "sink"); + link_ok = gst_element_link(pending_session_info->nice_src_rtp, pending_session_info->dtls_dec_rtp); g_warn_if_fail(link_ok); gst_element_set_locked_state(pending_session_info->dtls_dec_rtp, FALSE); @@ -2229,7 +2089,7 @@ on_dtls_enc_key_set(GstElement *dtls_srtp_enc, AgentAndSessionIdPair *data) */ g_mutex_lock(&transport_agent->priv->sessions_lock); pending_session_info = g_hash_table_lookup(transport_agent->priv->pending_sessions, GUINT_TO_POINTER(stream_id)); - /* _FIXME: What to do about RTCP? It's not guaranteed to ever be enabled if + /* FIXME: What to do about RTCP? It's not guaranteed to ever be enabled if * RTCP muxing is used but the usage wasn't known beforehand */ if (pending_session_info && dtls_srtp_enc == pending_session_info->dtls_enc_rtp) { @@ -2969,7 +2829,7 @@ static GstElement * on_rtpbin_request_aux_receiver(G_GNUC_UNUSED GstElement *rtp g_object_set(rtxrecv, "payload-type-map", pt_map, NULL); gst_structure_free(pt_map); - /* _FIXME: how do we get rtx-time? */ + /* FIXME: how do we get rtx-time? */ return create_aux_bin("rtprtxrecv", rtxrecv, session_id); @@ -3628,7 +3488,7 @@ static GstFlowReturn new_data_callback(GstAppSink *appsink, OwrTransportAgent *t break; case OWR_DATA_CHANNEL_PPID_BINARY_PARTIAL: g_warning("PPID: DATA_CHANNEL_PPID_BINARY_PARTIAL - Deprecated - Not supported"); - /* _TODO: Seems like chrome is using this.. maybe it should be supported to at least receive + /* TODO: Seems like chrome is using this.. maybe it should be supported to at least receive * this kind of messages even if it is deprecated?. */ break; case OWR_DATA_CHANNEL_PPID_BINARY: @@ -3636,7 +3496,7 @@ static GstFlowReturn new_data_callback(GstAppSink *appsink, OwrTransportAgent *t break; case OWR_DATA_CHANNEL_PPID_STRING_PARTIAL: g_warning("PPID: DATA_CHANNEL_PPID_STRING_PARTIAL - Deprecated - Not supported"); - /* _TODO: Seems like chrome is using this.. maybe it should be supported to at least receive + /* TODO: Seems like chrome is using this.. maybe it should be supported to at least receive * this kind of messages even if it is deprecated? */ break; default: @@ -4339,7 +4199,7 @@ static void on_feedback_rtcp(GObject *session, guint type, guint fbtype, guint s n_loss = GST_READ_UINT8(fci_buf + 2); n_ecn = GST_READ_UINT8(fci_buf + 3); timestamp = GST_READ_UINT32_BE(fci_buf + 4); - /* _TODO: Fix qbit */ + /* TODO: Fix qbit */ gst_buffer_unmap(fci, &info); g_signal_emit_by_name(scream_queue, "incoming-feedback", media_ssrc, timestamp, highest_seq, n_loss, n_ecn, qbit); From dd0316399b6ac42d68112dee122d11bb0002736d Mon Sep 17 00:00:00 2001 From: Balazs Kreith Date: Sat, 13 Feb 2016 20:10:47 +0100 Subject: [PATCH 18/18] add mprtp plugin to transport pipeline, and provide interfaces to attach and detach subflows dynamically. Change test-send-receive test in order to contain mprtp join and detach possibility --- tests/test_send_receive.c | 23 +- transport/owr_transport_agent.c | 396 +++++++++++++++++++++++++++++++- transport/owr_transport_agent.h | 12 +- 3 files changed, 413 insertions(+), 18 deletions(-) diff --git a/tests/test_send_receive.c b/tests/test_send_receive.c index 35fb0c77..7afd6352 100644 --- a/tests/test_send_receive.c +++ b/tests/test_send_receive.c @@ -46,6 +46,10 @@ #include +typedef struct{ + OwrTransportAgent *snd, *rcv; +}TransportAgents; + static OwrTransportAgent *recv_transport_agent = NULL; static OwrMediaSession *recv_session_audio = NULL; static OwrMediaSession *recv_session_video = NULL; @@ -341,6 +345,15 @@ static gboolean dump_cb(gpointer *user_data) return G_SOURCE_REMOVE; } +static gboolean add_subflow(gpointer *user_data) +{ + g_print("Add subflow to the pipeline!\n"); + TransportAgents *agents = user_data; + owr_transport_agent_join_rcv_subflow(agents->rcv, 5720); + owr_transport_agent_join_snd_subflow(agents->snd, "127.0.0.1", 5720); + return G_SOURCE_REMOVE; +} + static const gchar *message_origin_name_func(gpointer origin) { if (!origin) { @@ -378,11 +391,11 @@ static const gchar *message_origin_name_func(gpointer origin) } } - int main(int argc, char **argv) { GOptionContext *options; GError *error = NULL; + TransportAgents agents; options = g_option_context_new(NULL); g_option_context_add_main_entries(options, entries, NULL); @@ -412,7 +425,7 @@ int main(int argc, char **argv) owr_bus_add_message_origin(bus, OWR_MESSAGE_ORIGIN(owr_window_registry_get())); - recv_transport_agent = owr_transport_agent_new(FALSE); + agents.rcv = recv_transport_agent = owr_transport_agent_new(FALSE); g_assert(OWR_IS_TRANSPORT_AGENT(recv_transport_agent)); owr_bus_add_message_origin(bus, OWR_MESSAGE_ORIGIN(recv_transport_agent)); @@ -423,7 +436,7 @@ int main(int argc, char **argv) owr_transport_agent_add_local_address(recv_transport_agent, local_addr); // SEND - send_transport_agent = owr_transport_agent_new(TRUE); + agents.snd = send_transport_agent = owr_transport_agent_new(TRUE); g_assert(OWR_IS_TRANSPORT_AGENT(send_transport_agent)); owr_bus_add_message_origin(bus, OWR_MESSAGE_ORIGIN(send_transport_agent)); @@ -503,6 +516,10 @@ int main(int argc, char **argv) g_timeout_add_seconds(10, (GSourceFunc)dump_cb, NULL); + //Todo: transport agent into one pointer. + g_timeout_add_seconds(10, (GSourceFunc)add_subflow, &agents); + + owr_run(); g_free(remote_addr); diff --git a/transport/owr_transport_agent.c b/transport/owr_transport_agent.c index 21e88cc6..b917eb64 100644 --- a/transport/owr_transport_agent.c +++ b/transport/owr_transport_agent.c @@ -97,6 +97,15 @@ static void owr_message_origin_interface_init(OwrMessageOriginInterface *interfa G_DEFINE_TYPE_WITH_CODE(OwrTransportAgent, owr_transport_agent, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(OWR_TYPE_MESSAGE_ORIGIN, owr_message_origin_interface_init)) + +typedef struct{ + guint8 id; + NiceAgent *agent; + GstElement *sink; + GstElement *src; + OwrTransportAgent *parent; +}Subflow; + typedef struct { OwrDataChannelState state; GstElement *data_sink, *data_src; @@ -123,6 +132,7 @@ typedef struct { typedef struct { GstElement *nice_src_rtp, *dtls_dec_rtp; + GstElement *mprtp_rcv; gulong nice_src_block_rtp; GstElement *nice_src_rtcp, *dtls_dec_rtcp; @@ -163,6 +173,14 @@ struct _OwrTransportAgentPrivate { GRWLock data_channels_rw_mutex; gboolean data_session_added, data_session_established; OwrMessageOriginBusSet *message_origin_bus_set; + + GstElement *mprtp_sch; + GstElement *mprtp_snd; + GstElement *mprtp_rcv; + GstElement *mprtp_ply; + GHashTable *subflows; + guint mprtp_actual_subflow_id_index; + gboolean mprtp_subflow_id_overflow_detected; }; typedef struct { @@ -360,7 +378,7 @@ static void owr_message_origin_interface_init(OwrMessageOriginInterface *interfa interface->get_bus_set = owr_transport_agent_get_bus_set; } -/* FIXME: Copy from owr/orw.c without any error handling whatsoever */ +/* _FIXME: Copy from owr/orw.c without any error handling whatsoever */ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer user_data) { gboolean ret, is_warning = FALSE; @@ -510,6 +528,209 @@ static void owr_transport_agent_init(OwrTransportAgent *transport_agent) priv->send_bins = g_hash_table_new_full(NULL, NULL, NULL, g_free); priv->message_origin_bus_set = owr_message_origin_bus_set_new(); + priv->subflows = g_hash_table_new_full(NULL, NULL, NULL, g_free); +} + + + +static guint8 get_new_subflow_id(OwrTransportAgent *transport_agent) +{ + Subflow *subflow; + gpointer val,key; + gboolean reserved[255]; + guint result,i; + GHashTableIter iter; + + if(transport_agent->priv->mprtp_actual_subflow_id_index == 255){ + transport_agent->priv->mprtp_subflow_id_overflow_detected = TRUE; + } + + if(!transport_agent->priv->mprtp_subflow_id_overflow_detected){ + if(transport_agent->priv->mprtp_actual_subflow_id_index == 0){ + transport_agent->priv->mprtp_actual_subflow_id_index = 2; + } + result = transport_agent->priv->mprtp_actual_subflow_id_index++; + goto done; + } + + g_hash_table_iter_init (&iter, transport_agent->priv->subflows); + while (g_hash_table_iter_next (&iter, (gpointer) & key, (gpointer) & val)) { + subflow = (Subflow *) val; + reserved[subflow->id] = TRUE; + } + + for(i=2; i<255; ++i){ + if(reserved[i] == FALSE){ + result = i; + goto done; + } + } + result = 0; +done: + return result; +} + + +guint8 owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, + const gchar *remote_address, + guint port) +{ + + Subflow *subflow; + GstElement *udpsink; + gchar *padname; + gchar *element_name; + gboolean synced_ok; + OwrTransportAgentPrivate *priv; + guint8 subflow_id = 0; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), 0); + g_return_val_if_fail(remote_address, 0); + + subflow_id = get_new_subflow_id(transport_agent); + g_return_val_if_fail(subflow_id > 0, 0); + + priv = transport_agent->priv; + + + subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); + if(subflow == NULL){ + subflow = g_malloc0(sizeof(Subflow)); + g_hash_table_insert(transport_agent->priv->subflows, + GINT_TO_POINTER(subflow_id), subflow); + + } + + element_name = g_strdup_printf("subflow-rtc-udpsink-%hhu", subflow_id); + subflow->sink = udpsink = gst_element_factory_make("udpsink", element_name); + g_free(element_name); + + if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), + udpsink)) { + GST_WARNING("Failed to add udpsrc-rtc to parent bin"); + return subflow_id; + } + + g_object_set (udpsink, "port", port, "host", remote_address, "sync", + FALSE, "async", FALSE, NULL); + + padname = g_strdup_printf("src_%hhu", subflow_id); + gst_element_link_pads(priv->mprtp_snd, padname, udpsink, "sink"); + g_free(padname); + + g_object_set(priv->mprtp_sch, "join-subflow", subflow_id, NULL); + + synced_ok = gst_element_sync_state_with_parent(udpsink); + g_warn_if_fail(synced_ok); + + return subflow_id; +} + + +void owr_transport_agent_detach_snd_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id) +{ + + Subflow *subflow; + OwrTransportAgentPrivate *priv; + + g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); + + priv = transport_agent->priv; + + subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); + if(subflow == NULL){ + GST_WARNING("Not existed subflow (%d) requested to detach at sending part", subflow_id); + return; + } + + g_object_set(priv->mprtp_sch, "detach-subflow", subflow_id, NULL); + gst_element_set_state(subflow->sink, GST_STATE_NULL); + if (!gst_bin_remove(GST_BIN(transport_agent->priv->transport_bin), subflow->sink)) { + GST_WARNING("Failed to remove sink for subflow %d", subflow_id); + } + subflow->sink = NULL; + if(subflow->src == NULL){ + g_hash_table_remove(priv->subflows, GUINT_TO_POINTER(subflow_id)); + } +} + +guint8 owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, + guint port) +{ + Subflow *subflow; + GstElement *udpsrc; + gchar *padname; + gchar *element_name; + gboolean synced_ok; + OwrTransportAgentPrivate *priv; + guint8 subflow_id = 0; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), 0); + subflow_id = get_new_subflow_id(transport_agent); + g_return_val_if_fail(subflow_id > 0, 0); + + priv = transport_agent->priv; + + subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); + if(subflow == NULL){ + subflow = g_malloc0(sizeof(Subflow)); + g_hash_table_insert(transport_agent->priv->subflows, + GINT_TO_POINTER(subflow_id), subflow); + } + + element_name = g_strdup_printf("subflow-udpsrc-%hhu", subflow_id); + subflow->src = udpsrc = gst_element_factory_make("udpsrc", element_name); + g_free(element_name); + + if (!gst_bin_add(GST_BIN(transport_agent->priv->transport_bin), + udpsrc)) { + GST_WARNING("Failed to add udpsrc-rtc to parent bin"); + return subflow_id; + } + + g_object_set (udpsrc, "port", port, NULL); + + padname = g_strdup_printf("sink_%hhu", subflow_id); + gst_element_link_pads(udpsrc, "src", priv->mprtp_rcv, padname); + g_free(padname); + + g_object_set(priv->mprtp_ply, "join-subflow", subflow_id, NULL); + + synced_ok = gst_element_sync_state_with_parent(udpsrc); + g_warn_if_fail(synced_ok); + + return subflow_id; +} + + +void owr_transport_agent_detach_rcv_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id) +{ + + Subflow *subflow; + OwrTransportAgentPrivate *priv; + + g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); + + priv = transport_agent->priv; + + subflow = (Subflow*) g_hash_table_lookup(priv->subflows, GUINT_TO_POINTER(subflow_id)); + if(subflow == NULL){ + GST_WARNING("Not existed subflow (%d) requested to detach at sending part", subflow_id); + return; + } + + g_object_set(priv->mprtp_ply, "detach-subflow", subflow_id, NULL); + gst_element_set_state(subflow->src, GST_STATE_NULL); + if (!gst_bin_remove(GST_BIN(transport_agent->priv->transport_bin), subflow->src)) { + GST_WARNING("Failed to remove src for subflow %d", subflow_id); + } + + subflow->src = NULL; + if(subflow->sink == NULL){ + g_hash_table_remove(priv->subflows, GUINT_TO_POINTER(subflow_id)); + } } @@ -816,7 +1037,7 @@ static void handle_new_send_source(OwrTransportAgent *transport_agent, return; } - /* FIXME - communicate what codec types are supported by the source + /* _FIXME - communicate what codec types are supported by the source * and if one is reusable, use it, else raw? g_object_get(send_payload, "codec-type", &codec_type, NULL); */ @@ -1381,6 +1602,118 @@ static void on_bitrate_change(GstElement *scream_queue, guint bitrate, guint ssr _owr_schedule_with_hash_table((GSourceFunc)emit_bitrate_change, args); } + +static GstElement *add_mprtp_scheduler_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) +{ + GstElement *mprtp_sch = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_sch_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); + + mprtp_sch = gst_element_factory_make("mprtpscheduler", element_name); + + g_object_set(mprtp_sch, "join-subflow", 1, NULL); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_sch; +} + + +static GstElement *add_mprtp_plaoyouter_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) +{ + GstElement *mprtp_sch = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_ply_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); + + mprtp_sch = gst_element_factory_make("mprtpplayouter", element_name); + + g_object_set(mprtp_sch, "join-subflow", 1, NULL); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_sch); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_sch; +} + + +static GstElement *add_mprtp_receiver_element(OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) +{ + GstElement *mprtp_rcv = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_rcv_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); + + mprtp_rcv = gst_element_factory_make("mprtpreceiver", element_name); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_rcv); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_rcv; +} + + + +static GstElement *add_mprtp_sender_element( + OwrTransportAgent *transport_agent, + guint stream_id, + gboolean for_datastream, + GstElement *bin) +{ + GstElement *mprtp_snd = NULL; + gchar *element_name; + gboolean added_ok; + + g_return_val_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent), NULL); + + element_name = g_strdup_printf("mprtp_snd_%s_%d", + for_datastream ? "datastr" : "rtcstr", + stream_id); + + mprtp_snd = gst_element_factory_make("mprtpsender", element_name); + + added_ok = gst_bin_add(GST_BIN(bin), mprtp_snd); + g_warn_if_fail(added_ok); + + g_free(element_name); + + return mprtp_snd; +} + static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, guint stream_id, gboolean rtp, gboolean rtcp) { gchar *rtpbin_pad_name, *dtls_srtp_pad_name; @@ -1413,7 +1746,7 @@ static void link_rtpbin_to_send_output_bin(OwrTransportAgent *transport_agent, g g_assert(scream_queue); g_signal_connect_object(scream_queue, "on-bitrate-change", G_CALLBACK(on_bitrate_change), media_session, 0); - /* TODO: Move connect to prepare_transport_bin_send_elements */ + /* _TODO: Move connect to prepare_transport_bin_send_elements */ /* RTP */ if (rtp) { @@ -1500,6 +1833,7 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age gchar *bin_name, *dtls_srtp_pad_name; OwrMediaSession *media_session; AgentAndSessionIdPair *agent_and_session_id_pair; + GstElement* mprtp_sch, *mprtp_snd; g_return_if_fail(OWR_IS_TRANSPORT_AGENT(transport_agent)); @@ -1520,14 +1854,22 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age media_session = OWR_MEDIA_SESSION(get_session(transport_agent, stream_id)); scream_queue = gst_element_factory_make("screamqueue", "screamqueue"); g_assert(scream_queue); + mprtp_sch = add_mprtp_scheduler_element(transport_agent, stream_id, FALSE, send_output_bin); + g_assert(mprtp_sch); + mprtp_snd = add_mprtp_sender_element(transport_agent, stream_id, FALSE, send_output_bin); + g_assert(mprtp_snd); + g_object_set(scream_queue, "scream-controller-id", transport_agent->priv->agent_id, NULL); g_signal_connect(scream_queue, "on-payload-adaptation-request", (GCallback)on_payload_adaptation_request, media_session); gst_bin_add(GST_BIN(send_output_bin), scream_queue); + //Todo: Add mprtp sender here. <-Theoretically done. pending_session_info->nice_sink_rtp = nice_element = add_nice_element(transport_agent, stream_id, TRUE, FALSE, send_output_bin); pending_session_info->dtls_enc_rtp = dtls_srtp_bin_rtp = add_dtls_srtp_bin(transport_agent, stream_id, TRUE, FALSE, send_output_bin); - linked_ok = gst_element_link(dtls_srtp_bin_rtp, nice_element); + linked_ok = gst_element_link_pads(dtls_srtp_bin_rtp, "src", mprtp_snd, "mprtp_sink"); + g_warn_if_fail(linked_ok); + linked_ok = gst_element_link_pads(mprtp_snd, "src_1", nice_element, "sink"); g_warn_if_fail(linked_ok); agent_and_session_id_pair = g_new0(AgentAndSessionIdPair, 1); @@ -1535,11 +1877,21 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age agent_and_session_id_pair->session_id = stream_id; g_signal_connect_data(dtls_srtp_bin_rtp, "on-key-set", G_CALLBACK(on_dtls_enc_key_set), agent_and_session_id_pair, (GClosureNotify) g_free, 0); + //Todo: Link mprtp scheduler here. <-Theoretically done. dtls_srtp_pad_name = g_strdup_printf("rtp_sink_%u", stream_id); - linked_ok = gst_element_link_pads(scream_queue, "src", dtls_srtp_bin_rtp, dtls_srtp_pad_name); + linked_ok = gst_element_link_pads(scream_queue, "src", + mprtp_sch, "rtp_sink"); + linked_ok = gst_element_link_pads(mprtp_sch, "mprtp_src", + dtls_srtp_bin_rtp, dtls_srtp_pad_name); g_free(dtls_srtp_pad_name); g_warn_if_fail(linked_ok); + //Todo: Sync mprtp scheduler here. <-Theoretically done. + g_warn_if_fail(linked_ok); + synced_ok = gst_element_sync_state_with_parent(mprtp_snd); + g_warn_if_fail(synced_ok); + synced_ok = gst_element_sync_state_with_parent(mprtp_sch); + g_warn_if_fail(synced_ok); synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); synced_ok = gst_element_sync_state_with_parent(scream_queue); @@ -1566,6 +1918,9 @@ static void prepare_transport_bin_send_elements(OwrTransportAgent *transport_age send_bin_info->send_output_bin = send_output_bin; send_bin_info->linked_rtcp = FALSE; + transport_agent->priv->mprtp_sch = mprtp_sch; + transport_agent->priv->mprtp_snd = mprtp_snd; + g_hash_table_insert(transport_agent->priv->send_bins, GINT_TO_POINTER(stream_id), send_bin_info); } @@ -1588,6 +1943,7 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ gboolean linked_ok, synced_ok; GstElement *receive_input_bin; ScreamRx *scream_rx; + GstElement *mprtp_ply, *mprtp_rcv; #ifdef TEST_RTX GstElement *identity; #endif @@ -1610,6 +1966,9 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ return; } + transport_agent->priv->mprtp_rcv = mprtp_rcv = add_mprtp_receiver_element(transport_agent, stream_id, FALSE, receive_input_bin); + transport_agent->priv->mprtp_ply = mprtp_ply = add_mprtp_plaoyouter_element(transport_agent, stream_id, FALSE, receive_input_bin); + pending_session_info->mprtp_rcv = transport_agent->priv->mprtp_rcv; pending_session_info->nice_src_rtp = nice_element = add_nice_element(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); pending_session_info->dtls_dec_rtp = dtls_srtp_bin = add_dtls_srtp_bin(transport_agent, stream_id, FALSE, FALSE, receive_input_bin); @@ -1620,10 +1979,20 @@ static void prepare_transport_bin_receive_elements(OwrTransportAgent *transport_ pending_session_info->nice_src_block_rtp = gst_pad_add_probe(nice_src_pad, GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST, (GstPadProbeCallback)nice_src_pad_block, agent_and_session_id_pair, (GDestroyNotify) g_free); gst_object_unref(nice_src_pad); + //Todo: Sync mprtp_rcv, mprtp_ply here. //<- Theoretically done synced_ok = gst_element_sync_state_with_parent(nice_element); g_warn_if_fail(synced_ok); + synced_ok = gst_element_sync_state_with_parent(mprtp_rcv); + g_warn_if_fail(synced_ok); + synced_ok = gst_element_sync_state_with_parent(mprtp_ply); + g_warn_if_fail(synced_ok); - rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); + // +// rtp_src_pad = gst_element_get_static_pad(dtls_srtp_bin, "rtp_src"); +// ghost_pad_and_add_to_bin(rtp_src_pad, receive_input_bin, "rtp_src"); +// gst_object_unref(rtp_src_pad); + gst_element_link_pads(dtls_srtp_bin, "rtp_src", mprtp_ply, "mprtp_sink"); + rtp_src_pad = gst_element_get_static_pad(mprtp_ply, "mprtp_src"); ghost_pad_and_add_to_bin(rtp_src_pad, receive_input_bin, "rtp_src"); gst_object_unref(rtp_src_pad); @@ -2011,7 +2380,10 @@ static void on_new_selected_pair(NiceAgent *nice_agent, GstPad *pad; gboolean sync_ok, link_ok; - link_ok = gst_element_link(pending_session_info->nice_src_rtp, pending_session_info->dtls_dec_rtp); +// link_ok = gst_element_link(pending_session_info->nice_src_rtp, pending_session_info->dtls_dec_rtp); + link_ok = gst_element_link_pads(pending_session_info->nice_src_rtp, "src", pending_session_info->mprtp_rcv, "sink_1"); + g_warn_if_fail(link_ok); + link_ok = gst_element_link_pads(pending_session_info->mprtp_rcv, "mprtp_src", pending_session_info->dtls_dec_rtp, "sink"); g_warn_if_fail(link_ok); gst_element_set_locked_state(pending_session_info->dtls_dec_rtp, FALSE); @@ -2089,7 +2461,7 @@ on_dtls_enc_key_set(GstElement *dtls_srtp_enc, AgentAndSessionIdPair *data) */ g_mutex_lock(&transport_agent->priv->sessions_lock); pending_session_info = g_hash_table_lookup(transport_agent->priv->pending_sessions, GUINT_TO_POINTER(stream_id)); - /* FIXME: What to do about RTCP? It's not guaranteed to ever be enabled if + /* _FIXME: What to do about RTCP? It's not guaranteed to ever be enabled if * RTCP muxing is used but the usage wasn't known beforehand */ if (pending_session_info && dtls_srtp_enc == pending_session_info->dtls_enc_rtp) { @@ -2829,7 +3201,7 @@ static GstElement * on_rtpbin_request_aux_receiver(G_GNUC_UNUSED GstElement *rtp g_object_set(rtxrecv, "payload-type-map", pt_map, NULL); gst_structure_free(pt_map); - /* FIXME: how do we get rtx-time? */ + /* _FIXME: how do we get rtx-time? */ return create_aux_bin("rtprtxrecv", rtxrecv, session_id); @@ -3488,7 +3860,7 @@ static GstFlowReturn new_data_callback(GstAppSink *appsink, OwrTransportAgent *t break; case OWR_DATA_CHANNEL_PPID_BINARY_PARTIAL: g_warning("PPID: DATA_CHANNEL_PPID_BINARY_PARTIAL - Deprecated - Not supported"); - /* TODO: Seems like chrome is using this.. maybe it should be supported to at least receive + /* _TODO: Seems like chrome is using this.. maybe it should be supported to at least receive * this kind of messages even if it is deprecated?. */ break; case OWR_DATA_CHANNEL_PPID_BINARY: @@ -3496,7 +3868,7 @@ static GstFlowReturn new_data_callback(GstAppSink *appsink, OwrTransportAgent *t break; case OWR_DATA_CHANNEL_PPID_STRING_PARTIAL: g_warning("PPID: DATA_CHANNEL_PPID_STRING_PARTIAL - Deprecated - Not supported"); - /* TODO: Seems like chrome is using this.. maybe it should be supported to at least receive + /* _TODO: Seems like chrome is using this.. maybe it should be supported to at least receive * this kind of messages even if it is deprecated? */ break; default: @@ -4199,7 +4571,7 @@ static void on_feedback_rtcp(GObject *session, guint type, guint fbtype, guint s n_loss = GST_READ_UINT8(fci_buf + 2); n_ecn = GST_READ_UINT8(fci_buf + 3); timestamp = GST_READ_UINT32_BE(fci_buf + 4); - /* TODO: Fix qbit */ + /* _TODO: Fix qbit */ gst_buffer_unmap(fci, &info); g_signal_emit_by_name(scream_queue, "incoming-feedback", media_ssrc, timestamp, highest_seq, n_loss, n_ecn, qbit); diff --git a/transport/owr_transport_agent.h b/transport/owr_transport_agent.h index 06b8e616..88fd4e0e 100644 --- a/transport/owr_transport_agent.h +++ b/transport/owr_transport_agent.h @@ -77,9 +77,15 @@ void owr_transport_agent_set_local_port_range(OwrTransportAgent *transport_agent void owr_transport_agent_add_session(OwrTransportAgent *agent, OwrSession *session); gchar * owr_transport_agent_get_dot_data(OwrTransportAgent *transport_agent); -//void owr_transport_join_subflow(OwrTransportAgent *transport_agent, guint subflow_id, const gchar *remote_address, guint port); -//void owr_transport_detach_subflow(OwrTransportAgent *transport_agent, guint subflow_id); - +guint8 owr_transport_agent_join_snd_subflow(OwrTransportAgent *transport_agent, + const gchar *remote_address, + guint port); +void owr_transport_agent_detach_snd_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id); +guint8 owr_transport_agent_join_rcv_subflow(OwrTransportAgent *transport_agent, + guint port); +void owr_transport_agent_detach_rcv_subflow(OwrTransportAgent *transport_agent, + guint8 subflow_id); G_END_DECLS #endif /* __OWR_TRANSPORT_AGENT_H__ */