jack: add a transport mode enum

Clients can configure the desired behaviour via "transport" property. The
default behaviour is ignoring the transport state. Other modes are master and
slave.
This commit is contained in:
Stefan Sauer 2012-01-11 14:47:36 +01:00
parent 834e58be9e
commit bc1fa747a7
6 changed files with 146 additions and 34 deletions

View file

@ -46,6 +46,27 @@ gst_jack_connect_get_type (void)
return (GType) jack_connect_type;
}
GType
gst_jack_transport_get_type (void)
{
static volatile gsize type = 0;
if (g_once_init_enter (&type)) {
static const GEnumValue enum_values[] = {
{GST_JACK_TRANSPORT_AUTONOMOUS,
"No transport support", "autonomous"},
{GST_JACK_TRANSPORT_MASTER,
"Start and stop transport with state changes", "master"},
{GST_JACK_TRANSPORT_SLAVE,
"Follow transport state changes", "slave"},
{0, NULL, NULL},
};
GType tmp = g_enum_register_static ("GstJackTransport", enum_values);
g_once_init_leave (&type, tmp);
}
return (GType) type;
}
static gpointer
gst_jack_client_copy (gpointer jclient)

View file

@ -37,19 +37,35 @@
*
* Specify how the output ports will be connected.
*/
typedef enum {
GST_JACK_CONNECT_NONE,
GST_JACK_CONNECT_AUTO,
GST_JACK_CONNECT_AUTO_FORCED
} GstJackConnect;
/**
* GstJackTransport:
* @GST_JACK_TRANSPORT_AUTONOMOUS: no transport support
* @GST_JACK_TRANSPORT_MASTER: start and stop transport with state-changes
* @GST_JACK_TRANSPORT_SLAVE: follow transport state changes
*
* The jack transport state allow to sync multiple clients. This enum defines a
* client behaviour regarding to the transport mechanism.
*/
typedef enum {
GST_JACK_TRANSPORT_AUTONOMOUS,
GST_JACK_TRANSPORT_MASTER,
GST_JACK_TRANSPORT_SLAVE
} GstJackTransport;
typedef jack_default_audio_sample_t sample_t;
#define GST_TYPE_JACK_CONNECT (gst_jack_connect_get_type())
#define GST_TYPE_JACK_CLIENT (gst_jack_client_get_type ())
#define GST_TYPE_JACK_CONNECT (gst_jack_connect_get_type ())
#define GST_TYPE_JACK_TRANSPORT (gst_jack_transport_get_type ())
#define GST_TYPE_JACK_CLIENT (gst_jack_client_get_type ())
GType gst_jack_client_get_type(void);
GType gst_jack_connect_get_type(void);
GType gst_jack_transport_get_type(void);
#endif // _GST_JACK_H_

View file

@ -191,25 +191,21 @@ 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 */
/*
FIXME: qjackctl's initial transport state is stopped
it can be started using jack_transport_start (jack_client_t *);
need to figure out what the policy here is
if (sink->transport == GST_JACK_TRANSPORT_SLAVE) {
GstState state = gst_jack_audio_client_get_transport_state (sink->client);
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));
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;
@ -576,6 +572,13 @@ gst_jack_ring_buffer_start (GstRingBuffer * buf)
GST_DEBUG_OBJECT (sink, "start");
if (sink->transport == GST_JACK_TRANSPORT_MASTER) {
jack_client_t *client;
client = gst_jack_audio_client_get_client (sink->client);
jack_transport_start (client);
}
return TRUE;
}
@ -588,6 +591,13 @@ gst_jack_ring_buffer_pause (GstRingBuffer * buf)
GST_DEBUG_OBJECT (sink, "pause");
if (sink->transport == GST_JACK_TRANSPORT_MASTER) {
jack_client_t *client;
client = gst_jack_audio_client_get_client (sink->client);
jack_transport_stop (client);
}
return TRUE;
}
@ -600,6 +610,13 @@ gst_jack_ring_buffer_stop (GstRingBuffer * buf)
GST_DEBUG_OBJECT (sink, "stop");
if (sink->transport == GST_JACK_TRANSPORT_MASTER) {
jack_client_t *client;
client = gst_jack_audio_client_get_client (sink->client);
jack_transport_stop (client);
}
return TRUE;
}
@ -666,7 +683,8 @@ enum
#define DEFAULT_PROP_CONNECT GST_JACK_CONNECT_AUTO
#define DEFAULT_PROP_SERVER NULL
#define DEFAULT_PROP_CLIENT_NAME NULL
#define DEFAULT_PROP_CLIENT_NAME NULL
#define DEFAULT_PROP_TRANSPORT GST_JACK_TRANSPORT_AUTONOMOUS
enum
{
@ -675,6 +693,7 @@ enum
PROP_SERVER,
PROP_CLIENT,
PROP_CLIENT_NAME,
PROP_TRANSPORT,
PROP_LAST
};
@ -752,6 +771,19 @@ gst_jack_audio_sink_class_init (GstJackAudioSinkClass * klass)
GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* GstJackAudioSink:transport
*
* The jack transport behaviour for the client.
*
* Since: 0.10.31
*/
g_object_class_install_property (gobject_class, PROP_TRANSPORT,
g_param_spec_enum ("transport", "Transport mode",
"Jack transport behaviour of the client",
GST_TYPE_JACK_TRANSPORT, DEFAULT_PROP_TRANSPORT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_sink_getcaps);
gstbaseaudiosink_class->create_ringbuffer =
@ -773,8 +805,9 @@ gst_jack_audio_sink_init (GstJackAudioSink * sink,
sink->jclient = NULL;
sink->ports = NULL;
sink->port_count = 0;
sink->client_name = g_strdup (DEFAULT_PROP_CLIENT_NAME);
sink->buffers = NULL;
sink->client_name = g_strdup (DEFAULT_PROP_CLIENT_NAME);
sink->transport = DEFAULT_PROP_TRANSPORT;
}
static void
@ -818,6 +851,9 @@ gst_jack_audio_sink_set_property (GObject * object, guint prop_id,
sink->jclient = g_value_get_boxed (value);
}
break;
case PROP_TRANSPORT:
sink->transport = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -845,6 +881,9 @@ gst_jack_audio_sink_get_property (GObject * object, guint prop_id,
case PROP_CLIENT:
g_value_set_boxed (value, sink->jclient);
break;
case PROP_TRANSPORT:
g_value_set_enum (value, sink->transport);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;

View file

@ -59,6 +59,7 @@ struct _GstJackAudioSink {
gchar *server;
jack_client_t *jclient;
gchar *client_name;
GstJackTransport transport;
/* our client */
GstJackAudioClient *client;

View file

@ -211,25 +211,21 @@ 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 */
/*
FIXME: qjackctl's initial transport state is stopped
it can be started using jack_transport_start (jack_client_t *);
need to figure out what the policy here is
if (src->transport == GST_JACK_TRANSPORT_SLAVE) {
GstState state = gst_jack_audio_client_get_transport_state (src->client);
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));
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;
@ -588,6 +584,13 @@ gst_jack_ring_buffer_start (GstRingBuffer * buf)
GST_DEBUG_OBJECT (src, "start");
if (src->transport == GST_JACK_TRANSPORT_MASTER) {
jack_client_t *client;
client = gst_jack_audio_client_get_client (src->client);
jack_transport_start (client);
}
return TRUE;
}
@ -600,6 +603,13 @@ gst_jack_ring_buffer_pause (GstRingBuffer * buf)
GST_DEBUG_OBJECT (src, "pause");
if (src->transport == GST_JACK_TRANSPORT_MASTER) {
jack_client_t *client;
client = gst_jack_audio_client_get_client (src->client);
jack_transport_stop (client);
}
return TRUE;
}
@ -612,6 +622,13 @@ gst_jack_ring_buffer_stop (GstRingBuffer * buf)
GST_DEBUG_OBJECT (src, "stop");
if (src->transport == GST_JACK_TRANSPORT_MASTER) {
jack_client_t *client;
client = gst_jack_audio_client_get_client (src->client);
jack_transport_stop (client);
}
return TRUE;
}
@ -670,6 +687,7 @@ enum
#define DEFAULT_PROP_CONNECT GST_JACK_CONNECT_AUTO
#define DEFAULT_PROP_SERVER NULL
#define DEFAULT_PROP_CLIENT_NAME NULL
#define DEFAULT_PROP_TRANSPORT GST_JACK_TRANSPORT_AUTONOMOUS
enum
{
@ -678,6 +696,7 @@ enum
PROP_SERVER,
PROP_CLIENT,
PROP_CLIENT_NAME,
PROP_TRANSPORT,
PROP_LAST
};
@ -772,6 +791,19 @@ gst_jack_audio_src_class_init (GstJackAudioSrcClass * klass)
GST_PARAM_MUTABLE_READY | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
* GstJackAudioSink:transport
*
* The jack transport behaviour for the client.
*
* Since: 0.10.31
*/
g_object_class_install_property (gobject_class, PROP_TRANSPORT,
g_param_spec_enum ("transport", "Transport mode",
"Jack transport behaviour of the client",
GST_TYPE_JACK_TRANSPORT, DEFAULT_PROP_TRANSPORT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_src_getcaps);
gstbaseaudiosrc_class->create_ringbuffer =
GST_DEBUG_FUNCPTR (gst_jack_audio_src_create_ringbuffer);
@ -783,11 +815,6 @@ gst_jack_audio_src_class_init (GstJackAudioSrcClass * klass)
gst_jack_audio_client_init ();
}
/* initialize the new element
* instantiate pads and add them to element
* set pad calback functions
* initialize instance structure
*/
static void
gst_jack_audio_src_init (GstJackAudioSrc * src, GstJackAudioSrcClass * gclass)
{
@ -799,6 +826,7 @@ gst_jack_audio_src_init (GstJackAudioSrc * src, GstJackAudioSrcClass * gclass)
src->port_count = 0;
src->buffers = NULL;
src->client_name = g_strdup (DEFAULT_PROP_CLIENT_NAME);
src->transport = DEFAULT_PROP_TRANSPORT;
}
static void
@ -840,6 +868,9 @@ gst_jack_audio_src_set_property (GObject * object, guint prop_id,
src->jclient = g_value_get_boxed (value);
}
break;
case PROP_TRANSPORT:
src->transport = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -865,6 +896,9 @@ gst_jack_audio_src_get_property (GObject * object, guint prop_id,
case PROP_CLIENT:
g_value_set_boxed (value, src->jclient);
break;
case PROP_TRANSPORT:
g_value_set_enum (value, src->transport);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;

View file

@ -76,6 +76,7 @@ struct _GstJackAudioSrc
gchar *server;
jack_client_t *jclient;
gchar *client_name;
GstJackTransport transport;
/* our client */
GstJackAudioClient *client;