bluez-alsa: update gst-helper to handle corking and use the Multimedia role on A2DP 39/23439/1
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>
Thu, 19 Dec 2019 15:25:28 +0000 (17:25 +0200)
committerScott Murray <scott.murray@konsulko.com>
Fri, 20 Dec 2019 00:26:13 +0000 (00:26 +0000)
Bug-AGL: SPEC-2792

Change-Id: I2247550d6059c31596651e84fdd617f849722422
Signed-off-by: George Kiagiadakis <george.kiagiadakis@collabora.com>
(cherry picked from commit 40eb01c5c943509df2f4a52c3fe75a5d0cf0123b)

meta-pipewire/recipes-connectivity/bluez-alsa/bluez-alsa/0001-utils-add-a-gstreamer-helper-application-for-interco.patch

index 37c0321..6c9a388 100644 (file)
@@ -1,4 +1,4 @@
-From 33555a493af67f3acc2129764a1b093aec6254d8 Mon Sep 17 00:00:00 2001
+From f2e6a0a324106b40195f88953e55a355875d2b1b Mon Sep 17 00:00:00 2001
 From: George Kiagiadakis <george.kiagiadakis@collabora.com>
 Date: Fri, 4 Oct 2019 20:51:24 +0300
 Subject: [PATCH] utils: add a gstreamer helper application for interconnection
@@ -24,8 +24,8 @@ Upstream-Status: Inappropriate
 ---
  configure.ac       |   7 +
  utils/Makefile.am  |  20 +++
- utils/gst-helper.c | 379 +++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 406 insertions(+)
+ utils/gst-helper.c | 432 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 459 insertions(+)
  create mode 100644 utils/gst-helper.c
 
 diff --git a/configure.ac b/configure.ac
@@ -76,10 +76,10 @@ index 9057f2c..9790474 100644
 +endif
 diff --git a/utils/gst-helper.c b/utils/gst-helper.c
 new file mode 100644
-index 0000000..1b021ee
+index 0000000..de1d47c
 --- /dev/null
 +++ b/utils/gst-helper.c
-@@ -0,0 +1,379 @@
+@@ -0,0 +1,432 @@
 +/* Bluez-Alsa PipeWire integration GStreamer helper
 + *
 + * Copyright © 2016-2019 Arkadiusz Bokowy
@@ -123,6 +123,9 @@ index 0000000..1b021ee
 +      int ba_pcm_ctrl_fd;
 +      /* the gstreamer pipelines (sink & source) */
 +      GstElement *pipeline[2];
++      /* the queue & pwaudiosink of the sink pipeline */
++      GstElement *queue;
++      GstElement *pwelem;
 +};
 +
 +static struct ba_dbus_ctx dbus_ctx;
@@ -141,11 +144,44 @@ index 0000000..1b021ee
 +      main_loop_on = false;
 +}
 +
++static GstBusSyncReply
++bus_sync_handler(GstBus *bus, GstMessage *message, gpointer user_data)
++{
++      struct worker *w = user_data;
++      GstState s;
++
++      switch (GST_MESSAGE_TYPE (message)) {
++      case GST_MESSAGE_REQUEST_STATE:
++              gst_message_parse_request_state (message, &s);
++
++              debug ("corked: %d", (s == GST_STATE_PAUSED));
++
++              /* drop queue data when corked */
++              g_object_set (w->queue,
++                      "leaky", (s == GST_STATE_PAUSED) ? 2 /* downstream */ : 0 /* no */,
++                      NULL);
++              gst_element_set_state (w->pwelem, s);
++
++              /* flush the queue when resuming */
++              if (s == GST_STATE_PLAYING) {
++                      gst_element_send_event (w->queue, gst_event_new_flush_start ());
++                      gst_element_send_event (w->queue, gst_event_new_flush_stop (FALSE));
++              }
++              break;
++      default:
++              break;
++      }
++
++      gst_message_unref (message);
++      return GST_BUS_DROP;
++}
++
 +static int
 +worker_start_pipeline(struct worker *w, int id, int mode, int profile)
 +{
 +      GError *gerr = NULL;
 +      DBusError err = DBUS_ERROR_INIT;
++      const gchar * role = NULL;
 +
 +      if (w->pipeline[id])
 +              return 0;
@@ -172,9 +208,15 @@ index 0000000..1b021ee
 +                      "! rawaudioparse use-sink-caps=true ! m. "
 +                      /* take the mixer output, convert and push to pipewire */
 +                      "m.src ! capsfilter name=capsf3 ! audioconvert ! audioresample "
-+                      "! audio/x-raw,format=F32LE,rate=48000 ! pwaudiosink name=pwelem",
++                      "! audio/x-raw,format=F32LE,rate=48000 ! identity sync=true "
++                      "! queue name=queue leaky=no max-size-time=0 max-size-buffers=0 max-size-bytes=192000 "
++                      "! pwaudiosink name=pwelem",
 +                      &gerr);
-+      } else if (mode == BA_PCM_FLAG_SOURCE && profile == BA_PCM_FLAG_PROFILE_SCO) {
++
++              /* a2dp is for music, sco is for calls */
++              role = (profile == BA_PCM_FLAG_PROFILE_A2DP) ? "Multimedia" : "Communication";
++      }
++      else if (mode == BA_PCM_FLAG_SOURCE && profile == BA_PCM_FLAG_PROFILE_SCO) {
 +              debug("source start");
 +              w->pipeline[id] = gst_parse_launch(
 +                      /* read from pipewire and put the buffers on a leaky queue, which
@@ -183,9 +225,11 @@ index 0000000..1b021ee
 +                         9600 bytes = 50ms @ F32LE/1ch/48000
 +                      */
 +                      "pwaudiosrc name=pwelem ! audio/x-raw,format=F32LE,rate=48000 "
-+                      "! queue leaky=downstream max-size-time=0 max-size-buffers=0 max-size-bytes=9600 "
++                      "! queue name=queue leaky=downstream max-size-time=0 max-size-buffers=0 max-size-bytes=9600 "
 +                      "! audioconvert ! audioresample ! capsfilter name=capsf "
 +                      "! fdsink name=fdelem", &gerr);
++
++              role = "Communication";
 +      }
 +
 +      if (gerr) {
@@ -198,6 +242,7 @@ index 0000000..1b021ee
 +              g_autofree gchar *capsstr = NULL;
 +              g_autoptr (GstElement) fdelem = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "fdelem");
 +              g_autoptr (GstElement) pwelem = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "pwelem");
++              g_autoptr (GstElement) queue = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "queue");
 +              g_autoptr (GstElement) capsf = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "capsf");
 +              g_autoptr (GstElement) capsf2 = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "capsf2");
 +              g_autoptr (GstElement) capsf3 = gst_bin_get_by_name(GST_BIN(w->pipeline[id]), "capsf3");
@@ -208,8 +253,9 @@ index 0000000..1b021ee
 +                              "rate", G_TYPE_INT, w->ba_pcm.sampling,
 +                              NULL);
 +              g_autoptr (GstStructure) stream_props = gst_structure_new("props",
-+                              "media.role", G_TYPE_STRING, "Communication",
-+                              "wireplumber.keep-linked", G_TYPE_STRING, "1",
++                              "media.role", G_TYPE_STRING, role,
++                              "bluealsa.profile", G_TYPE_STRING,
++                                      (profile == BA_PCM_FLAG_PROFILE_SCO) ? "sco" : "a2dp",
 +                              NULL);
 +
 +              g_object_set(capsf, "caps", caps, NULL);
@@ -224,6 +270,13 @@ index 0000000..1b021ee
 +              g_object_set(fdelem, "fd", w->ba_pcm_fd, NULL);
 +              g_object_set(pwelem, "stream-properties", stream_props, NULL);
 +
++              if (mode == BA_PCM_FLAG_SINK) {
++                      g_autoptr (GstBus) bus = gst_pipeline_get_bus(GST_PIPELINE(w->pipeline[id]));
++                      gst_bus_set_sync_handler(bus, bus_sync_handler, w, NULL);
++                      w->queue = queue;
++                      w->pwelem = pwelem;
++              }
++
 +              gst_element_set_state(w->pipeline[id], GST_STATE_PLAYING);
 +      }
 +
@@ -460,5 +513,5 @@ index 0000000..1b021ee
 +      return ret;
 +}
 -- 
-2.23.0
+2.24.0