1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153 |
- /*
- This file is part of GNUnet.
- Copyright (C) 2016 GNUnet e.V.
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: AGPL3.0-or-later
- */
- /**
- * @file conversation/gnunet_gst.c
- * @brief FIXME
- * @author Hark
- */
- #include "gnunet_gst_def.h"
- /**
- * Our configuration.
- */
- static struct GNUNET_CONFIGURATION_Handle *cfg;
- void
- dump_buffer (unsigned n, const unsigned char*buf)
- {
- const unsigned char *p, *end;
- unsigned i, j;
- end = buf + n;
- for (i = 0;; i += 16)
- {
- p = buf + i;
- for (j = 0; j < 16; j++)
- {
- fprintf (stderr, "%02X ", p[j]);
- if (p + j >= end)
- goto BREAKOUT;
- }
- fprintf (stderr, " ");
- p = buf + i;
- for (j = 0; j < 16; j++)
- {
- fprintf (stderr, "%c", isprint (p[j]) ? p[j] :
- '.');
- if (p + j >= end)
- goto BREAKOUT;
- }
- fprintf (stderr, "\n");
- }
- BREAKOUT:
- return;
- }
- /***
- * load gnunet configuration
- */
- void
- gg_load_configuration (GNUNET_gstData *d)
- {
- char *audiobackend_string;
- cfg = GNUNET_CONFIGURATION_create ();
- GNUNET_CONFIGURATION_load (cfg, "mediahelper.conf");
- GNUNET_CONFIGURATION_get_value_string (cfg, "MEDIAHELPER", "JACK_PP_IN",
- &d->jack_pp_in);
- GNUNET_CONFIGURATION_get_value_string (cfg, "MEDIAHELPER", "JACK_PP_OUT",
- &d->jack_pp_out);
- GNUNET_CONFIGURATION_get_value_string (cfg, "MEDIAHELPER", "AUDIOBACKEND",
- &audiobackend_string);
- // printf("abstring: %s \n", audiobackend_string);
- if (0 == strcasecmp (audiobackend_string, "AUTO"))
- {
- d->audiobackend = AUTO;
- }
- else if (0 == strcasecmp (audiobackend_string, "JACK"))
- {
- d->audiobackend = JACK;
- }
- else if (0 == strcasecmp (audiobackend_string, "ALSA"))
- {
- d->audiobackend = ALSA;
- }
- else if (0 == strcasecmp (audiobackend_string, "FAKE"))
- {
- d->audiobackend = FAKE;
- }
- else if (0 == strcasecmp (audiobackend_string, "TEST"))
- {
- d->audiobackend = TEST;
- }
- else
- {
- d->audiobackend = AUTO;
- }
- if (GNUNET_CONFIGURATION_get_value_yesno (cfg, "MEDIAHELPER",
- "REMOVESILENCE") == GNUNET_YES)
- {
- d->dropsilence = TRUE;
- }
- else
- {
- d->dropsilence = FALSE;
- }
- if (GNUNET_CONFIGURATION_get_value_yesno (cfg, "MEDIAHELPER",
- "NO_GN_HEADERS") == GNUNET_YES)
- {
- d->pure_ogg = TRUE;
- }
- else
- {
- d->pure_ogg = FALSE;
- }
- if (GNUNET_CONFIGURATION_get_value_yesno (cfg, "MEDIAHELPER", "USERTP") ==
- GNUNET_YES)
- {
- d->usertp = TRUE;
- }
- else
- {
- d->usertp = FALSE;
- }
- // GNUNET_CONFIGURATION_write(cfg, "mediahelper.conf");
- }
- static void
- write_data (const char *ptr, size_t msg_size)
- {
- ssize_t ret;
- size_t off;
- off = 0;
- while (off < msg_size)
- {
- ret = write (1, &ptr[off], msg_size - off);
- if (0 >= ret)
- {
- if (-1 == ret)
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "write");
- // quit (2);
- }
- off += ret;
- }
- }
- extern GstFlowReturn
- on_appsink_new_sample (GstElement *element, GNUNET_gstData *d)
- {
- // size of message including gnunet header
- size_t msg_size;
- GstSample *s;
- GstBuffer *b;
- GstMapInfo map;
- /*
- const GstStructure *si;
- char *si_str;
- GstCaps *s_caps;
- char *caps_str;
- */if (gst_app_sink_is_eos (GST_APP_SINK (element)))
- return GST_FLOW_OK;
- // pull sample from appsink
- s = gst_app_sink_pull_sample (GST_APP_SINK (element));
- if (s == NULL)
- return GST_FLOW_OK;
- if (! GST_IS_SAMPLE (s))
- return GST_FLOW_OK;
- b = gst_sample_get_buffer (s);
- GST_WARNING ("caps are %" GST_PTR_FORMAT, gst_sample_get_caps (s));
- gst_buffer_map (b, &map, GST_MAP_READ);
- size_t len;
- len = map.size;
- if (len > UINT16_MAX - sizeof(struct AudioMessage))
- {
- // this should never happen?
- printf ("GSTREAMER sample too big! \n");
- exit (20);
- len = UINT16_MAX - sizeof(struct AudioMessage);
- }
- msg_size = sizeof(struct AudioMessage) + len;
- // copy the data into audio_message
- GNUNET_memcpy (((char *) &(d->audio_message)[1]), map.data, len);
- (d->audio_message)->header.size = htons ((uint16_t) msg_size);
- if (d->pure_ogg)
- // write the audio_message without the gnunet headers
- write_data ((const char *) &(d->audio_message)[1], len);
- else
- write_data ((const char *) d->audio_message, msg_size);
- gst_sample_unref (s);
- return GST_FLOW_OK;
- }
- /***
- * Dump a pipeline graph
- */
- extern void
- pl_graph (GstElement *pipeline)
- {
- #ifdef IS_SPEAKER
- gst_debug_bin_to_dot_file_with_ts (GST_BIN (pipeline),
- GST_DEBUG_GRAPH_SHOW_ALL,
- "playback_helper.dot");
- #endif
- #ifdef IS_MIC
- gst_debug_bin_to_dot_file_with_ts (GST_BIN (pipeline),
- GST_DEBUG_GRAPH_SHOW_ALL,
- "record_helper.dot");
- #endif
- // load_configuration();
- }
- extern gboolean
- gnunet_gst_bus_call (GstBus *bus, GstMessage *msg, gpointer data)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Bus message\n");
- switch (GST_MESSAGE_TYPE (msg))
- {
- case GST_MESSAGE_EOS:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "End of stream\n");
- exit (10);
- break;
- case GST_MESSAGE_ERROR:
- {
- gchar *debug;
- GError *error;
- gst_message_parse_error (msg, &error, &debug);
- g_free (debug);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error: %s\n",
- error->message);
- g_error_free (error);
- exit (10);
- break;
- }
- default:
- break;
- }
- return TRUE;
- }
- /* called when pipeline changes state */
- extern void
- state_changed_cb (GstBus *bus, GstMessage *msg, GNUNET_gstData *d)
- {
- GstState old_state, new_state, pending_state;
- gst_message_parse_state_changed (msg, &old_state, &new_state,
- &pending_state);
- switch (new_state)
- {
- case GST_STATE_READY:
- // printf("ready.... \n");
- // pl_graph(GST_ELEMENT(d->pipeline));
- break;
- case GST_STATE_PLAYING:
- // GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
- // printf("Playing.... \n");
- pl_graph (GST_ELEMENT (d->pipeline));
- break;
- case GST_STATE_VOID_PENDING:
- // printf("void_pending.... \n");
- // pl_graph(GST_ELEMENT(d->pipeline));
- break;
- case GST_STATE_NULL:
- // printf("null.... \n");
- // pl_graph(GST_ELEMENT(d->pipeline));
- break;
- case GST_STATE_PAUSED:
- // printf("paused.... \n");
- // pl_graph(GST_ELEMENT(d->pipeline));
- break;
- }
- }
- static void
- application_cb (GstBus *bus, GstMessage *msg, GNUNET_gstData *data)
- {
- // printf("application cb");
- return;
- }
- static void
- error_cb (GstBus *bus, GstMessage *msg, GNUNET_gstData *data)
- {
- // printf("error cb");
- return;
- }
- static void
- eos_cb (GstBus *bus, GstMessage *msg, GNUNET_gstData *data)
- {
- // printf("eos cb");
- return;
- }
- extern void
- gg_setup_gst_bus (GNUNET_gstData *d)
- {
- GstBus *bus;
- bus = gst_element_get_bus (GST_ELEMENT (d->pipeline));
- gst_bus_add_signal_watch (bus);
- g_signal_connect (G_OBJECT (bus), "message::error", (GCallback) error_cb,
- d);
- g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback) eos_cb,
- d);
- g_signal_connect (G_OBJECT (bus), "message::state-changed",
- (GCallback) state_changed_cb, d);
- g_signal_connect (G_OBJECT (bus), "message::application",
- (GCallback) application_cb, d);
- g_signal_connect (G_OBJECT (bus), "message::about-to-finish",
- (GCallback) application_cb, d);
- gst_object_unref (bus);
- }
- /*
- * take buffer from gstreamer and feed it to gnunet
- */
- /*
- extern int
- feed_buffer_to_gnunet (GNUNET_gstData * d)
- {
- GstSample *s;
- GstBuffer *b;
- GstMapInfo m;
- size_t len, msg_size;
- const char *ptr;
- int phase;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pulling...\n");
- s = gst_app_sink_pull_sample (GST_APP_SINK(d->appsink));
- if (NULL == s)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "pulled NULL\n");
- return OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "...pulled!\n");
- const GstStructure *si;
- char *si_str;
- GstCaps *s_caps;
- char *caps_str;
- si = gst_sample_get_info (s);
- if (si)
- {
- si_str = gst_structure_to_string (si);
- if (si_str)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample %s\n", si_str);
- g_free (si_str);
- }
- }
- else
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with no info\n");
- s_caps = gst_sample_get_caps (s);
- if (s_caps)
- {
- caps_str = gst_caps_to_string (s_caps);
- if (caps_str)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with caps %s\n", caps_str);
- g_free (caps_str);
- }
- }
- else
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got sample with no caps\n");
- b = gst_sample_get_buffer (s);
- if (NULL == b || !gst_buffer_map (b, &m, GST_MAP_READ))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got NULL buffer %p or failed to map the buffer\n", b);
- gst_sample_unref (s);
- return FAIL;
- }
- len = m.size;
- if (len > UINT16_MAX - sizeof (struct AudioMessage))
- {
- GNUNET_break (0);
- len = UINT16_MAX - sizeof (struct AudioMessage);
- }
- msg_size = sizeof (struct AudioMessage) + len;
- audio_message.header.size = htons ((uint16_t) msg_size);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending %u bytes of audio data\n", (unsigned int) msg_size);
- for (phase = 0; phase < 2; phase++)
- {
- size_t offset;
- size_t to_send;
- ssize_t ret;
- if (0 == phase && !d->pure_ogg)
- {
- //#ifdef DEBUG_RECORD_PURE_OGG
- // if (d->pure_ogg)
- // break;
- //#endif
- ptr = (const char *) &audio_message;
- to_send = sizeof (audio_message);
- }
- else
- {
- ptr = (const char *) m.data;
- to_send = len;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending %u bytes on phase %d\n", (unsigned int) to_send, phase);
- for (offset = 0; offset < to_send; offset += ret)
- {
- ret = write (1, &ptr[offset], to_send - offset);
- if (0 >= ret)
- {
- if (-1 == ret)
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Failed to write %u bytes at offset %u (total %u) in phase %d: %s\n",
- (unsigned int) to_send - offset, (unsigned int) offset,
- (unsigned int) (to_send + offset), phase, strerror (errno));
- // abort_send = 1;
- return FAIL;
- }
- }
- // if (abort_send)
- // break;
- }
- gst_buffer_unmap (b, &m);
- gst_sample_unref (s);
- }
- */
- extern int
- feed_buffer_to_gst (const char *audio, size_t b_len, GNUNET_gstData *d)
- {
- GstBuffer *b;
- gchar *bufspace;
- GstFlowReturn flow;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Feeding %u bytes to GStreamer\n",
- (unsigned int) b_len);
- bufspace = g_memdup (audio, b_len);
- b = gst_buffer_new_wrapped (bufspace, b_len);
- if (NULL == b)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Failed to wrap a buffer\n");
- g_free (bufspace);
- return GNUNET_SYSERR;
- }
- if (GST_APP_SRC (d->appsrc) == NULL)
- exit (10);
- flow = gst_app_src_push_buffer (GST_APP_SRC (d->appsrc), b);
- /* They all return GNUNET_OK, because currently player stops when
- * data stops coming. This might need to be changed for the player
- * to also stop when pipeline breaks.
- */
- switch (flow)
- {
- case GST_FLOW_OK:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Fed %u bytes to the pipeline\n",
- (unsigned int) b_len);
- break;
- case GST_FLOW_FLUSHING:
- /* buffer was dropped, because pipeline state is not PAUSED or PLAYING */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Dropped a buffer\n");
- break;
- case GST_FLOW_EOS:
- /* end of stream */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "EOS\n");
- break;
- default:
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Unexpected push result\n");
- break;
- }
- return GNUNET_OK;
- }
- /**
- * debug making elements
- */
- extern GstElement *
- gst_element_factory_make_debug (gchar *factoryname, gchar *name)
- {
- GstElement *element;
- element = gst_element_factory_make (factoryname, name);
- if (element == NULL)
- {
- printf ("\n Failed to create element - type: %s name: %s \n", factoryname,
- name);
- exit (10);
- return element;
- }
- else
- {
- return element;
- }
- }
- /*
- static gboolean
- gst_element_link_many_debug(...)
- {
- va_list arguments;
- gst_element_link_many(argptr);
- }
- #define gst_element_link_many(...) \
- gst_element_link_many_debug(__VA_ARGS__)
- */
- extern void
- lf (char *msg)
- {
- printf ("linking elements failed: %s", msg);
- exit (10);
- }
- /***
- * used to set properties on autoaudiosink's chosen sink
- */
- static void
- autoaudiosink_child_added (GstChildProxy *child_proxy,
- GObject *object,
- gchar *name,
- gpointer user_data)
- {
- if (GST_IS_AUDIO_BASE_SRC (object))
- g_object_set (object,
- "buffer-time", (gint64) BUFFER_TIME,
- "latency-time", (gint64) LATENCY_TIME,
- NULL);
- }
- /***
- * used to set properties on autoaudiosource's chosen sink
- */
- static void
- autoaudiosource_child_added (GstChildProxy *child_proxy, GObject *object,
- gchar *name, gpointer user_data)
- {
- if (GST_IS_AUDIO_BASE_SRC (object))
- g_object_set (object, "buffer-time", (gint64) BUFFER_TIME, "latency-time",
- (gint64) LATENCY_TIME, NULL);
- }
- GstElement *
- get_pipeline (GstElement *element)
- {
- GstPipeline *p;
- p = GST_PIPELINE (gst_object_get_parent (GST_OBJECT (element)));
- return GST_ELEMENT (p);
- }
- static void
- decoder_ogg_pad_added (GstElement *element,
- GstPad *pad,
- gpointer data)
- {
- GstPad *sinkpad;
- GstElement *decoder = (GstElement *) data;
- printf ("==== ogg pad added callback \n");
- /* We can now link this pad with the opus-decoder sink pad */
- // pl_graph(get_pipeline(element));
- sinkpad = gst_element_get_static_pad (decoder, "sink");
- gst_pad_link (pad, sinkpad);
- gst_element_link_many (element, decoder, NULL);
- gst_object_unref (sinkpad);
- }
- int
- gnunet_read (GNUNET_gstData *d)
- {
- char readbuf[MAXLINE];
- int ret;
- printf ("read \n");
- ret = read (0, readbuf, sizeof(readbuf));
- if (0 > ret)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _ ("Read error from STDIN: %d %s\n"),
- ret, strerror (errno));
- return FAIL;
- }
- // toff += ret;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received %d bytes of audio data\n",
- (int) ret);
- if (0 == ret)
- return FAIL;
- // #ifdef DEBUG_READ_PURE_OGG
- if (d->pure_ogg)
- {
- feed_buffer_to_gst (readbuf, ret, d);
- }
- else
- {
- // #endif
- GNUNET_MST_from_buffer (d->stdin_mst,
- readbuf,
- ret,
- GNUNET_NO,
- GNUNET_NO);
- }
- return 0;
- }
- /**
- * Message callback
- *
- * @param msg message we received.
- * @return #GNUNET_OK on success,
- * #GNUNET_NO to stop further processing due to disconnect (no error)
- * #GNUNET_SYSERR to stop further processing due to error
- */
- static int
- stdin_receiver (void *cls,
- const struct GNUNET_MessageHeader *msg)
- {
- struct AudioMessage *audio;
- size_t b_len;
- printf ("stdin receiver \n ");
- dump_buffer (sizeof(msg),
- (const unsigned char *) msg);
- switch (ntohs (msg->type))
- {
- case GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO:
- audio = (struct AudioMessage *) msg;
- b_len = ntohs (audio->header.size) - sizeof(struct AudioMessage);
- printf ("feeding buffer to gst \n ");
- feed_buffer_to_gst ((const char *) &audio[1], b_len, cls);
- break;
- default:
- printf ("No audio message: %u \n ", ntohs (msg->type));
- break;
- }
- return GNUNET_OK;
- }
- GstBin *
- get_app (GNUNET_gstData *d, int type)
- {
- GstBin *bin;
- GstPad *pad, *ghostpad;
- if (type == SOURCE)
- {
- bin = GST_BIN (gst_bin_new ("Gnunet appsrc"));
- GNUNET_assert (GNUNET_OK ==
- GNUNET_log_setup ("gnunet-helper-audio-playback",
- "WARNING",
- NULL));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Audio playback starts\n");
- printf (" creating appsrc \n ");
- // d->audio_message.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
- // d->audio_message = GNUNET_malloc (UINT16_MAX);
- // d->audio_message = (AudioMessage*)malloc(sizeof(struct AudioMessage));
- // d->audio_message = GNUNET_malloc(sizeof(struct AudioMessage));
- // d->audio_message.header.type = htons (GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
- d->stdin_mst = GNUNET_MST_create (&stdin_receiver, d);
- if (d->stdin_mst == NULL)
- printf ("stdin_mst = NULL");
- d->appsrc = gst_element_factory_make ("appsrc", "appsrc");
- gst_bin_add_many (bin, d->appsrc, NULL);
- // gst_element_link_many ( encoder, muxer, NULL);
- pad = gst_element_get_static_pad (d->appsrc, "src");
- ghostpad = gst_ghost_pad_new ("src", pad);
- }
- if (type == SINK)
- {
- bin = GST_BIN (gst_bin_new ("Gnunet appsink"));
- GNUNET_assert (GNUNET_OK ==
- GNUNET_log_setup ("gnunet-helper-audio-record",
- "WARNING",
- NULL));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Audio source starts\n");
- d->appsink = gst_element_factory_make ("appsink", "appsink");
- // Move this out of here!
- d->audio_message = GNUNET_malloc (UINT16_MAX);
- (d->audio_message)->header.type = htons (
- GNUNET_MESSAGE_TYPE_CONVERSATION_AUDIO);
- g_object_set (G_OBJECT (d->appsink), "emit-signals", TRUE, "sync", TRUE,
- NULL);
- g_signal_connect (d->appsink, "new-sample",
- G_CALLBACK (on_appsink_new_sample), &d);
- gst_bin_add_many (bin, d->appsink, NULL);
- // gst_element_link_many ( encoder, muxer, NULL);
- pad = gst_element_get_static_pad (d->appsink, "sink");
- ghostpad = gst_ghost_pad_new ("sink", pad);
- }
- /* set the bin pads */
- gst_pad_set_active (ghostpad, TRUE);
- gst_element_add_pad (GST_ELEMENT (bin), ghostpad);
- gst_object_unref (pad);
- return bin;
- }
- extern GstBin *
- get_coder (GNUNET_gstData *d, int type)
- {
- GstBin *bin;
- GstPad *srcpad, *sinkpad, *srcghostpad, *sinkghostpad;
- GstCaps *rtpcaps;
- GstElement *encoder, *muxer, *decoder, *demuxer, *jitterbuffer,
- *rtpcapsfilter;
- if (d->usertp == TRUE)
- {
- /*
- * application/x-rtp, media=(string)audio, clock-rate=(int)48000, encoding-name=(string)OPUS, sprop-maxcapturerate=(string)48000, sprop-stereo=(string)0, payload=(int)96, encoding-params=(string)2, ssrc=(uint)630297634, timestamp-offset=(uint)678334141, seqnum-offset=(uint)16938 */
- /*
- rtpcaps = gst_caps_new_simple ("application/x-rtp",
- "media", G_TYPE_STRING, "audio",
- "clock-rate", G_TYPE_INT, SAMPLING_RATE,
- "encoding-name", G_TYPE_STRING, "OPUS",
- "payload", G_TYPE_INT, 96,
- "sprop-stereo", G_TYPE_STRING, "0",
- "encoding-params", G_TYPE_STRING, "2",
- NULL);
- */ rtpcaps = gst_caps_new_simple ("application/x-rtp",
- "media", G_TYPE_STRING, "audio",
- "clock-rate", G_TYPE_INT, SAMPLING_RATE,
- "encoding-name", G_TYPE_STRING, "OPUS",
- "payload", G_TYPE_INT, 96,
- "sprop-stereo", G_TYPE_STRING, "0",
- "encoding-params", G_TYPE_STRING, "2",
- NULL);
- rtpcapsfilter = gst_element_factory_make ("capsfilter", "rtpcapsfilter");
- g_object_set (G_OBJECT (rtpcapsfilter),
- "caps", rtpcaps,
- NULL);
- gst_caps_unref (rtpcaps);
- }
- if (type == ENCODER)
- {
- bin = GST_BIN (gst_bin_new ("Gnunet audioencoder"));
- encoder = gst_element_factory_make ("opusenc", "opus-encoder");
- if (d->usertp == TRUE)
- {
- muxer = gst_element_factory_make ("rtpopuspay", "rtp-payloader");
- }
- else
- {
- muxer = gst_element_factory_make ("oggmux", "ogg-muxer");
- }
- g_object_set (G_OBJECT (encoder),
- /* "bitrate", 64000, */
- /* "bandwidth", OPUS_BANDWIDTH_FULLBAND, */
- "inband-fec", INBAND_FEC_MODE,
- "packet-loss-percentage", PACKET_LOSS_PERCENTAGE,
- "max-payload-size", MAX_PAYLOAD_SIZE,
- "audio", TRUE, /* VoIP, not audio */
- "frame-size", OPUS_FRAME_SIZE,
- NULL);
- if (d->usertp != TRUE)
- {
- g_object_set (G_OBJECT (muxer),
- "max-delay", OGG_MAX_DELAY,
- "max-page-delay", OGG_MAX_PAGE_DELAY,
- NULL);
- }
- gst_bin_add_many (bin, encoder, muxer, NULL);
- gst_element_link_many (encoder, muxer, NULL);
- sinkpad = gst_element_get_static_pad (encoder, "sink");
- sinkghostpad = gst_ghost_pad_new ("sink", sinkpad);
- srcpad = gst_element_get_static_pad (muxer, "src");
- srcghostpad = gst_ghost_pad_new ("src", srcpad);
- }
- if (type == DECODER)
- {
- bin = GST_BIN (gst_bin_new ("Gnunet audiodecoder"));
- // decoder
- if (d->usertp == TRUE)
- {
- demuxer = gst_element_factory_make ("rtpopusdepay", "ogg-demuxer");
- jitterbuffer = gst_element_factory_make ("rtpjitterbuffer",
- "rtpjitterbuffer");
- }
- else
- {
- demuxer = gst_element_factory_make ("oggdemux", "ogg-demuxer");
- }
- decoder = gst_element_factory_make ("opusdec", "opus-decoder");
- if (d->usertp == TRUE)
- {
- gst_bin_add_many (bin, rtpcapsfilter, jitterbuffer, demuxer, decoder,
- NULL);
- gst_element_link_many (rtpcapsfilter, jitterbuffer, demuxer, decoder,
- NULL);
- sinkpad = gst_element_get_static_pad (rtpcapsfilter, "sink");
- }
- else
- {
- gst_bin_add_many (bin, demuxer, decoder, NULL);
- g_signal_connect (demuxer,
- "pad-added",
- G_CALLBACK (decoder_ogg_pad_added),
- decoder);
- sinkpad = gst_element_get_static_pad (demuxer, "sink");
- }
- sinkghostpad = gst_ghost_pad_new ("sink", sinkpad);
- srcpad = gst_element_get_static_pad (decoder, "src");
- srcghostpad = gst_ghost_pad_new ("src", srcpad);
- }
- // add pads to the bin
- gst_pad_set_active (sinkghostpad, TRUE);
- gst_element_add_pad (GST_ELEMENT (bin), sinkghostpad);
- gst_pad_set_active (srcghostpad, TRUE);
- gst_element_add_pad (GST_ELEMENT (bin), srcghostpad);
- return bin;
- }
- extern GstBin *
- get_audiobin (GNUNET_gstData *d, int type)
- {
- GstBin *bin;
- GstElement *sink, *source, *queue, *conv, *resampler, *removesilence, *filter;
- GstPad *pad, *ghostpad;
- GstCaps *caps;
- if (type == SINK)
- {
- bin = GST_BIN (gst_bin_new ("Gnunet audiosink"));
- /* Create all the elements */
- if (d->dropsilence == TRUE)
- {
- queue = gst_element_factory_make ("queue", "queue");
- removesilence = gst_element_factory_make ("removesilence",
- "removesilence");
- }
- conv = gst_element_factory_make ("audioconvert", "converter");
- resampler = gst_element_factory_make ("audioresample", "resampler");
- if (d->audiobackend == AUTO)
- {
- sink = gst_element_factory_make ("autoaudiosink", "audiosink");
- g_signal_connect (sink, "child-added", G_CALLBACK (
- autoaudiosink_child_added), NULL);
- }
- if (d->audiobackend == ALSA)
- {
- sink = gst_element_factory_make ("alsaaudiosink", "audiosink");
- }
- if (d->audiobackend == JACK)
- {
- sink = gst_element_factory_make ("jackaudiosink", "audiosink");
- g_object_set (G_OBJECT (sink), "client-name", "gnunet", NULL);
- if (g_object_class_find_property
- (G_OBJECT_GET_CLASS (sink), "port-pattern"))
- {
- // char *portpattern = "system";
- g_object_set (G_OBJECT (sink), "port-pattern", d->jack_pp_out,
- NULL);
- }
- }
- if (d->audiobackend == FAKE)
- {
- sink = gst_element_factory_make ("fakesink", "audiosink");
- }
- g_object_set (sink,
- "buffer-time", (gint64) BUFFER_TIME,
- "latency-time", (gint64) LATENCY_TIME,
- NULL);
- if (d->dropsilence == TRUE)
- {
- // Do not remove silence by default
- g_object_set (removesilence, "remove", FALSE, NULL);
- g_object_set (queue, "max-size-buffers", 12, NULL);
- /*
- g_signal_connect (source,
- "need-data",
- G_CALLBACK(appsrc_need_data),
- NULL);
- g_signal_connect (source,
- "enough-data",
- G_CALLBACK(appsrc_enough_data),
- NULL);
- *//*
- g_signal_connect (queue,
- "notify::current-level-bytes",
- G_CALLBACK(queue_current_level),
- NULL);
- g_signal_connect (queue,
- "underrun",
- G_CALLBACK(queue_underrun),
- NULL);
- g_signal_connect (queue,
- "running",
- G_CALLBACK(queue_running),
- NULL);
- g_signal_connect (queue,
- "overrun",
- G_CALLBACK(queue_overrun),
- NULL);
- g_signal_connect (queue,
- "pushing",
- G_CALLBACK(queue_pushing),
- NULL);
- */ }
- gst_bin_add_many (bin, conv, resampler, sink, NULL);
- gst_element_link_many (conv, resampler, sink, NULL);
- if (d->dropsilence == TRUE)
- {
- gst_bin_add_many (bin, queue, removesilence, NULL);
- if (! gst_element_link_many (queue, removesilence, conv, NULL))
- lf ("queue, removesilence, conv ");
- pad = gst_element_get_static_pad (queue, "sink");
- }
- else
- {
- pad = gst_element_get_static_pad (conv, "sink");
- }
- ghostpad = gst_ghost_pad_new ("sink", pad);
- }
- else
- {
- // SOURCE
- bin = GST_BIN (gst_bin_new ("Gnunet audiosource"));
- // source = gst_element_factory_make("audiotestsrc", "audiotestsrcbla");
- if (d->audiobackend == AUTO)
- {
- source = gst_element_factory_make ("autoaudiosrc", "audiosource");
- }
- if (d->audiobackend == ALSA)
- {
- source = gst_element_factory_make ("alsasrc", "audiosource");
- }
- if (d->audiobackend == JACK)
- {
- source = gst_element_factory_make ("jackaudiosrc", "audiosource");
- }
- if (d->audiobackend == TEST)
- {
- source = gst_element_factory_make ("audiotestsrc", "audiosource");
- }
- filter = gst_element_factory_make ("capsfilter", "filter");
- conv = gst_element_factory_make ("audioconvert", "converter");
- resampler = gst_element_factory_make ("audioresample", "resampler");
- if (d->audiobackend == AUTO)
- {
- g_signal_connect (source, "child-added", G_CALLBACK (
- autoaudiosource_child_added), NULL);
- }
- else
- {
- if (GST_IS_AUDIO_BASE_SRC (source))
- g_object_set (source, "buffer-time", (gint64) BUFFER_TIME,
- "latency-time", (gint64) LATENCY_TIME, NULL);
- if (d->audiobackend == JACK)
- {
- g_object_set (G_OBJECT (source), "client-name", "gnunet", NULL);
- if (g_object_class_find_property
- (G_OBJECT_GET_CLASS (source), "port-pattern"))
- {
- char *portpattern = "moc";
- g_object_set (G_OBJECT (source), "port-pattern", portpattern,
- NULL);
- }
- }
- }
- caps = gst_caps_new_simple ("audio/x-raw",
- /* "format", G_TYPE_STRING, "S16LE", */
- /* "rate", G_TYPE_INT, SAMPLING_RATE,*/
- "channels", G_TYPE_INT, OPUS_CHANNELS,
- /* "layout", G_TYPE_STRING, "interleaved",*/
- NULL);
- g_object_set (G_OBJECT (filter),
- "caps", caps,
- NULL);
- gst_caps_unref (caps);
- gst_bin_add_many (bin, source, filter, conv, resampler, NULL);
- gst_element_link_many (source, filter, conv, resampler, NULL);
- pad = gst_element_get_static_pad (resampler, "src");
- /* pads */
- ghostpad = gst_ghost_pad_new ("src", pad);
- }
- /* set the bin pads */
- gst_pad_set_active (ghostpad, TRUE);
- gst_element_add_pad (GST_ELEMENT (bin), ghostpad);
- gst_object_unref (pad);
- return bin;
- }
|