summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2012-01-25 13:22:43 +0100
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-01-25 13:22:43 +0100
commita2a430024136fd947637ff56a4fea6a2689ca59d (patch)
tree8cab3177242814f02b1e49a51d81b5f2f1660621 /ext
parent071c6e8f15f2afff7ca4ce5934c3bae1d76aea95 (diff)
parent8fb0beaf00aeae2ef6081d08f0d74d6e655a53da (diff)
Merge branch 'master' into 0.11
Conflicts: configure.ac ext/kate/gstkateenc.c gst/colorspace/colorspace.c gst/mpegvideoparse/mpegvideoparse.c
Diffstat (limited to 'ext')
-rw-r--r--ext/Makefile.am8
-rw-r--r--ext/chromaprint/Makefile.am14
-rw-r--r--ext/chromaprint/gstchromaprint.c317
-rw-r--r--ext/chromaprint/gstchromaprint.h77
-rw-r--r--ext/cog/gstcogmse.c8
-rw-r--r--ext/gme/gstgme.c2
-rw-r--r--ext/gsm/gstgsmdec.c257
-rw-r--r--ext/gsm/gstgsmdec.h20
-rw-r--r--ext/gsm/gstgsmenc.c147
-rw-r--r--ext/gsm/gstgsmenc.h12
-rw-r--r--ext/kate/gstkateenc.c41
-rw-r--r--ext/opencv/gsttemplatematch.c2
-rw-r--r--ext/resindvd/resindvdbin.c23
-rw-r--r--ext/resindvd/resindvdsrc.c1
-rw-r--r--ext/resindvd/rsnaudiomunge.c2
-rw-r--r--ext/resindvd/rsndec.c34
-rw-r--r--ext/rsvg/gstrsvgoverlay.c13
-rw-r--r--ext/schroedinger/gstschrodec.c27
-rw-r--r--ext/schroedinger/gstschroenc.c27
-rw-r--r--ext/schroedinger/gstschroutils.c23
-rw-r--r--ext/schroedinger/gstschroutils.h6
-rw-r--r--ext/spc/gstspc.c2
-rw-r--r--ext/vp8/gstvp8enc.c3
23 files changed, 730 insertions, 336 deletions
diff --git a/ext/Makefile.am b/ext/Makefile.am
index dc62386ca..a1636f690 100644
--- a/ext/Makefile.am
+++ b/ext/Makefile.am
@@ -58,6 +58,12 @@ else
CELT_DIR=
endif
+if USE_CHROMAPRINT
+CHROMAPRINT_DIR=chromaprint
+else
+CHROMAPRINT_DIR=
+endif
+
if USE_COG
COG_DIR=cog
else
@@ -397,6 +403,7 @@ SUBDIRS=\
$(BZ2_DIR) \
$(CDAUDIO_DIR) \
$(CELT_DIR) \
+ $(CHROMAPRINT_DIR) \
$(COG_DIR) \
$(CURL_DIR) \
$(DC1394_DIR) \
@@ -456,6 +463,7 @@ DIST_SUBDIRS = \
bz2 \
cdaudio \
celt \
+ chromaprint \
cog \
curl \
dc1394 \
diff --git a/ext/chromaprint/Makefile.am b/ext/chromaprint/Makefile.am
new file mode 100644
index 000000000..115d8c298
--- /dev/null
+++ b/ext/chromaprint/Makefile.am
@@ -0,0 +1,14 @@
+plugin_LTLIBRARIES = libgstchromaprint.la
+
+libgstchromaprint_la_SOURCES = gstchromaprint.c gstchromaprint.h
+
+libgstchromaprint_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) \
+ $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
+ $(CHROMAPRINT_CFLAGS)
+libgstchromaprint_la_LIBADD = \
+ $(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) $(GST_LIBS) \
+ $(CHROMAPRINT_LIBS)
+libgstchromaprint_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstchromaprint_la_LIBTOOLFLAGS = --tag=disable-static
+
+noinst_HEADERS = gstchromaprint.h
diff --git a/ext/chromaprint/gstchromaprint.c b/ext/chromaprint/gstchromaprint.c
new file mode 100644
index 000000000..c0a129301
--- /dev/null
+++ b/ext/chromaprint/gstchromaprint.c
@@ -0,0 +1,317 @@
+/* GStreamer chromaprint audio fingerprinting element
+ * Copyright (C) 2006 M. Derezynski
+ * Copyright (C) 2008 Eric Buehl
+ * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
+ * Copyright (C) 2011 Lukáš Lalinský <lalinsky@gmail.com>
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:element-chromaprint
+ *
+ * The chromaprint element calculates an acoustic fingerprint for an
+ * audio stream which can be used to identify a song and look up
+ * further metadata from the <ulink url="http://acoustid.org/">Acoustid</ulink>
+ * and Musicbrainz databases.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch -m uridecodebin uri=file:///path/to/song.ogg ! audioconvert ! chromaprint ! fakesink
+ * ]|
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gstchromaprint.h"
+
+#define DEFAULT_MAX_DURATION 120
+
+#define PAD_CAPS \
+ "audio/x-raw-int, " \
+ "rate = (int) [ 1, MAX ], " \
+ "channels = (int) [ 1, 2 ], " \
+ "endianness = (int) { BYTE_ORDER }, " \
+ "width = (int) { 16 }, " \
+ "depth = (int) { 16 }, " \
+ "signed = (boolean) true"
+
+GST_DEBUG_CATEGORY_STATIC (gst_chromaprint_debug);
+#define GST_CAT_DEFAULT gst_chromaprint_debug
+
+enum
+{
+ PROP_0,
+ PROP_FINGERPRINT,
+ PROP_MAX_DURATION
+};
+
+
+GST_BOILERPLATE (GstChromaprint, gst_chromaprint, GstElement,
+ GST_TYPE_AUDIO_FILTER);
+
+static void gst_chromaprint_finalize (GObject * object);
+static void gst_chromaprint_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_chromaprint_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+static GstFlowReturn gst_chromaprint_transform_ip (GstBaseTransform * trans,
+ GstBuffer * buf);
+static gboolean gst_chromaprint_event (GstBaseTransform * trans,
+ GstEvent * event);
+
+static void
+gst_chromaprint_base_init (gpointer g_class)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
+ GstAudioFilterClass *audio_filter_class = (GstAudioFilterClass *) g_class;
+ GstCaps *caps;
+
+ gst_element_class_set_details_simple (element_class,
+ "Chromaprint fingerprinting element",
+ "Filter/Analyzer/Audio",
+ "Find an audio fingerprint using the Chromaprint library",
+ "Lukáš Lalinský <lalinsky@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
+gst_chromaprint_class_init (GstChromaprintClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstBaseTransformClass *gstbasetrans_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
+
+ gobject_class->set_property = gst_chromaprint_set_property;
+ gobject_class->get_property = gst_chromaprint_get_property;
+
+ /* FIXME: do we need this in addition to the tag message ? */
+ g_object_class_install_property (gobject_class, PROP_FINGERPRINT,
+ g_param_spec_string ("fingerprint", "Resulting fingerprint",
+ "Resulting fingerprint", NULL, G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class, PROP_MAX_DURATION,
+ g_param_spec_uint ("duration", "Duration limit",
+ "Number of seconds of audio to use for fingerprinting",
+ 0, G_MAXUINT, DEFAULT_MAX_DURATION,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_chromaprint_finalize);
+
+ gstbasetrans_class->transform_ip =
+ GST_DEBUG_FUNCPTR (gst_chromaprint_transform_ip);
+ gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_chromaprint_event);
+ gstbasetrans_class->passthrough_on_same_caps = TRUE;
+}
+
+static void
+gst_chromaprint_reset (GstChromaprint * chromaprint)
+{
+ if (chromaprint->fingerprint) {
+ chromaprint_dealloc (chromaprint->fingerprint);
+ chromaprint->fingerprint = NULL;
+ }
+
+ chromaprint->nsamples = 0;
+ chromaprint->duration = 0;
+ chromaprint->record = TRUE;
+}
+
+static void
+gst_chromaprint_create_fingerprint (GstChromaprint * chromaprint)
+{
+ GstTagList *tags;
+
+ if (chromaprint->duration <= 3)
+ return;
+
+ GST_DEBUG_OBJECT (chromaprint,
+ "Generating fingerprint based on %d seconds of audio",
+ chromaprint->duration);
+
+ chromaprint_finish (chromaprint->context);
+ chromaprint_get_fingerprint (chromaprint->context, &chromaprint->fingerprint);
+ chromaprint->record = FALSE;
+
+ tags = gst_tag_list_new_full (GST_TAG_CHROMAPRINT_FINGERPRINT,
+ chromaprint->fingerprint, NULL);
+
+ gst_element_found_tags (GST_ELEMENT (chromaprint), tags);
+}
+
+static void
+gst_chromaprint_init (GstChromaprint * chromaprint,
+ GstChromaprintClass * gclass)
+{
+ gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (chromaprint), TRUE);
+
+ chromaprint->context = chromaprint_new (CHROMAPRINT_ALGORITHM_DEFAULT);
+ chromaprint->fingerprint = NULL;
+ chromaprint->max_duration = DEFAULT_MAX_DURATION;
+ gst_chromaprint_reset (chromaprint);
+}
+
+static void
+gst_chromaprint_finalize (GObject * object)
+{
+ GstChromaprint *chromaprint = GST_CHROMAPRINT (object);
+
+ chromaprint->record = FALSE;
+
+ if (chromaprint->context) {
+ chromaprint_free (chromaprint->context);
+ chromaprint->context = NULL;
+ }
+
+ if (chromaprint->fingerprint) {
+ chromaprint_dealloc (chromaprint->fingerprint);
+ chromaprint->fingerprint = NULL;
+ }
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static GstFlowReturn
+gst_chromaprint_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
+{
+ GstChromaprint *chromaprint = GST_CHROMAPRINT (trans);
+ gint rate = GST_AUDIO_FILTER (chromaprint)->format.rate;
+ gint channels = GST_AUDIO_FILTER (chromaprint)->format.channels;
+ guint nsamples;
+
+ if (G_UNLIKELY (rate <= 0 || channels <= 0))
+ return GST_FLOW_NOT_NEGOTIATED;
+
+ if (!chromaprint->record)
+ return GST_FLOW_OK;
+
+ nsamples = GST_BUFFER_SIZE (buf) / (channels * 2);
+
+ if (nsamples == 0)
+ return GST_FLOW_OK;
+
+ if (chromaprint->nsamples == 0) {
+ chromaprint_start (chromaprint->context, rate, channels);
+ }
+ chromaprint->nsamples += nsamples;
+ chromaprint->duration = chromaprint->nsamples / rate;
+
+ chromaprint_feed (chromaprint->context, GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf) / 2);
+
+ if (chromaprint->duration >= chromaprint->max_duration
+ && !chromaprint->fingerprint) {
+ gst_chromaprint_create_fingerprint (chromaprint);
+ }
+
+ return GST_FLOW_OK;
+}
+
+static gboolean
+gst_chromaprint_event (GstBaseTransform * trans, GstEvent * event)
+{
+ GstChromaprint *chromaprint = GST_CHROMAPRINT (trans);
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_FLUSH_STOP:
+ case GST_EVENT_NEWSEGMENT:
+ GST_DEBUG_OBJECT (trans, "Got %s event, clearing buffer",
+ GST_EVENT_TYPE_NAME (event));
+ gst_chromaprint_reset (chromaprint);
+ break;
+ case GST_EVENT_EOS:
+ if (!chromaprint->fingerprint) {
+ gst_chromaprint_create_fingerprint (chromaprint);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static void
+gst_chromaprint_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstChromaprint *chromaprint = GST_CHROMAPRINT (object);
+
+ switch (prop_id) {
+ case PROP_MAX_DURATION:
+ chromaprint->max_duration = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_chromaprint_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstChromaprint *chromaprint = GST_CHROMAPRINT (object);
+
+ switch (prop_id) {
+ case PROP_FINGERPRINT:
+ g_value_set_string (value, chromaprint->fingerprint);
+ break;
+ case PROP_MAX_DURATION:
+ g_value_set_uint (value, chromaprint->max_duration);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+ gboolean ret;
+
+ GST_DEBUG_CATEGORY_INIT (gst_chromaprint_debug, "chromaprint",
+ 0, "chromaprint element");
+
+ GST_INFO ("libchromaprint %s", chromaprint_get_version ());
+
+ ret = gst_element_register (plugin, "chromaprint", GST_RANK_NONE,
+ GST_TYPE_CHROMAPRINT);
+
+ if (ret) {
+ gst_tag_register (GST_TAG_CHROMAPRINT_FINGERPRINT, GST_TAG_FLAG_META,
+ G_TYPE_STRING, "chromaprint fingerprint", "Chromaprint fingerprint",
+ NULL);
+ }
+
+ return ret;
+}
+
+GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "chromaprint",
+ "Calculate Chromaprint fingerprint from audio files",
+ plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/ext/chromaprint/gstchromaprint.h b/ext/chromaprint/gstchromaprint.h
new file mode 100644
index 000000000..12bad8a13
--- /dev/null
+++ b/ext/chromaprint/gstchromaprint.h
@@ -0,0 +1,77 @@
+/* GStreamer chromaprint audio fingerprinting element
+ * Copyright (C) 2006 M. Derezynski
+ * Copyright (C) 2008 Eric Buehl
+ * Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
+ * Copyright (C) 2011 Lukáš Lalinský <<user@hostname.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_CHROMAPRINT_H__
+#define __GST_CHROMAPRINT_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstadapter.h>
+#include <gst/audio/gstaudiofilter.h>
+#include <gst/audio/audio.h>
+#include <chromaprint.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_CHROMAPRINT \
+ (gst_chromaprint_get_type())
+#define GST_CHROMAPRINT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CHROMAPRINT,GstChromaprint))
+#define GST_CHROMAPRINT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CHROMAPRINT,GstChromaprintClass))
+#define GST_IS_CHROMAPRINT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CHROMAPRINT))
+#define GST_IS_CHROMAPRINT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CHROMAPRINT))
+
+#define GST_TAG_CHROMAPRINT_FINGERPRINT "chromaprint-fingerprint"
+
+typedef struct _GstChromaprint GstChromaprint;
+typedef struct _GstChromaprintClass GstChromaprintClass;
+
+/**
+ * GstChromaprint:
+ *
+ * Opaque #GstChromaprint element structure
+ */
+struct _GstChromaprint
+{
+ GstAudioFilter element;
+
+ /*< private >*/
+ ChromaprintContext * context;
+ char * fingerprint;
+ gboolean record;
+ guint64 nsamples;
+ guint duration;
+ guint max_duration;
+};
+
+struct _GstChromaprintClass
+{
+ GstAudioFilterClass parent_class;
+};
+
+GType gst_chromaprint_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_CHROMAPRINT_H__ */
diff --git a/ext/cog/gstcogmse.c b/ext/cog/gstcogmse.c
index 3ce16a37b..ad38d8dfb 100644
--- a/ext/cog/gstcogmse.c
+++ b/ext/cog/gstcogmse.c
@@ -208,6 +208,9 @@ gst_mse_finalize (GObject * object)
gst_object_unref (fs->sinkpad_test);
g_mutex_free (fs->lock);
g_cond_free (fs->cond);
+ gst_buffer_replace (&fs->buffer_ref, NULL);
+
+ GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}
static GstCaps *
@@ -243,7 +246,7 @@ gst_mse_getcaps (GstPad * pad)
}
if (pad != fs->sinkpad_test) {
- peercaps = gst_pad_peer_get_caps (fs->sinkpad_ref);
+ peercaps = gst_pad_peer_get_caps (fs->sinkpad_test);
if (peercaps) {
icaps = gst_caps_intersect (caps, peercaps);
gst_caps_unref (caps);
@@ -310,6 +313,7 @@ gst_mse_reset (GstMSE * fs)
fs->luma_mse_sum = 0;
fs->chroma_mse_sum = 0;
fs->n_frames = 0;
+ fs->cancel = FALSE;
if (fs->buffer_ref) {
gst_buffer_unref (fs->buffer_ref);
@@ -435,9 +439,11 @@ gst_mse_sink_event (GstPad * pad, GstEvent * event)
break;
case GST_EVENT_FLUSH_START:
GST_DEBUG ("flush start");
+ fs->cancel = TRUE;
break;
case GST_EVENT_FLUSH_STOP:
GST_DEBUG ("flush stop");
+ fs->cancel = FALSE;
break;
default:
break;
diff --git a/ext/gme/gstgme.c b/ext/gme/gstgme.c
index 7a70c7a3c..75d9ff423 100644
--- a/ext/gme/gstgme.c
+++ b/ext/gme/gstgme.c
@@ -161,6 +161,8 @@ gst_gme_dec_dispose (GObject * object)
g_object_unref (gme->adapter);
gme->adapter = NULL;
}
+
+ GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
}
static GstFlowReturn
diff --git a/ext/gsm/gstgsmdec.c b/ext/gsm/gstgsmdec.c
index 3318bdc77..2bf475f26 100644
--- a/ext/gsm/gstgsmdec.c
+++ b/ext/gsm/gstgsmdec.c
@@ -43,43 +43,16 @@ enum
ARG_0
};
-static void gst_gsmdec_base_init (gpointer g_class);
-static void gst_gsmdec_class_init (GstGSMDec * klass);
-static void gst_gsmdec_init (GstGSMDec * gsmdec);
-static void gst_gsmdec_finalize (GObject * object);
-
-static gboolean gst_gsmdec_sink_setcaps (GstPad * pad, GstCaps * caps);
-static gboolean gst_gsmdec_sink_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn gst_gsmdec_chain (GstPad * pad, GstBuffer * buf);
-
-static GstElementClass *parent_class = NULL;
+static gboolean gst_gsmdec_start (GstAudioDecoder * dec);
+static gboolean gst_gsmdec_stop (GstAudioDecoder * dec);
+static gboolean gst_gsmdec_set_format (GstAudioDecoder * dec, GstCaps * caps);
+static GstFlowReturn gst_gsmdec_parse (GstAudioDecoder * dec,
+ GstAdapter * adapter, gint * offset, gint * length);
+static GstFlowReturn gst_gsmdec_handle_frame (GstAudioDecoder * dec,
+ GstBuffer * in_buf);
/*static guint gst_gsmdec_signals[LAST_SIGNAL] = { 0 }; */
-GType
-gst_gsmdec_get_type (void)
-{
- static GType gsmdec_type = 0;
-
- if (!gsmdec_type) {
- static const GTypeInfo gsmdec_info = {
- sizeof (GstGSMDecClass),
- gst_gsmdec_base_init,
- NULL,
- (GClassInitFunc) gst_gsmdec_class_init,
- NULL,
- NULL,
- sizeof (GstGSMDec),
- 0,
- (GInstanceInitFunc) gst_gsmdec_init,
- };
-
- gsmdec_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstGSMDec", &gsmdec_info, 0);
- }
- return gsmdec_type;
-}
-
#define ENCODED_SAMPLES 160
static GstStaticPadTemplate gsmdec_sink_template =
@@ -101,6 +74,9 @@ GST_STATIC_PAD_TEMPLATE ("src",
"depth = (int) 16, " "rate = (int) [1, MAX], " "channels = (int) 1")
);
+GST_BOILERPLATE (GstGSMDec, gst_gsmdec, GstAudioDecoder,
+ GST_TYPE_AUDIO_DECODER);
+
static void
gst_gsmdec_base_init (gpointer g_class)
{
@@ -116,63 +92,60 @@ gst_gsmdec_base_init (gpointer g_class)
}
static void
-gst_gsmdec_class_init (GstGSMDec * klass)
+gst_gsmdec_class_init (GstGSMDecClass * klass)
{
- GObjectClass *gobject_class;
+ GstAudioDecoderClass *base_class;
- gobject_class = (GObjectClass *) klass;
+ base_class = (GstAudioDecoderClass *) klass;
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_gsmdec_finalize;
+ base_class->start = GST_DEBUG_FUNCPTR (gst_gsmdec_start);
+ base_class->stop = GST_DEBUG_FUNCPTR (gst_gsmdec_stop);
+ base_class->set_format = GST_DEBUG_FUNCPTR (gst_gsmdec_set_format);
+ base_class->parse = GST_DEBUG_FUNCPTR (gst_gsmdec_parse);
+ base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_gsmdec_handle_frame);
GST_DEBUG_CATEGORY_INIT (gsmdec_debug, "gsmdec", 0, "GSM Decoder");
}
static void
-gst_gsmdec_init (GstGSMDec * gsmdec)
+gst_gsmdec_init (GstGSMDec * gsmdec, GstGSMDecClass * klass)
{
- /* create the sink and src pads */
- gsmdec->sinkpad =
- gst_pad_new_from_static_template (&gsmdec_sink_template, "sink");
- gst_pad_set_setcaps_function (gsmdec->sinkpad, gst_gsmdec_sink_setcaps);
- gst_pad_set_event_function (gsmdec->sinkpad, gst_gsmdec_sink_event);
- gst_pad_set_chain_function (gsmdec->sinkpad, gst_gsmdec_chain);
- gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->sinkpad);
-
- gsmdec->srcpad =
- gst_pad_new_from_static_template (&gsmdec_src_template, "src");
- gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad);
+}
+
+static gboolean
+gst_gsmdec_start (GstAudioDecoder * dec)
+{
+ GstGSMDec *gsmdec = GST_GSMDEC (dec);
+
+ GST_DEBUG_OBJECT (dec, "start");
gsmdec->state = gsm_create ();
- gsmdec->adapter = gst_adapter_new ();
- gsmdec->next_of = 0;
- gsmdec->next_ts = 0;
+ return TRUE;
}
-static void
-gst_gsmdec_finalize (GObject * object)
+static gboolean
+gst_gsmdec_stop (GstAudioDecoder * dec)
{
- GstGSMDec *gsmdec;
+ GstGSMDec *gsmdec = GST_GSMDEC (dec);
- gsmdec = GST_GSMDEC (object);
+ GST_DEBUG_OBJECT (dec, "stop");
- g_object_unref (gsmdec->adapter);
gsm_destroy (gsmdec->state);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ return TRUE;
}
static gboolean
-gst_gsmdec_sink_setcaps (GstPad * pad, GstCaps * caps)
+gst_gsmdec_set_format (GstAudioDecoder * dec, GstCaps * caps)
{
GstGSMDec *gsmdec;
GstCaps *srccaps;
GstStructure *s;
gboolean ret = FALSE;
+ gint rate;
- gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
+ gsmdec = GST_GSMDEC (dec);
s = gst_caps_get_structure (caps, 0);
if (s == NULL)
@@ -186,7 +159,9 @@ gst_gsmdec_sink_setcaps (GstPad * pad, GstCaps * caps)
else
goto wrong_caps;
- if (!gst_structure_get_int (s, "rate", &gsmdec->rate)) {
+ gsmdec->needed = 33;
+
+ if (!gst_structure_get_int (s, "rate", &rate)) {
GST_WARNING_OBJECT (gsmdec, "missing sample rate parameter from sink caps");
goto beach;
}
@@ -194,21 +169,16 @@ gst_gsmdec_sink_setcaps (GstPad * pad, GstCaps * caps)
/* MSGSM needs different framing */
gsm_option (gsmdec->state, GSM_OPT_WAV49, &gsmdec->use_wav49);
- gsmdec->duration = gst_util_uint64_scale (ENCODED_SAMPLES,
- GST_SECOND, gsmdec->rate);
-
/* Setting up src caps based on the input sample rate. */
srccaps = gst_caps_new_simple ("audio/x-raw-int",
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"signed", G_TYPE_BOOLEAN, TRUE,
"width", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
- "rate", G_TYPE_INT, gsmdec->rate, "channels", G_TYPE_INT, 1, NULL);
-
- ret = gst_pad_set_caps (gsmdec->srcpad, srccaps);
+ "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, 1, NULL);
+ ret = gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec), srccaps);
gst_caps_unref (srccaps);
- gst_object_unref (gsmdec);
return ret;
@@ -218,127 +188,66 @@ wrong_caps:
GST_ERROR_OBJECT (gsmdec, "invalid caps received");
beach:
- gst_object_unref (gsmdec);
return ret;
}
-static gboolean
-gst_gsmdec_sink_event (GstPad * pad, GstEvent * event)
+static GstFlowReturn
+gst_gsmdec_parse (GstAudioDecoder * dec, GstAdapter * adapter,
+ gint * offset, gint * length)
{
- gboolean res;
- GstGSMDec *gsmdec;
+ GstGSMDec *gsmdec = GST_GSMDEC (dec);
+ guint size;
+
+ size = gst_adapter_available (adapter);
+ g_return_val_if_fail (size > 0, GST_FLOW_ERROR);
- gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_FLUSH_START:
- res = gst_pad_push_event (gsmdec->srcpad, event);
- break;
- case GST_EVENT_FLUSH_STOP:
- gst_segment_init (&gsmdec->segment, GST_FORMAT_UNDEFINED);
- res = gst_pad_push_event (gsmdec->srcpad, event);
- break;
- case GST_EVENT_NEWSEGMENT:
- {
- gboolean update;
- GstFormat format;
- gdouble rate, arate;
- gint64 start, stop, time;
-
- gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
- &start, &stop, &time);
-
- /* now configure the values */
- gst_segment_set_newsegment_full (&gsmdec->segment, update,
- rate, arate, format, start, stop, time);
-
- /* and forward */
- res = gst_pad_push_event (gsmdec->srcpad, event);
- break;
- }
- case GST_EVENT_EOS:
- default:
- res = gst_pad_push_event (gsmdec->srcpad, event);
- break;
+ /* WAV49 requires alternating 33 and 32 bytes of input */
+ if (gsmdec->use_wav49) {
+ gsmdec->needed = (gsmdec->needed == 33 ? 32 : 33);
}
- gst_object_unref (gsmdec);
+ if (size < gsmdec->needed)
+ return GST_FLOW_UNEXPECTED;
- return res;
+ *offset = 0;
+ *length = gsmdec->needed;
+
+ return GST_FLOW_OK;
}
static GstFlowReturn
-gst_gsmdec_chain (GstPad * pad, GstBuffer * buf)
+gst_gsmdec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
{
GstGSMDec *gsmdec;
gsm_byte *data;
GstFlowReturn ret = GST_FLOW_OK;
- GstClockTime timestamp;
- gint needed;
-
- gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
-
- timestamp = GST_BUFFER_TIMESTAMP (buf);
-
- if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
- gst_adapter_clear (gsmdec->adapter);
- gsmdec->next_ts = GST_CLOCK_TIME_NONE;
- /* FIXME, do some good offset */
- gsmdec->next_of = 0;
- }
- gst_adapter_push (gsmdec->adapter, buf);
-
- needed = 33;
- /* do we have enough bytes to read a frame */
- while (gst_adapter_available (gsmdec->adapter) >= needed) {
- GstBuffer *outbuf;
-
- /* always the same amount of output samples */
- outbuf = gst_buffer_new_and_alloc (ENCODED_SAMPLES * sizeof (gsm_signal));
-
- /* If we are not given any timestamp, interpolate from last seen
- * timestamp (if any). */
- if (timestamp == GST_CLOCK_TIME_NONE)
- timestamp = gsmdec->next_ts;
-
- GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
-
- /* interpolate in the next run */
- if (timestamp != GST_CLOCK_TIME_NONE)
- gsmdec->next_ts = timestamp + gsmdec->duration;
- timestamp = GST_CLOCK_TIME_NONE;
-
- GST_BUFFER_DURATION (outbuf) = gsmdec->duration;
- GST_BUFFER_OFFSET (outbuf) = gsmdec->next_of;
- if (gsmdec->next_of != -1)
- gsmdec->next_of += ENCODED_SAMPLES;
- GST_BUFFER_OFFSET_END (outbuf) = gsmdec->next_of;
-
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (gsmdec->srcpad));
-
- /* now encode frame into the output buffer */
- data = (gsm_byte *) gst_adapter_peek (gsmdec->adapter, needed);
- if (gsm_decode (gsmdec->state, data,
- (gsm_signal *) GST_BUFFER_DATA (outbuf)) < 0) {
- /* invalid frame */
- GST_WARNING_OBJECT (gsmdec, "tried to decode an invalid frame, skipping");
- }
- gst_adapter_flush (gsmdec->adapter, needed);
-
- /* WAV49 requires alternating 33 and 32 bytes of input */
- if (gsmdec->use_wav49)
- needed = (needed == 33 ? 32 : 33);
-
- GST_DEBUG_OBJECT (gsmdec, "Pushing buffer of size %d ts %" GST_TIME_FORMAT,
- GST_BUFFER_SIZE (outbuf),
- GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
-
- /* push */
- ret = gst_pad_push (gsmdec->srcpad, outbuf);
+ GstBuffer *outbuf;
+
+ /* no fancy draining */
+ if (G_UNLIKELY (!buffer))
+ return GST_FLOW_OK;
+
+ gsmdec = GST_GSMDEC (dec);
+
+ /* always the same amount of output samples */
+ outbuf = gst_buffer_new_and_alloc (ENCODED_SAMPLES * sizeof (gsm_signal));
+
+ /* now encode frame into the output buffer */
+ data = (gsm_byte *) GST_BUFFER_DATA (buffer);
+ if (gsm_decode (gsmdec->state, data,
+ (gsm_signal *) GST_BUFFER_DATA (outbuf)) < 0) {
+ /* invalid frame */
+ GST_AUDIO_DECODER_ERROR (gsmdec, 1, STREAM, DECODE, (NULL),
+ ("tried to decode an invalid frame"), ret);
+ if (ret != GST_FLOW_OK)
+ goto exit;
+ gst_buffer_unref (outbuf);
+ outbuf = NULL;
}
- gst_object_unref (gsmdec);
+ gst_audio_decoder_finish_frame (dec, outbuf, 1);
+exit:
return ret;
}
diff --git a/ext/gsm/gstgsmdec.h b/ext/gsm/gstgsmdec.h
index 0013aa47e..d3ddec604 100644
--- a/ext/gsm/gstgsmdec.h
+++ b/ext/gsm/gstgsmdec.h
@@ -21,7 +21,7 @@
#define __GST_GSMDEC_H__
#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
+#include <gst/audio/gstaudiodecoder.h>
#ifdef GSM_HEADER_IN_SUBDIR
#include <gsm/gsm.h>
@@ -47,28 +47,16 @@ typedef struct _GstGSMDecClass GstGSMDecClass;
struct _GstGSMDec
{
- GstElement element;
-
- /* pads */
- GstPad *sinkpad, *srcpad;
+ GstAudioDecoder element;
gsm state;
gint use_wav49;
- gint64 next_of;
- GstClockTime next_ts;
-
- GstAdapter *adapter;
-
- GstSegment segment;
-
- gint rate;
-
- GstClockTime duration;
+ gint needed;
};
struct _GstGSMDecClass
{
- GstElementClass parent_class;
+ GstAudioDecoderClass parent_class;
};
GType gst_gsmdec_get_type (void);
diff --git a/ext/gsm/gstgsmenc.c b/ext/gsm/gstgsmenc.c
index 434c4b1fa..e8c97c1f0 100644
--- a/ext/gsm/gstgsmenc.c
+++ b/ext/gsm/gstgsmenc.c
@@ -43,39 +43,12 @@ enum
ARG_0
};
-static void gst_gsmenc_base_init (gpointer g_class);
-static void gst_gsmenc_class_init (GstGSMEnc * klass);
-static void gst_gsmenc_init (GstGSMEnc * gsmenc);
-static void gst_gsmenc_finalize (GObject * object);
-
-static gboolean gst_gsmenc_setcaps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_gsmenc_chain (GstPad * pad, GstBuffer * buf);
-
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_gsmenc_get_type (void)
-{
- static GType gsmenc_type = 0;
-
- if (!gsmenc_type) {
- static const GTypeInfo gsmenc_info = {
- sizeof (GstGSMEncClass),
- gst_gsmenc_base_init,
- NULL,
- (GClassInitFunc) gst_gsmenc_class_init,
- NULL,
- NULL,
- sizeof (GstGSMEnc),
- 0,
- (GInstanceInitFunc) gst_gsmenc_init,
- };
-
- gsmenc_type =
- g_type_register_static (GST_TYPE_ELEMENT, "GstGSMEnc", &gsmenc_info, 0);
- }
- return gsmenc_type;
-}
+static gboolean gst_gsmenc_start (GstAudioEncoder * enc);
+static gboolean gst_gsmenc_stop (GstAudioEncoder * enc);
+static gboolean gst_gsmenc_set_format (GstAudioEncoder * enc,
+ GstAudioInfo * info);
+static GstFlowReturn gst_gsmenc_handle_frame (GstAudioEncoder * enc,
+ GstBuffer * in_buf);
static GstStaticPadTemplate gsmenc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
@@ -95,6 +68,9 @@ GST_STATIC_PAD_TEMPLATE ("sink",
"depth = (int) 16, " "rate = (int) 8000, " "channels = (int) 1")
);
+GST_BOILERPLATE (GstGSMEnc, gst_gsmenc, GstAudioEncoder,
+ GST_TYPE_AUDIO_ENCODER);
+
static void
gst_gsmenc_base_init (gpointer g_class)
{
@@ -110,34 +86,32 @@ gst_gsmenc_base_init (gpointer g_class)
}
static void
-gst_gsmenc_class_init (GstGSMEnc * klass)
+gst_gsmenc_class_init (GstGSMEncClass * klass)
{
- GObjectClass *gobject_class;
+ GstAudioEncoderClass *base_class;
- gobject_class = (GObjectClass *) klass;
+ base_class = (GstAudioEncoderClass *) klass;
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = gst_gsmenc_finalize;
+ base_class->start = GST_DEBUG_FUNCPTR (gst_gsmenc_start);
+ base_class->stop = GST_DEBUG_FUNCPTR (gst_gsmenc_stop);
+ base_class->set_format = GST_DEBUG_FUNCPTR (gst_gsmenc_set_format);
+ base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_gsmenc_handle_frame);
GST_DEBUG_CATEGORY_INIT (gsmenc_debug, "gsmenc", 0, "GSM Encoder");
}
static void
-gst_gsmenc_init (GstGSMEnc * gsmenc)
+gst_gsmenc_init (GstGSMEnc * gsmenc, GstGSMEncClass * klass)
{
- gint use_wav49;
+}
- /* create the sink and src pads */
- gsmenc->sinkpad =
- gst_pad_new_from_static_template (&gsmenc_sink_template, "sink");
- gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain);
- gst_pad_set_setcaps_function (gsmenc->sinkpad, gst_gsmenc_setcaps);
- gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad);
+static gboolean
+gst_gsmenc_start (GstAudioEncoder * enc)
+{
+ GstGSMEnc *gsmenc = GST_GSMENC (enc);
+ gint use_wav49;
- gsmenc->srcpad =
- gst_pad_new_from_static_template (&gsmenc_src_template, "src");
- gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->srcpad);
+ GST_DEBUG_OBJECT (enc, "start");
gsmenc->state = gsm_create ();
@@ -145,78 +119,69 @@ gst_gsmenc_init (GstGSMEnc * gsmenc)
use_wav49 = 0;
gsm_option (gsmenc->state, GSM_OPT_WAV49, &use_wav49);
- gsmenc->adapter = gst_adapter_new ();
- gsmenc->next_ts = 0;
+ return TRUE;
}
-static void
-gst_gsmenc_finalize (GObject * object)
+static gboolean
+gst_gsmenc_stop (GstAudioEncoder * enc)
{
- GstGSMEnc *gsmenc;
-
- gsmenc = GST_GSMENC (object);
+ GstGSMEnc *gsmenc = GST_GSMENC (enc);
- g_object_unref (gsmenc->adapter);
+ GST_DEBUG_OBJECT (enc, "stop");
gsm_destroy (gsmenc->state);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ return TRUE;
}
static gboolean
-gst_gsmenc_setcaps (GstPad * pad, GstCaps * caps)
+gst_gsmenc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
{
- GstGSMEnc *gsmenc;
GstCaps *srccaps;
- gsmenc = GST_GSMENC (gst_pad_get_parent (pad));
-
srccaps = gst_static_pad_template_get_caps (&gsmenc_src_template);
+ gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (benc), srccaps);
- gst_pad_set_caps (gsmenc->srcpad, srccaps);
-
- gst_object_unref (gsmenc);
+ /* report needs to base class */
+ gst_audio_encoder_set_frame_samples_min (benc, 160);
+ gst_audio_encoder_set_frame_samples_max (benc, 160);
+ gst_audio_encoder_set_frame_max (benc, 1);
return TRUE;
}
-
static GstFlowReturn
-gst_gsmenc_chain (GstPad * pad, GstBuffer * buf)
+gst_gsmenc_handle_frame (GstAudioEncoder * benc, GstBuffer * buffer)
{
GstGSMEnc *gsmenc;
gsm_signal *data;
GstFlowReturn ret = GST_FLOW_OK;
+ GstBuffer *outbuf;
- gsmenc = GST_GSMENC (gst_pad_get_parent (pad));
+ gsmenc = GST_GSMENC (benc);
- if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
- gst_adapter_clear (gsmenc->adapter);
+ /* we don't deal with squeezing remnants, so simply discard those */
+ if (G_UNLIKELY (buffer == NULL)) {
+ GST_DEBUG_OBJECT (gsmenc, "no data");
+ goto done;
}
- gst_adapter_push (gsmenc->adapter, buf);
-
- while (gst_adapter_available (gsmenc->adapter) >= 320) {
- GstBuffer *outbuf;
-
- outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte));
- GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
- GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
- gsmenc->next_ts += 20 * GST_MSECOND;
-
- /* encode 160 16-bit samples into 33 bytes */
- data = (gsm_signal *) gst_adapter_peek (gsmenc->adapter, 320);
- gsm_encode (gsmenc->state, data, (gsm_byte *) GST_BUFFER_DATA (outbuf));
- gst_adapter_flush (gsmenc->adapter, 320);
+ if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) < 320)) {
+ GST_DEBUG_OBJECT (gsmenc, "discarding trailing data %d",
+ GST_BUFFER_SIZE (buffer));
+ ret = gst_audio_encoder_finish_frame (benc, NULL, -1);
+ goto done;
+ }
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (gsmenc->srcpad));
+ outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte));
- GST_DEBUG_OBJECT (gsmenc, "Pushing buffer of size %d",
- GST_BUFFER_SIZE (outbuf));
+ /* encode 160 16-bit samples into 33 bytes */
+ data = (gsm_signal *) GST_BUFFER_DATA (buffer);
+ gsm_encode (gsmenc->state, data, (gsm_byte *) GST_BUFFER_DATA (outbuf));
- ret = gst_pad_push (gsmenc->srcpad, outbuf);
- }
+ GST_LOG_OBJECT (gsmenc, "encoded to %d bytes", GST_BUFFER_SIZE (outbuf));
- gst_object_unref (gsmenc);
+ ret = gst_audio_encoder_finish_frame (benc, outbuf, 160);
+done:
return ret;
}
diff --git a/ext/gsm/gstgsmenc.h b/ext/gsm/gstgsmenc.h
index ba3b089b7..28b8e2e29 100644
--- a/ext/gsm/gstgsmenc.h
+++ b/ext/gsm/gstgsmenc.h
@@ -21,7 +21,7 @@
#define __GST_GSMENC_H__
#include <gst/gst.h>
-#include <gst/base/gstadapter.h>
+#include <gst/audio/gstaudioencoder.h>
#ifdef GSM_HEADER_IN_SUBDIR
#include <gsm/gsm.h>
@@ -47,20 +47,14 @@ typedef struct _GstGSMEncClass GstGSMEncClass;
struct _GstGSMEnc
{
- GstElement element;
-
- /* pads */
- GstPad *sinkpad, *srcpad;
- GstAdapter *adapter;
+ GstAudioEncoder element;
gsm state;
- GstClockTime next_ts;
- gboolean firstBuf;
};
struct _GstGSMEncClass
{
- GstElementClass parent_class;
+ GstAudioEncoderClass parent_class;
};
GType gst_gsmenc_get_type (void);
diff --git a/ext/kate/gstkateenc.c b/ext/kate/gstkateenc.c
index 8ee8b69df..450e8e61e 100644
--- a/ext/kate/gstkateenc.c
+++ b/ext/kate/gstkateenc.c
@@ -924,33 +924,32 @@ gst_kate_enc_chain_text (GstKateEnc * ke, GstBuffer * buf,
("kate_encode_set_markup_type: %d", ret));
rflow = GST_FLOW_ERROR;
} else {
- char *text;
- gsize text_len;
+ const char *text;
+ size_t text_len;
+ gboolean need_unmap = TRUE;
+ kate_float t0 = start / (double) GST_SECOND;
+ kate_float t1 = stop / (double) GST_SECOND;
text = gst_buffer_map (buf, &text_len, NULL, GST_MAP_READ);
- if (text) {
- kate_float t0 = start / (double) GST_SECOND;
- kate_float t1 = stop / (double) GST_SECOND;
- GST_LOG_OBJECT (ke, "Encoding text: %*.*s (%u bytes) from %f to %f",
- (int) text_len, (int) text_len, text, text_len, t0, t1);
-
- ret = kate_encode_text (&ke->k, t0, t1, text, text_len, &kp);
+ if (text == NULL) {
+ text = "";
+ text_len = 0;
+ need_unmap = FALSE;
+ }
- if (G_UNLIKELY (ret < 0)) {
- GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
- ("Failed to encode text: %d", ret));
- rflow = GST_FLOW_ERROR;
- } else {
- rflow =
- gst_kate_enc_chain_push_packet (ke, &kp, start, stop - start + 1);
- }
- } else {
- /* FIXME: this should not be an error, we should ignore it and move on */
+ GST_LOG_OBJECT (ke, "Encoding text: %*.*s (%u bytes) from %f to %f",
+ (int) text_len, (int) text_len, GST_BUFFER_DATA (buf),
+ GST_BUFFER_SIZE (buf), t0, t1);
+ ret = kate_encode_text (&ke->k, t0, t1, text, text_len, &kp);
+ if (G_UNLIKELY (ret < 0)) {
GST_ELEMENT_ERROR (ke, STREAM, ENCODE, (NULL),
- ("no text in text packet"));
+ ("Failed to encode text: %d", ret));
rflow = GST_FLOW_ERROR;
+ } else {
+ rflow = gst_kate_enc_chain_push_packet (ke, &kp, start, stop - start + 1);
}
- gst_buffer_unmap (buf, text, text_len);
+ if (need_unmap)
+ gst_buffer_unmap (buf, text, text_len);
}
return rflow;
diff --git a/ext/opencv/gsttemplatematch.c b/ext/opencv/gsttemplatematch.c
index 4f26121db..84640ff3b 100644
--- a/ext/opencv/gsttemplatematch.c
+++ b/ext/opencv/gsttemplatematch.c
@@ -296,6 +296,8 @@ gst_template_match_finalize (GObject * object)
if (filter->cvTemplateImage) {
cvReleaseImage (&filter->cvTemplateImage);
}
+
+ GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}
/* chain function
diff --git a/ext/resindvd/resindvdbin.c b/ext/resindvd/resindvdbin.c
index 5885b238a..8c2d94fd6 100644
--- a/ext/resindvd/resindvdbin.c
+++ b/ext/resindvd/resindvdbin.c
@@ -470,18 +470,16 @@ create_elements (RsnDvdBin * dvdbin)
RSN_TYPE_STREAM_SELECTOR, "audioselect", "Audio stream selector"))
return FALSE;
- if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, NULL,
- RSN_TYPE_AUDIODEC, "auddec", "audio decoder"))
+ if (!try_create_piece (dvdbin, DVD_ELEM_AUD_MUNGE, NULL,
+ RSN_TYPE_AUDIOMUNGE, "audioearlymunge", "Audio output filter"))
return FALSE;
- /* rsnaudiomunge goes after the audio decoding to regulate the stream */
- if (!try_create_piece (dvdbin, DVD_ELEM_AUD_MUNGE, NULL,
- RSN_TYPE_AUDIOMUNGE, "audiomunge", "Audio output filter"))
+ if (!try_create_piece (dvdbin, DVD_ELEM_AUDDEC, NULL,
+ RSN_TYPE_AUDIODEC, "auddec", "audio decoder"))
return FALSE;
- src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "src");
- sink =
- gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "sink");
+ src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src");
+ sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "sink");
if (src == NULL || sink == NULL)
goto failed_aud_connect;
if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
@@ -491,7 +489,8 @@ create_elements (RsnDvdBin * dvdbin)
src = sink = NULL;
src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_SELECT], "src");
- sink = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "sink");
+ sink =
+ gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "sink");
if (src == NULL || sink == NULL)
goto failed_aud_connect;
if (GST_PAD_LINK_FAILED (gst_pad_link (src, sink)))
@@ -501,7 +500,7 @@ create_elements (RsnDvdBin * dvdbin)
src = sink = NULL;
/* ghost audio munge output pad onto bin */
- src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], "src");
+ src = gst_element_get_static_pad (dvdbin->pieces[DVD_ELEM_AUDDEC], "src");
if (src == NULL)
goto failed_aud_ghost;
src_templ = gst_static_pad_template_get (&audio_src_template);
@@ -701,7 +700,7 @@ demux_pad_added (GstElement * element, GstPad * pad, RsnDvdBin * dvdbin)
gst_element_get_request_pad (dvdbin->pieces[DVD_ELEM_SPU_SELECT],
"sink_%u");
skip_mq = TRUE;
- } else if (can_sink_caps (dvdbin->pieces[DVD_ELEM_AUDDEC], caps)) {
+ } else if (can_sink_caps (dvdbin->pieces[DVD_ELEM_AUD_MUNGE], caps)) {
GST_LOG_OBJECT (dvdbin, "Found audio pad w/ caps %" GST_PTR_FORMAT, caps);
dest_pad =
gst_element_get_request_pad (dvdbin->pieces[DVD_ELEM_AUD_SELECT],
@@ -720,7 +719,7 @@ demux_pad_added (GstElement * element, GstPad * pad, RsnDvdBin * dvdbin)
("No MPEG video decoder found"));
} else {
GST_ELEMENT_WARNING (dvdbin, STREAM, CODEC_NOT_FOUND, (NULL),
- ("No MPEG video decoder found"));
+ ("No MPEG audio decoder found"));
}
}
diff --git a/ext/resindvd/resindvdsrc.c b/ext/resindvd/resindvdsrc.c
index a0059fdaa..e3eba9f91 100644
--- a/ext/resindvd/resindvdsrc.c
+++ b/ext/resindvd/resindvdsrc.c
@@ -269,6 +269,7 @@ rsn_dvdsrc_finalize (GObject * object)
g_mutex_free (src->dvd_lock);
g_mutex_free (src->branch_lock);
g_cond_free (src->still_cond);
+ g_free (src->device);
gst_buffer_replace (&src->alloc_buf, NULL);
gst_buffer_replace (&src->next_buf, NULL);
diff --git a/ext/resindvd/rsnaudiomunge.c b/ext/resindvd/rsnaudiomunge.c
index 5e6f9cc6f..2b78dfea9 100644
--- a/ext/resindvd/rsnaudiomunge.c
+++ b/ext/resindvd/rsnaudiomunge.c
@@ -155,9 +155,9 @@ rsn_audiomunge_set_caps (GstPad * pad, GstCaps * caps)
g_return_val_if_fail (munge != NULL, FALSE);
otherpad = (pad == munge->srcpad) ? munge->sinkpad : munge->srcpad;
- gst_object_unref (munge);
ret = gst_pad_set_caps (otherpad, caps);
+ gst_object_unref (munge);
return ret;
}
diff --git a/ext/resindvd/rsndec.c b/ext/resindvd/rsndec.c
index 3abc0065c..662e932d5 100644
--- a/ext/resindvd/rsndec.c
+++ b/ext/resindvd/rsndec.c
@@ -247,18 +247,50 @@ _get_decoder_factories (gpointer arg)
GstPadTemplate *templ = gst_element_class_get_pad_template (klass,
"sink");
RsnDecFactoryFilterCtx ctx = { NULL, };
+ GstCaps *raw;
+ gboolean raw_audio;
ctx.desired_caps = gst_pad_template_get_caps (templ);
+
+ raw = gst_caps_from_string ("audio/x-raw-float");
+ raw_audio = gst_caps_can_intersect (raw, ctx.desired_caps);
+ if (raw_audio) {
+ GstCaps *sub = gst_caps_subtract (ctx.desired_caps, raw);
+ ctx.desired_caps = sub;
+ } else {
+ gst_caps_ref (ctx.desired_caps);
+ }
+ gst_caps_unref (raw);
+
/* Set decoder caps to empty. Will be filled by the factory_filter */
ctx.decoder_caps = gst_caps_new_empty ();
+ GST_DEBUG ("Finding factories for caps: %" GST_PTR_FORMAT, ctx.desired_caps);
factories = gst_default_registry_feature_filter (
(GstPluginFeatureFilter) rsndec_factory_filter, FALSE, &ctx);
+ /* If these are audio caps, we add audioconvert, which is not a decoder,
+ but allows raw audio to go through relatively unmolested - this will
+ come handy when we have to send placeholder silence to allow preroll
+ for those DVDs which have titles with no audio track. */
+ if (raw_audio) {
+ GstPluginFeature *feature;
+ GST_DEBUG ("These are audio caps, adding audioconvert");
+ feature =
+ gst_default_registry_find_feature ("audioconvert",
+ GST_TYPE_ELEMENT_FACTORY);
+ if (feature) {
+ factories = g_list_append (factories, feature);
+ } else {
+ GST_WARNING ("Could not find feature audioconvert");
+ }
+ }
+
factories = g_list_sort (factories, (GCompareFunc) sort_by_ranks);
GST_DEBUG ("Available decoder caps %" GST_PTR_FORMAT, ctx.decoder_caps);
gst_caps_unref (ctx.decoder_caps);
+ gst_caps_unref (ctx.desired_caps);
return factories;
}
@@ -343,7 +375,7 @@ static GstStaticPadTemplate audio_sink_template =
GST_STATIC_CAPS ("audio/mpeg,mpegversion=(int)1;"
"audio/x-private1-lpcm;"
"audio/x-private1-ac3;" "audio/ac3;" "audio/x-ac3;"
- "audio/x-private1-dts;")
+ "audio/x-private1-dts; audio/x-raw-float")
);
static GstStaticPadTemplate audio_src_template = GST_STATIC_PAD_TEMPLATE ("src",
diff --git a/ext/rsvg/gstrsvgoverlay.c b/ext/rsvg/gstrsvgoverlay.c
index 1cbd0990c..9d4ce6025 100644
--- a/ext/rsvg/gstrsvgoverlay.c
+++ b/ext/rsvg/gstrsvgoverlay.c
@@ -123,6 +123,8 @@ static GstStaticPadTemplate data_sink_template =
GST_BOILERPLATE (GstRsvgOverlay, gst_rsvg_overlay, GstVideoFilter,
GST_TYPE_VIDEO_FILTER);
+static void gst_rsvg_overlay_finalize (GObject * object);
+
static void
gst_rsvg_overlay_set_svg_data (GstRsvgOverlay * overlay, const gchar * data,
gboolean consider_as_filename)
@@ -467,6 +469,7 @@ gst_rsvg_overlay_class_init (GstRsvgOverlayClass * klass)
gobject_class->set_property = gst_rsvg_overlay_set_property;
gobject_class->get_property = gst_rsvg_overlay_get_property;
+ gobject_class->finalize = gst_rsvg_overlay_finalize;
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DATA,
g_param_spec_string ("data", "data", "SVG data.", "",
@@ -542,3 +545,13 @@ gst_rsvg_overlay_init (GstRsvgOverlay * overlay, GstRsvgOverlayClass * klass)
GST_DEBUG_FUNCPTR (gst_rsvg_overlay_data_sink_event));
gst_element_add_pad (GST_ELEMENT (overlay), overlay->data_sinkpad);
}
+
+static void
+gst_rsvg_overlay_finalize (GObject * object)
+{
+ GstRsvgOverlay *overlay = GST_RSVG_OVERLAY (object);
+
+ g_object_unref (overlay->adapter);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
diff --git a/ext/schroedinger/gstschrodec.c b/ext/schroedinger/gstschrodec.c
index 50bb40480..c8fa8336e 100644
--- a/ext/schroedinger/gstschrodec.c
+++ b/ext/schroedinger/gstschrodec.c
@@ -102,7 +102,7 @@ static GstStaticPadTemplate gst_schro_dec_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YUY2, AYUV }"))
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV (GST_SCHRO_YUV_LIST))
);
GST_BOILERPLATE (GstSchroDec, gst_schro_dec, GstBaseVideoDecoder,
@@ -313,12 +313,25 @@ parse_sequence_header (GstSchroDec * schro_dec, guint8 * data, int size)
ret = schro_parse_decode_sequence_header (data + 13, size - 13,
&video_format);
if (ret) {
- if (video_format.chroma_format == SCHRO_CHROMA_444) {
- state->format = GST_VIDEO_FORMAT_AYUV;
- } else if (video_format.chroma_format == SCHRO_CHROMA_422) {
- state->format = GST_VIDEO_FORMAT_YUY2;
- } else if (video_format.chroma_format == SCHRO_CHROMA_420) {
- state->format = GST_VIDEO_FORMAT_I420;
+ int bit_depth;
+
+ bit_depth = schro_video_format_get_bit_depth (&video_format);
+
+ if (bit_depth == 8) {
+ if (video_format.chroma_format == SCHRO_CHROMA_444) {
+ state->format = GST_VIDEO_FORMAT_AYUV;
+ } else if (video_format.chroma_format == SCHRO_CHROMA_422) {
+ state->format = GST_VIDEO_FORMAT_UYVY;
+ } else if (video_format.chroma_format == SCHRO_CHROMA_420) {
+ state->format = GST_VIDEO_FORMAT_I420;
+ }
+ } else if (bit_depth <= 10) {
+ state->format = GST_VIDEO_FORMAT_v210;
+ } else if (bit_depth <= 16) {
+ state->format = GST_VIDEO_FORMAT_AYUV64;
+ } else {
+ GST_ERROR ("bit depth too large (%d > 16)", bit_depth);
+ state->format = GST_VIDEO_FORMAT_AYUV64;
}
state->fps_n = video_format.frame_rate_numerator;
state->fps_d = video_format.frame_rate_denominator;
diff --git a/ext/schroedinger/gstschroenc.c b/ext/schroedinger/gstschroenc.c
index c2064d3ca..1fb75f98e 100644
--- a/ext/schroedinger/gstschroenc.c
+++ b/ext/schroedinger/gstschroenc.c
@@ -107,7 +107,7 @@ static GstStaticPadTemplate gst_schro_enc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }"))
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV (GST_SCHRO_YUV_LIST))
);
static GstStaticPadTemplate gst_schro_enc_src_template =
@@ -271,13 +271,18 @@ gst_schro_enc_set_format (GstBaseVideoEncoder * base_video_encoder,
switch (state->format) {
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
+ case GST_VIDEO_FORMAT_Y42B:
schro_enc->video_format->chroma_format = SCHRO_CHROMA_420;
break;
case GST_VIDEO_FORMAT_YUY2:
case GST_VIDEO_FORMAT_UYVY:
+ case GST_VIDEO_FORMAT_v216:
+ case GST_VIDEO_FORMAT_v210:
schro_enc->video_format->chroma_format = SCHRO_CHROMA_422;
break;
case GST_VIDEO_FORMAT_AYUV:
+ case GST_VIDEO_FORMAT_Y444:
+ case GST_VIDEO_FORMAT_AYUV64:
schro_enc->video_format->chroma_format = SCHRO_CHROMA_444;
break;
case GST_VIDEO_FORMAT_ARGB:
@@ -300,8 +305,24 @@ gst_schro_enc_set_format (GstBaseVideoEncoder * base_video_encoder,
schro_enc->video_format->aspect_ratio_numerator = state->par_n;
schro_enc->video_format->aspect_ratio_denominator = state->par_d;
- schro_video_format_set_std_signal_range (schro_enc->video_format,
- SCHRO_SIGNAL_RANGE_8BIT_VIDEO);
+ switch (state->format) {
+ default:
+ schro_video_format_set_std_signal_range (schro_enc->video_format,
+ SCHRO_SIGNAL_RANGE_8BIT_VIDEO);
+ break;
+ case GST_VIDEO_FORMAT_v210:
+ schro_video_format_set_std_signal_range (schro_enc->video_format,
+ SCHRO_SIGNAL_RANGE_10BIT_VIDEO);
+ break;
+ case GST_VIDEO_FORMAT_v216:
+ case GST_VIDEO_FORMAT_AYUV64:
+ schro_enc->video_format->luma_offset = 64 << 8;
+ schro_enc->video_format->luma_excursion = 219 << 8;
+ schro_enc->video_format->chroma_offset = 128 << 8;
+ schro_enc->video_format->chroma_excursion = 224 << 8;
+ break;
+ }
+
schro_video_format_set_std_colour_spec (schro_enc->video_format,
SCHRO_COLOUR_SPEC_HDTV);
diff --git a/ext/schroedinger/gstschroutils.c b/ext/schroedinger/gstschroutils.c
index 66514a3d5..99a22c8a4 100644
--- a/ext/schroedinger/gstschroutils.c
+++ b/ext/schroedinger/gstschroutils.c
@@ -72,6 +72,29 @@ gst_schro_buffer_wrap (GstBuffer * buf, GstVideoFormat format, int width,
frame =
schro_frame_new_from_data_AYUV (GST_BUFFER_DATA (buf), width, height);
break;
+ case GST_VIDEO_FORMAT_Y42B:
+ frame =
+ schro_frame_new_from_data_Y42B (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_Y444:
+ frame =
+ schro_frame_new_from_data_Y444 (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_v210:
+ frame =
+ schro_frame_new_from_data_v210 (GST_BUFFER_DATA (buf), width, height);
+ break;
+ case GST_VIDEO_FORMAT_v216:
+ frame =
+ schro_frame_new_from_data_v216 (GST_BUFFER_DATA (buf), width, height);
+ break;
+#ifdef SCHRO_FRAME_FORMAT_AY64
+ /* Added in 1.0.11 */
+ case GST_VIDEO_FORMAT_AYUV64:
+ frame =
+ schro_frame_new_from_data_AY64 (GST_BUFFER_DATA (buf), width, height);
+ break;
+#endif
#if 0
case GST_VIDEO_FORMAT_ARGB:
{
diff --git a/ext/schroedinger/gstschroutils.h b/ext/schroedinger/gstschroutils.h
index 4e8ca2de3..a9924a633 100644
--- a/ext/schroedinger/gstschroutils.h
+++ b/ext/schroedinger/gstschroutils.h
@@ -24,6 +24,12 @@
#include <gst/video/video.h>
#include <schroedinger/schro.h>
+#ifdef SCHRO_FRAME_FORMAT_AY64
+#define GST_SCHRO_YUV_LIST "{ I420, YV12, YUY2, UYVY, AYUV, Y42B, Y444, v216, v210, AY64 }"
+#else
+#define GST_SCHRO_YUV_LIST "{ I420, YV12, YUY2, UYVY, AYUV, Y42B, Y444 }"
+#endif
+
SchroFrame *
gst_schro_buffer_wrap (GstBuffer *buf, GstVideoFormat format, int width,
int height);
diff --git a/ext/spc/gstspc.c b/ext/spc/gstspc.c
index 2c74a9c56..916718235 100644
--- a/ext/spc/gstspc.c
+++ b/ext/spc/gstspc.c
@@ -169,6 +169,8 @@ gst_spc_dec_dispose (GObject * object)
}
spc_tag_free (&spc->tag_info);
+
+ GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
}
static GstFlowReturn
diff --git a/ext/vp8/gstvp8enc.c b/ext/vp8/gstvp8enc.c
index 7a1832843..ea92a76ce 100644
--- a/ext/vp8/gstvp8enc.c
+++ b/ext/vp8/gstvp8enc.c
@@ -1174,6 +1174,9 @@ gst_vp8_enc_shape_output (GstBaseVideoEncoder * base_video_encoder,
gst_util_uint64_scale (frame->presentation_frame_number + 1,
GST_SECOND * state->fps_d, state->fps_n);
+ GST_LOG_OBJECT (base_video_encoder, "src ts: %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
+
ret = gst_pad_push (GST_BASE_VIDEO_CODEC_SRC_PAD (base_video_encoder), buf);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (encoder, "flow error %d", ret);