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 ())
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define GST_JACK_FORMAT_STR "F32LE"
+#else
+#define GST_JACK_FORMAT_STR "F32BE"
+#endif
+
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_
gint i, j, flen, channels;
sample_t *data;
- buf = GST_RING_BUFFER_CAST (arg);
+ buf = GST_AUDIO_RING_BUFFER_CAST (arg);
sink = GST_JACK_AUDIO_SINK (GST_OBJECT_PARENT (buf));
- channels = buf->spec.channels;
-
+ channels = GST_AUDIO_INFO_CHANNELS (&buf->spec.info);
+
+ /* handle transport state requisitions */
+ 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));
+ }
+ }
+
/* get target buffers */
for (i = 0; i < channels; i++) {
sink->buffers[i] =
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));
+
+ gst_element_class_set_details_simple (gstelement_class, "Audio Sink (Jack)",
+ "Sink/Audio", "Output audio to a JACK server",
+ "Wim Taymans <wim.taymans@gmail.com>");
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&jackaudiosink_sink_factory));
+
gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_sink_getcaps);
- gstbaseaudiosink_class->create_ringbuffer =
+ gstaudiobasesink_class->create_ringbuffer =
GST_DEBUG_FUNCPTR (gst_jack_audio_sink_create_ringbuffer);
/* ref class from a thread-safe context to work around missing bit of
gint channels, i, j, flen;
sample_t *data;
- buf = GST_RING_BUFFER_CAST (arg);
+ buf = GST_AUDIO_RING_BUFFER_CAST (arg);
src = GST_JACK_AUDIO_SRC (GST_OBJECT_PARENT (buf));
- channels = buf->spec.channels;
-
+ channels = GST_AUDIO_INFO_CHANNELS (&buf->spec.info);
+
+ /* handle transport state requisitions */
+ 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));
+ }
+ }
+
/* get input buffers */
for (i = 0; i < channels; i++)
src->buffers[i] =
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));
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&src_factory));
+
+ gst_element_class_set_details_simple (gstelement_class, "Audio Source (Jack)",
+ "Source/Audio", "Captures audio from a JACK server",
+ "Tristan Matthews <tristan@sat.qc.ca>");
+
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_jack_audio_src_getcaps);
- gstbaseaudiosrc_class->create_ringbuffer =
+ gstaudiobasesrc_class->create_ringbuffer =
GST_DEBUG_FUNCPTR (gst_jack_audio_src_create_ringbuffer);
/* ref class from a thread-safe context to work around missing bit of
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)
+gst_jack_audio_src_init (GstJackAudioSrc * src)
{
//gst_base_src_set_live(GST_BASE_SRC (src), TRUE);
src->connect = DEFAULT_PROP_CONNECT;
break;
}
- return gst_pad_event_default (pad, event);
+ return gst_pad_event_default (pad, parent, event);
}
+
+ static void
+ gst_matroska_mux_free_codec_priv (GstMatroskaTrackContext * context)
+ {
+ if (context->codec_priv != NULL) {
+ g_free (context->codec_priv);
+ context->codec_priv = NULL;
+ context->codec_priv_size = 0;
+ }
+ }
+
static void
gst_matroska_mux_build_vobsub_private (GstMatroskaTrackContext * context,
const guint * clut)
} else if (!strcmp (mimetype, "video/x-h264")) {
gst_matroska_mux_set_codec_id (context,
GST_MATROSKA_CODEC_ID_VIDEO_MPEG4_AVC);
-
- if (context->codec_priv != NULL) {
- g_free (context->codec_priv);
- context->codec_priv = NULL;
- context->codec_priv_size = 0;
- }
-
+ gst_matroska_mux_free_codec_priv (context);
/* Create avcC header */
if (codec_buf != NULL) {
- context->codec_priv_size = GST_BUFFER_SIZE (codec_buf);
+ context->codec_priv_size = gst_buffer_get_size (codec_buf);
context->codec_priv = g_malloc0 (context->codec_priv_size);
- memcpy (context->codec_priv, GST_BUFFER_DATA (codec_buf),
- context->codec_priv_size);
+ gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
}
} else if (!strcmp (mimetype, "video/x-theora")) {
const GValue *streamheader;
/* global headers may be in codec data */
if (codec_buf != NULL) {
- context->codec_priv_size = GST_BUFFER_SIZE (codec_buf);
+ gst_matroska_mux_free_codec_priv (context);
+ context->codec_priv_size = gst_buffer_get_size (codec_buf);
context->codec_priv = g_malloc0 (context->codec_priv_size);
- memcpy (context->codec_priv, GST_BUFFER_DATA (codec_buf),
- context->codec_priv_size);
+ gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
}
} else if (!strcmp (mimetype, "video/x-msmpeg")) {
msmpeg43:
GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);
- priv_data_size = GST_BUFFER_SIZE (codec_data_buf);
+ priv_data_size = gst_buffer_get_size (codec_data_buf);
priv_data = g_malloc0 (priv_data_size);
- memcpy (priv_data, GST_BUFFER_DATA (codec_data_buf), priv_data_size);
+ gst_buffer_extract (codec_data_buf, 0, priv_data, -1);
+ gst_matroska_mux_free_codec_priv (context);
context->codec_priv = priv_data;
context->codec_priv_size = priv_data_size;
}
}
for (i = 0; i < bufarr->len; ++i) {
- memcpy (priv_data + offset, GST_BUFFER_DATA (buf[i]),
- GST_BUFFER_SIZE (buf[i]));
- offset += GST_BUFFER_SIZE (buf[i]);
+ gst_buffer_extract (buf[i], 0, priv_data + offset, -1);
+ offset += gst_buffer_get_size (buf[i]);
}
+ gst_matroska_mux_free_codec_priv (context);
context->codec_priv = priv_data;
context->codec_priv_size = priv_data_size;
return FALSE;
}
- context->codec_priv = g_malloc (GST_BUFFER_SIZE (buffer) - 9);
- context->codec_priv_size = GST_BUFFER_SIZE (buffer) - 9;
- memcpy (context->codec_priv, GST_BUFFER_DATA (buffer) + 9,
- GST_BUFFER_SIZE (buffer) - 9);
+ gst_matroska_mux_free_codec_priv (context);
+ context->codec_priv_size = gst_buffer_get_size (buffer) - 9;
+ context->codec_priv = g_malloc (context->codec_priv_size);
+ gst_buffer_extract (buffer, 9, context->codec_priv, -1);
for (i = 1; i < bufarr->len; i++) {
+ guint old_size;
bufval = &g_array_index (bufarr, GValue, i);
if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
return FALSE;
}
- context->codec_priv = g_malloc (GST_BUFFER_SIZE (buffer));
- context->codec_priv_size = GST_BUFFER_SIZE (buffer);
- memcpy (context->codec_priv, GST_BUFFER_DATA (buffer),
- GST_BUFFER_SIZE (buffer));
+ gst_matroska_mux_free_codec_priv (context);
+ context->codec_priv_size = gst_buffer_get_size (buffer);
+ context->codec_priv = g_malloc (context->codec_priv_size);
+ gst_buffer_extract (buffer, 0, context->codec_priv, -1);
bufval = &g_array_index (bufarr, GValue, 1);
GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);
- priv_data_size = GST_BUFFER_SIZE (codec_data_buf);
+ priv_data_size = gst_buffer_get_size (codec_data_buf);
priv_data = g_malloc0 (priv_data_size);
- memcpy (priv_data, GST_BUFFER_DATA (codec_data_buf), priv_data_size);
+ gst_buffer_extract (codec_data_buf, 0, priv_data, -1);
+ gst_matroska_mux_free_codec_priv (context);
+
context->codec_priv = priv_data;
context->codec_priv_size = priv_data_size;
}
return TRUE;
}
- if (context->codec_priv != NULL)
- g_free (context->codec_priv);
+ gst_matroska_mux_free_codec_priv (context);
priv_data = g_malloc0 (priv_data_size);
- memcpy (priv_data, GST_BUFFER_DATA (buf), priv_data_size);
+ memcpy (priv_data, priv_buffer_data, priv_data_size);
context->codec_priv = priv_data;
context->codec_priv_size = priv_data_size;
+ gst_buffer_unmap (buf, priv_buffer_data, priv_data_size);
}
GST_DEBUG_OBJECT (pad, "codec_id %s, codec data size %u",
NULL);
else
gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_ATTACHMENT,
- tagbuffer, NULL);
+ tagsample, NULL);
+
- /* the tag list adds it own ref */
- gst_buffer_unref (tagbuffer);
++ /* the list adds it own ref */
++ gst_buffer_unref (tagsample);
}
g_free (filename);