jack: rework transport support
authorStefan Sauer <ensonic@users.sf.net>
Tue, 7 Feb 2012 20:57:47 +0000 (21:57 +0100)
committerStefan Sauer <ensonic@users.sf.net>
Tue, 7 Feb 2012 20:59:29 +0000 (21:59 +0100)
Move common code to jackclient. There we can also handle the request state
message in a better way, as the element callbacks are only run if the element is
active.

ext/jack/gstjackaudioclient.c
ext/jack/gstjackaudiosink.c
ext/jack/gstjackaudiosrc.c

index c33949f..ef544d1 100644 (file)
@@ -22,6 +22,7 @@
 #include <string.h>
 
 #include "gstjackaudioclient.h"
+#include "gstjack.h"
 
 #include <gst/glib-compat-private.h>
 
@@ -77,14 +78,29 @@ struct _GstJackAudioClient
   gpointer user_data;
 };
 
-typedef jack_default_audio_sample_t sample_t;
-
 typedef struct
 {
   jack_nframes_t nframes;
   gpointer user_data;
 } JackCB;
 
+static gboolean
+jack_handle_transport_change (GstJackAudioClient * client, GstState state)
+{
+  GstObject *obj = GST_OBJECT_PARENT (client->user_data);
+  GstJackTransport mode;
+
+  g_object_get (obj, "transport", &mode, NULL);
+  if ((mode == GST_JACK_TRANSPORT_SLAVE) && (GST_STATE (obj) != state)) {
+    GST_INFO_OBJECT (obj, "requesting state change: %s",
+        gst_element_state_get_name (state));
+    gst_element_post_message (GST_ELEMENT (obj),
+        gst_message_new_request_state (obj, state));
+    return TRUE;
+  }
+  return FALSE;
+}
+
 static int
 jack_process_cb (jack_nframes_t nframes, void *arg)
 {
@@ -111,6 +127,8 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
       default:
         break;
     }
+    GST_DEBUG ("num of clients: src=%d, sink=%d",
+        g_list_length (conn->src_clients), g_list_length (conn->sink_clients));
   }
 
   g_mutex_lock (conn->lock);
@@ -141,6 +159,27 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
       }
     }
   }
+
+  /* handle transport state requisition, do sinks first, stop after the first
+   * element that handled it */
+  if (conn->transport_state != GST_STATE_VOID_PENDING) {
+    for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) {
+      if (jack_handle_transport_change ((GstJackAudioClient *) walk->data,
+              conn->transport_state)) {
+        conn->transport_state = GST_STATE_VOID_PENDING;
+        break;
+      }
+    }
+  }
+  if (conn->transport_state != GST_STATE_VOID_PENDING) {
+    for (walk = conn->src_clients; walk; walk = g_list_next (walk)) {
+      if (jack_handle_transport_change ((GstJackAudioClient *) walk->data,
+              conn->transport_state)) {
+        conn->transport_state = GST_STATE_VOID_PENDING;
+        break;
+      }
+    }
+  }
   g_mutex_unlock (conn->lock);
   return res;
 }
@@ -259,6 +298,7 @@ gst_jack_audio_make_connection (const gchar * id, const gchar * server,
   jack_on_shutdown (jclient, jack_shutdown_cb, conn);
 
   /* all callbacks are set, activate the client */
+  GST_INFO ("activate jack_client %p", jclient);
   if ((res = jack_activate (jclient)))
     goto could_not_activate;
 
@@ -353,6 +393,7 @@ gst_jack_audio_unref_connection (GstJackAudioConnection * conn)
      *      waiting for the JACK thread, and can thus cause deadlock in 
      *      jack_process_cb()
      */
+    GST_INFO ("deactivate jack_client %p", conn->client);
     if ((res = jack_deactivate (conn->client))) {
       /* we only warn, this means the server is probably shut down and the client
        * is gone anyway. */
index 681671a..1a7fc28 100644 (file)
@@ -195,18 +195,6 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
   buf = GST_RING_BUFFER_CAST (arg);
   sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
 
-  /* handle transport state requisitions */
-  if (sink->transport == GST_JACK_TRANSPORT_SLAVE) {
-    GstState state = gst_jack_audio_client_get_transport_state (sink->client);
-
-    if ((state != GST_STATE_VOID_PENDING) && (GST_STATE (sink) != state)) {
-      GST_DEBUG_OBJECT (sink, "requesting state change: %s",
-          gst_element_state_get_name (state));
-      gst_element_post_message (GST_ELEMENT (sink),
-          gst_message_new_request_state (GST_OBJECT (sink), state));
-    }
-  }
-
   channels = buf->spec.channels;
 
   /* get target buffers */
index b85fe40..e2b2bc0 100644 (file)
@@ -215,18 +215,6 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
   buf = GST_RING_BUFFER_CAST (arg);
   src = GST_JACK_AUDIO_SRC (GST_OBJECT_PARENT (buf));
 
-  /* handle transport state requisitions */
-  if (src->transport == GST_JACK_TRANSPORT_SLAVE) {
-    GstState state = gst_jack_audio_client_get_transport_state (src->client);
-
-    if ((state != GST_STATE_VOID_PENDING) && (GST_STATE (src) != state)) {
-      GST_DEBUG_OBJECT (src, "requesting state change: %s",
-          gst_element_state_get_name (state));
-      gst_element_post_message (GST_ELEMENT (src),
-          gst_message_new_request_state (GST_OBJECT (src), state));
-    }
-  }
-
   channels = buf->spec.channels;
 
   /* get input buffers */