mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-21 13:36:39 +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;
|
gint n_clients;
|
||||||
GList *src_clients;
|
GList *src_clients;
|
||||||
GList *sink_clients;
|
GList *sink_clients;
|
||||||
|
|
||||||
|
/* transport state handling */
|
||||||
|
gint cur_ts;
|
||||||
|
GstState transport_state;
|
||||||
} GstJackAudioConnection;
|
} GstJackAudioConnection;
|
||||||
|
|
||||||
/* an object sharing a jack_client_t connection. */
|
/* 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;
|
GstJackAudioConnection *conn = (GstJackAudioConnection *) arg;
|
||||||
GList *walk;
|
GList *walk;
|
||||||
int res = 0;
|
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);
|
g_mutex_lock (conn->lock);
|
||||||
/* call sources first, then sinks. Sources will either push data into the
|
/* 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);
|
g_mutex_unlock (conn->lock);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +248,8 @@ gst_jack_audio_make_connection (const gchar * id, const gchar * server,
|
||||||
conn->n_clients = 0;
|
conn->n_clients = 0;
|
||||||
conn->src_clients = NULL;
|
conn->src_clients = NULL;
|
||||||
conn->sink_clients = NULL;
|
conn->sink_clients = NULL;
|
||||||
|
conn->cur_ts = -1;
|
||||||
|
conn->transport_state = GST_STATE_VOID_PENDING;
|
||||||
|
|
||||||
/* set our callbacks */
|
/* set our callbacks */
|
||||||
jack_set_process_callback (jclient, jack_process_cb, conn);
|
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;
|
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);
|
gboolean gst_jack_audio_client_set_active (GstJackAudioClient *client, gboolean active);
|
||||||
|
|
||||||
|
GstState gst_jack_audio_client_get_transport_state (GstJackAudioClient *client);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_JACK_AUDIO_CLIENT_H__ */
|
#endif /* __GST_JACK_AUDIO_CLIENT_H__ */
|
||||||
|
|
|
@ -191,10 +191,20 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
|
||||||
guint8 *readptr;
|
guint8 *readptr;
|
||||||
gint i, j, flen, channels;
|
gint i, j, flen, channels;
|
||||||
sample_t *data;
|
sample_t *data;
|
||||||
|
GstState state;
|
||||||
|
|
||||||
buf = GST_RING_BUFFER_CAST (arg);
|
buf = GST_RING_BUFFER_CAST (arg);
|
||||||
sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
|
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;
|
channels = buf->spec.channels;
|
||||||
|
|
||||||
/* get target buffers */
|
/* get target buffers */
|
||||||
|
|
|
@ -211,10 +211,20 @@ jack_process_cb (jack_nframes_t nframes, void *arg)
|
||||||
gint writeseg;
|
gint writeseg;
|
||||||
gint channels, i, j, flen;
|
gint channels, i, j, flen;
|
||||||
sample_t *data;
|
sample_t *data;
|
||||||
|
GstState state;
|
||||||
|
|
||||||
buf = GST_RING_BUFFER_CAST (arg);
|
buf = GST_RING_BUFFER_CAST (arg);
|
||||||
src = GST_JACK_AUDIO_SRC (GST_OBJECT_PARENT (buf));
|
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;
|
channels = buf->spec.channels;
|
||||||
|
|
||||||
/* get input buffers */
|
/* get input buffers */
|
||||||
|
|
Loading…
Reference in a new issue