Commit bc1fa747 authored by Stefan Sauer's avatar Stefan Sauer

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.
parent 834e58be
......@@ -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)
......
......@@ -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_
......@@ -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
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 (sink->transport == GST_JACK_TRANSPORT_SLAVE) {
GstState 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;
......@@ -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;
......
......@@ -59,6 +59,7 @@ struct _GstJackAudioSink {
gchar *server;
jack_client_t *jclient;
gchar *client_name;
GstJackTransport transport;
/* our client */
GstJackAudioClient *client;
......
......@@ -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
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 (src->transport == GST_JACK_TRANSPORT_SLAVE) {
GstState 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;
......@@ -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;
......
......@@ -76,6 +76,7 @@ struct _GstJackAudioSrc
gchar *server;
jack_client_t *jclient;
gchar *client_name;
GstJackTransport transport;
/* our client */
GstJackAudioClient *client;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment