summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2013-03-19 10:14:05 +0100
committerWim Taymans <wim.taymans@collabora.co.uk>2013-03-19 10:15:05 +0100
commit4a44dc5ecfe7b5d375ef7df6ff418b82812f688e (patch)
treec90673d33ff65f17289942aa36d3d560122ff922
parent52908193b0b67faf8939fe6bf716d4e163059771 (diff)
port wildmidi
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=696041
-rw-r--r--configure.ac2
-rw-r--r--ext/timidity/gstwildmidi.c236
2 files changed, 129 insertions, 109 deletions
diff --git a/configure.ac b/configure.ac
index 68a439b28..62cfc8863 100644
--- a/configure.ac
+++ b/configure.ac
@@ -328,7 +328,7 @@ GST_PLUGINS_NONPORTED=" aiff \
gsettings ladspa \
musepack musicbrainz nas neon ofa openal rsvg sdl sndfile timidity \
directdraw direct3d9 acm wininet \
- wildmidi xvid lv2 teletextdec sndio wasapi"
+ xvid lv2 teletextdec sndio wasapi"
AC_SUBST(GST_PLUGINS_NONPORTED)
dnl these are all the gst plug-ins, compilable without additional libs
diff --git a/ext/timidity/gstwildmidi.c b/ext/timidity/gstwildmidi.c
index 1ae642b80..5efc0675c 100644
--- a/ext/timidity/gstwildmidi.c
+++ b/ext/timidity/gstwildmidi.c
@@ -32,16 +32,12 @@
* <refsect2>
* <title>Example pipeline</title>
* |[
- * gst-launch filesrc location=song.mid ! wildmidi ! alsasink
+ * gst-launch-1.0 filesrc location=song.mid ! wildmidi ! alsasink
* ]| This example pipeline will parse the midi and render to raw audio which is
* played via alsa.
* </refsect2>
*/
-/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
- * with newer GLib versions (>= 2.31.0) */
-#define GLIB_DISABLE_DEPRECATION_WARNINGS
-
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@@ -84,18 +80,23 @@ enum
static void gst_wildmidi_finalize (GObject * object);
-static gboolean gst_wildmidi_sink_event (GstPad * pad, GstEvent * event);
-static gboolean gst_wildmidi_src_event (GstPad * pad, GstEvent * event);
+static gboolean gst_wildmidi_sink_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
+static gboolean gst_wildmidi_src_event (GstPad * pad, GstObject * parent,
+ GstEvent * event);
static GstStateChangeReturn gst_wildmidi_change_state (GstElement * element,
GstStateChange transition);
-static gboolean gst_wildmidi_activate (GstPad * pad);
-static gboolean gst_wildmidi_activatepull (GstPad * pad, gboolean active);
+static gboolean gst_wildmidi_activate (GstPad * pad, GstObject * parent);
+static gboolean gst_wildmidi_activatemode (GstPad * pad, GstObject * parent,
+ GstPadMode mode, gboolean active);
static void gst_wildmidi_loop (GstPad * sinkpad);
-static GstFlowReturn gst_wildmidi_chain (GstPad * sinkpad, GstBuffer * buffer);
+static GstFlowReturn gst_wildmidi_chain (GstPad * sinkpad, GstObject * parent,
+ GstBuffer * buffer);
-static gboolean gst_wildmidi_src_query (GstPad * pad, GstQuery * query);
+static gboolean gst_wildmidi_src_query (GstPad * pad, GstObject * parent,
+ GstQuery * query);
static void gst_wildmidi_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
@@ -111,27 +112,13 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("audio/x-raw-int, "
+ GST_STATIC_CAPS ("audio/x-raw, "
+ "format = (string) S16LE, "
"rate = (int) 44100, "
- "channels = (int) 2, "
- "endianness = (int) LITTLE_ENDIAN, "
- "width = (int) 16, " "depth = (int) 16, " "signed = (boolean) true"));
-
-GST_BOILERPLATE (GstWildmidi, gst_wildmidi, GstElement, GST_TYPE_ELEMENT);
+ "channels = (int) 2, " "layout = (string) interleaved"));
-static void
-gst_wildmidi_base_init (gpointer gclass)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&src_factory));
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&sink_factory));
- gst_element_class_set_static_metadata (element_class, "WildMidi",
- "Codec/Decoder/Audio",
- "Midi Synthesizer Element", "Wouter Paesen <wouter@blue-gate.be>");
-}
+#define parent_class gst_wildmidi_parent_class
+G_DEFINE_TYPE (GstWildmidi, gst_wildmidi, GST_TYPE_ELEMENT);
static gboolean
wildmidi_open_config (void)
@@ -252,6 +239,14 @@ gst_wildmidi_class_init (GstWildmidiClass * klass)
"High Quality", DEFAULT_HIGH_QUALITY,
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_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sink_factory));
+ gst_element_class_set_static_metadata (gstelement_class, "WildMidi",
+ "Codec/Decoder/Audio",
+ "Midi Synthesizer Element", "Wouter Paesen <wouter@blue-gate.be>");
+
gstelement_class->change_state = gst_wildmidi_change_state;
}
@@ -261,24 +256,18 @@ gst_wildmidi_class_init (GstWildmidiClass * klass)
* initialize structure
*/
static void
-gst_wildmidi_init (GstWildmidi * filter, GstWildmidiClass * g_class)
+gst_wildmidi_init (GstWildmidi * filter)
{
- GstElementClass *klass = GST_ELEMENT_GET_CLASS (filter);
-
- filter->sinkpad =
- gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
- "sink"), "sink");
+ filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
- gst_pad_set_activatepull_function (filter->sinkpad,
- gst_wildmidi_activatepull);
+ gst_pad_set_activatemode_function (filter->sinkpad,
+ gst_wildmidi_activatemode);
gst_pad_set_activate_function (filter->sinkpad, gst_wildmidi_activate);
gst_pad_set_event_function (filter->sinkpad, gst_wildmidi_sink_event);
gst_pad_set_chain_function (filter->sinkpad, gst_wildmidi_chain);
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
- filter->srcpad =
- gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
- "src"), "src");
+ filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
gst_pad_set_query_function (filter->srcpad, gst_wildmidi_src_query);
gst_pad_set_event_function (filter->srcpad, gst_wildmidi_src_event);
@@ -357,17 +346,15 @@ done:
}
static gboolean
-gst_wildmidi_src_query (GstPad * pad, GstQuery * query)
+gst_wildmidi_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
gboolean res = TRUE;
- GstWildmidi *wildmidi = GST_WILDMIDI (gst_pad_get_parent (pad));
+ GstWildmidi *wildmidi = GST_WILDMIDI (parent);
GstFormat src_format, dst_format;
gint64 src_value, dst_value;
- if (!wildmidi->song) {
- gst_object_unref (wildmidi);
+ if (!wildmidi->song)
return FALSE;
- }
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_DURATION:
@@ -377,7 +364,7 @@ gst_wildmidi_src_query (GstPad * pad, GstQuery * query)
break;
case GST_QUERY_POSITION:
gst_query_set_position (query, GST_FORMAT_TIME,
- gst_util_uint64_scale_int (wildmidi->o_segment->last_stop, GST_SECOND,
+ gst_util_uint64_scale_int (wildmidi->o_segment->position, GST_SECOND,
WILDMIDI_RATE));
break;
case GST_QUERY_CONVERT:
@@ -410,7 +397,6 @@ gst_wildmidi_src_query (GstPad * pad, GstQuery * query)
break;
}
- gst_object_unref (wildmidi);
return res;
}
@@ -418,12 +404,13 @@ static GstEvent *
gst_wildmidi_get_new_segment_event (GstWildmidi * wildmidi, GstFormat format)
{
gint64 start, stop, time;
- GstSegment *segment;
+ GstSegment *segment, newseg;
GstEvent *event;
GstFormat src_format;
segment = wildmidi->o_segment;
src_format = segment->format;
+ newseg = *segment;
/* convert the segment values to the target format */
gst_wildmidi_src_convert (wildmidi, src_format, segment->start, &format,
@@ -433,8 +420,12 @@ gst_wildmidi_get_new_segment_event (GstWildmidi * wildmidi, GstFormat format)
gst_wildmidi_src_convert (wildmidi, src_format, segment->time, &format,
&time);
- event = gst_event_new_new_segment_full (FALSE,
- segment->rate, segment->applied_rate, format, start, stop, time);
+ newseg.format = format;
+ newseg.start = start;
+ newseg.stop = stop;
+ newseg.time = time;
+
+ event = gst_event_new_segment (&newseg);
return event;
}
@@ -495,15 +486,15 @@ gst_wildmidi_do_seek (GstWildmidi * wildmidi, GstEvent * event)
GST_PAD_STREAM_LOCK (wildmidi->sinkpad);
if (flush) {
- gst_pad_push_event (wildmidi->srcpad, gst_event_new_flush_stop ());
+ gst_pad_push_event (wildmidi->srcpad, gst_event_new_flush_stop (TRUE));
}
/* update the segment now */
- gst_segment_set_seek (segment, rate, dst_format, flags,
+ gst_segment_do_seek (segment, rate, dst_format, flags,
start_type, start, stop_type, stop, &update);
- /* we need to seek to last_stop in the segment now, sample will be updated */
- sample = segment->last_stop;
+ /* we need to seek to position in the segment now, sample will be updated */
+ sample = segment->position;
GST_OBJECT_LOCK (wildmidi);
#ifdef HAVE_WILDMIDI_0_2_2
@@ -518,7 +509,7 @@ gst_wildmidi_do_seek (GstWildmidi * wildmidi, GstEvent * event)
GST_OBJECT_UNLOCK (wildmidi);
- segment->start = segment->time = segment->last_stop = sample;
+ segment->start = segment->time = segment->position = sample;
gst_pad_push_event (wildmidi->srcpad,
gst_wildmidi_get_new_segment_event (wildmidi, GST_FORMAT_TIME));
@@ -534,10 +525,10 @@ gst_wildmidi_do_seek (GstWildmidi * wildmidi, GstEvent * event)
}
static gboolean
-gst_wildmidi_src_event (GstPad * pad, GstEvent * event)
+gst_wildmidi_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
gboolean res = FALSE;
- GstWildmidi *wildmidi = GST_WILDMIDI (gst_pad_get_parent (pad));
+ GstWildmidi *wildmidi = GST_WILDMIDI (parent);
GST_DEBUG_OBJECT (pad, "%s event received", GST_EVENT_TYPE_NAME (event));
@@ -549,38 +540,71 @@ gst_wildmidi_src_event (GstPad * pad, GstEvent * event)
break;
}
- g_object_unref (wildmidi);
return res;
}
static gboolean
-gst_wildmidi_activate (GstPad * sinkpad)
+gst_wildmidi_activate (GstPad * sinkpad, GstObject * parent)
{
- if (gst_pad_check_pull_range (sinkpad))
- return gst_pad_activate_pull (sinkpad, TRUE);
+ GstQuery *query;
+ gboolean pull_mode;
+
+ query = gst_query_new_scheduling ();
+
+ if (!gst_pad_peer_query (sinkpad, query)) {
+ gst_query_unref (query);
+ goto activate_push;
+ }
+
+ pull_mode = gst_query_has_scheduling_mode_with_flags (query,
+ GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
+ gst_query_unref (query);
+
+ if (!pull_mode)
+ goto activate_push;
- return gst_pad_activate_push (sinkpad, TRUE);
+ GST_DEBUG_OBJECT (sinkpad, "activating pull");
+ return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
+
+activate_push:
+ {
+ GST_DEBUG_OBJECT (sinkpad, "activating push");
+ return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
+ }
}
static gboolean
-gst_wildmidi_activatepull (GstPad * pad, gboolean active)
+gst_wildmidi_activatemode (GstPad * pad, GstObject * parent,
+ GstPadMode mode, gboolean active)
{
- if (active) {
- return gst_pad_start_task (pad, (GstTaskFunction) gst_wildmidi_loop, pad,
- NULL);
- } else {
- return gst_pad_stop_task (pad);
+ gboolean res;
+
+ switch (mode) {
+ case GST_PAD_MODE_PUSH:
+ res = TRUE;
+ break;
+ case GST_PAD_MODE_PULL:
+ if (active) {
+ res = gst_pad_start_task (pad, (GstTaskFunction) gst_wildmidi_loop,
+ pad, NULL);
+ } else {
+ res = gst_pad_stop_task (pad);
+ }
+ break;
+ default:
+ res = FALSE;
+ break;
}
+ return res;
}
static GstBuffer *
gst_wildmidi_clip_buffer (GstWildmidi * wildmidi, GstBuffer * buffer)
{
- gint64 start, stop;
- gint64 new_start, new_stop;
+ guint64 start, stop;
+ guint64 new_start, new_stop;
gint64 offset, length;
- GstBuffer *out;
guint64 bpf;
/* clipping disabled for now */
@@ -603,65 +627,64 @@ gst_wildmidi_clip_buffer (GstWildmidi * wildmidi, GstBuffer * buffer)
length = new_stop - new_start;
bpf = wildmidi->bytes_per_frame;
- out = gst_buffer_create_sub (buffer, offset * bpf, length * bpf);
+ buffer = gst_buffer_make_writable (buffer);
+ gst_buffer_resize (buffer, offset * bpf, length * bpf);
- GST_BUFFER_OFFSET (out) = new_start;
- GST_BUFFER_OFFSET_END (out) = new_stop;
- GST_BUFFER_TIMESTAMP (out) =
+ GST_BUFFER_OFFSET (buffer) = new_start;
+ GST_BUFFER_OFFSET_END (buffer) = new_stop;
+ GST_BUFFER_TIMESTAMP (buffer) =
gst_util_uint64_scale_int (new_start, GST_SECOND, WILDMIDI_RATE);
- GST_BUFFER_DURATION (out) =
+ GST_BUFFER_DURATION (buffer) =
gst_util_uint64_scale_int (new_stop, GST_SECOND, WILDMIDI_RATE) -
- GST_BUFFER_TIMESTAMP (out);
-
- gst_buffer_unref (buffer);
+ GST_BUFFER_TIMESTAMP (buffer);
- return out;
+ return buffer;
}
/* generate audio data and advance internal timers */
static GstBuffer *
gst_wildmidi_get_buffer (GstWildmidi * wildmidi)
{
- size_t bytes_read;
+ size_t size;
gint64 samples;
GstBuffer *buffer;
GstSegment *segment;
- guint8 *data;
- guint size;
+ GstMapInfo info;
guint bpf;
bpf = wildmidi->bytes_per_frame;
buffer = gst_buffer_new_and_alloc (256 * bpf);
- data = GST_BUFFER_DATA (buffer);
- size = GST_BUFFER_SIZE (buffer);
+ gst_buffer_map (buffer, &info, GST_MAP_READWRITE);
GST_OBJECT_LOCK (wildmidi);
- bytes_read = WildMidi_GetOutput (wildmidi->song, (char *) data,
- (unsigned long int) size);
+ size = WildMidi_GetOutput (wildmidi->song, (char *) info.data,
+ (unsigned long int) info.size);
GST_OBJECT_UNLOCK (wildmidi);
- if (bytes_read == 0) {
+ gst_buffer_unmap (buffer, &info);
+
+ if (size == 0) {
gst_buffer_unref (buffer);
return NULL;
}
/* adjust buffer size */
- size = GST_BUFFER_SIZE (buffer) = bytes_read;
+ gst_buffer_resize (buffer, 0, size);
segment = wildmidi->o_segment;
- GST_BUFFER_OFFSET (buffer) = segment->last_stop;
+ GST_BUFFER_OFFSET (buffer) = segment->position;
GST_BUFFER_TIMESTAMP (buffer) =
- gst_util_uint64_scale_int (segment->last_stop, GST_SECOND, WILDMIDI_RATE);
+ gst_util_uint64_scale_int (segment->position, GST_SECOND, WILDMIDI_RATE);
samples = size / bpf;
- segment->last_stop += samples;
+ segment->position += samples;
- GST_BUFFER_OFFSET_END (buffer) = segment->last_stop;
+ GST_BUFFER_OFFSET_END (buffer) = segment->position;
GST_BUFFER_DURATION (buffer) =
- gst_util_uint64_scale_int (segment->last_stop, GST_SECOND,
+ gst_util_uint64_scale_int (segment->position, GST_SECOND,
WILDMIDI_RATE) - GST_BUFFER_TIMESTAMP (buffer);
GST_DEBUG_OBJECT (wildmidi, "buffer ts: %" GST_TIME_FORMAT ", "
@@ -718,8 +741,7 @@ gst_wildmidi_parse_song (GstWildmidi * wildmidi)
gst_caps_unref (outcaps);
/* we keep an internal segment in samples */
- gst_segment_set_newsegment (wildmidi->o_segment, FALSE, 1.0,
- GST_FORMAT_DEFAULT, 0, GST_CLOCK_TIME_NONE, 0);
+ gst_segment_init (wildmidi->o_segment, GST_FORMAT_DEFAULT);
gst_pad_push_event (wildmidi->srcpad,
gst_wildmidi_get_new_segment_event (wildmidi, GST_FORMAT_TIME));
@@ -752,7 +774,6 @@ gst_wildmidi_do_play (GstWildmidi * wildmidi)
wildmidi->discont = FALSE;
}
- gst_buffer_set_caps (out, GST_PAD_CAPS (wildmidi->srcpad));
ret = gst_pad_push (wildmidi->srcpad, out);
return ret;
@@ -761,15 +782,15 @@ gst_wildmidi_do_play (GstWildmidi * wildmidi)
eos:
{
GST_LOG_OBJECT (wildmidi, "Song ended");
- return GST_FLOW_UNEXPECTED;
+ return GST_FLOW_EOS;
}
}
static gboolean
-gst_wildmidi_sink_event (GstPad * pad, GstEvent * event)
+gst_wildmidi_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
gboolean res = FALSE;
- GstWildmidi *wildmidi = GST_WILDMIDI (gst_pad_get_parent (pad));
+ GstWildmidi *wildmidi = GST_WILDMIDI (parent);
GST_DEBUG_OBJECT (pad, "%s event received", GST_EVENT_TYPE_NAME (event));
@@ -787,16 +808,15 @@ gst_wildmidi_sink_event (GstPad * pad, GstEvent * event)
break;
}
- gst_object_unref (wildmidi);
return res;
}
static GstFlowReturn
-gst_wildmidi_chain (GstPad * sinkpad, GstBuffer * buffer)
+gst_wildmidi_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buffer)
{
GstWildmidi *wildmidi;
- wildmidi = GST_WILDMIDI (GST_PAD_PARENT (sinkpad));
+ wildmidi = GST_WILDMIDI (parent);
/* push stuff in the adapter, we will start doing something in the sink event
* handler when we get EOS */
@@ -821,7 +841,7 @@ gst_wildmidi_loop (GstPad * sinkpad)
ret =
gst_pad_pull_range (wildmidi->sinkpad, wildmidi->offset, -1, &buffer);
- if (ret == GST_FLOW_UNEXPECTED) {
+ if (ret == GST_FLOW_EOS) {
GST_DEBUG_OBJECT (wildmidi, "Song loaded");
wildmidi->state = GST_WILDMIDI_STATE_PARSE;
} else if (ret != GST_FLOW_OK) {
@@ -831,7 +851,7 @@ gst_wildmidi_loop (GstPad * sinkpad)
} else {
GST_DEBUG_OBJECT (wildmidi, "pushing buffer");
gst_adapter_push (wildmidi->adapter, buffer);
- wildmidi->offset += GST_BUFFER_SIZE (buffer);
+ wildmidi->offset += gst_buffer_get_size (buffer);
}
break;
}
@@ -858,11 +878,11 @@ pause:
GST_DEBUG_OBJECT (wildmidi, "pausing task, reason %s", reason);
gst_pad_pause_task (sinkpad);
- if (ret == GST_FLOW_UNEXPECTED) {
+ if (ret == GST_FLOW_EOS) {
/* perform EOS logic */
event = gst_event_new_eos ();
gst_pad_push_event (wildmidi->srcpad, event);
- } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
+ } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
event = gst_event_new_eos ();
/* for fatal errors we post an error message, post the error
* first so the app knows about the error first. */