From 62275e8fdbdd37116437f255fd26cae91d3a1c19 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Tue, 28 Jan 2020 08:35:01 +0100 Subject: [PATCH] Working sound in loopback --- src/dcall.c | 69 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/src/dcall.c b/src/dcall.c index 7055d79..065f4a7 100644 --- a/src/dcall.c +++ b/src/dcall.c @@ -1,14 +1,8 @@ #include -int main(int argc, char *argv[]) { - GMainLoop *loop; - GstElement *rx, *tx; +int create_rx_chain(GstElement *pipeline) { GstElement *rx_tap, *rx_jitterbuffer, *rx_depay, *rx_opusdec, *rx_resample, *rx_sink; - gst_init (&argc, &argv); - loop = g_main_loop_new (NULL, FALSE); - - rx = gst_pipeline_new ("rx"); rx_tap = gst_element_factory_make("udpsrc", "rx-tap"); rx_jitterbuffer = gst_element_factory_make("rtpjitterbuffer", "rx-jitterbuffer"); rx_depay = gst_element_factory_make("rtpopusdepay", "rx-depay"); @@ -16,8 +10,8 @@ int main(int argc, char *argv[]) { rx_resample = gst_element_factory_make("audioresample", "rx-audioresample"); rx_sink = gst_element_factory_make("autoaudiosink", "rx-sink"); - if (!rx || !rx_tap || !rx_jitterbuffer || !rx_depay || !rx_opusdec || !rx_resample || !rx_sink) { - g_printerr ("One element could not be created. Exiting.\n"); + if (!rx_tap || !rx_jitterbuffer || !rx_depay || !rx_opusdec || !rx_resample || !rx_sink) { + g_printerr ("One element of the rx chain could not be created. Exiting.\n"); return -1; } @@ -31,18 +25,67 @@ int main(int argc, char *argv[]) { g_object_set(G_OBJECT (rx_opusdec), "plc", TRUE, NULL); g_object_set(G_OBJECT (rx_opusdec), "use-inband-fec", FALSE, NULL); - gst_bin_add_many (GST_BIN (rx), rx_tap, rx_jitterbuffer, rx_depay, rx_opusdec, rx_resample, rx_sink, NULL); + gst_bin_add_many (GST_BIN (pipeline), rx_tap, rx_jitterbuffer, rx_depay, rx_opusdec, rx_resample, rx_sink, NULL); gst_element_link_many (rx_tap, rx_jitterbuffer, rx_depay, rx_opusdec, rx_resample, rx_sink, NULL); - gst_element_set_state (rx, GST_STATE_PLAYING); + return 0; +} + +int create_tx_chain(GstElement *pipeline) { + GstElement *tx_tap, *tx_resample, *tx_opusenc, *tx_pay, *tx_sink; + + tx_tap = gst_element_factory_make("autoaudiosrc", "tx-tap"); + tx_resample = gst_element_factory_make("audioresample", "tx-resample"); + tx_opusenc = gst_element_factory_make("opusenc", "tx-opusenc"); + tx_pay = gst_element_factory_make("rtpopuspay", "tx-rtpopuspay"); + tx_sink = gst_element_factory_make("udpsink", "tx-sink"); + + if (!tx_tap || !tx_resample || !tx_opusenc || !tx_pay || !tx_sink) { + g_printerr("One element of the tx chain could not be created. Exiting.\n"); + return -1; + } + + gst_util_set_object_arg(G_OBJECT(tx_opusenc), "audio-type", "voice"); + g_object_set(G_OBJECT(tx_opusenc), "inband-fec", FALSE, NULL); + g_object_set(G_OBJECT(tx_opusenc), "frame-size", 40, NULL); + g_object_set(G_OBJECT(tx_opusenc), "bitrate", 32000, NULL); + g_object_set(G_OBJECT(tx_opusenc), "dtx", FALSE, NULL); // gstreamer dtx opus implem. is broken + + g_object_set(G_OBJECT(tx_sink), "host", "127.0.0.1", NULL); + g_object_set(G_OBJECT(tx_sink), "port", 5000, NULL); + g_object_set(G_OBJECT(tx_sink), "async", FALSE, NULL); + + gst_bin_add_many(GST_BIN(pipeline), tx_tap, tx_resample, tx_opusenc, tx_pay, tx_sink, NULL); + gst_element_link_many(tx_tap, tx_resample, tx_opusenc, tx_pay, tx_sink, NULL); + + return 0; +} + +int main(int argc, char *argv[]) { + GMainLoop *loop; + GstElement *pipeline; + + gst_init (&argc, &argv); + loop = g_main_loop_new (NULL, FALSE); + + pipeline = gst_pipeline_new ("pipeline"); + if (!pipeline) { + g_printerr ("Pipeline could not be created. Exiting.\n"); + return -1; + } + + if (create_rx_chain (pipeline) != 0) return -1; + if (create_tx_chain (pipeline) != 0) return -1; + + gst_element_set_state (pipeline, GST_STATE_PLAYING); g_print ("Running...\n"); g_main_loop_run (loop); g_print ("Returned, stopping playback\n"); - gst_element_set_state (rx, GST_STATE_NULL); + gst_element_set_state (pipeline, GST_STATE_NULL); - gst_object_unref (GST_OBJECT (rx)); + gst_object_unref (GST_OBJECT (pipeline)); g_main_loop_unref (loop); return 0;