messenger-gtk

Gtk+3 graphical user interfaces for GNUnet Messenger
Log | Files | Refs | Submodules | README | LICENSE

commit d8b35ac19fe6bfff949a915fd0603a5dd1a38dfd
parent d5d9c3378e1cd461249db071624869fc34cf9144
Author: Jacki <jacki@thejackimonster.de>
Date:   Thu, 20 Jun 2024 21:41:32 +0200

Get rtp streaming from audio input working

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Msrc/application.c | 2+-
Msrc/discourse.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/src/application.c b/src/application.c @@ -26,8 +26,8 @@ #include "request.h" #include "resources.h" -#include <gnunet/gnunet_chat_lib.h> #include <gnunet/gnunet_common.h> +#include <gnunet/gnunet_chat_lib.h> #include <gstreamer-1.0/gst/gst.h> #include <gtk-3.0/gtk/gtk.h> #include <libhandy-1/handy.h> diff --git a/src/discourse.c b/src/discourse.c @@ -26,6 +26,7 @@ #include <gnunet/gnunet_common.h> #include <gnunet/gnunet_chat_lib.h> +#include <gstreamer-1.0/gst/gst.h> static void _setup_gst_pipelines_of_subscription(MESSENGER_DiscourseSubscriptionInfo *info) @@ -47,6 +48,55 @@ _setup_gst_pipelines_of_subscription(MESSENGER_DiscourseSubscriptionInfo *info) // https://gstreamer.freedesktop.org/documentation/audiomixer/audiomixer.html?gi-language=c } +static GstFlowReturn +_new_audio_sample(GstElement *sink, gpointer data) +{ + g_assert((sink) && (data)); + + MESSENGER_DiscourseInfo *info = (MESSENGER_DiscourseInfo*) data; + + GstSample *sample; + g_signal_emit_by_name(sink, "pull-sample", &sample); + + if (!sample) + return GST_FLOW_ERROR; + + GstBuffer *buffer = gst_sample_get_buffer(sample); + + if (!buffer) + goto cleanup_sample; + + gsize size = gst_buffer_get_size(buffer); + if (!size) + goto cleanup_sample; + + GstMapInfo mapping; + if (gst_buffer_map(buffer, &mapping, GST_MAP_READ)) + { + GNUNET_CHAT_discourse_write(info->discourse, (const char*) mapping.data, mapping.size); + gst_buffer_unmap(buffer, &mapping); + } + +cleanup_sample: + gst_sample_unref(sample); + return GST_FLOW_OK; +} + +/* This function is called when an error message is posted on the bus */ +static void +error_cb(GstBus *bus, GstMessage *msg, gpointer data) +{ + GError *err; + gchar *debug_info; + + /* Print error details on the screen */ + gst_message_parse_error (msg, &err, &debug_info); + g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message); + g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none"); + g_clear_error (&err); + g_free (debug_info); +} + static void _setup_gst_pipelines(MESSENGER_DiscourseInfo *info) { @@ -65,6 +115,30 @@ _setup_gst_pipelines(MESSENGER_DiscourseInfo *info) GST_BIN(info->record_pipeline), "sink" ); + { + GstBus *bus = gst_element_get_bus(info->record_pipeline); + gst_bus_add_signal_watch(bus); + g_signal_connect(G_OBJECT(bus), "message::error", (GCallback)error_cb, info); + gst_object_unref(bus); + + GstCaps *caps = gst_caps_new_simple ( + "application/x-rtp", + "media", G_TYPE_STRING, "audio", + "payload", G_TYPE_INT, 96, + "clock-rate", G_TYPE_INT, 44100, + "encoding-name", G_TYPE_STRING, "L16", + "channels", G_TYPE_INT, 1, + NULL + ); + + g_object_set(info->record_sink, "emit-signals", TRUE, "caps", caps, NULL); + g_signal_connect(info->record_sink, "new-sample", G_CALLBACK(_new_audio_sample), info); + + gst_caps_unref(caps); + + gst_element_set_state(info->record_pipeline, GST_STATE_PLAYING); + } + // TODO: Have mix_pipeline in background while being subscribed to discourse! info->mix_pipeline = gst_parse_launch(