mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
ofa: remove ofa audio fingerprinting plugin
I think the MusicIP database for this has been defunct for years, so I can't imagine this plugin is particularly useful or still used by anyone. See https://musicbrainz.org/doc/Fingerprinting#PUID Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1153>
This commit is contained in:
parent
40fb39502e
commit
e7c8b23b71
8 changed files with 0 additions and 818 deletions
|
@ -12219,10 +12219,6 @@
|
||||||
"GstNvRCMode::vbr",
|
"GstNvRCMode::vbr",
|
||||||
"GstNvRCMode::vbr-hq",
|
"GstNvRCMode::vbr-hq",
|
||||||
"GstNvRCMode::vbr-minqp",
|
"GstNvRCMode::vbr-minqp",
|
||||||
"GstOFA",
|
|
||||||
"GstOFA!sink",
|
|
||||||
"GstOFA!src",
|
|
||||||
"GstOFA:fingerprint",
|
|
||||||
"GstObject",
|
"GstObject",
|
||||||
"GstObject.flags",
|
"GstObject.flags",
|
||||||
"GstObject.lock",
|
"GstObject.lock",
|
||||||
|
@ -33559,7 +33555,6 @@
|
||||||
"element-nvmpegvideodec",
|
"element-nvmpegvideodec",
|
||||||
"element-nvvp8dec",
|
"element-nvvp8dec",
|
||||||
"element-nvvp9dec",
|
"element-nvvp9dec",
|
||||||
"element-ofa",
|
|
||||||
"element-oggaviparse",
|
"element-oggaviparse",
|
||||||
"element-oggdemux",
|
"element-oggdemux",
|
||||||
"element-oggmux",
|
"element-oggmux",
|
||||||
|
@ -62017,8 +62012,6 @@
|
||||||
"nvvp9dec",
|
"nvvp9dec",
|
||||||
"nvvp9dec!sink",
|
"nvvp9dec!sink",
|
||||||
"nvvp9dec!src",
|
"nvvp9dec!src",
|
||||||
"ofa",
|
|
||||||
"ofa:fingerprint",
|
|
||||||
"oggaviparse",
|
"oggaviparse",
|
||||||
"oggdemux",
|
"oggdemux",
|
||||||
"oggmux",
|
"oggmux",
|
||||||
|
@ -62430,7 +62423,6 @@
|
||||||
"plugin-netsim",
|
"plugin-netsim",
|
||||||
"plugin-nle",
|
"plugin-nle",
|
||||||
"plugin-nvcodec",
|
"plugin-nvcodec",
|
||||||
"plugin-ofa",
|
|
||||||
"plugin-ogg",
|
"plugin-ogg",
|
||||||
"plugin-omx",
|
"plugin-omx",
|
||||||
"plugin-openal",
|
"plugin-openal",
|
||||||
|
|
|
@ -214903,60 +214903,6 @@
|
||||||
"tracers": {},
|
"tracers": {},
|
||||||
"url": "Unknown package origin"
|
"url": "Unknown package origin"
|
||||||
},
|
},
|
||||||
"ofa": {
|
|
||||||
"description": "Calculate MusicIP fingerprint from audio files",
|
|
||||||
"elements": {
|
|
||||||
"ofa": {
|
|
||||||
"author": "Milosz Derezynski <internalerror@gmail.com>, Eric Buehl <eric.buehl@gmail.com>",
|
|
||||||
"description": "Find a music fingerprint using MusicIP's libofa",
|
|
||||||
"hierarchy": [
|
|
||||||
"GstOFA",
|
|
||||||
"GstAudioFilter",
|
|
||||||
"GstBaseTransform",
|
|
||||||
"GstElement",
|
|
||||||
"GstObject",
|
|
||||||
"GInitiallyUnowned",
|
|
||||||
"GObject"
|
|
||||||
],
|
|
||||||
"klass": "MusicIP Fingerprinting element",
|
|
||||||
"long-name": "OFA",
|
|
||||||
"pad-templates": {
|
|
||||||
"sink": {
|
|
||||||
"caps": "audio/x-raw:\n format: { S16LE, S16BE }\n rate: [ 1, 2147483647 ]\n channels: [ 1, 2 ]\n",
|
|
||||||
"direction": "sink",
|
|
||||||
"presence": "always"
|
|
||||||
},
|
|
||||||
"src": {
|
|
||||||
"caps": "audio/x-raw:\n format: { S16LE, S16BE }\n rate: [ 1, 2147483647 ]\n channels: [ 1, 2 ]\n",
|
|
||||||
"direction": "src",
|
|
||||||
"presence": "always"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"fingerprint": {
|
|
||||||
"blurb": "Resulting fingerprint",
|
|
||||||
"conditionally-available": false,
|
|
||||||
"construct": false,
|
|
||||||
"construct-only": false,
|
|
||||||
"controllable": false,
|
|
||||||
"default": "NULL",
|
|
||||||
"mutable": "null",
|
|
||||||
"readable": true,
|
|
||||||
"type": "gchararray",
|
|
||||||
"writable": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rank": "none"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"filename": "gstofa",
|
|
||||||
"license": "GPL",
|
|
||||||
"other-types": {},
|
|
||||||
"package": "GStreamer Bad Plug-ins",
|
|
||||||
"source": "gst-plugins-bad",
|
|
||||||
"tracers": {},
|
|
||||||
"url": "Unknown package origin"
|
|
||||||
},
|
|
||||||
"openal": {
|
"openal": {
|
||||||
"description": "OpenAL plugin library",
|
"description": "OpenAL plugin library",
|
||||||
"elements": {
|
"elements": {
|
||||||
|
|
|
@ -36,7 +36,6 @@ subdir('mpeg2enc')
|
||||||
subdir('mplex')
|
subdir('mplex')
|
||||||
subdir('musepack')
|
subdir('musepack')
|
||||||
subdir('neon')
|
subdir('neon')
|
||||||
subdir('ofa')
|
|
||||||
subdir('onnx')
|
subdir('onnx')
|
||||||
subdir('openal')
|
subdir('openal')
|
||||||
subdir('openaptx')
|
subdir('openaptx')
|
||||||
|
|
|
@ -1,289 +0,0 @@
|
||||||
/* GStreamer ofa fingerprinting element
|
|
||||||
* Copyright (C) 2006 M. Derezynski
|
|
||||||
* Copyright (C) 2008 Eric Buehl
|
|
||||||
* Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Library General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Library General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this library; if not, write to the
|
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
||||||
* Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
|
||||||
#include <ofa1/ofa.h>
|
|
||||||
#include "gstofa.h"
|
|
||||||
|
|
||||||
#define PAD_CAPS \
|
|
||||||
"audio/x-raw, " \
|
|
||||||
"format = { S16LE, S16BE }, " \
|
|
||||||
"rate = (int) [ 1, MAX ], " \
|
|
||||||
"channels = (int) [ 1, 2 ]"
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_ofa_debug);
|
|
||||||
#define GST_CAT_DEFAULT gst_ofa_debug
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PROP_0,
|
|
||||||
PROP_FINGERPRINT,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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_sink_event (GstBaseTransform * trans, GstEvent * event);
|
|
||||||
static gboolean ofa_element_init (GstPlugin * plugin);
|
|
||||||
|
|
||||||
#define parent_class gst_ofa_parent_class
|
|
||||||
G_DEFINE_TYPE (GstOFA, gst_ofa, GST_TYPE_AUDIO_FILTER);
|
|
||||||
GST_ELEMENT_REGISTER_DEFINE_CUSTOM (ofa, ofa_element_init);
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_ofa_finalize (GObject * object)
|
|
||||||
{
|
|
||||||
GstOFA *ofa = GST_OFA (object);
|
|
||||||
|
|
||||||
if (ofa->adapter) {
|
|
||||||
g_object_unref (ofa->adapter);
|
|
||||||
ofa->adapter = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (ofa->fingerprint);
|
|
||||||
ofa->fingerprint = NULL;
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_ofa_class_init (GstOFAClass * 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_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_ofa_finalize;
|
|
||||||
|
|
||||||
gstbasetrans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_ofa_transform_ip);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
GstAudioFilter *audiofilter = GST_AUDIO_FILTER (ofa);
|
|
||||||
const guint8 *samples;
|
|
||||||
const gchar *fingerprint;
|
|
||||||
gint rate, channels, endianness;
|
|
||||||
GstTagList *tags;
|
|
||||||
gsize available;
|
|
||||||
|
|
||||||
available = gst_adapter_available (ofa->adapter);
|
|
||||||
|
|
||||||
if (available == 0) {
|
|
||||||
GST_WARNING_OBJECT (ofa, "No data to take fingerprint from");
|
|
||||||
ofa->record = FALSE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 %" G_GSIZE_FORMAT
|
|
||||||
" samples", available / sizeof (gint16));
|
|
||||||
|
|
||||||
samples = gst_adapter_map (ofa->adapter, available);
|
|
||||||
|
|
||||||
fingerprint = ofa_create_print ((unsigned char *) samples, endianness,
|
|
||||||
available / sizeof (gint16), rate, (channels == 2) ? 1 : 0);
|
|
||||||
|
|
||||||
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_INFO_OBJECT (ofa, "Generated fingerprint: %s", fingerprint);
|
|
||||||
ofa->fingerprint = g_strdup (fingerprint);
|
|
||||||
|
|
||||||
// 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");
|
|
||||||
|
|
||||||
done:
|
|
||||||
|
|
||||||
ofa->record = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
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_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;
|
|
||||||
break;
|
|
||||||
case GST_EVENT_EOS:
|
|
||||||
/* we got to the end of the stream but never generated a fingerprint
|
|
||||||
* (probably under 135 seconds)
|
|
||||||
*/
|
|
||||||
if (!ofa->fingerprint && ofa->record)
|
|
||||||
create_fingerprint (ofa);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_ofa_init (GstOFA * ofa)
|
|
||||||
{
|
|
||||||
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (ofa), TRUE);
|
|
||||||
|
|
||||||
ofa->fingerprint = NULL;
|
|
||||||
ofa->record = TRUE;
|
|
||||||
|
|
||||||
ofa->adapter = gst_adapter_new ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
gst_ofa_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
|
|
||||||
{
|
|
||||||
GstAudioFilter *audiofilter = GST_AUDIO_FILTER (trans);
|
|
||||||
GstOFA *ofa = GST_OFA (trans);
|
|
||||||
guint64 nframes;
|
|
||||||
GstClockTime duration;
|
|
||||||
gint rate, channels;
|
|
||||||
|
|
||||||
rate = GST_AUDIO_INFO_RATE (&audiofilter->info);
|
|
||||||
channels = GST_AUDIO_INFO_CHANNELS (&audiofilter->info);
|
|
||||||
|
|
||||||
if (rate == 0 || channels == 0)
|
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
|
||||||
|
|
||||||
if (!ofa->record)
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
|
|
||||||
gst_adapter_push (ofa->adapter, gst_buffer_copy (buf));
|
|
||||||
|
|
||||||
nframes = gst_adapter_available (ofa->adapter) / (channels * 2);
|
|
||||||
duration = GST_FRAMES_TO_CLOCK_TIME (nframes, rate);
|
|
||||||
|
|
||||||
if (duration >= 135 * GST_SECOND && ofa->fingerprint == NULL)
|
|
||||||
create_fingerprint (ofa);
|
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_ofa_get_property (GObject * object, guint prop_id, GValue * value,
|
|
||||||
GParamSpec * pspec)
|
|
||||||
{
|
|
||||||
GstOFA *ofa = GST_OFA (object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_FINGERPRINT:
|
|
||||||
g_value_set_string (value, ofa->fingerprint);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
ofa_element_init (GstPlugin * plugin)
|
|
||||||
{
|
|
||||||
gboolean ret;
|
|
||||||
int major, minor, rev;
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_ofa_debug, "ofa", 0, "ofa element");
|
|
||||||
|
|
||||||
ofa_get_version (&major, &minor, &rev);
|
|
||||||
|
|
||||||
GST_DEBUG ("libofa %d.%d.%d", major, minor, rev);
|
|
||||||
|
|
||||||
ret = gst_element_register (plugin, "ofa", GST_RANK_NONE, GST_TYPE_OFA);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
/* TODO: get this into core */
|
|
||||||
gst_tag_register (GST_TAG_OFA_FINGERPRINT, GST_TAG_FLAG_META,
|
|
||||||
G_TYPE_STRING, "ofa fingerprint", "OFA fingerprint", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
plugin_init (GstPlugin * plugin)
|
|
||||||
{
|
|
||||||
return GST_ELEMENT_REGISTER (ofa, plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: someone write a libofa replacement with an LGPL or BSD license */
|
|
||||||
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
|
||||||
GST_VERSION_MINOR,
|
|
||||||
ofa,
|
|
||||||
"Calculate MusicIP fingerprint from audio files",
|
|
||||||
plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
|
|
|
@ -1,81 +0,0 @@
|
||||||
/* GStreamer
|
|
||||||
*
|
|
||||||
* gstofa.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 M. Derezynski
|
|
||||||
* Copyright (C) 2008 Eric Buehl
|
|
||||||
* Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Library General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Library General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this library; if not, write to the
|
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
||||||
* Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __GST_OFA_H__
|
|
||||||
#define __GST_OFA_H__
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
|
||||||
#include <gst/base/gstadapter.h>
|
|
||||||
#include <gst/audio/gstaudiofilter.h>
|
|
||||||
#include <gst/audio/audio.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GST_TYPE_OFA \
|
|
||||||
(gst_ofa_get_type())
|
|
||||||
#define GST_OFA(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OFA,GstOFA))
|
|
||||||
#define GST_OFA_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OFA,GstOFAClass))
|
|
||||||
#define GST_IS_OFA(obj) \
|
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OFA))
|
|
||||||
#define GST_IS_OFA_CLASS(klass) \
|
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OFA))
|
|
||||||
|
|
||||||
#define GST_TAG_OFA_FINGERPRINT "ofa-fingerprint"
|
|
||||||
|
|
||||||
typedef struct _GstOFA GstOFA;
|
|
||||||
typedef struct _GstOFAClass GstOFAClass;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GstOFA:
|
|
||||||
*
|
|
||||||
* Opaque #GstOFA data structure
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct _GstOFA
|
|
||||||
{
|
|
||||||
GstAudioFilter audiofilter;
|
|
||||||
|
|
||||||
/*< private > */
|
|
||||||
|
|
||||||
GstAdapter *adapter;
|
|
||||||
char *fingerprint;
|
|
||||||
gboolean record;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GstOFAClass
|
|
||||||
{
|
|
||||||
GstAudioFilterClass audiofilter_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
GType gst_ofa_get_type (void);
|
|
||||||
|
|
||||||
GST_ELEMENT_REGISTER_DECLARE (ofa);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __GST_OFA_H__ */
|
|
|
@ -1,13 +0,0 @@
|
||||||
ofa_dep = dependency('libofa', version: '>= 0.9.3', required: get_option('ofa'))
|
|
||||||
|
|
||||||
if ofa_dep.found()
|
|
||||||
gstofa = library('gstofa', 'gstofa.c',
|
|
||||||
c_args: gst_plugins_bad_args,
|
|
||||||
include_directories: [configinc],
|
|
||||||
dependencies: [gstaudio_dep, ofa_dep],
|
|
||||||
install: true,
|
|
||||||
install_dir: plugins_install_dir,
|
|
||||||
)
|
|
||||||
pkgconfig.generate(gstofa, install_dir: plugins_pkgconfig_install_dir)
|
|
||||||
plugins += [gstofa]
|
|
||||||
endif
|
|
|
@ -132,7 +132,6 @@ option('msdk', type : 'feature', value : 'auto', description : 'Intel Media SDK
|
||||||
option('musepack', type : 'feature', value : 'auto', description : 'libmpcdec Musepack decoder plugin')
|
option('musepack', type : 'feature', value : 'auto', description : 'libmpcdec Musepack decoder plugin')
|
||||||
option('neon', type : 'feature', value : 'auto', description : 'NEON HTTP source plugin')
|
option('neon', type : 'feature', value : 'auto', description : 'NEON HTTP source plugin')
|
||||||
option('nvcodec', type : 'feature', value : 'auto', description : 'NVIDIA GPU codec plugin')
|
option('nvcodec', type : 'feature', value : 'auto', description : 'NVIDIA GPU codec plugin')
|
||||||
option('ofa', type : 'feature', value : 'auto', description : 'Open Fingerprint Architecture library plugin')
|
|
||||||
option('onnx', type : 'feature', value : 'auto', description : 'ONNX neural network plugin')
|
option('onnx', type : 'feature', value : 'auto', description : 'ONNX neural network plugin')
|
||||||
option('openal', type : 'feature', value : 'auto', description : 'OpenAL plugin')
|
option('openal', type : 'feature', value : 'auto', description : 'OpenAL plugin')
|
||||||
option('openexr', type : 'feature', value : 'auto', description : 'OpenEXR plugin')
|
option('openexr', type : 'feature', value : 'auto', description : 'OpenEXR plugin')
|
||||||
|
|
|
@ -1,371 +0,0 @@
|
||||||
/* GStreamer
|
|
||||||
* Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Library General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Library General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this library; if not, write to the
|
|
||||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gst/check/gstcheck.h>
|
|
||||||
|
|
||||||
static gboolean found_fingerprint = FALSE;
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
bus_handler (GstBus * bus, GstMessage * message, gpointer data)
|
|
||||||
{
|
|
||||||
GMainLoop *loop = (GMainLoop *) data;
|
|
||||||
|
|
||||||
switch (message->type) {
|
|
||||||
case GST_MESSAGE_EOS:
|
|
||||||
g_main_loop_quit (loop);
|
|
||||||
break;
|
|
||||||
case GST_MESSAGE_WARNING:
|
|
||||||
case GST_MESSAGE_ERROR:{
|
|
||||||
GError *gerror;
|
|
||||||
gchar *debug;
|
|
||||||
|
|
||||||
if (message->type == GST_MESSAGE_WARNING)
|
|
||||||
gst_message_parse_warning (message, &gerror, &debug);
|
|
||||||
else
|
|
||||||
gst_message_parse_error (message, &gerror, &debug);
|
|
||||||
gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
|
|
||||||
g_error_free (gerror);
|
|
||||||
g_free (debug);
|
|
||||||
g_main_loop_quit (loop);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GST_MESSAGE_TAG:
|
|
||||||
{
|
|
||||||
GstTagList *tag_list;
|
|
||||||
gchar *fpr, *p;
|
|
||||||
|
|
||||||
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;
|
|
||||||
while (*p) {
|
|
||||||
fail_unless (g_ascii_isalnum (*p) || *p == '=' || *p == '+'
|
|
||||||
|| *p == '/');
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (fpr);
|
|
||||||
gst_tag_list_unref (tag_list);
|
|
||||||
|
|
||||||
found_fingerprint = TRUE;
|
|
||||||
|
|
||||||
g_main_loop_quit (loop);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_START_TEST (test_ofa_le_1ch)
|
|
||||||
{
|
|
||||||
GstElement *pipeline;
|
|
||||||
GstElement *audiotestsrc, *audioconvert, *capsfilter, *ofa, *fakesink;
|
|
||||||
|
|
||||||
GstBus *bus;
|
|
||||||
GMainLoop *loop;
|
|
||||||
GstCaps *caps;
|
|
||||||
gint64 position;
|
|
||||||
GstFormat fmt = GST_FORMAT_TIME;
|
|
||||||
guint bus_watch = 0;
|
|
||||||
|
|
||||||
pipeline = gst_pipeline_new ("pipeline");
|
|
||||||
fail_unless (pipeline != NULL);
|
|
||||||
|
|
||||||
audiotestsrc = gst_element_factory_make ("audiotestsrc", "src");
|
|
||||||
fail_unless (audiotestsrc != NULL);
|
|
||||||
g_object_set (G_OBJECT (audiotestsrc), "wave", 0, "freq", 440.0, NULL);
|
|
||||||
|
|
||||||
audioconvert = gst_element_factory_make ("audioconvert", "audioconvert");
|
|
||||||
fail_unless (audioconvert != NULL);
|
|
||||||
g_object_set (G_OBJECT (audioconvert), "dithering", 0, NULL);
|
|
||||||
|
|
||||||
capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
|
|
||||||
fail_unless (capsfilter != 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);
|
|
||||||
|
|
||||||
ofa = gst_element_factory_make ("ofa", "ofa");
|
|
||||||
fail_unless (ofa != NULL);
|
|
||||||
|
|
||||||
fakesink = gst_element_factory_make ("fakesink", "sink");
|
|
||||||
fail_unless (fakesink != NULL);
|
|
||||||
|
|
||||||
gst_bin_add_many (GST_BIN (pipeline), audiotestsrc, audioconvert, capsfilter,
|
|
||||||
ofa, fakesink, NULL);
|
|
||||||
|
|
||||||
fail_unless (gst_element_link_many (audiotestsrc, audioconvert, capsfilter,
|
|
||||||
ofa, fakesink, NULL));
|
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, TRUE);
|
|
||||||
fail_unless (loop != NULL);
|
|
||||||
|
|
||||||
bus = gst_element_get_bus (pipeline);
|
|
||||||
fail_unless (bus != NULL);
|
|
||||||
bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
|
|
||||||
gst_object_unref (bus);
|
|
||||||
|
|
||||||
found_fingerprint = FALSE;
|
|
||||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
|
||||||
g_main_loop_run (loop);
|
|
||||||
|
|
||||||
fail_unless (gst_element_query_position (audiotestsrc, fmt, &position));
|
|
||||||
fail_unless (position >= 135 * GST_SECOND);
|
|
||||||
|
|
||||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
|
||||||
|
|
||||||
fail_unless (found_fingerprint == TRUE);
|
|
||||||
g_object_unref (pipeline);
|
|
||||||
g_main_loop_unref (loop);
|
|
||||||
g_source_remove (bus_watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
|
|
||||||
GST_START_TEST (test_ofa_be_1ch)
|
|
||||||
{
|
|
||||||
GstElement *pipeline;
|
|
||||||
GstElement *audiotestsrc, *audioconvert, *capsfilter, *ofa, *fakesink;
|
|
||||||
GstBus *bus;
|
|
||||||
GMainLoop *loop;
|
|
||||||
GstCaps *caps;
|
|
||||||
gint64 position;
|
|
||||||
GstFormat fmt = GST_FORMAT_TIME;
|
|
||||||
guint bus_watch = 0;
|
|
||||||
|
|
||||||
pipeline = gst_pipeline_new ("pipeline");
|
|
||||||
fail_unless (pipeline != NULL);
|
|
||||||
|
|
||||||
audiotestsrc = gst_element_factory_make ("audiotestsrc", "src");
|
|
||||||
fail_unless (audiotestsrc != NULL);
|
|
||||||
g_object_set (G_OBJECT (audiotestsrc), "wave", 0, "freq", 440.0, NULL);
|
|
||||||
|
|
||||||
audioconvert = gst_element_factory_make ("audioconvert", "audioconvert");
|
|
||||||
fail_unless (audioconvert != NULL);
|
|
||||||
g_object_set (G_OBJECT (audioconvert), "dithering", 0, NULL);
|
|
||||||
|
|
||||||
capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
|
|
||||||
fail_unless (capsfilter != 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);
|
|
||||||
|
|
||||||
ofa = gst_element_factory_make ("ofa", "ofa");
|
|
||||||
fail_unless (ofa != NULL);
|
|
||||||
|
|
||||||
fakesink = gst_element_factory_make ("fakesink", "sink");
|
|
||||||
fail_unless (fakesink != NULL);
|
|
||||||
|
|
||||||
gst_bin_add_many (GST_BIN (pipeline), audiotestsrc, audioconvert, capsfilter,
|
|
||||||
ofa, fakesink, NULL);
|
|
||||||
|
|
||||||
fail_unless (gst_element_link_many (audiotestsrc, audioconvert, capsfilter,
|
|
||||||
ofa, fakesink, NULL));
|
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, TRUE);
|
|
||||||
fail_unless (loop != NULL);
|
|
||||||
|
|
||||||
bus = gst_element_get_bus (pipeline);
|
|
||||||
fail_unless (bus != NULL);
|
|
||||||
bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
|
|
||||||
gst_object_unref (bus);
|
|
||||||
|
|
||||||
found_fingerprint = FALSE;
|
|
||||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
|
||||||
g_main_loop_run (loop);
|
|
||||||
|
|
||||||
fail_unless (gst_element_query_position (audiotestsrc, fmt, &position));
|
|
||||||
fail_unless (position >= 135 * GST_SECOND);
|
|
||||||
|
|
||||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
|
||||||
|
|
||||||
fail_unless (found_fingerprint == TRUE);
|
|
||||||
g_object_unref (pipeline);
|
|
||||||
g_main_loop_unref (loop);
|
|
||||||
g_source_remove (bus_watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
GST_START_TEST (test_ofa_le_2ch)
|
|
||||||
{
|
|
||||||
GstElement *pipeline;
|
|
||||||
GstElement *audiotestsrc, *audioconvert, *capsfilter, *ofa, *fakesink;
|
|
||||||
GstBus *bus;
|
|
||||||
GMainLoop *loop;
|
|
||||||
GstCaps *caps;
|
|
||||||
gint64 position;
|
|
||||||
GstFormat fmt = GST_FORMAT_TIME;
|
|
||||||
guint bus_watch = 0;
|
|
||||||
|
|
||||||
pipeline = gst_pipeline_new ("pipeline");
|
|
||||||
fail_unless (pipeline != NULL);
|
|
||||||
|
|
||||||
audiotestsrc = gst_element_factory_make ("audiotestsrc", "src");
|
|
||||||
fail_unless (audiotestsrc != NULL);
|
|
||||||
g_object_set (G_OBJECT (audiotestsrc), "wave", 0, "freq", 440.0, NULL);
|
|
||||||
|
|
||||||
audioconvert = gst_element_factory_make ("audioconvert", "audioconvert");
|
|
||||||
fail_unless (audioconvert != NULL);
|
|
||||||
g_object_set (G_OBJECT (audioconvert), "dithering", 0, NULL);
|
|
||||||
|
|
||||||
capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
|
|
||||||
fail_unless (capsfilter != 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);
|
|
||||||
|
|
||||||
ofa = gst_element_factory_make ("ofa", "ofa");
|
|
||||||
fail_unless (ofa != NULL);
|
|
||||||
|
|
||||||
fakesink = gst_element_factory_make ("fakesink", "sink");
|
|
||||||
fail_unless (fakesink != NULL);
|
|
||||||
|
|
||||||
gst_bin_add_many (GST_BIN (pipeline), audiotestsrc, audioconvert, capsfilter,
|
|
||||||
ofa, fakesink, NULL);
|
|
||||||
|
|
||||||
fail_unless (gst_element_link_many (audiotestsrc, audioconvert, capsfilter,
|
|
||||||
ofa, fakesink, NULL));
|
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, TRUE);
|
|
||||||
fail_unless (loop != NULL);
|
|
||||||
|
|
||||||
bus = gst_element_get_bus (pipeline);
|
|
||||||
fail_unless (bus != NULL);
|
|
||||||
bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
|
|
||||||
gst_object_unref (bus);
|
|
||||||
|
|
||||||
found_fingerprint = FALSE;
|
|
||||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
|
||||||
g_main_loop_run (loop);
|
|
||||||
|
|
||||||
fail_unless (gst_element_query_position (audiotestsrc, fmt, &position));
|
|
||||||
fail_unless (position >= 135 * GST_SECOND);
|
|
||||||
|
|
||||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
|
||||||
|
|
||||||
fail_unless (found_fingerprint == TRUE);
|
|
||||||
g_object_unref (pipeline);
|
|
||||||
g_main_loop_unref (loop);
|
|
||||||
g_source_remove (bus_watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
|
|
||||||
GST_START_TEST (test_ofa_be_2ch)
|
|
||||||
{
|
|
||||||
GstElement *pipeline;
|
|
||||||
GstElement *audiotestsrc, *audioconvert, *capsfilter, *ofa, *fakesink;
|
|
||||||
GstBus *bus;
|
|
||||||
GMainLoop *loop;
|
|
||||||
GstCaps *caps;
|
|
||||||
gint64 position;
|
|
||||||
GstFormat fmt = GST_FORMAT_TIME;
|
|
||||||
guint bus_watch = 0;
|
|
||||||
|
|
||||||
pipeline = gst_pipeline_new ("pipeline");
|
|
||||||
fail_unless (pipeline != NULL);
|
|
||||||
|
|
||||||
audiotestsrc = gst_element_factory_make ("audiotestsrc", "src");
|
|
||||||
fail_unless (audiotestsrc != NULL);
|
|
||||||
g_object_set (G_OBJECT (audiotestsrc), "wave", 0, "freq", 440.0, NULL);
|
|
||||||
|
|
||||||
audioconvert = gst_element_factory_make ("audioconvert", "audioconvert");
|
|
||||||
fail_unless (audioconvert != NULL);
|
|
||||||
g_object_set (G_OBJECT (audioconvert), "dithering", 0, NULL);
|
|
||||||
|
|
||||||
capsfilter = gst_element_factory_make ("capsfilter", "capsfilter");
|
|
||||||
fail_unless (capsfilter != 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);
|
|
||||||
|
|
||||||
ofa = gst_element_factory_make ("ofa", "ofa");
|
|
||||||
fail_unless (ofa != NULL);
|
|
||||||
|
|
||||||
fakesink = gst_element_factory_make ("fakesink", "sink");
|
|
||||||
fail_unless (fakesink != NULL);
|
|
||||||
|
|
||||||
gst_bin_add_many (GST_BIN (pipeline), audiotestsrc, audioconvert, capsfilter,
|
|
||||||
ofa, fakesink, NULL);
|
|
||||||
|
|
||||||
fail_unless (gst_element_link_many (audiotestsrc, audioconvert, capsfilter,
|
|
||||||
ofa, fakesink, NULL));
|
|
||||||
|
|
||||||
loop = g_main_loop_new (NULL, TRUE);
|
|
||||||
fail_unless (loop != NULL);
|
|
||||||
|
|
||||||
bus = gst_element_get_bus (pipeline);
|
|
||||||
fail_unless (bus != NULL);
|
|
||||||
bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
|
|
||||||
gst_object_unref (bus);
|
|
||||||
|
|
||||||
found_fingerprint = FALSE;
|
|
||||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
|
||||||
g_main_loop_run (loop);
|
|
||||||
|
|
||||||
fail_unless (gst_element_query_position (audiotestsrc, fmt, &position));
|
|
||||||
fail_unless (position >= 135 * GST_SECOND);
|
|
||||||
|
|
||||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
|
||||||
|
|
||||||
fail_unless (found_fingerprint == TRUE);
|
|
||||||
g_object_unref (pipeline);
|
|
||||||
g_main_loop_unref (loop);
|
|
||||||
g_source_remove (bus_watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_END_TEST;
|
|
||||||
|
|
||||||
static Suite *
|
|
||||||
ofa_suite (void)
|
|
||||||
{
|
|
||||||
Suite *s = suite_create ("OFA");
|
|
||||||
TCase *tc_chain = tcase_create ("linear");
|
|
||||||
|
|
||||||
/* time out after 120s, not the default 3 */
|
|
||||||
tcase_set_timeout (tc_chain, 120);
|
|
||||||
|
|
||||||
suite_add_tcase (s, tc_chain);
|
|
||||||
tcase_add_test (tc_chain, test_ofa_le_1ch);
|
|
||||||
tcase_add_test (tc_chain, test_ofa_be_1ch);
|
|
||||||
tcase_add_test (tc_chain, test_ofa_le_2ch);
|
|
||||||
tcase_add_test (tc_chain, test_ofa_be_2ch);
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_CHECK_MAIN (ofa)
|
|
Loading…
Reference in a new issue