summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim@centricular.net>2013-05-12 22:41:32 +0100
committerTim-Philipp Müller <tim@centricular.net>2013-05-12 23:42:06 +0100
commit020c93b973a7e601a8f9ac1a0fad808074e130c8 (patch)
tree1018416f6438c75c50e3e7f4b2914fd4157edeeb
parent0c23ac056552102c42fa95a3a5edfeef894a5276 (diff)
downloadgstreamer-plugins-bad-020c93b973a7e601a8f9ac1a0fad808074e130c8.tar.gz
ofa: port to 1.0
-rw-r--r--configure.ac2
-rw-r--r--ext/ofa/Makefile.am4
-rw-r--r--ext/ofa/gstofa.c135
-rw-r--r--ext/ofa/gstofa.h4
-rw-r--r--tests/check/elements/ofa.c65
5 files changed, 92 insertions, 118 deletions
diff --git a/configure.ac b/configure.ac
index 395c64f74..dec7b6110 100644
--- a/configure.ac
+++ b/configure.ac
@@ -346,7 +346,7 @@ GST_PLUGINS_NONPORTED=" cdxaparse \
linsys vcd \
apexsink cdaudio dc1394 dirac directfb \
gsettings \
- musepack nas ofa openal sdl sndfile timidity \
+ musepack nas openal sdl sndfile timidity \
directdraw direct3d9 acm wininet \
xvid lv2 teletextdec sndio osx_video quicktime"
AC_SUBST(GST_PLUGINS_NONPORTED)
diff --git a/ext/ofa/Makefile.am b/ext/ofa/Makefile.am
index 6d1bcc7f6..c896ccb35 100644
--- a/ext/ofa/Makefile.am
+++ b/ext/ofa/Makefile.am
@@ -8,8 +8,8 @@ libgstofa_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
$(OFA_CFLAGS)
libgstofa_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
- -lgstaudio-$(GST_API_VERSION) \
- $(GST_BASE_LIBS) \
+ -lgstaudio-$(GST_API_VERSION) \
+ $(GST_BASE_LIBS) \
$(GST_LIBS) \
$(OFA_LIBS)
diff --git a/ext/ofa/gstofa.c b/ext/ofa/gstofa.c
index 3a78a892c..70d7ae685 100644
--- a/ext/ofa/gstofa.c
+++ b/ext/ofa/gstofa.c
@@ -1,7 +1,4 @@
-/* GStreamer
- *
- * gstofa.c
- *
+/* GStreamer ofa fingerprinting element
* Copyright (C) 2006 M. Derezynski
* Copyright (C) 2008 Eric Buehl
* Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
@@ -31,13 +28,10 @@
#include "gstofa.h"
#define PAD_CAPS \
- "audio/x-raw-int, " \
+ "audio/x-raw, " \
+ "format = { S16LE, S16BE }, " \
"rate = (int) [ 1, MAX ], " \
- "channels = (int) [ 1, 2 ], " \
- "endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
- "width = (int) { 16 }, " \
- "depth = (int) { 16 }, " \
- "signed = (boolean) true"
+ "channels = (int) [ 1, 2 ]"
GST_DEBUG_CATEGORY_STATIC (gst_ofa_debug);
#define GST_CAT_DEFAULT gst_ofa_debug
@@ -48,32 +42,15 @@ enum
PROP_FINGERPRINT,
};
-
-GST_BOILERPLATE (GstOFA, gst_ofa, GstAudioFilter, GST_TYPE_AUDIO_FILTER);
+#define parent_class gst_ofa_parent_class
+G_DEFINE_TYPE (GstOFA, gst_ofa, GST_TYPE_AUDIO_FILTER);
static void gst_ofa_finalize (GObject * object);
static void gst_ofa_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstFlowReturn gst_ofa_transform_ip (GstBaseTransform * trans,
GstBuffer * buf);
-static gboolean gst_ofa_event (GstBaseTransform * trans, GstEvent * event);
-
-static void
-gst_ofa_base_init (gpointer g_class)
-{
- GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
- GstAudioFilterClass *audio_filter_class = (GstAudioFilterClass *) g_class;
- GstCaps *caps;
-
- gst_element_class_set_static_metadata (gstelement_class, "OFA",
- "MusicIP Fingerprinting element",
- "Find a music fingerprint using MusicIP's libofa",
- "Milosz Derezynski <internalerror@gmail.com>, Eric Buehl <eric.buehl@gmail.com>");
-
- caps = gst_caps_from_string (PAD_CAPS);
- gst_audio_filter_class_add_pad_templates (audio_filter_class, caps);
- gst_caps_unref (caps);
-}
+static gboolean gst_ofa_sink_event (GstBaseTransform * trans, GstEvent * event);
static void
gst_ofa_finalize (GObject * object)
@@ -94,34 +71,45 @@ gst_ofa_finalize (GObject * object)
static void
gst_ofa_class_init (GstOFAClass * klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GstBaseTransformClass *gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
+ GstAudioFilterClass *audio_filter_class = GST_AUDIO_FILTER_CLASS (klass);
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstCaps *caps;
- gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_ofa_get_property);
+ gobject_class->get_property = gst_ofa_get_property;
g_object_class_install_property (gobject_class, PROP_FINGERPRINT,
g_param_spec_string ("fingerprint", "Resulting fingerprint",
"Resulting fingerprint", NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ofa_finalize);
+ gobject_class->finalize = gst_ofa_finalize;
gstbasetrans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_ofa_transform_ip);
- gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_ofa_event);
+ gstbasetrans_class->sink_event = GST_DEBUG_FUNCPTR (gst_ofa_sink_event);
gstbasetrans_class->passthrough_on_same_caps = TRUE;
+
+ gst_element_class_set_static_metadata (gstelement_class, "OFA",
+ "MusicIP Fingerprinting element",
+ "Find a music fingerprint using MusicIP's libofa",
+ "Milosz Derezynski <internalerror@gmail.com>, "
+ "Eric Buehl <eric.buehl@gmail.com>");
+
+ caps = gst_caps_from_string (PAD_CAPS);
+ gst_audio_filter_class_add_pad_templates (audio_filter_class, caps);
+ gst_caps_unref (caps);
}
static void
create_fingerprint (GstOFA * ofa)
{
- GstBuffer *buf;
- GstAudioFilter *ofa_filter = GST_AUDIO_FILTER (ofa);
- gint rate = ofa_filter->format.rate;
- gint channels = ofa_filter->format.channels;
- gint endianness =
- ofa_filter->format.bigend ? OFA_BIG_ENDIAN : OFA_LITTLE_ENDIAN;
+ GstAudioFilter *audiofilter = GST_AUDIO_FILTER (ofa);
+ const guint8 *samples;
+ const gchar *fingerprint;
+ gint rate, channels, endianness;
GstTagList *tags;
- guint available;
+ gsize available;
available = gst_adapter_available (ofa->adapter);
@@ -131,52 +119,60 @@ create_fingerprint (GstOFA * ofa)
return;
}
- if (GST_AUDIO_FILTER (ofa)->format.bigend)
+ rate = GST_AUDIO_INFO_RATE (&audiofilter->info);
+ channels = GST_AUDIO_INFO_CHANNELS (&audiofilter->info);
+ if (GST_AUDIO_INFO_ENDIANNESS (&audiofilter->info) == G_BIG_ENDIAN)
endianness = OFA_BIG_ENDIAN;
else
endianness = OFA_LITTLE_ENDIAN;
- GST_DEBUG_OBJECT (ofa, "Generating fingerprint for %u samples",
- available / 2);
+ GST_DEBUG_OBJECT (ofa, "Generating fingerprint for %" G_GSIZE_FORMAT
+ " samples", available / sizeof (gint16));
- buf = gst_adapter_take_buffer (ofa->adapter, available);
+ samples = gst_adapter_map (ofa->adapter, available);
- ofa->fingerprint = g_strdup (ofa_create_print (GST_BUFFER_DATA (buf),
- endianness, GST_BUFFER_SIZE (buf) / 2, rate,
- (channels == 2) ? 1 : 0));
+ fingerprint = ofa_create_print ((unsigned char *) samples, endianness,
+ available / sizeof (gint16), rate, (channels == 2) ? 1 : 0);
- if (ofa->fingerprint) {
- GST_INFO_OBJECT (ofa, "Generated fingerprint: %s", ofa->fingerprint);
- } else {
+ gst_adapter_unmap (ofa->adapter);
+ gst_adapter_flush (ofa->adapter, available);
+
+ if (fingerprint == NULL) {
GST_WARNING_OBJECT (ofa, "Failed to generate fingerprint");
+ goto done;
}
- gst_buffer_unref (buf);
+ GST_INFO_OBJECT (ofa, "Generated fingerprint: %s", fingerprint);
+ ofa->fingerprint = g_strdup (fingerprint);
- if (ofa->fingerprint) {
- tags = gst_tag_list_new ();
- gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE,
- GST_TAG_OFA_FINGERPRINT, ofa->fingerprint, NULL);
- gst_element_found_tags (GST_ELEMENT (ofa), tags);
+ // FIXME: combine with upstream tags
+ tags = gst_tag_list_new (GST_TAG_OFA_FINGERPRINT, ofa->fingerprint, NULL);
+ gst_pad_push_event (GST_BASE_TRANSFORM_SRC_PAD (ofa),
+ gst_event_new_tag (tags));
- g_object_notify (G_OBJECT (ofa), "fingerprint");
- }
+ g_object_notify (G_OBJECT (ofa), "fingerprint");
+
+done:
ofa->record = FALSE;
}
static gboolean
-gst_ofa_event (GstBaseTransform * trans, GstEvent * event)
+gst_ofa_sink_event (GstBaseTransform * trans, GstEvent * event)
{
GstOFA *ofa = GST_OFA (trans);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_STOP:
- case GST_EVENT_NEWSEGMENT:
+ case GST_EVENT_SEGMENT:
GST_DEBUG_OBJECT (ofa, "Got %s event, clearing buffer",
GST_EVENT_TYPE_NAME (event));
gst_adapter_clear (ofa->adapter);
+ /* FIXME: should we really always reset this instead of using an
+ * already-existing fingerprint? Assumes fingerprints are always
+ * extracted in a separate pipeline instead of a live playback
+ * situation */
ofa->record = TRUE;
g_free (ofa->fingerprint);
ofa->fingerprint = NULL;
@@ -192,11 +188,11 @@ gst_ofa_event (GstBaseTransform * trans, GstEvent * event)
break;
}
- return TRUE;
+ return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
}
static void
-gst_ofa_init (GstOFA * ofa, GstOFAClass * g_class)
+gst_ofa_init (GstOFA * ofa)
{
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (ofa), TRUE);
@@ -209,14 +205,17 @@ gst_ofa_init (GstOFA * ofa, GstOFAClass * g_class)
static GstFlowReturn
gst_ofa_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
+ GstAudioFilter *audiofilter = GST_AUDIO_FILTER (trans);
GstOFA *ofa = GST_OFA (trans);
- GstAudioFilter *ofa_filter = GST_AUDIO_FILTER (ofa);
guint64 nframes;
GstClockTime duration;
- gint rate = ofa_filter->format.rate;
- gint channels = ofa_filter->format.channels;
+ gint rate, channels;
+
+ rate = GST_AUDIO_INFO_RATE (&audiofilter->info);
+ channels = GST_AUDIO_INFO_CHANNELS (&audiofilter->info);
- g_return_val_if_fail (rate > 0 && channels > 0, GST_FLOW_NOT_NEGOTIATED);
+ if (rate == 0 || channels == 0)
+ return GST_FLOW_NOT_NEGOTIATED;
if (!ofa->record)
return GST_FLOW_OK;
@@ -253,7 +252,6 @@ static gboolean
plugin_init (GstPlugin * plugin)
{
gboolean ret;
-
int major, minor, rev;
GST_DEBUG_CATEGORY_INIT (gst_ofa_debug, "ofa", 0, "ofa element");
@@ -273,6 +271,7 @@ plugin_init (GstPlugin * plugin)
return ret;
}
+/* FIXME: someone write a libofa replacement with an LGPL or BSD license */
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
ofa,
diff --git a/ext/ofa/gstofa.h b/ext/ofa/gstofa.h
index 347a8ca4c..e719df56e 100644
--- a/ext/ofa/gstofa.h
+++ b/ext/ofa/gstofa.h
@@ -58,7 +58,7 @@ typedef struct _GstOFAClass GstOFAClass;
struct _GstOFA
{
- GstAudioFilter element;
+ GstAudioFilter audiofilter;
/*< private > */
@@ -69,7 +69,7 @@ struct _GstOFA
struct _GstOFAClass
{
- GstAudioFilterClass parent_class;
+ GstAudioFilterClass audiofilter_class;
};
GType gst_ofa_get_type (void);
diff --git a/tests/check/elements/ofa.c b/tests/check/elements/ofa.c
index 1e589d6ef..b12a20d97 100644
--- a/tests/check/elements/ofa.c
+++ b/tests/check/elements/ofa.c
@@ -40,7 +40,6 @@ bus_handler (GstBus * bus, GstMessage * message, gpointer data)
else
gst_message_parse_error (message, &gerror, &debug);
gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
- gst_message_unref (message);
g_error_free (gerror);
g_free (debug);
g_main_loop_quit (loop);
@@ -53,6 +52,13 @@ bus_handler (GstBus * bus, GstMessage * message, gpointer data)
gst_message_parse_tag (message, &tag_list);
+ GST_DEBUG ("tag message: %" GST_PTR_FORMAT, tag_list);
+
+ if (!gst_tag_list_get_value_index (tag_list, "ofa-fingerprint", 0)) {
+ gst_tag_list_unref (tag_list);
+ break;
+ }
+
fail_unless (gst_tag_list_get_string (tag_list, "ofa-fingerprint", &fpr));
p = fpr;
@@ -102,12 +108,8 @@ GST_START_TEST (test_ofa_le_1ch)
capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
fail_unless (capsfilter != NULL);
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "rate", G_TYPE_INT, 44100,
- "channels", G_TYPE_INT, 1,
- "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16LE",
+ "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1, NULL);
g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL);
gst_caps_unref (caps);
@@ -135,7 +137,7 @@ GST_START_TEST (test_ofa_le_1ch)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
- fail_unless (gst_element_query_position (audiotestsrc, &fmt, &position));
+ fail_unless (gst_element_query_position (audiotestsrc, fmt, &position));
fail_unless (position >= 135 * GST_SECOND);
gst_element_set_state (pipeline, GST_STATE_NULL);
@@ -173,12 +175,8 @@ GST_START_TEST (test_ofa_be_1ch)
capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
fail_unless (capsfilter != NULL);
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "rate", G_TYPE_INT, 44100,
- "channels", G_TYPE_INT, 1,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16BE",
+ "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1, NULL);
g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL);
gst_caps_unref (caps);
@@ -206,7 +204,7 @@ GST_START_TEST (test_ofa_be_1ch)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
- fail_unless (gst_element_query_position (audiotestsrc, &fmt, &position));
+ fail_unless (gst_element_query_position (audiotestsrc, fmt, &position));
fail_unless (position >= 135 * GST_SECOND);
gst_element_set_state (pipeline, GST_STATE_NULL);
@@ -243,12 +241,8 @@ GST_START_TEST (test_ofa_le_2ch)
capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
fail_unless (capsfilter != NULL);
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "rate", G_TYPE_INT, 44100,
- "channels", G_TYPE_INT, 2,
- "endianness", G_TYPE_INT, G_LITTLE_ENDIAN,
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16LE",
+ "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 2, NULL);
g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL);
gst_caps_unref (caps);
@@ -276,7 +270,7 @@ GST_START_TEST (test_ofa_le_2ch)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
- fail_unless (gst_element_query_position (audiotestsrc, &fmt, &position));
+ fail_unless (gst_element_query_position (audiotestsrc, fmt, &position));
fail_unless (position >= 135 * GST_SECOND);
gst_element_set_state (pipeline, GST_STATE_NULL);
@@ -314,12 +308,8 @@ GST_START_TEST (test_ofa_be_2ch)
capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
fail_unless (capsfilter != NULL);
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "rate", G_TYPE_INT, 44100,
- "channels", G_TYPE_INT, 2,
- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+ caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S16BE",
+ "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 2, NULL);
g_object_set (G_OBJECT (capsfilter), "caps", caps, NULL);
gst_caps_unref (caps);
@@ -347,7 +337,7 @@ GST_START_TEST (test_ofa_be_2ch)
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
- fail_unless (gst_element_query_position (audiotestsrc, &fmt, &position));
+ fail_unless (gst_element_query_position (audiotestsrc, fmt, &position));
fail_unless (position >= 135 * GST_SECOND);
gst_element_set_state (pipeline, GST_STATE_NULL);
@@ -378,19 +368,4 @@ ofa_suite (void)
return s;
}
-int
-main (int argc, char **argv)
-{
- int nf;
-
- Suite *s = ofa_suite ();
- SRunner *sr = srunner_create (s);
-
- gst_check_init (&argc, &argv);
-
- srunner_run_all (sr, CK_NORMAL);
- nf = srunner_ntests_failed (sr);
- srunner_free (sr);
-
- return nf;
-}
+GST_CHECK_MAIN (ofa)