From 482e4e1f33a1860a8c93c0acb2566a8a1ed4d1e2 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Thu, 30 Jan 2020 17:07:51 +0100 Subject: [PATCH] Parameterize dcall --- src/dcall.c | 78 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/src/dcall.c b/src/dcall.c index 3233b36..8ac01bf 100644 --- a/src/dcall.c +++ b/src/dcall.c @@ -11,7 +11,8 @@ struct dcall_elements { GstElement *pipeline; GstElement *rx_tap, *rx_jitterbuffer, *rx_depay, *rx_opusdec, *rx_resample, *rx_echocancel, *rx_sink; GstElement *tx_tap, *tx_echocancel, *tx_queue, *tx_resample, *tx_opusenc, *tx_pay, *tx_sink; - char* remote_host; + char *remote_host, *audio_tap, *audio_sink, *audio_file, *gstreamer_log_path; + int remote_port, latency; guint64 grtppktlost; }; @@ -22,7 +23,7 @@ int create_rx_chain(struct dcall_elements* de) { de->rx_opusdec = gst_element_factory_make("opusdec", "rx-opusdec"); de->rx_resample = gst_element_factory_make("audioresample", "rx-audioresample"); de->rx_echocancel = gst_element_factory_make("webrtcechoprobe", "rx-echocancel"); - de->rx_sink = gst_element_factory_make("pulsesink", "rx-sink"); + de->rx_sink = gst_element_factory_make(de->audio_sink, "rx-sink"); if (!de->rx_tap || !de->rx_jitterbuffer || !de->rx_depay || !de->rx_opusdec || !de->rx_resample || !de->rx_echocancel || !de->rx_sink) { g_printerr ("One element of the rx chain could not be created. Exiting.\n"); @@ -35,17 +36,19 @@ int create_rx_chain(struct dcall_elements* de) { g_object_set(G_OBJECT (de->rx_jitterbuffer), "do-lost", TRUE, NULL); g_object_set(G_OBJECT (de->rx_jitterbuffer), "do-retransmission", FALSE, NULL); - g_object_set(G_OBJECT (de->rx_jitterbuffer), "latency", 150, NULL); + g_object_set(G_OBJECT (de->rx_jitterbuffer), "latency", de->latency, NULL); g_object_set(G_OBJECT (de->rx_jitterbuffer), "drop-on-latency", FALSE, NULL); //g_object_set(G_OBJECT (de->rx_jitterbuffer), "post-drop-messages", TRUE, NULL); g_object_set(G_OBJECT (de->rx_opusdec), "plc", TRUE, NULL); g_object_set(G_OBJECT (de->rx_opusdec), "use-inband-fec", FALSE, NULL); - GstStructure *props; - props = gst_structure_from_string ("props,media.role=phone", NULL); - g_object_set (de->rx_sink, "stream-properties", props, NULL); - gst_structure_free (props); + if (strcmp(de->audio_sink, "pulsesrc") == 0) { + GstStructure *props; + props = gst_structure_from_string ("props,media.role=phone", NULL); + g_object_set (de->rx_sink, "stream-properties", props, NULL); + gst_structure_free (props); + } gst_bin_add_many (GST_BIN (de->pipeline), de->rx_tap, de->rx_jitterbuffer, de->rx_depay, de->rx_opusdec, de->rx_resample, de->rx_echocancel, de->rx_sink, NULL); gst_element_link_many (de->rx_tap, de->rx_jitterbuffer, de->rx_depay, de->rx_opusdec, de->rx_resample, de->rx_echocancel, de->rx_sink, NULL); @@ -54,7 +57,7 @@ int create_rx_chain(struct dcall_elements* de) { } int create_tx_chain(struct dcall_elements* de) { - de->tx_tap = gst_element_factory_make("pulsesrc", "tx-tap"); + de->tx_tap = gst_element_factory_make(de->audio_tap, "tx-tap"); de->tx_resample = gst_element_factory_make("audioresample", "tx-resample"); de->tx_echocancel = gst_element_factory_make("webrtcdsp", "tx-echocancel"); de->tx_queue = gst_element_factory_make("queue", "tx-queue"); @@ -74,7 +77,7 @@ int create_tx_chain(struct dcall_elements* de) { g_object_set(G_OBJECT(de->tx_opusenc), "dtx", FALSE, NULL); // gstreamer dtx opus implem. is broken g_object_set(G_OBJECT(de->tx_sink), "host", de->remote_host, NULL); - g_object_set(G_OBJECT(de->tx_sink), "port", 5000, NULL); + g_object_set(G_OBJECT(de->tx_sink), "port", de->remote_port, NULL); g_object_set(G_OBJECT(de->tx_sink), "async", FALSE, NULL); g_object_set(G_OBJECT(de->tx_echocancel), "echo-cancel", TRUE, NULL); @@ -86,10 +89,12 @@ int create_tx_chain(struct dcall_elements* de) { g_object_set(G_OBJECT(de->tx_echocancel), "probe", "rx-echocancel", NULL); g_object_set(G_OBJECT(de->tx_echocancel), "voice-detection", FALSE, NULL); - GstStructure *props; - props = gst_structure_from_string ("props,media.role=phone", NULL); - g_object_set (de->tx_tap, "stream-properties", props, NULL); - gst_structure_free (props); + if (strcmp(de->audio_tap, "pulsesrc") == 0) { + GstStructure *props; + props = gst_structure_from_string ("props,media.role=phone", NULL); + g_object_set (de->tx_tap, "stream-properties", props, NULL); + gst_structure_free (props); + } gst_bin_add_many(GST_BIN(de->pipeline), de->tx_tap, de->tx_echocancel, de->tx_queue, de->tx_resample, de->tx_opusenc, de->tx_pay, de->tx_sink, NULL); gst_element_link_many( de->tx_tap, de->tx_resample, de->tx_echocancel, de->tx_queue, de->tx_opusenc, de->tx_pay, de->tx_sink, NULL); @@ -139,21 +144,52 @@ gboolean stop_handler(gpointer user_data) { } int main(int argc, char *argv[]) { - setenv("GST_DEBUG_FILE", "dcall.log", 0); - setenv("GST_DEBUG", "3,opusdec:5", 0); - GMainLoop *loop; struct dcall_elements de = { + .audio_file = "voice.mp3", + .gstreamer_log_path = "dcall.log", + .latency = 150, + .remote_port = 5000, + .remote_host = "127.13.3.7", + .audio_sink = "pulsesink", + .audio_tap = "pulsesrc", .grtppktlost = 0 }; + int opt = 0; - /* Check input arguments */ - if (argc != 2) { - g_printerr ("Usage: %s \n", argv[0]); - return -1; + while ((opt = getopt(argc, argv, "t:s:r:p:l:d:a:h")) != -1) { + switch(opt) { + case 'a': //latency + de.audio_file = optarg; + break; + case 'd': + de.gstreamer_log_path = optarg; + break; + case 'l': + de.latency = atoi(optarg); + break; + case 'p': + de.remote_port = atoi(optarg); + break; + case 'r': + de.remote_host = optarg; + break; + case 's': + de.audio_sink = optarg; + break; + case 't': + de.audio_tap = optarg; + break; + case 'h': + default: + g_print("Usage: %s [-a