mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
jack: add transport control handling
This feature allows to start and stop playback from other jack applications (e.g. qjackctl).
This commit is contained in:
parent
d1bb060d71
commit
7d4044aa46
4 changed files with 68 additions and 1 deletions
|
@ -55,6 +55,10 @@ typedef struct
|
|||
gint n_clients;
|
||||
GList *src_clients;
|
||||
GList *sink_clients;
|
||||
|
||||
/* transport state handling */
|
||||
gint cur_ts;
|
||||
GstState transport_state;
|
||||
} GstJackAudioConnection;
|
||||
|
||||
/* an object sharing a jack_client_t connection. */
|
||||
|
@ -87,6 +91,27 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
g_mutex_lock (conn->lock);
|
||||
/* call sources first, then sinks. Sources will either push data into the
|
||||
|
@ -117,7 +142,6 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
|
|||
}
|
||||
}
|
||||
g_mutex_unlock (conn->lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -224,6 +248,8 @@ gst_jack_audio_make_connection (const gchar * id, const gchar * server,
|
|||
conn->n_clients = 0;
|
||||
conn->src_clients = NULL;
|
||||
conn->sink_clients = NULL;
|
||||
conn->cur_ts = -1;
|
||||
conn->transport_state = GST_STATE_VOID_PENDING;
|
||||
|
||||
/* set our callbacks */
|
||||
jack_set_process_callback (jclient, jack_process_cb, conn);
|
||||
|
@ -525,3 +551,22 @@ gst_jack_audio_client_set_active (GstJackAudioClient * client, gboolean active)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_jack_audio_client_get_transport_state:
|
||||
* @client: a #GstJackAudioClient
|
||||
*
|
||||
* Check the current transport state. The client can use this to request a state
|
||||
* change from the application.
|
||||
*
|
||||
* Returns: the state, %GST_STATE_VOID_PENDING for no change in the transport
|
||||
* state
|
||||
*/
|
||||
GstState
|
||||
gst_jack_audio_client_get_transport_state (GstJackAudioClient * client)
|
||||
{
|
||||
GstState state = client->conn->transport_state;
|
||||
|
||||
client->conn->transport_state = GST_STATE_VOID_PENDING;
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ jack_client_t * gst_jack_audio_client_get_client (GstJackAudioClient *
|
|||
|
||||
gboolean gst_jack_audio_client_set_active (GstJackAudioClient *client, gboolean active);
|
||||
|
||||
GstState gst_jack_audio_client_get_transport_state (GstJackAudioClient *client);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_JACK_AUDIO_CLIENT_H__ */
|
||||
|
|
|
@ -191,10 +191,20 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
|
|||
guint8 *readptr;
|
||||
gint i, j, flen, channels;
|
||||
sample_t *data;
|
||||
GstState state;
|
||||
|
||||
buf = GST_RING_BUFFER_CAST (arg);
|
||||
sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
||||
|
||||
/* handle transport state requisitions */
|
||||
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 */
|
||||
|
|
|
@ -211,10 +211,20 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
|
|||
gint writeseg;
|
||||
gint channels, i, j, flen;
|
||||
sample_t *data;
|
||||
GstState state;
|
||||
|
||||
buf = GST_RING_BUFFER_CAST (arg);
|
||||
src = GST_JACK_AUDIO_SRC (GST_OBJECT_PARENT (buf));
|
||||
|
||||
/* handle transport state requisitions */
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue