[gstreamer-plugins-fc] BR gstreamer1-devel for merged GStreamer 1.0.x plugin libgst1fcdec.so
Michael Schwendt
mschwendt at fedoraproject.org
Thu May 2 15:35:29 UTC 2013
commit 530412f7d047eab4c9f05fc80c5a19e6d8da3619
Author: Michael Schwendt <mschwendt at fedoraproject.org>
Date: Thu May 2 17:35:24 2013 +0200
BR gstreamer1-devel for merged GStreamer 1.0.x plugin libgst1fcdec.so
gstreamer-plugin-fc-0.2-gstreamer1.patch | 1004 ++++++++++++++++++++++++++++++
gstreamer-plugins-fc.spec | 39 +-
2 files changed, 1032 insertions(+), 11 deletions(-)
---
diff --git a/gstreamer-plugin-fc-0.2-gstreamer1.patch b/gstreamer-plugin-fc-0.2-gstreamer1.patch
new file mode 100644
index 0000000..12df221
--- /dev/null
+++ b/gstreamer-plugin-fc-0.2-gstreamer1.patch
@@ -0,0 +1,1004 @@
+diff -Nur gstreamer-plugin-fc-0.2-orig/acinclude.m4 gstreamer-plugin-fc-0.2/acinclude.m4
+--- gstreamer-plugin-fc-0.2-orig/acinclude.m4 2008-10-15 17:34:40.000000000 +0200
++++ gstreamer-plugin-fc-0.2/acinclude.m4 2013-04-30 11:56:09.000000000 +0200
+@@ -100,63 +100,3 @@
+ CFLAGS="$fc_save_cflags"
+ CC="$fc_save_cc"
+ ])
+-
+-dnl -------------------------------------------------------------------------
+-dnl PKG_CHECK_MODULES(EXAMPLE, gtk+-2.0 >= 2.4.0 glib = 2.4.0, action-if, action-not)
+-dnl defines EXAMPLE_LIBS, EXAMPLE_CFLAGS, see pkg-config man page
+-dnl also defines EXAMPLE_PKG_ERRORS on error
+-dnl -------------------------------------------------------------------------
+-
+-AC_DEFUN([PKG_CHECK_MODULES], [
+- succeeded=no
+-
+- if test -z "$PKG_CONFIG"; then
+- AC_PATH_PROG(PKG_CONFIG, pkg-config, "")
+- fi
+-
+- if test -z "$PKG_CONFIG"; then
+- echo "*** The pkg-config script could not be found. Make sure it is"
+- echo "*** in your path, or set the PKG_CONFIG environment variable"
+- echo "*** to the full path to pkg-config."
+- echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+- exit -1
+- else
+- PKG_CONFIG_MIN_VERSION=0.9.0
+- if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+- AC_MSG_CHECKING(for $2)
+-
+- if $PKG_CONFIG --exists "$2" ; then
+- AC_MSG_RESULT(yes)
+- succeeded=yes
+-
+- AC_MSG_CHECKING($1_CFLAGS)
+- $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
+- AC_MSG_RESULT($$1_CFLAGS)
+-
+- AC_MSG_CHECKING($1_LIBS)
+- $1_LIBS=`$PKG_CONFIG --libs "$2"`
+- AC_MSG_RESULT($$1_LIBS)
+- else
+- $1_CFLAGS=""
+- $1_LIBS=""
+- ## If we have a custom action on failure, don't print errors, but
+- ## do set a variable so people can do so.
+- $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+- ifelse([$4], ,echo $$1_PKG_ERRORS,)
+- fi
+-
+- AC_SUBST($1_CFLAGS)
+- AC_SUBST($1_LIBS)
+- else
+- echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+- echo "*** See http://www.freedesktop.org/software/pkgconfig"
+- fi
+- fi
+-
+- if test $succeeded = yes; then
+- ifelse([$3], , :, [$3])
+- else
+- ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
+- fi
+-])
+-
+diff -Nur gstreamer-plugin-fc-0.2-orig/configure.in gstreamer-plugin-fc-0.2/configure.in
+--- gstreamer-plugin-fc-0.2-orig/configure.in 2010-06-19 21:14:37.000000000 +0200
++++ gstreamer-plugin-fc-0.2/configure.in 2013-05-01 23:21:17.000000000 +0200
+@@ -1,6 +1,7 @@
+-AC_INIT(gstfcdec.c)
+-AM_INIT_AUTOMAKE(gstreamer-plugin-fc, 0.2)
+-AC_CONFIG_HEADERS(config.h)
++AC_INIT([gstfcdec], [0.2])
++AM_INIT_AUTOMAKE([foreign])
++AC_CONFIG_SRCDIR([gstfcdec.c])
++AC_CONFIG_HEADERS([config.h])
+ AC_CONFIG_MACRO_DIR([m4])
+
+ AC_CANONICAL_HOST
+@@ -10,6 +11,23 @@
+
+ AC_HEADER_STDC
+
++AM_DISABLE_STATIC
++AM_PROG_LIBTOOL
++
++AC_PATH_PROG(RM,rm,rm)
++
++PKG_PROG_PKG_CONFIG()
++
++m4_ifdef([PKG_CHECK_VAR], [],
++[AC_DEFUN([PKG_CHECK_VAR],
++ [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
++ AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
++ _PKG_CONFIG([$1], [variable="][$3]["], [$2])
++ AS_VAR_COPY([$1], [pkg_cv_][$1])
++ AS_VAR_IF([$1], [""], [$5], [$4])dnl
++ ])# PKG_CHECK_VAR
++])
++
+ AC_CHECK_HEADER(fc14audiodecoder.h,
+ [],[AC_MSG_ERROR([fc14audiodecoder.h not found])])
+ AC_CHECK_LIB(fc14audiodecoder,fc14dec_new)
+@@ -17,42 +35,49 @@
+ AC_MSG_ERROR([libfc14audiodecoder not found])
+ fi
+
+-dnl versions of gstreamer and plugins-base
++dnl === GStreamer 0.10.x ===
++
+ GST_MAJORMINOR=0.10
+ GST_REQUIRED=0.10.0
+-GSTPB_REQUIRED=0.10.0
+
+-PKG_CHECK_MODULES(GST, \
+- gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED,
+- HAVE_GST=yes,HAVE_GST=no)
+-
+-if test "x$GST_LIBS" != "x"; then
+- CFLAGS="$CFLAGS $GST_CFLAGS"
+- CXXFLAGS="$CXXFLAGS $GST_CFLAGS"
+- LIBS="$LIBS $GST_LIBS"
+- AC_MSG_RESULT(yes)
+-else
+- AC_MSG_RESULT(no)
++AC_MSG_CHECKING([GStreamer $GST_MAJORMINOR])
++PKG_CHECK_EXISTS([gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED], AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]) )
++
++PKG_CHECK_MODULES([GST],[gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED],[HAVE_GST=yes],[HAVE_GST=no])
++if test "$HAVE_GST" = "yes"; then
++
++ PKG_CHECK_VAR([GST_PLUGIN_DIR], [gstreamer-$GST_MAJORMINOR], [pluginsdir], [], [AC_MSG_ERROR([Cannot retrieve GStreamer pluginsdir pkgconfig variable])])
+ fi
+
+-AC_PATH_PROG(RM,rm,rm)
++dnl === GStreamer 1.0.x ===
+
+-AM_DISABLE_STATIC
+-AM_PROG_LIBTOOL
++GST1_MAJORMINOR=1.0
++GST1_REQUIRED=1.0.0
++
++AC_MSG_CHECKING([GStreamer $GST1_MAJORMINOR])
++PKG_CHECK_EXISTS([gstreamer-$GST1_MAJORMINOR >= $GST1_REQUIRED], AC_MSG_RESULT([yes]), AC_MSG_RESULT([no]) )
++
++PKG_CHECK_MODULES([GST1],[gstreamer-$GST1_MAJORMINOR >= $GST1_REQUIRED],[HAVE_GST1=yes],[HAVE_GST1=no])
++if test "$HAVE_GST1" = "yes"; then
++ PKG_CHECK_VAR([GST1_PLUGIN_DIR], [gstreamer-$GST1_MAJORMINOR], [pluginsdir], [], [AC_MSG_ERROR([Cannot retrieve GStreamer pluginsdir pkgconfig variable])])
++
++ PKG_CHECK_MODULES([GST1_AUDIO],[gstreamer-audio-$GST1_MAJORMINOR >= $GST1_REQUIRED],[],AC_MSG_ERROR([gstreamer-audio-$GST1_MAJORMINOR.pc not found!]))
++fi
++
++dnl ===
+
+-dnl set the location where plugins should be installed
+-if test "x${prefix}" = "x$HOME"; then
+- GST_PLUGIN_DIR="$HOME/.gstreamer-$GST_MAJORMINOR/plugins"
+-else
+- GST_PLUGIN_DIR="\$(libdir)/gstreamer-$GST_MAJORMINOR"
++if test "$HAVE_GST" = "no"; then
++ if test "$HAVE_GST1" = "no"; then
++ AC_MSG_ERROR([No GStreamer API found!])
++ fi
+ fi
+-AC_SUBST(GST_PLUGIN_DIR)
+
+ dnl set proper LDFLAGS for plugins
+ GST_PLUGIN_LDFLAGS='-module -avoid-version -export-symbols-regex [_]*\(gst_\|Gst\|GST_\).*'
+ AC_SUBST(GST_PLUGIN_LDFLAGS)
+
+-dnl make GST_MAJORMINOR available in Makefile.am
+-AC_SUBST(GST_MAJORMINOR)
++AM_CONDITIONAL([GST_COND], [test "$HAVE_GST" = yes])
++AM_CONDITIONAL([GST1_COND], [test "$HAVE_GST1" = yes])
++AC_CONFIG_FILES([gst1/Makefile])
+
+-AC_OUTPUT(Makefile)
++AC_OUTPUT([Makefile])
+diff -Nur gstreamer-plugin-fc-0.2-orig/gst1/gst1fcdec.c gstreamer-plugin-fc-0.2/gst1/gst1fcdec.c
+--- gstreamer-plugin-fc-0.2-orig/gst1/gst1fcdec.c 1970-01-01 01:00:00.000000000 +0100
++++ gstreamer-plugin-fc-0.2/gst1/gst1fcdec.c 2013-05-02 17:28:45.000000000 +0200
+@@ -0,0 +1,702 @@
++/*
++ * GStreamer plugin - AMIGA Future Composer audio file decoder
++ * Copyright (C) 2008 Michael Schwendt <mschwendt at users.sf.net>
++ *
++ * Based on GStreamer Plugin Writer's Guide (1.0.6 and 0.10.20.1) templates:
++ * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart.org>
++ * Copyright (C) 2005 Ronald S. Bultje <rbultje at ronald.bitfreak.net>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program 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 General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++/**
++ * SECTION:element-fcdec
++ *
++ * AMIGA Future Composer module decoder/player.
++ *
++ * <refsect2>
++ * <title>Example launch line</title>
++ * |[
++ * gst-launch -v filesrc location=Astaroth.FC13 ! fcdec ! audioconvert ! alsasink
++ * ]|
++ * </refsect2>
++ */
++
++#include <string.h>
++#include <fc14audiodecoder.h>
++#include <gst/audio/audio.h>
++
++#include "config.h"
++#include "gstfcdec.h"
++
++#define OUR_MIME_TYPE "audio/x-futcomp"
++
++#define DEFAULT_BLOCKSIZE 4096
++#define DEFAULT_MAXSIZE 128*1024
++
++#define GST_CAT_DEFAULT gst_fcdec_debug
++GST_DEBUG_CATEGORY_STATIC (gst_fcdec_debug);
++
++enum
++{
++ PROP_0,
++ PROP_BLOCKSIZE,
++ PROP_METADATA
++};
++
++static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
++ GST_PAD_SINK,
++ GST_PAD_ALWAYS,
++ GST_STATIC_CAPS (OUR_MIME_TYPE)
++ );
++
++#define FORMATS "{ "GST_AUDIO_NE(S16)","GST_AUDIO_NE(U16)", S8, U8 }"
++
++static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
++ GST_PAD_SRC,
++ GST_PAD_ALWAYS,
++ GST_STATIC_CAPS ("audio/x-raw, "
++ "format = (string) " FORMATS ", "
++ "layout = (string) interleaved, "
++ "rate = (int) [ 11025, 48000 ], "
++ "channels = (int) [ 1, 2 ]"
++ )
++ );
++
++#define gst_fcdec_parent_class parent_class
++G_DEFINE_TYPE (GstFCDec, gst_fcdec, GST_TYPE_ELEMENT);
++
++static void gst_fcdec_class_init (GstFCDecClass *gclass);
++static void gst_fcdec_init (GstFCDec *fcdec);
++static void gst_fcdec_finalize (GObject *object);
++
++static GstFlowReturn gst_fcdec_chain (GstPad *pad, GstObject *parent, GstBuffer *buf);
++static gboolean gst_fcdec_sink_event (GstPad *pad, GstObject *parent, GstEvent *event);
++
++static gboolean gst_fcdec_src_convert (GstPad *pad, GstFormat src_format,
++ gint64 src_value, GstFormat *dest_format, gint64 *dest_value);
++
++static gboolean gst_fcdec_src_event (GstPad *pad, GstObject *parent, GstEvent *event);
++static gboolean gst_fcdec_src_query (GstPad *pad, GstObject *parent, GstQuery *query);
++
++static void gst_fcdec_get_property (GObject *object, guint prop_id,
++ GValue *value, GParamSpec *pspec);
++static void gst_fcdec_set_property (GObject *object, guint prop_id,
++ const GValue *value, GParamSpec *pspec);
++
++/* GObject vmethod implementations */
++
++/* initialize the plugin's class */
++static void
++gst_fcdec_class_init (GstFCDecClass *klass)
++{
++ GObjectClass *gobject_class = (GObjectClass*)klass;
++ GstElementClass *gstelement_class = (GstElementClass*)klass;
++
++ gst_element_class_set_details_simple(gstelement_class,
++ "Future Composer decoder",
++ "Codec/Decoder/Audio",
++ "decodes AMIGA Future Composer modules",
++ "Michael Schwendt <mschwendt at users.sf.net>");
++
++ gobject_class->finalize = gst_fcdec_finalize;
++ gobject_class->set_property = gst_fcdec_set_property;
++ gobject_class->get_property = gst_fcdec_get_property;
++
++ g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
++ g_param_spec_ulong ("blocksize", "Block size",
++ "Size in bytes to output per buffer", 1, G_MAXULONG,
++ DEFAULT_BLOCKSIZE, (GParamFlags) G_PARAM_READWRITE));
++ g_object_class_install_property (gobject_class, PROP_METADATA,
++ g_param_spec_boxed ("metadata", "Metadata", "Metadata", GST_TYPE_CAPS,
++ (GParamFlags) G_PARAM_READABLE));
++
++ gst_element_class_add_pad_template (gstelement_class,
++ gst_static_pad_template_get (&src_factory));
++ gst_element_class_add_pad_template (gstelement_class,
++ gst_static_pad_template_get (&sink_factory));
++}
++
++/* initialize the new element
++ * instantiate pads and add them to element
++ * set pad callback functions
++ * initialize instance structure
++ */
++static void
++gst_fcdec_init (GstFCDec *fcdec)
++{
++ fcdec->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
++ gst_pad_set_chain_function (fcdec->sinkpad, gst_fcdec_chain);
++ gst_pad_set_event_function (fcdec->sinkpad, gst_fcdec_sink_event);
++ gst_element_add_pad (GST_ELEMENT (fcdec), fcdec->sinkpad);
++
++ fcdec->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
++ gst_pad_set_event_function (fcdec->srcpad, gst_fcdec_src_event);
++ gst_pad_set_query_function (fcdec->srcpad, gst_fcdec_src_query);
++ gst_pad_use_fixed_caps (fcdec->srcpad);
++ gst_element_add_pad (GST_ELEMENT (fcdec), fcdec->srcpad);
++
++ fcdec->decoder = fc14dec_new();
++
++ fcdec->filebuf = (guchar *) g_malloc (DEFAULT_MAXSIZE);
++ if (fcdec->filebuf) {
++ fcdec->filebufsize = DEFAULT_MAXSIZE;
++ }
++ else {
++ fcdec->filebufsize = 0;
++ }
++ fcdec->filelen = 0;
++ fcdec->blocksize = DEFAULT_BLOCKSIZE;
++ fcdec->totalbytes = 0;
++ fcdec->nsecs = 0;
++}
++
++static void
++gst_fcdec_finalize (GObject *object)
++{
++ GstFCDec *fcdec = GST_FCDEC (object);
++
++ g_free (fcdec->filebuf);
++ fc14dec_delete(fcdec->decoder);
++
++ G_OBJECT_CLASS (parent_class)->finalize (object);
++}
++
++static gboolean
++fcdec_negotiate (GstFCDec *fcdec)
++{
++ GstCaps *allowed;
++ GstStructure *structure;
++ int rate = 44100;
++ int channels = 1;
++ GstCaps *caps;
++ const gchar *str;
++ GstAudioFormat format;
++ gchar *stream_id;
++
++ allowed = gst_pad_get_pad_template_caps (fcdec->srcpad);
++ allowed = gst_caps_make_writable (allowed);
++
++ GST_DEBUG_OBJECT (fcdec, "allowed caps: %" GST_PTR_FORMAT, allowed);
++ allowed = gst_caps_normalize (allowed);
++ structure = gst_caps_get_structure (allowed, 0);
++
++ str = gst_structure_get_string (structure, "format");
++ if (str == NULL) {
++ goto invalid_format;
++ }
++
++ format = gst_audio_format_from_string (str);
++ switch (format) {
++ case GST_AUDIO_FORMAT_S8:
++ fcdec->bits = 8;
++ fcdec->zerosample = 0x00;
++ break;
++ case GST_AUDIO_FORMAT_U8:
++ fcdec->bits = 8;
++ fcdec->zerosample = 0x80;
++ break;
++ case GST_AUDIO_FORMAT_S16:
++ fcdec->bits = 16;
++ fcdec->zerosample = 0x0000;
++ break;
++ case GST_AUDIO_FORMAT_U16:
++ fcdec->bits = 16;
++ fcdec->zerosample = 0x8000;
++ break;
++ default:
++ goto invalid_format;
++ }
++
++ gst_structure_get_int (structure, "rate", &rate);
++ fcdec->frequency = rate;
++ gst_structure_get_int (structure, "channels", &channels);
++ fcdec->channels = channels;
++
++ stream_id = gst_pad_create_stream_id (fcdec->srcpad, GST_ELEMENT_CAST (fcdec), NULL);
++ gst_pad_push_event (fcdec->srcpad, gst_event_new_stream_start (stream_id));
++ g_free (stream_id);
++
++ caps = gst_caps_new_simple ("audio/x-raw",
++ "format", G_TYPE_STRING, gst_audio_format_to_string (format),
++ "layout", G_TYPE_STRING, "interleaved",
++ "rate", G_TYPE_INT, fcdec->frequency,
++ "channels", G_TYPE_INT, fcdec->channels, NULL);
++ gst_pad_set_caps (fcdec->srcpad, caps);
++ gst_caps_unref (caps);
++
++ gst_caps_unref (allowed);
++
++ return TRUE;
++
++invalid_format:
++ {
++ GST_DEBUG_OBJECT (fcdec, "invalid audio caps");
++ gst_caps_unref (allowed);
++ return FALSE;
++ }
++}
++
++static void
++play_loop (GstPad *pad)
++{
++ GstFlowReturn ret;
++ GstFCDec *fcdec;
++ GstBuffer *out;
++ GstMapInfo out_map;
++ gint64 value, offset, time;
++ GstFormat format;
++
++ fcdec = GST_FCDEC (gst_pad_get_parent (pad));
++
++ out = gst_buffer_new_and_alloc (fcdec->blocksize);
++
++ if (!gst_buffer_map (out, &out_map, GST_MAP_WRITE) ) {
++ return;
++ }
++ fc14dec_buffer_fill(fcdec->decoder,out_map.data,out_map.size);
++ gst_buffer_unmap (out, &out_map);
++
++ if (fc14dec_song_end(fcdec->decoder)) {
++ gst_pad_pause_task (pad);
++ gst_pad_push_event (pad, gst_event_new_eos ());
++ goto done;
++ }
++
++ format = GST_FORMAT_DEFAULT;
++ gst_fcdec_src_convert (fcdec->srcpad,
++ GST_FORMAT_BYTES, fcdec->totalbytes, &format, &offset);
++ GST_BUFFER_OFFSET (out) = offset;
++
++ format = GST_FORMAT_TIME;
++ gst_fcdec_src_convert (fcdec->srcpad,
++ GST_FORMAT_BYTES, fcdec->totalbytes, &format, &time);
++ GST_BUFFER_PTS (out) = time;
++
++ fcdec->totalbytes += fcdec->blocksize;
++
++ format = GST_FORMAT_DEFAULT;
++ gst_fcdec_src_convert (fcdec->srcpad,
++ GST_FORMAT_BYTES, fcdec->totalbytes, &format, &value);
++ GST_BUFFER_OFFSET_END (out) = value;
++
++ format = GST_FORMAT_TIME;
++ gst_fcdec_src_convert (fcdec->srcpad,
++ GST_FORMAT_BYTES, fcdec->totalbytes, &format, &value);
++ GST_BUFFER_DURATION (out) = value - time;
++
++ if ((ret = gst_pad_push (fcdec->srcpad, out)) != GST_FLOW_OK) {
++ // if (ret == GST_FLOW_NOT_LINKED) {
++ // printf("flow not linked\n");
++ // }
++ goto pause;
++ }
++
++done:
++ return;
++
++ /* ERRORS */
++pause:
++ {
++ const gchar *reason = gst_flow_get_name (ret);
++
++ GST_DEBUG_OBJECT (fcdec, "pausing task, reason %s", reason);
++ gst_pad_pause_task (pad);
++
++ if (ret == GST_FLOW_ERROR || ret == GST_FLOW_NOT_LINKED) {
++ if (ret == GST_FLOW_EOS) {
++ /* perform EOS logic, FIXME, segment seek? */
++ gst_pad_push_event (pad, gst_event_new_eos ());
++ } else {
++ /* for fatal errors we post an error message */
++ GST_ELEMENT_ERROR (fcdec, STREAM, FAILED,
++ (NULL), ("streaming task paused, reason %s", reason));
++ gst_pad_push_event (pad, gst_event_new_eos ());
++ }
++ }
++ goto done;
++ }
++}
++
++static gboolean
++start_play_file(GstFCDec *fcdec)
++{
++ GstSegment *seg;
++
++ if (!fcdec->filebuf || !fcdec->filelen ||
++ !fc14dec_init(fcdec->decoder,fcdec->filebuf,fcdec->filelen) ) {
++ GST_ELEMENT_ERROR (fcdec, LIBRARY, INIT,
++ ("Could not load FC module"), ("Could not load FC module"));
++ return FALSE;
++ }
++ /*
++ if (!fcdec_negotiate (fcdec)) {
++ GST_ELEMENT_ERROR (fcdec, CORE, NEGOTIATION,
++ ("Could not negotiate format"), ("Could not negotiate format"));
++ return FALSE;
++ }
++ */
++
++ //printf("format = %s\n",fc14dec_format_name(fcdec->decoder));
++ fcdec->nsecs = 1000*1000*fc14dec_duration(fcdec->decoder);
++ fc14dec_mixer_init(fcdec->decoder,fcdec->frequency,fcdec->bits,fcdec->channels,fcdec->zerosample);
++
++ seg = gst_segment_new();
++ gst_segment_init(seg, GST_FORMAT_TIME);
++ gst_pad_push_event (fcdec->srcpad, gst_event_new_segment(seg));
++ gst_segment_free(seg);
++
++ return gst_pad_start_task (fcdec->srcpad,
++ (GstTaskFunction) play_loop, fcdec->srcpad, NULL);
++}
++
++static gboolean
++gst_fcdec_handle_seek (GstFCDec *fcdec, GstEvent *event)
++{
++ GstSeekType starttype, stoptype;
++ GstSeekFlags flags;
++ GstFormat format;
++ gdouble rate;
++ gint64 start, stop;
++
++ gst_event_parse_seek (event, &rate, &format, &flags, &starttype, &start,
++ &stoptype, &stop);
++
++ // TODO: convert this if necessary
++ if (format != GST_FORMAT_TIME) {
++ GST_DEBUG_OBJECT (fcdec, "only support seeks in TIME format");
++ return FALSE;
++ }
++
++ gst_pad_push_event (fcdec->srcpad, gst_event_new_flush_start ());
++
++ format = GST_FORMAT_BYTES;
++ gst_fcdec_src_convert (fcdec->srcpad,
++ GST_FORMAT_TIME, start, &format, &fcdec->totalbytes);
++
++ fc14dec_seek(fcdec->decoder, start/(1000*1000));
++
++ gst_pad_push_event (fcdec->srcpad, gst_event_new_flush_stop (TRUE));
++
++ GstSegment *seg = gst_segment_new();
++ gst_segment_init(seg, GST_FORMAT_TIME);
++ gboolean update;
++ gst_segment_do_seek(seg,rate,GST_FORMAT_TIME,GST_SEEK_FLAG_NONE,GST_SEEK_TYPE_SET,start,GST_SEEK_TYPE_NONE,start,&update);
++ gst_pad_push_event (fcdec->srcpad, gst_event_new_segment(seg));
++ gst_segment_free(seg);
++
++ gst_pad_start_task (fcdec->srcpad,
++ (GstTaskFunction) play_loop, fcdec->srcpad, NULL);
++ return TRUE;
++}
++
++static gboolean
++gst_fcdec_sink_event (GstPad *pad, GstObject *parent, GstEvent *event)
++{
++ gboolean ret;
++ GstFCDec *fcdec;
++
++ fcdec = GST_FCDEC (parent);
++
++ switch (GST_EVENT_TYPE (event)) {
++ case GST_EVENT_EOS:
++ ret = start_play_file (fcdec);
++ break;
++ case GST_EVENT_SEGMENT:
++ ret = TRUE;
++ break;
++ case GST_EVENT_CAPS:
++ ret = fcdec_negotiate(fcdec);
++ if (!ret) {
++ GST_ELEMENT_ERROR (fcdec, CORE, NEGOTIATION,
++ ("Could not negotiate format"), ("Could not negotiate format"));
++ }
++ break;
++ default:
++ ret = gst_pad_event_default (pad, parent, event);
++ break;
++ }
++ return ret;
++}
++
++/* chain function
++ * this function does the actual processing
++ */
++static GstFlowReturn
++gst_fcdec_chain (GstPad *pad, GstObject *parent, GstBuffer *buf)
++{
++ GstFCDec *fcdec;
++ guint64 size;
++ GstMapInfo buf_map;
++ gboolean ret;
++
++ fcdec = GST_FCDEC (parent);
++ ret = gst_buffer_map (buf, &buf_map, GST_MAP_READ);
++ if ( !ret ) {
++ return GST_FLOW_ERROR;
++ }
++ size = buf_map.size;
++
++ // g_print ("Have data of size %" G_GSIZE_FORMAT" bytes!\n",
++ // gst_buffer_get_size (buf));
++
++ if (fcdec->filelen + size > fcdec->filebufsize) {
++ fcdec->filebufsize += DEFAULT_MAXSIZE;
++ fcdec->filebuf = (guchar *) g_realloc(fcdec->filebuf,fcdec->filebufsize);
++ if ( !fcdec->filebuf ) {
++ GST_ELEMENT_ERROR (fcdec, STREAM, DECODE,
++ (NULL), ("Input data buffer reallocation failed"));
++ fcdec->filebufsize = fcdec->filelen = 0;
++ return GST_FLOW_ERROR;
++ }
++ }
++
++ memcpy (fcdec->filebuf + fcdec->filelen, buf_map.data, size);
++ fcdec->filelen += size;
++
++ gst_buffer_unmap (buf, &buf_map);
++ gst_buffer_unref (buf);
++
++ return GST_FLOW_OK;
++}
++
++static gboolean
++gst_fcdec_src_convert (GstPad *pad, GstFormat src_format, gint64 src_value,
++ GstFormat *dest_format, gint64 *dest_value)
++{
++ gboolean res = TRUE;
++ guint scale = 1;
++ GstFCDec *fcdec;
++ gint bytes_per_sample;
++
++ fcdec = GST_FCDEC (gst_pad_get_parent (pad));
++
++ if (src_format == *dest_format) {
++ *dest_value = src_value;
++ return TRUE;
++ }
++
++ bytes_per_sample = (fcdec->bits >> 3) * fcdec->channels;
++
++ switch (src_format) {
++ case GST_FORMAT_BYTES:
++ switch (*dest_format) {
++ case GST_FORMAT_DEFAULT:
++ if (bytes_per_sample == 0)
++ return FALSE;
++ *dest_value = src_value / bytes_per_sample;
++ break;
++ case GST_FORMAT_TIME:
++ {
++ gint byterate = bytes_per_sample * fcdec->frequency;
++
++ if (byterate == 0)
++ return FALSE;
++ *dest_value =
++ gst_util_uint64_scale_int (src_value, GST_SECOND, byterate);
++ break;
++ }
++ default:
++ res = FALSE;
++ }
++ break;
++ case GST_FORMAT_DEFAULT:
++ switch (*dest_format) {
++ case GST_FORMAT_BYTES:
++ *dest_value = src_value * bytes_per_sample;
++ break;
++ case GST_FORMAT_TIME:
++ if (fcdec->frequency == 0)
++ return FALSE;
++ *dest_value =
++ gst_util_uint64_scale_int (src_value, GST_SECOND,
++ fcdec->frequency);
++ break;
++ default:
++ res = FALSE;
++ }
++ break;
++ case GST_FORMAT_TIME:
++ switch (*dest_format) {
++ case GST_FORMAT_BYTES:
++ scale = bytes_per_sample;
++ // fallthrough
++ case GST_FORMAT_DEFAULT:
++ *dest_value =
++ gst_util_uint64_scale_int (src_value,
++ scale * fcdec->frequency, GST_SECOND);
++ break;
++ default:
++ res = FALSE;
++ }
++ break;
++ default:
++ res = FALSE;
++ }
++ return res;
++}
++
++static gboolean
++gst_fcdec_src_event (GstPad *pad, GstObject *parent, GstEvent *event)
++{
++ gboolean res = FALSE;
++ GstFCDec *fcdec;
++
++ fcdec = GST_FCDEC (parent);
++
++ switch (GST_EVENT_TYPE (event)) {
++ case GST_EVENT_SEEK:
++ res = gst_fcdec_handle_seek (fcdec, event);
++ gst_event_unref( event);
++ break;
++ default:
++ res = gst_pad_event_default (pad, parent, event);
++ break;
++ }
++
++ return res;
++}
++
++static gboolean
++gst_fcdec_src_query (GstPad *pad, GstObject *parent, GstQuery *query)
++{
++ gboolean ret = TRUE;
++ GstFCDec *fcdec;
++ GstFormat format;
++
++ fcdec = GST_FCDEC (parent);
++
++ switch (GST_QUERY_TYPE (query)) {
++ case GST_QUERY_POSITION:
++ {
++ gint64 current;
++
++ gst_query_parse_position (query, &format, NULL);
++ /* we only know about our bytes, convert to requested format */
++ ret &= gst_fcdec_src_convert (pad,
++ GST_FORMAT_BYTES, fcdec->totalbytes, &format, ¤t);
++ if (ret) {
++ gst_query_set_position (query, format, current);
++ }
++ break;
++ }
++ case GST_QUERY_DURATION:
++ gst_query_parse_duration (query, &format, NULL);
++ GST_DEBUG_OBJECT(fcdec, "nsec song length: %" G_GUINT64_FORMAT, fcdec->nsecs);
++ gint64 val;
++ ret = gst_fcdec_src_convert (pad, GST_FORMAT_TIME,
++ fcdec->nsecs,
++ &format, &val);
++ if (ret) {
++ gst_query_set_duration (query, format, val);
++ }
++ break;
++ //case GST_QUERY_SEEKING:
++ //break;
++ default:
++ ret = gst_pad_query_default (pad, parent, query);
++ break;
++ }
++ return ret;
++}
++
++static void
++gst_fcdec_set_property (GObject * object, guint prop_id,
++ const GValue * value, GParamSpec * pspec)
++{
++ GstFCDec *fcdec = GST_FCDEC (object);
++
++ switch (prop_id) {
++ case PROP_BLOCKSIZE:
++ fcdec->blocksize = g_value_get_ulong (value);
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++ break;
++ }
++}
++
++static void
++gst_fcdec_get_property (GObject * object, guint prop_id,
++ GValue * value, GParamSpec * pspec)
++{
++ GstFCDec *fcdec = GST_FCDEC (object);
++
++ switch (prop_id) {
++ case PROP_BLOCKSIZE:
++ g_value_set_ulong (value, fcdec->blocksize);
++ break;
++ case PROP_METADATA:
++ g_value_set_boxed (value, NULL);
++ break;
++ default:
++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
++ break;
++ }
++}
++
++/* GstElement vmethod implementations */
++
++static void
++gst_fcdec_type_find (GstTypeFind * tf, gpointer ignore)
++{
++ GstCaps *caps;
++
++ const guint8 *data = gst_type_find_peek (tf, 0, 5);
++ if (data == NULL)
++ return;
++
++ void *decoder = fc14dec_new();
++ if (fc14dec_detect(decoder,(void*)data,5)) {
++ gchar ourtype[] = OUR_MIME_TYPE;
++ GST_DEBUG ("suggesting mime type %s", ourtype);
++ caps = gst_caps_new_simple (ourtype, NULL, NULL);
++ gst_type_find_suggest (tf, GST_TYPE_FIND_MAXIMUM, caps);
++ gst_caps_unref (caps);
++ }
++ fc14dec_delete(decoder);
++}
++
++/* entry point to initialize the plug-in
++ * initialize the plug-in itself
++ * register the element factories and other features
++ */
++static gboolean
++fcdec_init (GstPlugin * plugin)
++{
++ GST_DEBUG_CATEGORY_INIT (gst_fcdec_debug, "fcdec",
++ 0, "Future Composer decoder");
++
++ GstCaps *caps = gst_caps_new_simple(OUR_MIME_TYPE,NULL,NULL);
++ gst_type_find_register (plugin, OUR_MIME_TYPE, GST_RANK_PRIMARY,
++ gst_fcdec_type_find, NULL, caps, NULL, NULL);
++ gst_caps_unref(caps);
++
++ return gst_element_register (plugin, "fcdec", GST_RANK_PRIMARY,
++ GST_TYPE_FCDEC);
++}
++
++/* gstreamer looks for this structure to register fcdecs */
++GST_PLUGIN_DEFINE (
++ GST_VERSION_MAJOR,
++ GST_VERSION_MINOR,
++ fcdec,
++ "AMIGA Future Composer audio file decoder",
++ fcdec_init,
++ VERSION,
++ "GPL",
++ "GStreamer FC",
++ "http://xmms-fc.sf.net/"
++)
+diff -Nur gstreamer-plugin-fc-0.2-orig/gst1/gst1fcdec.h gstreamer-plugin-fc-0.2/gst1/gst1fcdec.h
+--- gstreamer-plugin-fc-0.2-orig/gst1/gst1fcdec.h 1970-01-01 01:00:00.000000000 +0100
++++ gstreamer-plugin-fc-0.2/gst1/gst1fcdec.h 2013-04-30 18:58:36.000000000 +0200
+@@ -0,0 +1,73 @@
++/*
++ * GStreamer plugin - AMIGA Future Composer audio file decoder
++ * Copyright (C) 2008 Michael Schwendt <mschwendt at users.sf.net>
++ *
++ * Based on GStreamer Plugin Writer's Guide (0.10.20.1) templates:
++ * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart.org>
++ * Copyright (C) 2005 Ronald S. Bultje <rbultje at ronald.bitfreak.net>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program 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 General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++#ifndef __GST_FCDEC_H__
++#define __GST_FCDEC_H__
++
++#include <gst/gst.h>
++
++G_BEGIN_DECLS
++
++/* #defines don't like whitespacey bits */
++#define GST_TYPE_FCDEC \
++ (gst_fcdec_get_type())
++#define GST_FCDEC(obj) \
++ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FCDEC,GstFCDec))
++#define GST_FCDEC_CLASS(klass) \
++ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FCDEC,GstFCDecClass))
++#define GST_IS_FCDEC(obj) \
++ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FCDEC))
++#define GST_IS_FCDEC_CLASS(klass) \
++ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FCDEC))
++
++typedef struct _GstFCDec GstFCDec;
++typedef struct _GstFCDecClass GstFCDecClass;
++
++struct _GstFCDec
++{
++ GstElement element;
++
++ GstPad *sinkpad, *srcpad;
++
++ void *decoder;
++
++ guchar *filebuf;
++ guint filebufsize, filelen;
++ gint64 totalbytes;
++
++ gulong blocksize;
++
++ gint frequency, bits, channels, zerosample;
++ gint64 nsecs;
++};
++
++struct _GstFCDecClass
++{
++ GstElementClass parent_class;
++};
++
++GType gst_fcdec_get_type (void);
++
++G_END_DECLS
++
++#endif /* __GST_FCDEC_H__ */
+diff -Nur gstreamer-plugin-fc-0.2-orig/gst1/Makefile.am gstreamer-plugin-fc-0.2/gst1/Makefile.am
+--- gstreamer-plugin-fc-0.2-orig/gst1/Makefile.am 1970-01-01 01:00:00.000000000 +0100
++++ gstreamer-plugin-fc-0.2/gst1/Makefile.am 2013-05-01 22:58:19.000000000 +0200
+@@ -0,0 +1,13 @@
++gst1plugindir = @GST1_PLUGIN_DIR@
++
++AM_CPPFLAGS = @GST1_CFLAGS@ @GST1_AUDIO_CFLAGS@
++
++gst1plugin_LTLIBRARIES = libgst1fcdec.la
++
++libgst1fcdec_la_LIBADD = @GST1_LIBS@ @GST1_AUDIO_LIBS@
++
++libgst1fcdec_la_LDFLAGS = @GST_PLUGIN_LDFLAGS@
++
++libgst1fcdec_la_SOURCES = \
++gst1fcdec.c \
++gst1fcdec.h
+diff -Nur gstreamer-plugin-fc-0.2-orig/Makefile.am gstreamer-plugin-fc-0.2/Makefile.am
+--- gstreamer-plugin-fc-0.2-orig/Makefile.am 2010-06-19 21:09:43.000000000 +0200
++++ gstreamer-plugin-fc-0.2/Makefile.am 2013-05-01 23:21:20.000000000 +0200
+@@ -7,9 +7,19 @@
+
+ EXTRA_DIST = m4 config.h.in
+
++if GST1_COND
++ GST1_MAYBE = gst1
++endif
++SUBDIRS = $(GST1_MAYBE)
++
+ plugindir = @GST_PLUGIN_DIR@
+
+-plugin_LTLIBRARIES = libgstfcdec.la
++AM_CPPFLAGS = @GST_CFLAGS@
++
++plugin_LTLIBRARIES =
++if GST_COND
++plugin_LTLIBRARIES += libgstfcdec.la
++endif
+
+ libgstfcdec_la_LDFLAGS = @GST_PLUGIN_LDFLAGS@
+
diff --git a/gstreamer-plugins-fc.spec b/gstreamer-plugins-fc.spec
index addf3e4..b1db738 100644
--- a/gstreamer-plugins-fc.spec
+++ b/gstreamer-plugins-fc.spec
@@ -1,35 +1,45 @@
-%define gst_majorminor 0.10
-%define gstreamer_ver 0.10.0
-
Name: gstreamer-plugins-fc
Version: 0.2
-Release: 6%{?dist}
-Summary: Future Composer input plugin for GStreamer
+Release: 7%{?dist}
+Summary: Future Composer input plugin for GStreamer 0.10.x
Group: Applications/Multimedia
License: GPLv2+
URL: http://xmms-fc.sourceforge.net
Source0: http://downloads.sourceforge.net/xmms-fc/gstreamer-plugin-fc-%{version}.tar.bz2
-BuildRequires: gstreamer-devel >= %{gstreamer_ver}
+BuildRequires: gstreamer-devel >= 0.10
BuildRequires: libfc14audiodecoder-devel
-# for %%{_libdir}/gstreamer-%%{gst_majorminor}
+# for %%{_libdir}/gstreamer-0.10
Requires: gstreamer%{?_isa}
# fixed upstream
Patch0: gstfcdec-0.2-configure.patch
BuildRequires: automake autoconf libtool
-
+# from cvs
+Patch1: gstreamer-plugin-fc-0.2-gstreamer1.patch
%description
This is an input plugin for GStreamer which can play back Future Composer
music files from AMIGA. Song-length detection and seek are implemented, too.
+%package -n gstreamer1-plugins-fc
+Summary: Future Composer input plugin for GStreamer 1.0.x
+Group: Applications/Multimedia
+BuildRequires: gstreamer1-devel >= 1.0
+# for %%{_libdir}/gstreamer-1.0
+Requires: gstreamer1%{?_isa}
+
+%description -n gstreamer1-plugins-fc
+This is an input plugin for GStreamer which can play back Future Composer
+music files from AMIGA. Song-length detection and seek are implemented, too.
+
%prep
%setup -q -n gstreamer-plugin-fc-%{version}
# https://bugzilla.redhat.com/925503
-%patch0 -p1
+#patch0 -p1
+%patch1 -p1
mv configure.in configure.ac
libtoolize -f ; autoreconf -f -i
@@ -46,12 +56,19 @@ find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
%files
-%defattr(-,root,root,-)
%doc COPYING README ChangeLog
-%{_libdir}/gstreamer-%{gst_majorminor}/*.so
+%{_libdir}/gstreamer-0.10/*.so
+
+
+%files -n gstreamer1-plugins-fc
+%doc COPYING README ChangeLog
+%{_libdir}/gstreamer-1.0/*.so
%changelog
+* Thu May 2 2013 Michael Schwendt <mschwendt at fedoraproject.org> - 0.2-7
+- BR gstreamer1-devel for merged GStreamer 1.0.x plugin libgst1fcdec.so
+
* Fri Apr 26 2013 Michael Schwendt <mschwendt at fedoraproject.org> - 0.2-6
- BR automake autoconf libtool and reconf for aarch64 updates (#925503).
- Update configure.in and rename it to configure.ac.
More information about the scm-commits
mailing list