]> www.infradead.org Git - pidgin-chime.git/commitdiff
Move audio hacks out to chat.c and leave the Chime parts relatively sane
authorDavid Woodhouse <dwmw@amazon.co.uk>
Mon, 11 Dec 2017 22:35:29 +0000 (22:35 +0000)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 31 Jan 2018 20:18:05 +0000 (20:18 +0000)
One step closer to doing things "properly"...

chat.c
chime-call-audio.c
chime-call-audio.h
chime-call-transport.c
chime-call.c
chime-call.h

diff --git a/chat.c b/chat.c
index c619279668b4ab8fa789b345ff7842904a01080f..e7430dd38085f2fd6fe08ecce45bb6d7c510cfc2 100644 (file)
--- a/chat.c
+++ b/chat.c
 
 #include <libsoup/soup.h>
 
+#include <gst/gstelement.h>
+#include <gst/gstpipeline.h>
+#include <gst/gstutils.h>
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+
 struct chime_chat {
        /* msgs first as it's a "subclass". Really ought to do proper GTypes here... */
        struct chime_msgs m;
@@ -43,6 +49,9 @@ struct chime_chat {
        ChimeCallAudio *audio;
        void *participants_ui;
        PurpleMedia *media;
+
+       GstElement *audio_inpipeline;
+       GstElement *audio_outpipeline;
 };
 
 /*
@@ -225,9 +234,61 @@ static void participants_closed_cb(gpointer _chat)
        g_signal_handlers_disconnect_matched(chat->call, G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA,
                                             0, 0, NULL, G_CALLBACK(on_call_participants), chat);
 }
-static void on_audio_state(ChimeCall *call, int audio_state, struct chime_chat *chat)
+static void on_audio_state(ChimeCall *call, ChimeAudioState audio_state, struct chime_chat *chat)
 {
        purple_debug(PURPLE_DEBUG_INFO, "chime", "Audio state %d\n", audio_state);
+
+       if (audio_state == CHIME_AUDIO_STATE_AUDIO_MUTED && chat->audio_outpipeline) {
+               gst_element_set_state(chat->audio_outpipeline, GST_STATE_PAUSED);
+       } else if (audio_state == CHIME_AUDIO_STATE_AUDIO && chat->audio_outpipeline) {
+               gst_element_set_state(chat->audio_outpipeline, GST_STATE_PLAYING);
+       } else if (audio_state == CHIME_AUDIO_STATE_AUDIO && !chat->audio_inpipeline) {
+               // GStreamer - server-to-speakers
+               chat->audio_inpipeline = gst_pipeline_new("dirt-pipeline");
+
+               GstAppSrc *src = GST_APP_SRC(gst_element_factory_make("appsrc", "appsrc"));
+               GstCaps *audio_caps;
+               audio_caps = gst_caps_from_string("audio/x-opus,channel-mapping-family=0");
+               g_object_set (src, "caps", audio_caps, "format", GST_FORMAT_TIME, NULL);
+               gst_app_src_set_size(src, -1);
+               gst_app_src_set_max_bytes(src, 100);
+               gst_base_src_set_live(GST_BASE_SRC(src), TRUE);
+               gst_app_src_set_stream_type(src, GST_APP_STREAM_TYPE_STREAM);
+
+               GstElement *opusdec = gst_element_factory_make("opusdec", "opusdec");
+               GstElement *convert = gst_element_factory_make("audioconvert", "audioconvert");
+               GstElement *resample = gst_element_factory_make("audioresample", "audioresample");
+               GstElement *sink = gst_element_factory_make("autoaudiosink", "autoaudiosink");
+               gst_bin_add_many(GST_BIN(chat->audio_inpipeline), GST_ELEMENT(src), opusdec, convert, resample, sink, NULL);
+               if(!gst_element_link_many(GST_ELEMENT(src), opusdec, convert, resample, sink, NULL)) {
+                       printf("Failed to link incoming pipeline\n");
+               }
+
+               // GStreamer - mic-to-server
+               chat->audio_outpipeline = gst_pipeline_new("upstream-audio");
+               GstElement *mic = gst_element_factory_make("autoaudiosrc", "autoaudiosrc");
+               convert = gst_element_factory_make("audioconvert", "audioconvert");
+               g_object_set(convert, "caps", gst_caps_from_string("audio/x-raw,format=S16,channels=1"), NULL);
+               resample = gst_element_factory_make("audioresample", "audioresample");
+               g_object_set(resample, "caps", gst_caps_from_string("audio/x-raw"), NULL);
+               GstElement *opusenc = gst_element_factory_make("opusenc", "opusenc");
+               g_object_set(opusenc, "caps", gst_caps_from_string("audio/x-raw,format=S16,channels=1"), NULL);
+               g_object_set(opusenc,
+                            "bitrate", 16000,
+                            "bitrate-type", "vbr",
+                            NULL);
+               GstElement *appsink = gst_element_factory_make("appsink", "appsink");
+               g_object_set(appsink, "caps", gst_caps_from_string("audio/x-opus,channels=1,channel-mapping-family=0"), NULL);
+               gst_bin_add_many(GST_BIN(chat->audio_outpipeline), mic, convert, resample, opusenc, appsink, NULL);
+               if(!gst_element_link_many(mic, convert, resample, opusenc, appsink, NULL)) {
+                       printf("Failed to link upstream pipeline\n");
+               }
+
+               chime_call_install_gst_app_callbacks(chat->call, src, GST_APP_SINK(appsink));
+               gst_element_set_state(chat->audio_inpipeline, GST_STATE_PLAYING);
+               gst_element_set_state(chat->audio_outpipeline, GST_STATE_PLAYING);
+       }
+
 }
 
 static void on_call_participants(ChimeCall *call, GHashTable *participants, struct chime_chat *chat)
@@ -303,12 +364,23 @@ void chime_destroy_chat(struct chime_chat *chat)
                                                          chat->media);
                        chat->media = NULL;
                }
-#if 0
-               if (chat->audio) {
-                       chime_connection_call_audio_close(chat->audio);
-                       chat->audio = NULL;
+
+               if (chat->audio_inpipeline) {
+                       GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(chat->audio_inpipeline), GST_DEBUG_GRAPH_SHOW_ALL, "chime-inpipeline");
+
+                       gst_element_set_state(chat->audio_inpipeline, GST_STATE_NULL);
+                       gst_object_unref(chat->audio_inpipeline);
+                       chat->audio_inpipeline = NULL;
                }
-#endif
+
+               if (chat->audio_outpipeline) {
+                       GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(chat->audio_outpipeline), GST_DEBUG_GRAPH_SHOW_ALL, "chime-outpipeline");
+
+                       gst_element_set_state(chat->audio_outpipeline, GST_STATE_NULL);
+                       gst_object_unref(chat->audio_outpipeline);
+                       chat->audio_outpipeline = NULL;
+               }
+
                chime_connection_close_meeting(cxn, chat->meeting);
                g_object_unref(chat->meeting);
        }
index 2b6cbc5320ba469df2b6f20f5dd962ffbd4190b1..5e297b34587d56dd1669b13938b335bad61614d4 100644 (file)
@@ -150,7 +150,7 @@ static void do_send_rt_packet(ChimeCallAudio *audio, GstBuffer *buffer)
                        audio->audio_msg.sample_time += (dts - audio->next_dts) / NS_PER_SAMPLE;
                }
                audio->next_dts = dts + dur;
-               if (audio->state == AUDIO_STATE_AUDIO) {
+               if (audio->state == CHIME_AUDIO_STATE_AUDIO) {
                        printf ("State %d, send audio\n", audio->state);
                        audio->audio_msg.audio.len = info.size;
                        audio->audio_msg.audio.data = info.data;
@@ -197,8 +197,8 @@ static gboolean audio_receive_auth_msg(ChimeCallAudio *audio, gconstpointer pkt,
        chime_debug("Got AuthMessage authorised %d %d\n", msg->has_authorized, msg->authorized);
        if (msg->has_authorized && msg->authorized) {
                do_send_rt_packet(audio, NULL);
-               chime_call_audio_set_state(audio, audio->muted ? AUDIO_STATE_AUDIOLESS :
-                                          (audio->local_mute ? AUDIO_STATE_AUDIO_MUTED : AUDIO_STATE_AUDIO));
+               chime_call_audio_set_state(audio, audio->muted ? CHIME_AUDIO_STATE_AUDIOLESS :
+                                          (audio->local_mute ? CHIME_AUDIO_STATE_AUDIO_MUTED : CHIME_AUDIO_STATE_AUDIO));
        }
 
        auth_message__free_unpacked(msg, NULL);
@@ -442,21 +442,7 @@ void chime_call_audio_close(ChimeCallAudio *audio, gboolean hangup)
        g_signal_handlers_disconnect_matched(G_OBJECT(audio->call), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, audio);
 
        chime_debug("close audio\n");
-#ifdef AUDIO_HACKS
-       if (audio->pipeline) {
-               GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(audio->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "chime-pipeline");
 
-               gst_element_set_state(audio->pipeline, GST_STATE_NULL);
-               gst_object_unref(audio->audio_src);
-               gst_object_unref(audio->pipeline);
-       }
-       if (audio->outpipe) {
-               GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(audio->outpipe), GST_DEBUG_GRAPH_SHOW_ALL, "chime-outpipe");
-
-               gst_element_set_state(audio->outpipe, GST_STATE_NULL);
-               gst_object_unref(audio->outpipe);
-       }
-#endif
        if (audio->data_ack_source)
                g_source_remove(audio->data_ack_source);
        if (audio->send_rt_source)
@@ -465,7 +451,7 @@ void chime_call_audio_close(ChimeCallAudio *audio, gboolean hangup)
        g_hash_table_destroy(audio->profiles);
        g_slist_free_full(audio->data_messages, (GDestroyNotify) free_msgbuf);
        chime_call_transport_disconnect(audio, hangup);
-       chime_call_audio_set_state(audio, AUDIO_STATE_HANGUP);
+       chime_call_audio_set_state(audio, CHIME_AUDIO_STATE_HANGUP);
        g_free(audio);
 }
 
@@ -513,7 +499,7 @@ static GstAppSrcCallbacks chime_appsrc_callbacks = {
        .enough_data = chime_appsrc_enough_data,
 };
 
-void chime_call_install_gst_app_callbacks(ChimeCallAudio *audio, GstAppSrc *appsrc, GstAppSink *appsink)
+void chime_call_audio_install_gst_app_callbacks(ChimeCallAudio *audio, GstAppSrc *appsrc, GstAppSink *appsink)
 {
        audio->audio_src = appsrc;
        audio->appsrc_need_data = FALSE;
@@ -530,57 +516,6 @@ ChimeCallAudio *chime_call_audio_open(ChimeConnection *cxn, ChimeCall *call, gbo
        g_mutex_init(&audio->transport_lock);
        g_mutex_init(&audio->rt_lock);
 
-#ifdef AUDIO_HACKS
-       if (!audio->muted) {
-               // GStreamer - server-to-speakers
-               audio->pipeline = gst_pipeline_new("dirt-pipeline");
-
-               GstAppSrc *src = GST_APP_SRC(gst_element_factory_make("appsrc", "appsrc"));
-               GstCaps *audio_caps;
-               audio_caps = gst_caps_from_string("audio/x-opus,channel-mapping-family=0");
-               g_object_set (src, "caps", audio_caps, "format", GST_FORMAT_TIME, NULL);
-               gst_app_src_set_size(src, -1);
-               gst_app_src_set_max_bytes(src, 100);
-               gst_base_src_set_live(GST_BASE_SRC(src), TRUE);
-               gst_app_src_set_stream_type(src, GST_APP_STREAM_TYPE_STREAM);
-
-               GstElement *opusdec = gst_element_factory_make("opusdec", "opusdec");
-               GstElement *convert = gst_element_factory_make("audioconvert", "audioconvert");
-               GstElement *resample = gst_element_factory_make("audioresample", "audioresample");
-               GstElement *sink = gst_element_factory_make("autoaudiosink", "autoaudiosink");
-               gst_bin_add_many(GST_BIN(audio->pipeline), GST_ELEMENT(src), opusdec, convert, resample, sink, NULL);
-               if(!gst_element_link_many(GST_ELEMENT(src), opusdec, convert, resample, sink, NULL)) {
-                       printf("Failed to link incoming pipeline\n");
-               }
-
-
-
-               // GStreamer - mic-to-server
-               audio->outpipe = gst_pipeline_new("upstream-audio");
-               GstElement *mic = gst_element_factory_make("autoaudiosrc", "autoaudiosrc");
-               convert = gst_element_factory_make("audioconvert", "audioconvert");
-               g_object_set(convert, "caps", gst_caps_from_string("audio/x-raw,format=S16,channels=1"), NULL);
-               resample = gst_element_factory_make("audioresample", "audioresample");
-               g_object_set(resample, "caps", gst_caps_from_string("audio/x-raw"), NULL);
-               GstElement *opusenc = gst_element_factory_make("opusenc", "opusenc");
-               g_object_set(opusenc, "caps", gst_caps_from_string("audio/x-raw,format=S16,channels=1"), NULL);
-               g_object_set(opusenc,
-                            "bitrate", 16000,
-                            "bitrate-type", "vbr",
-                            NULL);
-               GstElement *appsink = gst_element_factory_make("appsink", "appsink");
-               g_object_set(appsink, "caps", gst_caps_from_string("audio/x-opus,channels=1,channel-mapping-family=0"), NULL);
-               gst_bin_add_many(GST_BIN(audio->outpipe), mic, convert, resample, opusenc, appsink, NULL);
-               if(!gst_element_link_many(mic, convert, resample, opusenc, appsink, NULL)) {
-                       printf("Failed to link upstream pipeline\n");
-               }
-               chime_call_install_gst_app_callbacks(audio, src, GST_APP_SINK(appsink));
-               gst_element_set_state(audio->pipeline, GST_STATE_PLAYING);
-               gst_element_set_state(audio->outpipe, GST_STATE_PLAYING);
-
-       }
-#endif
-
        rtmessage__init(&audio->rt_msg);
        audio_message__init(&audio->audio_msg);
        client_status_message__init(&audio->client_status_msg);
@@ -591,7 +526,7 @@ ChimeCallAudio *chime_call_audio_open(ChimeConnection *cxn, ChimeCall *call, gbo
        audio->audio_msg.sample_time = g_random_int();
 
        chime_call_transport_connect(audio, muted);
-       chime_call_audio_set_state(audio, AUDIO_STATE_CONNECTING);
+       chime_call_audio_set_state(audio, CHIME_AUDIO_STATE_CONNECTING);
 
        return audio;
 }
@@ -607,7 +542,7 @@ void chime_call_audio_reopen(ChimeCallAudio *audio, gboolean muted)
                        g_source_remove(audio->data_ack_source);
                chime_call_transport_disconnect(audio, TRUE);
                chime_call_transport_connect(audio, muted);
-               chime_call_audio_set_state(audio, AUDIO_STATE_CONNECTING);
+               chime_call_audio_set_state(audio, CHIME_AUDIO_STATE_CONNECTING);
        }
 }
 
@@ -615,15 +550,9 @@ void chime_call_audio_reopen(ChimeCallAudio *audio, gboolean muted)
 void chime_call_audio_local_mute(ChimeCallAudio *audio, gboolean muted)
 {
        audio->local_mute = muted;
-       if (muted && audio->state == AUDIO_STATE_AUDIO) {
-               chime_call_audio_set_state(audio, AUDIO_STATE_AUDIO_MUTED);
-               if (audio->outpipe) {
-                       gst_element_set_state(audio->outpipe, GST_STATE_PAUSED);
-               }
-       } else if (!muted && audio->state == AUDIO_STATE_AUDIO_MUTED) {
-               chime_call_audio_set_state(audio, AUDIO_STATE_AUDIO);
-               if (audio->outpipe) {
-                       gst_element_set_state(audio->outpipe, GST_STATE_PLAYING);
-               }
-       }
+
+       if (muted && audio->state == CHIME_AUDIO_STATE_AUDIO)
+               chime_call_audio_set_state(audio, CHIME_AUDIO_STATE_AUDIO_MUTED);
+       else if (!muted && audio->state == CHIME_AUDIO_STATE_AUDIO_MUTED)
+               chime_call_audio_set_state(audio, CHIME_AUDIO_STATE_AUDIO);
 }
index 3db5caaf3e2ee94a168b5f5c6824c4cb1e29832b..e4eeb1ad589ee9b637eaa21ba9a119b61e826abc 100644 (file)
@@ -15,8 +15,6 @@
  * Lesser General Public License for more details.
  */
 
-#define AUDIO_HACKS
-
 #include "chime-connection.h"
 #include "chime-call.h"
 #include "chime-connection-private.h"
 #include "protobuf/rt_message.pb-c.h"
 #include "protobuf/data_message.pb-c.h"
 
-#ifdef AUDIO_HACKS
-#include <gst/gstelement.h>
-#include <gst/gstpipeline.h>
-#include <gst/gstutils.h>
 #include <gst/app/gstappsrc.h>
 #include <gst/app/gstappsink.h>
-#endif
-
-enum audio_state {
-       AUDIO_STATE_CONNECTING = 0,
-       AUDIO_STATE_FAILED,
-       AUDIO_STATE_AUDIOLESS,
-       AUDIO_STATE_AUDIO,
-       AUDIO_STATE_AUDIO_MUTED,
-       AUDIO_STATE_HANGUP,
-       AUDIO_STATE_DISCONNECTED,
-};
 
 struct _ChimeCallAudio {
        ChimeCall *call;
-       enum audio_state state;
+       ChimeAudioState state;
        gboolean local_mute;
        gboolean muted;
        GMutex transport_lock;
@@ -58,14 +41,12 @@ struct _ChimeCallAudio {
        gint32 data_next_logical_msg;
        GSList *data_messages;
        GHashTable *profiles;
-#ifdef AUDIO_HACKS
+
        GstClockTime next_dts;
        gint64 last_send_local_time;
        GstAppSrc *audio_src;
        gboolean appsrc_need_data;
-       GstElement *pipeline;
-       GstElement *outpipe;
-#endif
+
        GMutex rt_lock;
        guint send_rt_source;
        gint64 last_server_time_offset;
@@ -91,7 +72,7 @@ enum xrp_pkt_type {
 ChimeCallAudio *chime_call_audio_open(ChimeConnection *cxn, ChimeCall *call, gboolean muted);
 void chime_call_audio_close(ChimeCallAudio *audio, gboolean hangup);
 void chime_call_audio_reopen(ChimeCallAudio *audio, gboolean muted);
-void chime_call_audio_set_state(ChimeCallAudio *audio, enum audio_state state);
+void chime_call_audio_set_state(ChimeCallAudio *audio, ChimeAudioState state);
 void chime_call_audio_local_mute(ChimeCallAudio *audio, gboolean muted);
 
 /* Called from audio code */
@@ -102,4 +83,4 @@ void chime_call_transport_send_packet(ChimeCallAudio *audio, enum xrp_pkt_type t
 /* Callbacks into audio code from transport */
 gboolean audio_receive_packet(ChimeCallAudio *audio, gconstpointer pkt, gsize len);
 
-void chime_call_install_gst_app_callbacks(ChimeCallAudio *audio, GstAppSrc *appsrc, GstAppSink *appsink);
+void chime_call_audio_install_gst_app_callbacks(ChimeCallAudio *audio, GstAppSrc *appsrc, GstAppSink *appsink);
index ab792cd6a35bb359e78b23295ff880c7462a2a14..e3d20f96c4411a88ab6cb4e4947418d2190a20ff 100644 (file)
@@ -151,7 +151,7 @@ static void audio_ws_connect_cb(GObject *obj, GAsyncResult *res, gpointer _audio
        SoupWebsocketConnection *ws = chime_connection_websocket_connect_finish(cxn, res, &error);
        if (!ws) {
                chime_debug("audio ws error %s\n", error->message);
-               audio->state = AUDIO_STATE_FAILED;
+               audio->state = CHIME_AUDIO_STATE_FAILED;
                g_object_unref(cxn);
                return;
        }
index 6a8b760c60cfc7fab3496d5f1af44b3fd54bd2dc..a6fc16e6827455477305007e19946f7325d4c397 100644 (file)
@@ -504,7 +504,7 @@ void chime_call_set_mute(ChimeCall *call, gboolean muted)
                chime_call_audio_reopen(call->audio, muted);
 }
 
-void chime_call_audio_set_state(ChimeCallAudio *audio, enum audio_state state)
+void chime_call_audio_set_state(ChimeCallAudio *audio, ChimeAudioState state)
 {
        if (audio->state == state)
                return;
@@ -512,3 +512,9 @@ void chime_call_audio_set_state(ChimeCallAudio *audio, enum audio_state state)
        audio->state = state;
        g_signal_emit(audio->call, signals[AUDIO_STATE], 0, state);
 }
+
+void chime_call_install_gst_app_callbacks(ChimeCall *call, GstAppSrc *appsrc, GstAppSink *appsink)
+{
+       if (call->audio)
+               chime_call_audio_install_gst_app_callbacks(call->audio, appsrc, appsink);
+}
index 2a749eae477514e7a6f81bf3df36090bbebb3389..a82019428e8cfb259db5f4c79d300610234f929a 100644 (file)
@@ -26,6 +26,9 @@
 #include "chime-contact.h"
 #include "chime-object.h"
 
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+
 G_BEGIN_DECLS
 
 #define CHIME_TYPE_CALL (chime_call_get_type ())
@@ -86,6 +89,17 @@ GList *chime_call_get_participants(ChimeCall *self);
 struct _ChimeCallAudio;
 typedef struct _ChimeCallAudio ChimeCallAudio;
 
+typedef enum {
+       CHIME_AUDIO_STATE_CONNECTING = 0,
+       CHIME_AUDIO_STATE_FAILED,
+       CHIME_AUDIO_STATE_AUDIOLESS,
+       CHIME_AUDIO_STATE_AUDIO,
+       CHIME_AUDIO_STATE_AUDIO_MUTED,
+       CHIME_AUDIO_STATE_HANGUP,
+       CHIME_AUDIO_STATE_DISCONNECTED,
+} ChimeAudioState;
+
+void chime_call_install_gst_app_callbacks(ChimeCall *call, GstAppSrc *appsrc, GstAppSink *appsink);
 
 G_END_DECLS