Parameterize dcall
This commit is contained in:
parent
531d50a08b
commit
482e4e1f33
78
src/dcall.c
78
src/dcall.c
|
@ -11,7 +11,8 @@ struct dcall_elements {
|
||||||
GstElement *pipeline;
|
GstElement *pipeline;
|
||||||
GstElement *rx_tap, *rx_jitterbuffer, *rx_depay, *rx_opusdec, *rx_resample, *rx_echocancel, *rx_sink;
|
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;
|
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;
|
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_opusdec = gst_element_factory_make("opusdec", "rx-opusdec");
|
||||||
de->rx_resample = gst_element_factory_make("audioresample", "rx-audioresample");
|
de->rx_resample = gst_element_factory_make("audioresample", "rx-audioresample");
|
||||||
de->rx_echocancel = gst_element_factory_make("webrtcechoprobe", "rx-echocancel");
|
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) {
|
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");
|
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-lost", TRUE, NULL);
|
||||||
g_object_set(G_OBJECT (de->rx_jitterbuffer), "do-retransmission", FALSE, 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), "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_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), "plc", TRUE, NULL);
|
||||||
g_object_set(G_OBJECT (de->rx_opusdec), "use-inband-fec", FALSE, NULL);
|
g_object_set(G_OBJECT (de->rx_opusdec), "use-inband-fec", FALSE, NULL);
|
||||||
|
|
||||||
GstStructure *props;
|
if (strcmp(de->audio_sink, "pulsesrc") == 0) {
|
||||||
props = gst_structure_from_string ("props,media.role=phone", NULL);
|
GstStructure *props;
|
||||||
g_object_set (de->rx_sink, "stream-properties", props, NULL);
|
props = gst_structure_from_string ("props,media.role=phone", NULL);
|
||||||
gst_structure_free (props);
|
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_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);
|
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) {
|
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_resample = gst_element_factory_make("audioresample", "tx-resample");
|
||||||
de->tx_echocancel = gst_element_factory_make("webrtcdsp", "tx-echocancel");
|
de->tx_echocancel = gst_element_factory_make("webrtcdsp", "tx-echocancel");
|
||||||
de->tx_queue = gst_element_factory_make("queue", "tx-queue");
|
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_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), "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_sink), "async", FALSE, NULL);
|
||||||
|
|
||||||
g_object_set(G_OBJECT(de->tx_echocancel), "echo-cancel", TRUE, 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), "probe", "rx-echocancel", NULL);
|
||||||
g_object_set(G_OBJECT(de->tx_echocancel), "voice-detection", FALSE, NULL);
|
g_object_set(G_OBJECT(de->tx_echocancel), "voice-detection", FALSE, NULL);
|
||||||
|
|
||||||
GstStructure *props;
|
if (strcmp(de->audio_tap, "pulsesrc") == 0) {
|
||||||
props = gst_structure_from_string ("props,media.role=phone", NULL);
|
GstStructure *props;
|
||||||
g_object_set (de->tx_tap, "stream-properties", props, NULL);
|
props = gst_structure_from_string ("props,media.role=phone", NULL);
|
||||||
gst_structure_free (props);
|
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_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);
|
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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
setenv("GST_DEBUG_FILE", "dcall.log", 0);
|
|
||||||
setenv("GST_DEBUG", "3,opusdec:5", 0);
|
|
||||||
|
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
struct dcall_elements de = {
|
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
|
.grtppktlost = 0
|
||||||
};
|
};
|
||||||
|
int opt = 0;
|
||||||
|
|
||||||
/* Check input arguments */
|
while ((opt = getopt(argc, argv, "t:s:r:p:l:d:a:h")) != -1) {
|
||||||
if (argc != 2) {
|
switch(opt) {
|
||||||
g_printerr ("Usage: %s <Remote host>\n", argv[0]);
|
case 'a': //latency
|
||||||
return -1;
|
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 <audio file>] [-d <gstreamer debug file>] [-l <jitter buffer latency in ms>] [-r <remote host>] [-p <remote port>] [-t <audio tap>] [-s <audio sink>] [-h]\n", argv[0]);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
de.remote_host = argv[1];
|
setenv("GST_DEBUG_FILE", de.gstreamer_log_path, 0);
|
||||||
|
setenv("GST_DEBUG", "3,opusdec:5", 0);
|
||||||
|
|
||||||
gst_init (&argc, &argv);
|
gst_init (&argc, &argv);
|
||||||
loop = g_main_loop_new (NULL, FALSE);
|
loop = g_main_loop_new (NULL, FALSE);
|
||||||
|
|
Loading…
Reference in a new issue