Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / jack / gstjackaudioclient.c
1 /* GStreamer
2  * Copyright (C) 2006 Wim Taymans <wim@fluendo.com>
3  *
4  * gstjackaudioclient.c: jack audio client implementation
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <string.h>
23
24 #include "gstjackaudioclient.h"
25 #include "gstjack.h"
26
27 #include <gst/glib-compat-private.h>
28
29 GST_DEBUG_CATEGORY_STATIC (gst_jack_audio_client_debug);
30 #define GST_CAT_DEFAULT gst_jack_audio_client_debug
31
32 void
33 gst_jack_audio_client_init (void)
34 {
35   GST_DEBUG_CATEGORY_INIT (gst_jack_audio_client_debug, "jackclient", 0,
36       "jackclient helpers");
37 }
38
39 /* a list of global connections indexed by id and server. */
40 G_LOCK_DEFINE_STATIC (connections_lock);
41 static GList *connections;
42
43 /* the connection to a server  */
44 typedef struct
45 {
46   gint refcount;
47   GMutex lock;
48   GCond flush_cond;
49
50   /* id/server pair and the connection */
51   gchar *id;
52   gchar *server;
53   jack_client_t *client;
54
55   /* lists of GstJackAudioClients */
56   gint n_clients;
57   GList *src_clients;
58   GList *sink_clients;
59
60   /* transport state handling */
61   gint cur_ts;
62   GstState transport_state;
63 } GstJackAudioConnection;
64
65 /* an object sharing a jack_client_t connection. */
66 struct _GstJackAudioClient
67 {
68   GstJackAudioConnection *conn;
69
70   GstJackClientType type;
71   gboolean active;
72   gboolean deactivate;
73
74   JackShutdownCallback shutdown;
75   JackProcessCallback process;
76   JackBufferSizeCallback buffer_size;
77   JackSampleRateCallback sample_rate;
78   gpointer user_data;
79 };
80
81 typedef struct
82 {
83   jack_nframes_t nframes;
84   gpointer user_data;
85 } JackCB;
86
87 static gboolean
88 jack_handle_transport_change (GstJackAudioClient * client, GstState state)
89 {
90   GstObject *obj = GST_OBJECT_PARENT (client->user_data);
91   GstJackTransport mode;
92
93   g_object_get (obj, "transport", &mode, NULL);
94   if ((mode == GST_JACK_TRANSPORT_SLAVE) && (GST_STATE (obj) != state)) {
95     GST_INFO_OBJECT (obj, "requesting state change: %s",
96         gst_element_state_get_name (state));
97     gst_element_post_message (GST_ELEMENT (obj),
98         gst_message_new_request_state (obj, state));
99     return TRUE;
100   }
101   return FALSE;
102 }
103
104 static int
105 jack_process_cb (jack_nframes_t nframes, void *arg)
106 {
107   GstJackAudioConnection *conn = (GstJackAudioConnection *) arg;
108   GList *walk;
109   int res = 0;
110   jack_transport_state_t ts = jack_transport_query (conn->client, NULL);
111
112   if (ts != conn->cur_ts) {
113     conn->cur_ts = ts;
114     switch (ts) {
115       case JackTransportStopped:
116         GST_DEBUG ("transport state is 'stopped'");
117         conn->transport_state = GST_STATE_PAUSED;
118         break;
119       case JackTransportStarting:
120         GST_DEBUG ("transport state is 'starting'");
121         conn->transport_state = GST_STATE_READY;
122         break;
123       case JackTransportRolling:
124         GST_DEBUG ("transport state is 'rolling'");
125         conn->transport_state = GST_STATE_PLAYING;
126         break;
127       default:
128         break;
129     }
130     GST_DEBUG ("num of clients: src=%d, sink=%d",
131         g_list_length (conn->src_clients), g_list_length (conn->sink_clients));
132   }
133
134   g_mutex_lock (&conn->lock);
135   /* call sources first, then sinks. Sources will either push data into the
136    * ringbuffer of the sinks, which will then pull the data out of it, or
137    * sinks will pull the data from the sources. */
138   for (walk = conn->src_clients; walk; walk = g_list_next (walk)) {
139     GstJackAudioClient *client = (GstJackAudioClient *) walk->data;
140
141     /* only call active clients */
142     if ((client->active || client->deactivate) && client->process) {
143       res = client->process (nframes, client->user_data);
144       if (client->deactivate) {
145         client->deactivate = FALSE;
146         g_cond_signal (&conn->flush_cond);
147       }
148     }
149   }
150   for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) {
151     GstJackAudioClient *client = (GstJackAudioClient *) walk->data;
152
153     /* only call active clients */
154     if ((client->active || client->deactivate) && client->process) {
155       res = client->process (nframes, client->user_data);
156       if (client->deactivate) {
157         client->deactivate = FALSE;
158         g_cond_signal (&conn->flush_cond);
159       }
160     }
161   }
162
163   /* handle transport state requisition, do sinks first, stop after the first
164    * element that handled it */
165   if (conn->transport_state != GST_STATE_VOID_PENDING) {
166     for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) {
167       if (jack_handle_transport_change ((GstJackAudioClient *) walk->data,
168               conn->transport_state)) {
169         conn->transport_state = GST_STATE_VOID_PENDING;
170         break;
171       }
172     }
173   }
174   if (conn->transport_state != GST_STATE_VOID_PENDING) {
175     for (walk = conn->src_clients; walk; walk = g_list_next (walk)) {
176       if (jack_handle_transport_change ((GstJackAudioClient *) walk->data,
177               conn->transport_state)) {
178         conn->transport_state = GST_STATE_VOID_PENDING;
179         break;
180       }
181     }
182   }
183   g_mutex_unlock (&conn->lock);
184
185   return res;
186 }
187
188 /* we error out */
189 static int
190 jack_sample_rate_cb (jack_nframes_t nframes, void *arg)
191 {
192   return 0;
193 }
194
195 /* we error out */
196 static int
197 jack_buffer_size_cb (jack_nframes_t nframes, void *arg)
198 {
199   return 0;
200 }
201
202 static void
203 jack_shutdown_cb (void *arg)
204 {
205   GstJackAudioConnection *conn = (GstJackAudioConnection *) arg;
206   GList *walk;
207
208   GST_DEBUG ("disconnect client %s from server %s", conn->id,
209       GST_STR_NULL (conn->server));
210
211   g_mutex_lock (&conn->lock);
212   for (walk = conn->src_clients; walk; walk = g_list_next (walk)) {
213     GstJackAudioClient *client = (GstJackAudioClient *) walk->data;
214
215     if (client->shutdown)
216       client->shutdown (client->user_data);
217   }
218   for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) {
219     GstJackAudioClient *client = (GstJackAudioClient *) walk->data;
220
221     if (client->shutdown)
222       client->shutdown (client->user_data);
223   }
224   g_mutex_unlock (&conn->lock);
225 }
226
227 typedef struct
228 {
229   const gchar *id;
230   const gchar *server;
231 } FindData;
232
233 static gint
234 connection_find (GstJackAudioConnection * conn, FindData * data)
235 {
236   /* id's must match */
237   if (strcmp (conn->id, data->id))
238     return 1;
239
240   /* both the same or NULL */
241   if (conn->server == data->server)
242     return 0;
243
244   /* we cannot compare NULL */
245   if (conn->server == NULL || data->server == NULL)
246     return 1;
247
248   if (strcmp (conn->server, data->server))
249     return 1;
250
251   return 0;
252 }
253
254 /* make a connection with @id and @server. Returns NULL on failure with the
255  * status set. */
256 static GstJackAudioConnection *
257 gst_jack_audio_make_connection (const gchar * id, const gchar * server,
258     jack_client_t * jclient, jack_status_t * status)
259 {
260   GstJackAudioConnection *conn;
261   jack_options_t options;
262   gint res;
263
264   *status = 0;
265
266   GST_DEBUG ("new client %s, connecting to server %s", id,
267       GST_STR_NULL (server));
268
269   /* never start a server */
270   options = JackNoStartServer;
271   /* if we have a servername, use it */
272   if (server != NULL)
273     options |= JackServerName;
274   /* open the client */
275   if (jclient == NULL)
276     jclient = jack_client_open (id, options, status, server);
277   if (jclient == NULL)
278     goto could_not_open;
279
280   /* now create object */
281   conn = g_new (GstJackAudioConnection, 1);
282   conn->refcount = 1;
283   g_mutex_init (&conn->lock);
284   g_cond_init (&conn->flush_cond);
285   conn->id = g_strdup (id);
286   conn->server = g_strdup (server);
287   conn->client = jclient;
288   conn->n_clients = 0;
289   conn->src_clients = NULL;
290   conn->sink_clients = NULL;
291   conn->cur_ts = -1;
292   conn->transport_state = GST_STATE_VOID_PENDING;
293
294   /* set our callbacks  */
295   jack_set_process_callback (jclient, jack_process_cb, conn);
296   /* these callbacks cause us to error */
297   jack_set_buffer_size_callback (jclient, jack_buffer_size_cb, conn);
298   jack_set_sample_rate_callback (jclient, jack_sample_rate_cb, conn);
299   jack_on_shutdown (jclient, jack_shutdown_cb, conn);
300
301   /* all callbacks are set, activate the client */
302   GST_INFO ("activate jack_client %p", jclient);
303   if ((res = jack_activate (jclient)))
304     goto could_not_activate;
305
306   GST_DEBUG ("opened connection %p", conn);
307
308   return conn;
309
310   /* ERRORS */
311 could_not_open:
312   {
313     GST_DEBUG ("failed to open jack client, %d", *status);
314     return NULL;
315   }
316 could_not_activate:
317   {
318     GST_ERROR ("Could not activate client (%d)", res);
319     *status = JackFailure;
320     g_mutex_clear (&conn->lock);
321     g_free (conn->id);
322     g_free (conn->server);
323     g_free (conn);
324     return NULL;
325   }
326 }
327
328 static GstJackAudioConnection *
329 gst_jack_audio_get_connection (const gchar * id, const gchar * server,
330     jack_client_t * jclient, jack_status_t * status)
331 {
332   GstJackAudioConnection *conn;
333   GList *found;
334   FindData data;
335
336   GST_DEBUG ("getting connection for id %s, server %s", id,
337       GST_STR_NULL (server));
338
339   data.id = id;
340   data.server = server;
341
342   G_LOCK (connections_lock);
343   found =
344       g_list_find_custom (connections, &data, (GCompareFunc) connection_find);
345   if (found != NULL && jclient != NULL) {
346     /* we found it, increase refcount and return it */
347     conn = (GstJackAudioConnection *) found->data;
348     conn->refcount++;
349
350     GST_DEBUG ("found connection %p", conn);
351   } else {
352     /* make new connection */
353     conn = gst_jack_audio_make_connection (id, server, jclient, status);
354     if (conn != NULL) {
355       GST_DEBUG ("created connection %p", conn);
356       /* add to list on success */
357       connections = g_list_prepend (connections, conn);
358     } else {
359       GST_WARNING ("could not create connection");
360     }
361   }
362   G_UNLOCK (connections_lock);
363
364   return conn;
365 }
366
367 static void
368 gst_jack_audio_unref_connection (GstJackAudioConnection * conn)
369 {
370   gint res;
371   gboolean zero;
372
373   GST_DEBUG ("unref connection %p refcnt %d", conn, conn->refcount);
374
375   G_LOCK (connections_lock);
376   conn->refcount--;
377   if ((zero = (conn->refcount == 0))) {
378     GST_DEBUG ("closing connection %p", conn);
379     /* remove from list, we can release the mutex after removing the connection
380      * from the list because after that, nobody can access the connection anymore. */
381     connections = g_list_remove (connections, conn);
382   }
383   G_UNLOCK (connections_lock);
384
385   /* if we are zero, close and cleanup the connection */
386   if (zero) {
387     /* don't use conn->lock here. two reasons:
388      *
389      *  1) its not necessary: jack_deactivate() will not return until the JACK thread
390      *      associated with this connection is cleaned up by a thread join, hence 
391      *      no more callbacks can occur or be in progress.
392      *
393      * 2) it would deadlock anyway, because jack_deactivate() will sleep
394      *      waiting for the JACK thread, and can thus cause deadlock in 
395      *      jack_process_cb()
396      */
397     GST_INFO ("deactivate jack_client %p", conn->client);
398     if ((res = jack_deactivate (conn->client))) {
399       /* we only warn, this means the server is probably shut down and the client
400        * is gone anyway. */
401       GST_WARNING ("Could not deactivate Jack client (%d)", res);
402     }
403     /* close connection */
404     if ((res = jack_client_close (conn->client))) {
405       /* we assume the client is gone. */
406       GST_WARNING ("close failed (%d)", res);
407     }
408
409     /* free resources */
410     g_mutex_clear (&conn->lock);
411     g_cond_clear (&conn->flush_cond);
412     g_free (conn->id);
413     g_free (conn->server);
414     g_free (conn);
415   }
416 }
417
418 static void
419 gst_jack_audio_connection_add_client (GstJackAudioConnection * conn,
420     GstJackAudioClient * client)
421 {
422   g_mutex_lock (&conn->lock);
423   switch (client->type) {
424     case GST_JACK_CLIENT_SOURCE:
425       conn->src_clients = g_list_append (conn->src_clients, client);
426       conn->n_clients++;
427       break;
428     case GST_JACK_CLIENT_SINK:
429       conn->sink_clients = g_list_append (conn->sink_clients, client);
430       conn->n_clients++;
431       break;
432     default:
433       g_warning ("trying to add unknown client type");
434       break;
435   }
436   g_mutex_unlock (&conn->lock);
437 }
438
439 static void
440 gst_jack_audio_connection_remove_client (GstJackAudioConnection * conn,
441     GstJackAudioClient * client)
442 {
443   g_mutex_lock (&conn->lock);
444   switch (client->type) {
445     case GST_JACK_CLIENT_SOURCE:
446       conn->src_clients = g_list_remove (conn->src_clients, client);
447       conn->n_clients--;
448       break;
449     case GST_JACK_CLIENT_SINK:
450       conn->sink_clients = g_list_remove (conn->sink_clients, client);
451       conn->n_clients--;
452       break;
453     default:
454       g_warning ("trying to remove unknown client type");
455       break;
456   }
457   g_mutex_unlock (&conn->lock);
458 }
459
460 /**
461  * gst_jack_audio_client_get:
462  * @id: the client id
463  * @server: the server to connect to or NULL for the default server
464  * @type: the client type
465  * @shutdown: a callback when the jack server shuts down
466  * @process: a callback when samples are available
467  * @buffer_size: a callback when the buffer_size changes
468  * @sample_rate: a callback when the sample_rate changes
469  * @user_data: user data passed to the callbacks
470  * @status: pointer to hold the jack status code in case of errors
471  *
472  * Get the jack client connection for @id and @server. Connections to the same
473  * @id and @server will receive the same physical Jack client connection and
474  * will therefore be scheduled in the same process callback.
475  * 
476  * Returns: a #GstJackAudioClient.
477  */
478 GstJackAudioClient *
479 gst_jack_audio_client_new (const gchar * id, const gchar * server,
480     jack_client_t * jclient, GstJackClientType type,
481     void (*shutdown) (void *arg), JackProcessCallback process,
482     JackBufferSizeCallback buffer_size, JackSampleRateCallback sample_rate,
483     gpointer user_data, jack_status_t * status)
484 {
485   GstJackAudioClient *client;
486   GstJackAudioConnection *conn;
487
488   g_return_val_if_fail (id != NULL, NULL);
489   g_return_val_if_fail (status != NULL, NULL);
490
491   /* first get a connection for the id/server pair */
492   conn = gst_jack_audio_get_connection (id, server, jclient, status);
493   if (conn == NULL)
494     goto no_connection;
495
496   GST_INFO ("new client %s", id);
497
498   /* make new client using the connection */
499   client = g_new (GstJackAudioClient, 1);
500   client->active = client->deactivate = FALSE;
501   client->conn = conn;
502   client->type = type;
503   client->shutdown = shutdown;
504   client->process = process;
505   client->buffer_size = buffer_size;
506   client->sample_rate = sample_rate;
507   client->user_data = user_data;
508
509   /* add the client to the connection */
510   gst_jack_audio_connection_add_client (conn, client);
511
512   return client;
513
514   /* ERRORS */
515 no_connection:
516   {
517     GST_DEBUG ("Could not get server connection (%d)", *status);
518     return NULL;
519   }
520 }
521
522 /**
523  * gst_jack_audio_client_free:
524  * @client: a #GstJackAudioClient
525  *
526  * Free the resources used by @client.
527  */
528 void
529 gst_jack_audio_client_free (GstJackAudioClient * client)
530 {
531   GstJackAudioConnection *conn;
532
533   g_return_if_fail (client != NULL);
534
535   GST_INFO ("free client");
536
537   conn = client->conn;
538
539   /* remove from connection first so that it's not scheduled anymore after this
540    * call */
541   gst_jack_audio_connection_remove_client (conn, client);
542   gst_jack_audio_unref_connection (conn);
543
544   g_free (client);
545 }
546
547 /**
548  * gst_jack_audio_client_get_client:
549  * @client: a #GstJackAudioClient
550  *
551  * Get the jack audio client for @client. This function is used to perform
552  * operations on the jack server from this client.
553  *
554  * Returns: The jack audio client.
555  */
556 jack_client_t *
557 gst_jack_audio_client_get_client (GstJackAudioClient * client)
558 {
559   g_return_val_if_fail (client != NULL, NULL);
560
561   /* no lock needed, the connection and the client does not change 
562    * once the client is created. */
563   return client->conn->client;
564 }
565
566 /**
567  * gst_jack_audio_client_set_active:
568  * @client: a #GstJackAudioClient
569  * @active: new mode for the client
570  *
571  * Activate or deactive @client. When a client is activated it will receive
572  * callbacks when data should be processed.
573  *
574  * Returns: 0 if all ok.
575  */
576 gint
577 gst_jack_audio_client_set_active (GstJackAudioClient * client, gboolean active)
578 {
579   g_return_val_if_fail (client != NULL, -1);
580
581   /* make sure that we are not dispatching the client */
582   g_mutex_lock (&client->conn->lock);
583   if (client->active && !active) {
584     /* we need to process once more to flush the port */
585     client->deactivate = TRUE;
586
587     /* need to wait for process_cb run once more */
588     while (client->deactivate)
589       g_cond_wait (&client->conn->flush_cond, &client->conn->lock);
590   }
591   client->active = active;
592   g_mutex_unlock (&client->conn->lock);
593
594   return 0;
595 }
596
597 /**
598  * gst_jack_audio_client_get_transport_state:
599  * @client: a #GstJackAudioClient
600  *
601  * Check the current transport state. The client can use this to request a state
602  * change from the application.
603  *
604  * Returns: the state, %GST_STATE_VOID_PENDING for no change in the transport
605  * state
606  */
607 GstState
608 gst_jack_audio_client_get_transport_state (GstJackAudioClient * client)
609 {
610   GstState state = client->conn->transport_state;
611
612   client->conn->transport_state = GST_STATE_VOID_PENDING;
613   return state;
614 }