static void jack_shutdown_cb (void *arg) { GstJackAudioConnection *conn = (GstJackAudioConnection *) arg; GList *walk; GST_DEBUG ("disconnect client %s from server %s", conn->id, GST_STR_NULL (conn->server)); g_mutex_lock (&conn->lock); for (walk = conn->src_clients; walk; walk = g_list_next (walk)) { GstJackAudioClient *client = (GstJackAudioClient *) walk->data; client->server_down = TRUE; g_cond_signal (&conn->flush_cond); if (client->shutdown) client->shutdown (client->user_data); } for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) { GstJackAudioClient *client = (GstJackAudioClient *) walk->data; client->server_down = TRUE; g_cond_signal (&conn->flush_cond); if (client->shutdown) client->shutdown (client->user_data); } g_mutex_unlock (&conn->lock); }
static int jack_process_cb (jack_nframes_t nframes, void *arg) { GstJackAudioConnection *conn = (GstJackAudioConnection *) arg; GList *walk; int res = 0; g_mutex_lock (conn->lock); /* call sources first, then sinks. Sources will either push data into the * ringbuffer of the sinks, which will then pull the data out of it, or * sinks will pull the data from the sources. */ for (walk = conn->src_clients; walk; walk = g_list_next (walk)) { GstJackAudioClient *client = (GstJackAudioClient *) walk->data; /* only call active clients */ if ((client->active || client->deactivate) && client->process) { res = client->process (nframes, client->user_data); if (client->deactivate) { client->deactivate = FALSE; g_cond_signal (conn->flush_cond); } } } for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) { GstJackAudioClient *client = (GstJackAudioClient *) walk->data; /* only call active clients */ if ((client->active || client->deactivate) && client->process) { res = client->process (nframes, client->user_data); if (client->deactivate) { client->deactivate = FALSE; g_cond_signal (conn->flush_cond); } } } g_mutex_unlock (conn->lock); return res; }
static int jack_process_cb (jack_nframes_t nframes, void *arg) { GstJackAudioConnection *conn = (GstJackAudioConnection *) arg; GList *walk; int res = 0; jack_transport_state_t ts = jack_transport_query (conn->client, NULL); if (ts != conn->cur_ts) { conn->cur_ts = ts; switch (ts) { case JackTransportStopped: GST_DEBUG ("transport state is 'stopped'"); conn->transport_state = GST_STATE_PAUSED; break; case JackTransportStarting: GST_DEBUG ("transport state is 'starting'"); conn->transport_state = GST_STATE_READY; break; case JackTransportRolling: GST_DEBUG ("transport state is 'rolling'"); conn->transport_state = GST_STATE_PLAYING; break; 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); /* call sources first, then sinks. Sources will either push data into the * ringbuffer of the sinks, which will then pull the data out of it, or * sinks will pull the data from the sources. */ for (walk = conn->src_clients; walk; walk = g_list_next (walk)) { GstJackAudioClient *client = (GstJackAudioClient *) walk->data; /* only call active clients */ if ((client->active || client->deactivate) && client->process) { res = client->process (nframes, client->user_data); if (client->deactivate) { client->deactivate = FALSE; g_cond_signal (&conn->flush_cond); } } } for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) { GstJackAudioClient *client = (GstJackAudioClient *) walk->data; /* only call active clients */ if ((client->active || client->deactivate) && client->process) { res = client->process (nframes, client->user_data); if (client->deactivate) { client->deactivate = FALSE; g_cond_signal (&conn->flush_cond); } } } /* 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; }