[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, &current);
++      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