aiff: port to 1.0
authorWim Taymans <wim.taymans@collabora.co.uk>
Thu, 18 Apr 2013 15:18:12 +0000 (17:18 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Thu, 18 Apr 2013 15:18:49 +0000 (17:18 +0200)
configure.ac
gst/aiff/Makefile.am
gst/aiff/aiffmux.c
gst/aiff/aiffmux.h
gst/aiff/aiffparse.c
gst/aiff/aiffparse.h

index c15f5ecacaea6989c8c131b99e11b5460da9168c..2bc3219ad2a1bc3d9ff37db7814293ea8310ac81 100644 (file)
@@ -336,8 +336,7 @@ AG_GST_DEFAULT_ELEMENTS
 dnl *** plug-ins to include ***
 dnl Non ported plugins (non-dependant, then dependant)
 dnl Make sure you have a space before and after all plugins
-GST_PLUGINS_NONPORTED=" aiff \
- cdxaparse \
+GST_PLUGINS_NONPORTED=" cdxaparse \
  dccp faceoverlay \
  hdvparse ivfparse jp2kdecimator \
  librfb \
index ab971ef6f52d072df79223963b2c2defb98fb7b9..c1d1e48de3d97bd4ddfde4c291f77c3a38014c0b 100644 (file)
@@ -7,7 +7,7 @@ libgstaiff_la_CFLAGS = \
        $(GST_BASE_CFLAGS) \
        $(GST_CFLAGS)
 libgstaiff_la_LIBADD = \
-       $(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_API_VERSION) \
+       $(GST_PLUGINS_BASE_LIBS) -lgsttag-$(GST_API_VERSION) -lgstaudio-$(GST_API_VERSION)\
        $(GST_BASE_LIBS) \
        $(LIBM)
 libgstaiff_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
index cce45e7c2f8631bcb556a6d1f1e63c5f76030c35..593888496d828a9345d63215c1179661061b1305 100644 (file)
@@ -64,32 +64,8 @@ GST_DEBUG_CATEGORY (aiffmux_debug);
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("audio/x-raw-int, "
-        "width = (int) 8, "
-        "depth = (int) [ 1, 8 ], "
-        "signed = (boolean) true, "
-        "endianness = (int) BIG_ENDIAN, "
-        "channels = (int) [ 1, MAX ], "
-        "rate = (int) [ 1, MAX ];"
-        "audio/x-raw-int, "
-        "width = (int) 16, "
-        "depth = (int) [ 9, 16 ], "
-        "signed = (boolean) true, "
-        "endianness = (int) BIG_ENDIAN, "
-        "channels = (int) [ 1, MAX ], "
-        "rate = (int) [ 1, MAX ];"
-        "audio/x-raw-int, "
-        "width = (int) 24, "
-        "depth = (int) [ 17, 24 ], "
-        "signed = (boolean) true, "
-        "endianness = (int) BIG_ENDIAN, "
-        "channels = (int) [ 1, MAX ], "
-        "rate = (int) [ 1, MAX ];"
-        "audio/x-raw-int, "
-        "width = (int) 32, "
-        "depth = (int) [ 25, 32 ], "
-        "signed = (boolean) true, "
-        "endianness = (int) BIG_ENDIAN, "
+    GST_STATIC_CAPS ("audio/x-raw, "
+        "format = { S8, S16BE, S24BE, S32BE },"
         "channels = (int) [ 1, MAX ], " "rate = (int) [ 1, MAX ]")
     );
 
@@ -99,22 +75,8 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("audio/x-aiff")
     );
 
-GST_BOILERPLATE (GstAiffMux, gst_aiff_mux, GstElement, GST_TYPE_ELEMENT);
-
-static void
-gst_aiff_mux_base_init (gpointer gclass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  gst_element_class_set_static_metadata (element_class,
-      "AIFF audio muxer", "Muxer/Audio", "Multiplex raw audio into AIFF",
-      "Robert Swain <robert.swain@gmail.com>");
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_factory));
-}
+#define gst_aiff_mux_parent_class parent_class
+G_DEFINE_TYPE (GstAiffMux, gst_aiff_mux, GST_TYPE_ELEMENT);
 
 static GstStateChangeReturn
 gst_aiff_mux_change_state (GstElement * element, GstStateChange transition)
@@ -123,12 +85,9 @@ gst_aiff_mux_change_state (GstElement * element, GstStateChange transition)
   GstAiffMux *aiffmux = GST_AIFF_MUX (element);
 
   switch (transition) {
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      aiffmux->width = 0;
-      aiffmux->depth = 0;
-      aiffmux->channels = 0;
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      gst_audio_info_init (&aiffmux->info);
       aiffmux->length = 0;
-      aiffmux->rate = 0.0;
       aiffmux->sent_header = FALSE;
       aiffmux->overflow = FALSE;
       break;
@@ -136,7 +95,7 @@ gst_aiff_mux_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
   if (ret != GST_STATE_CHANGE_SUCCESS)
     return ret;
 
@@ -150,6 +109,15 @@ gst_aiff_mux_class_init (GstAiffMuxClass * klass)
 
   gstelement_class = (GstElementClass *) klass;
 
+  gst_element_class_set_static_metadata (gstelement_class,
+      "AIFF audio muxer", "Muxer/Audio", "Multiplex raw audio into AIFF",
+      "Robert Swain <robert.swain@gmail.com>");
+
+  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));
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_aiff_mux_change_state);
 }
@@ -235,15 +203,24 @@ static void
 gst_aiff_mux_write_comm_header (GstAiffMux * aiffmux, guint32 audio_data_size,
     GstByteWriter * writer)
 {
+  guint16 channels;
+  guint16 width, depth;
+  gdouble rate;
+
+  channels = GST_AUDIO_INFO_CHANNELS (&aiffmux->info);
+  width = GST_AUDIO_INFO_WIDTH (&aiffmux->info);
+  depth = GST_AUDIO_INFO_DEPTH (&aiffmux->info);
+  rate = GST_AUDIO_INFO_RATE (&aiffmux->info);
+
   gst_byte_writer_put_uint32_le_unchecked (writer,
       GST_MAKE_FOURCC ('C', 'O', 'M', 'M'));
   gst_byte_writer_put_uint32_be_unchecked (writer, 18);
-  gst_byte_writer_put_uint16_be_unchecked (writer, aiffmux->channels);
+  gst_byte_writer_put_uint16_be_unchecked (writer, channels);
   /* numSampleFrames value will be overwritten when known */
   gst_byte_writer_put_uint32_be_unchecked (writer,
-      audio_data_size / (aiffmux->width / 8 * aiffmux->channels));
-  gst_byte_writer_put_uint16_be_unchecked (writer, aiffmux->depth);
-  gst_aiff_mux_write_ext (writer, aiffmux->rate);
+      audio_data_size / (width / 8 * channels));
+  gst_byte_writer_put_uint16_be_unchecked (writer, depth);
+  gst_aiff_mux_write_ext (writer, rate);
 }
 
 static void
@@ -266,11 +243,13 @@ gst_aiff_mux_push_header (GstAiffMux * aiffmux, guint32 audio_data_size)
   GstFlowReturn ret;
   GstBuffer *outbuf;
   GstByteWriter *writer;
+  GstSegment seg;
 
   /* seek to beginning of file */
+  gst_segment_init (&seg, GST_FORMAT_BYTES);
+
   if (gst_pad_push_event (aiffmux->srcpad,
-          gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES,
-              0, GST_BUFFER_OFFSET_NONE, 0)) == FALSE) {
+          gst_event_new_segment (&seg)) == FALSE) {
     GST_ELEMENT_WARNING (aiffmux, STREAM, MUX,
         ("An output stream seeking error occurred when multiplexing."),
         ("Failed to seek to beginning of stream to write header."));
@@ -286,7 +265,7 @@ gst_aiff_mux_push_header (GstAiffMux * aiffmux, guint32 audio_data_size)
   gst_aiff_mux_write_ssnd_header (aiffmux, audio_data_size, writer);
 
   outbuf = gst_byte_writer_free_and_get_buffer (writer);
-  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (aiffmux->srcpad));
+
   ret = gst_pad_push (aiffmux->srcpad, outbuf);
 
   if (ret != GST_FLOW_OK) {
@@ -298,16 +277,15 @@ gst_aiff_mux_push_header (GstAiffMux * aiffmux, guint32 audio_data_size)
 }
 
 static GstFlowReturn
-gst_aiff_mux_chain (GstPad * pad, GstBuffer * buf)
+gst_aiff_mux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 {
-  GstAiffMux *aiffmux = GST_AIFF_MUX (GST_PAD_PARENT (pad));
+  GstAiffMux *aiffmux = GST_AIFF_MUX (parent);
   GstFlowReturn flow = GST_FLOW_OK;
   guint64 cur_size;
+  gsize buf_size;
 
-  if (!aiffmux->channels) {
-    gst_buffer_unref (buf);
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
+  if (!GST_AUDIO_INFO_CHANNELS (&aiffmux->info))
+    goto not_negotiated;
 
   if (G_UNLIKELY (aiffmux->overflow))
     goto overflow;
@@ -316,11 +294,8 @@ gst_aiff_mux_chain (GstPad * pad, GstBuffer * buf)
     /* use bogus size initially, we'll write the real
      * header when we get EOS and know the exact length */
     flow = gst_aiff_mux_push_header (aiffmux, 0x7FFF0000);
-
-    if (flow != GST_FLOW_OK) {
-      gst_buffer_unref (buf);
-      return flow;
-    }
+    if (flow != GST_FLOW_OK)
+      goto flow_error;
 
     GST_DEBUG_OBJECT (aiffmux, "wrote dummy header");
     aiffmux->sent_header = TRUE;
@@ -330,7 +305,9 @@ gst_aiff_mux_chain (GstPad * pad, GstBuffer * buf)
      A value of audiosize + AIFF_HEADER_LEN - 8 is written, so
      I'll error out if writing data that makes this overflow. */
   cur_size = aiffmux->length + AIFF_HEADER_LEN - 8;
-  if (G_UNLIKELY (cur_size + GST_BUFFER_SIZE (buf) >= G_MAXUINT32)) {
+  buf_size = gst_buffer_get_size (buf);
+
+  if (G_UNLIKELY (cur_size + buf_size >= G_MAXUINT32)) {
     GST_ERROR_OBJECT (aiffmux, "AIFF only supports about 4 GB worth of "
         "audio data, dropping any further data on the floor");
     GST_ELEMENT_WARNING (aiffmux, STREAM, MUX, ("AIFF has a 4GB size limit"),
@@ -340,36 +317,81 @@ gst_aiff_mux_chain (GstPad * pad, GstBuffer * buf)
     goto overflow;
   }
 
-  GST_LOG_OBJECT (aiffmux, "pushing %u bytes raw audio, ts=%" GST_TIME_FORMAT,
-      GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
+  GST_LOG_OBJECT (aiffmux,
+      "pushing %" G_GSIZE_FORMAT " bytes raw audio, ts=%" GST_TIME_FORMAT,
+      buf_size, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
 
-  buf = gst_buffer_make_metadata_writable (buf);
+  buf = gst_buffer_make_writable (buf);
 
-  gst_buffer_set_caps (buf, GST_PAD_CAPS (aiffmux->srcpad));
   GST_BUFFER_OFFSET (buf) = AIFF_HEADER_LEN + aiffmux->length;
   GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
 
-  aiffmux->length += GST_BUFFER_SIZE (buf);
+  aiffmux->length += buf_size;
 
   flow = gst_pad_push (aiffmux->srcpad, buf);
 
   return flow;
 
+not_negotiated:
+  {
+    GST_WARNING_OBJECT (aiffmux, "no input format negotiated");
+    gst_buffer_unref (buf);
+    return GST_FLOW_NOT_NEGOTIATED;
+  }
 overflow:
   {
     GST_WARNING_OBJECT (aiffmux, "output file too large, dropping buffer");
     gst_buffer_unref (buf);
     return GST_FLOW_OK;
   }
+flow_error:
+  {
+    GST_DEBUG_OBJECT (aiffmux, "got flow error %s", gst_flow_get_name (flow));
+    gst_buffer_unref (buf);
+    return flow;
+  }
 }
 
 static gboolean
-gst_aiff_mux_event (GstPad * pad, GstEvent * event)
+gst_aiff_mux_set_caps (GstAiffMux * aiffmux, GstCaps * caps)
+{
+  GstCaps *outcaps;
+  GstAudioInfo info;
+
+  if (aiffmux->sent_header) {
+    GST_WARNING_OBJECT (aiffmux, "cannot change format mid-stream");
+    return FALSE;
+  }
+
+  GST_DEBUG_OBJECT (aiffmux, "got caps: %" GST_PTR_FORMAT, caps);
+
+  if (!gst_audio_info_from_caps (&info, caps)) {
+    GST_WARNING_OBJECT (aiffmux, "caps incomplete");
+    return FALSE;
+  }
+
+  aiffmux->info = info;
+
+  GST_LOG_OBJECT (aiffmux,
+      "accepted caps: chans=%d depth=%d rate=%d",
+      GST_AUDIO_INFO_CHANNELS (&info), GST_AUDIO_INFO_DEPTH (&info),
+      GST_AUDIO_INFO_RATE (&info));
+
+  outcaps = gst_static_pad_template_get_caps (&src_factory);
+  gst_pad_push_event (aiffmux->srcpad, gst_event_new_caps (outcaps));
+  gst_caps_unref (outcaps);
+
+  return TRUE;
+}
+
+
+static gboolean
+gst_aiff_mux_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
   gboolean res = TRUE;
   GstAiffMux *aiffmux;
 
-  aiffmux = GST_AIFF_MUX (gst_pad_get_parent (pad));
+  aiffmux = GST_AIFF_MUX (parent);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_EOS:{
@@ -379,74 +401,41 @@ gst_aiff_mux_event (GstPad * pad, GstEvent * event)
       gst_aiff_mux_push_header (aiffmux, aiffmux->length);
 
       /* and forward the EOS event */
-      res = gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, parent, event);
+      break;
+    }
+    case GST_EVENT_CAPS:
+    {
+      GstCaps *caps;
+
+      gst_event_parse_caps (event, &caps);
+      res = gst_aiff_mux_set_caps (aiffmux, caps);
+      gst_event_unref (event);
       break;
     }
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       /* Just drop it, it's probably in TIME format
        * anyway. We'll send our own newsegment event */
       gst_event_unref (event);
       break;
     default:
-      res = gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, parent, event);
       break;
   }
-
-  gst_object_unref (aiffmux);
   return res;
 }
 
-static gboolean
-gst_aiff_mux_set_caps (GstPad * pad, GstCaps * caps)
-{
-  GstAiffMux *aiffmux;
-  GstStructure *structure;
-  gint chans, rate, depth;
-
-  aiffmux = GST_AIFF_MUX (GST_PAD_PARENT (pad));
-
-  if (aiffmux->sent_header) {
-    GST_WARNING_OBJECT (aiffmux, "cannot change format mid-stream");
-    return FALSE;
-  }
-
-  GST_DEBUG_OBJECT (aiffmux, "got caps: %" GST_PTR_FORMAT, caps);
-
-  structure = gst_caps_get_structure (caps, 0);
-  if (!gst_structure_get_int (structure, "channels", &chans) ||
-      !gst_structure_get_int (structure, "rate", &rate) ||
-      !gst_structure_get_int (structure, "depth", &depth)) {
-    GST_WARNING_OBJECT (aiffmux, "caps incomplete");
-    return FALSE;
-  }
-
-  aiffmux->channels = chans;
-  aiffmux->rate = rate;
-  aiffmux->depth = depth;
-  aiffmux->width = GST_ROUND_UP_8 (aiffmux->depth);
-
-  GST_LOG_OBJECT (aiffmux,
-      "accepted caps: chans=%u depth=%u rate=%lf",
-      aiffmux->channels, aiffmux->depth, aiffmux->rate);
-
-  return TRUE;
-}
-
 static void
-gst_aiff_mux_init (GstAiffMux * aiffmux, GstAiffMuxClass * gclass)
+gst_aiff_mux_init (GstAiffMux * aiffmux)
 {
   aiffmux->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
   gst_pad_set_chain_function (aiffmux->sinkpad,
       GST_DEBUG_FUNCPTR (gst_aiff_mux_chain));
   gst_pad_set_event_function (aiffmux->sinkpad,
       GST_DEBUG_FUNCPTR (gst_aiff_mux_event));
-  gst_pad_set_setcaps_function (aiffmux->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_aiff_mux_set_caps));
   gst_element_add_pad (GST_ELEMENT (aiffmux), aiffmux->sinkpad);
 
   aiffmux->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
   gst_pad_use_fixed_caps (aiffmux->srcpad);
-  gst_pad_set_caps (aiffmux->srcpad,
-      gst_static_pad_template_get_caps (&src_factory));
   gst_element_add_pad (GST_ELEMENT (aiffmux), aiffmux->srcpad);
 }
index da755ac3c79b379bdd05a5d89978af028d55a260..a49bea2f73796aa81d9f7f2351a5dbd907d607a2 100644 (file)
@@ -44,6 +44,7 @@
 #define __GST_AIFFMUX_H__
 
 #include <gst/gst.h>
+#include <gst/audio/audio.h>
 
 G_BEGIN_DECLS
 
@@ -74,12 +75,9 @@ struct _GstAiffMux
   GstPad *sinkpad;
   GstPad *srcpad;
 
-  guint width;
-  guint depth;
-  guint channels;
-  guint32 length;
-  gdouble rate;
+  GstAudioInfo info;
 
+  guint32 length;
   gboolean sent_header;
   gboolean overflow;
 };
index a49f92557debd0e1ec59e8dc4377ac546306281b..77fbdcae8162da54c6bf738a20c71f316e744b0a 100644 (file)
@@ -70,23 +70,26 @@ GST_DEBUG_CATEGORY (aiffparse_debug);
 
 static void gst_aiff_parse_dispose (GObject * object);
 
-static gboolean gst_aiff_parse_sink_activate (GstPad * sinkpad);
-static gboolean gst_aiff_parse_sink_activate_pull (GstPad * sinkpad,
-    gboolean active);
+static gboolean gst_aiff_parse_sink_activate (GstPad * sinkpad,
+    GstObject * parent);
+static gboolean gst_aiff_parse_sink_activate_mode (GstPad * sinkpad,
+    GstObject * parent, GstPadMode mode, gboolean active);
 static gboolean gst_aiff_parse_send_event (GstElement * element,
     GstEvent * event);
 static GstStateChangeReturn gst_aiff_parse_change_state (GstElement * element,
     GstStateChange transition);
 
-static const GstQueryType *gst_aiff_parse_get_query_types (GstPad * pad);
-static gboolean gst_aiff_parse_pad_query (GstPad * pad, GstQuery * query);
+static gboolean gst_aiff_parse_pad_query (GstPad * pad, GstObject * parent,
+    GstQuery * query);
 static gboolean gst_aiff_parse_pad_convert (GstPad * pad,
     GstFormat src_format,
     gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
 
-static GstFlowReturn gst_aiff_parse_chain (GstPad * pad, GstBuffer * buf);
+static GstFlowReturn gst_aiff_parse_chain (GstPad * pad, GstObject * parent,
+    GstBuffer * buf);
 static void gst_aiff_parse_loop (GstPad * pad);
-static gboolean gst_aiff_parse_srcpad_event (GstPad * pad, GstEvent * event);
+static gboolean gst_aiff_parse_srcpad_event (GstPad * pad, GstObject * parent,
+    GstEvent * event);
 
 static GstStaticPadTemplate sink_template_factory =
 GST_STATIC_PAD_TEMPLATE ("sink",
@@ -96,30 +99,15 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     );
 
 static GstStaticPadTemplate src_template_factory =
-    GST_STATIC_PAD_TEMPLATE ("src",
+GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS ";"
-        GST_AUDIO_FLOAT_PAD_TEMPLATE_CAPS)
+    GST_STATIC_CAPS (GST_AUDIO_CAPS_MAKE ("{ S8, S16BE, S16LE, S24BE, S24LE, "
+            "S32LE, S32BE, F32BE, F64BE }"))
     );
 
-GST_BOILERPLATE (GstAiffParse, gst_aiff_parse, GstElement, GST_TYPE_ELEMENT);
-
-static void
-gst_aiff_parse_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_template_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template_factory));
-
-  gst_element_class_set_static_metadata (element_class,
-      "AIFF audio demuxer", "Codec/Demuxer/Audio",
-      "Parse a .aiff file into raw audio",
-      "Pioneers of the Inevitable <songbird@songbirdnest.com>");
-}
+#define gst_aiff_parse_parent_class parent_class
+G_DEFINE_TYPE (GstAiffParse, gst_aiff_parse, GST_TYPE_ELEMENT);
 
 static void
 gst_aiff_parse_class_init (GstAiffParseClass * klass)
@@ -130,10 +118,18 @@ gst_aiff_parse_class_init (GstAiffParseClass * klass)
   gstelement_class = (GstElementClass *) klass;
   object_class = (GObjectClass *) klass;
 
-  parent_class = g_type_class_peek_parent (klass);
-
   object_class->dispose = gst_aiff_parse_dispose;
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_template_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_template_factory));
+
+  gst_element_class_set_static_metadata (gstelement_class,
+      "AIFF audio demuxer", "Codec/Demuxer/Audio",
+      "Parse a .aiff file into raw audio",
+      "Pioneers of the Inevitable <songbird@songbirdnest.com>");
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_aiff_parse_change_state);
   gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_aiff_parse_send_event);
@@ -158,10 +154,6 @@ gst_aiff_parse_reset (GstAiffParse * aiff)
   aiff->duration = 0;
   aiff->got_comm = FALSE;
 
-  if (aiff->caps) {
-    gst_caps_unref (aiff->caps);
-    aiff->caps = NULL;
-  }
   if (aiff->seek_event)
     gst_event_unref (aiff->seek_event);
   aiff->seek_event = NULL;
@@ -188,7 +180,7 @@ gst_aiff_parse_dispose (GObject * object)
 }
 
 static void
-gst_aiff_parse_init (GstAiffParse * aiffparse, GstAiffParseClass * g_class)
+gst_aiff_parse_init (GstAiffParse * aiffparse)
 {
   gst_aiff_parse_reset (aiffparse);
 
@@ -197,8 +189,8 @@ gst_aiff_parse_init (GstAiffParse * aiffparse, GstAiffParseClass * g_class)
       gst_pad_new_from_static_template (&sink_template_factory, "sink");
   gst_pad_set_activate_function (aiffparse->sinkpad,
       GST_DEBUG_FUNCPTR (gst_aiff_parse_sink_activate));
-  gst_pad_set_activatepull_function (aiffparse->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_aiff_parse_sink_activate_pull));
+  gst_pad_set_activatemode_function (aiffparse->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_aiff_parse_sink_activate_mode));
   gst_pad_set_chain_function (aiffparse->sinkpad,
       GST_DEBUG_FUNCPTR (gst_aiff_parse_chain));
   gst_element_add_pad (GST_ELEMENT_CAST (aiffparse), aiffparse->sinkpad);
@@ -207,8 +199,6 @@ gst_aiff_parse_init (GstAiffParse * aiffparse, GstAiffParseClass * g_class)
   aiffparse->srcpad =
       gst_pad_new_from_static_template (&src_template_factory, "src");
   gst_pad_use_fixed_caps (aiffparse->srcpad);
-  gst_pad_set_query_type_function (aiffparse->srcpad,
-      GST_DEBUG_FUNCPTR (gst_aiff_parse_get_query_types));
   gst_pad_set_query_function (aiffparse->srcpad,
       GST_DEBUG_FUNCPTR (gst_aiff_parse_pad_query));
   gst_pad_set_event_function (aiffparse->srcpad,
@@ -219,18 +209,23 @@ gst_aiff_parse_init (GstAiffParse * aiffparse, GstAiffParseClass * g_class)
 static gboolean
 gst_aiff_parse_parse_file_header (GstAiffParse * aiff, GstBuffer * buf)
 {
-  guint8 *data;
   guint32 header, type = 0;
+  GstMapInfo info;
 
-  if (GST_BUFFER_SIZE (buf) < 12) {
-    GST_WARNING_OBJECT (aiff, "Buffer too short");
+  if (!gst_buffer_map (buf, &info, GST_MAP_READ)) {
+    GST_WARNING_OBJECT (aiff, "Could not map buffer");
     goto not_aiff;
   }
 
-  data = GST_BUFFER_DATA (buf);
+  if (info.size < 12) {
+    GST_WARNING_OBJECT (aiff, "Buffer too short");
+    gst_buffer_unmap (buf, &info);
+    goto not_aiff;
+  }
 
-  header = GST_READ_UINT32_LE (data);
-  type = GST_READ_UINT32_LE (data + 8);
+  header = GST_READ_UINT32_LE (info.data);
+  type = GST_READ_UINT32_LE (info.data + 8);
+  gst_buffer_unmap (buf, &info);
 
   if (header != GST_MAKE_FOURCC ('F', 'O', 'R', 'M'))
     goto not_aiff;
@@ -286,14 +281,14 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
 {
   gboolean res;
   gdouble rate;
-  GstFormat format, bformat;
+  GstFormat format;
   GstSeekFlags flags;
   GstSeekType cur_type = GST_SEEK_TYPE_NONE, stop_type;
   gint64 cur, stop, upstream_size;
   gboolean flush;
   gboolean update;
   GstSegment seeksegment = { 0, };
-  gint64 last_stop;
+  gint64 position;
 
   if (event) {
     GST_DEBUG_OBJECT (aiff, "doing seek with event");
@@ -313,11 +308,11 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
       if (cur_type != GST_SEEK_TYPE_NONE)
         res =
             gst_pad_query_convert (aiff->srcpad, format, cur,
-            &aiff->segment.format, &cur);
+            aiff->segment.format, &cur);
       if (res && stop_type != GST_SEEK_TYPE_NONE)
         res =
             gst_pad_query_convert (aiff->srcpad, format, stop,
-            &aiff->segment.format, &stop);
+            aiff->segment.format, &stop);
       if (!res)
         goto no_format;
 
@@ -336,7 +331,7 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
 
   /* now we need to make sure the streaming thread is stopped. We do this by
    * either sending a FLUSH_START event downstream which will cause the
-   * streaming thread to stop with a WRONG_STATE.
+   * streaming thread to stop with a FLUSHING.
    * For a non-flushing seek we simply pause the task, which will happen as soon
    * as it completes one iteration (and thus might block when the sink is
    * blocking in preroll). */
@@ -352,9 +347,9 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
   GST_PAD_STREAM_LOCK (aiff->sinkpad);
 
   /* save current position */
-  last_stop = aiff->segment.last_stop;
+  position = aiff->segment.position;
 
-  GST_DEBUG_OBJECT (aiff, "stopped streaming at %" G_GINT64_FORMAT, last_stop);
+  GST_DEBUG_OBJECT (aiff, "stopped streaming at %" G_GINT64_FORMAT, position);
 
   /* copy segment, we need this because we still need the old
    * segment when we close the current segment. */
@@ -364,7 +359,7 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
    * right values in the segment to perform the seek */
   if (event) {
     GST_DEBUG_OBJECT (aiff, "configuring seek");
-    gst_segment_set_seek (&seeksegment, rate, format, flags,
+    gst_segment_do_seek (&seeksegment, rate, format, flags,
         cur_type, cur, stop_type, stop, &update);
   }
 
@@ -376,14 +371,14 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
   GST_DEBUG_OBJECT (aiff, "cur_type =%d", cur_type);
   if ((cur_type != GST_SEEK_TYPE_NONE)) {
     /* bring offset to bytes, if the bps is 0, we have the segment in BYTES and
-     * we can just copy the last_stop. If not, we use the bps to convert TIME to
+     * we can just copy the position. If not, we use the bps to convert TIME to
      * bytes. */
     if (aiff->bps > 0)
       aiff->offset =
-          gst_util_uint64_scale_ceil (seeksegment.last_stop,
+          gst_util_uint64_scale_ceil (seeksegment.position,
           (guint64) aiff->bps, GST_SECOND);
     else
-      aiff->offset = seeksegment.last_stop;
+      aiff->offset = seeksegment.position;
     GST_LOG_OBJECT (aiff, "offset=%" G_GUINT64_FORMAT, aiff->offset);
     aiff->offset -= (aiff->offset % aiff->bytes_per_sample);
     GST_LOG_OBJECT (aiff, "offset=%" G_GUINT64_FORMAT, aiff->offset);
@@ -412,8 +407,8 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
 
   /* make sure filesize is not exceeded due to rounding errors or so,
    * same precaution as in _stream_headers */
-  bformat = GST_FORMAT_BYTES;
-  if (gst_pad_query_peer_duration (aiff->sinkpad, &bformat, &upstream_size))
+  if (gst_pad_peer_query_duration (aiff->sinkpad, GST_FORMAT_BYTES,
+          &upstream_size))
     aiff->end_offset = MIN (aiff->end_offset, upstream_size);
 
   /* this is the range of bytes we will use for playback */
@@ -430,22 +425,7 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
   if (flush) {
     /* if we sent a FLUSH_START, we now send a FLUSH_STOP */
     GST_DEBUG_OBJECT (aiff, "sending flush stop");
-    gst_pad_push_event (aiff->srcpad, gst_event_new_flush_stop ());
-  } else if (aiff->segment_running) {
-    /* we are running the current segment and doing a non-flushing seek,
-     * close the segment first based on the previous last_stop. */
-    GST_DEBUG_OBJECT (aiff, "closing running segment %" G_GINT64_FORMAT
-        " to %" G_GINT64_FORMAT, aiff->segment.accum, aiff->segment.last_stop);
-
-    /* queue the segment for sending in the stream thread */
-    if (aiff->close_segment)
-      gst_event_unref (aiff->close_segment);
-    aiff->close_segment = gst_event_new_new_segment (TRUE,
-        aiff->segment.rate, aiff->segment.format,
-        aiff->segment.accum, aiff->segment.last_stop, aiff->segment.accum);
-
-    /* keep track of our last_stop */
-    seeksegment.accum = aiff->segment.last_stop;
+    gst_pad_push_event (aiff->srcpad, gst_event_new_flush_stop (TRUE));
   }
 
   /* now we did the seek and can activate the new segment values */
@@ -455,23 +435,20 @@ gst_aiff_parse_perform_seek (GstAiffParse * aiff, GstEvent * event)
   if (aiff->segment.flags & GST_SEEK_FLAG_SEGMENT) {
     gst_element_post_message (GST_ELEMENT_CAST (aiff),
         gst_message_new_segment_start (GST_OBJECT_CAST (aiff),
-            aiff->segment.format, aiff->segment.last_stop));
+            aiff->segment.format, aiff->segment.position));
   }
 
   /* now create the newsegment */
   GST_DEBUG_OBJECT (aiff, "Creating newsegment from %" G_GINT64_FORMAT
-      " to %" G_GINT64_FORMAT, aiff->segment.last_stop, stop);
+      " to %" G_GINT64_FORMAT, aiff->segment.position, stop);
 
   /* store the newsegment event so it can be sent from the streaming thread. */
   if (aiff->start_segment)
     gst_event_unref (aiff->start_segment);
-  aiff->start_segment =
-      gst_event_new_new_segment (FALSE, aiff->segment.rate,
-      aiff->segment.format, aiff->segment.last_stop, stop,
-      aiff->segment.last_stop);
+  aiff->start_segment = gst_event_new_segment (&aiff->segment);
 
   /* mark discont if we are going to stream from another position. */
-  if (last_stop != aiff->segment.last_stop) {
+  if (position != aiff->segment.position) {
     GST_DEBUG_OBJECT (aiff, "mark DISCONT, we did a seek to another position");
     aiff->discont = TRUE;
   }
@@ -519,9 +496,10 @@ gst_aiff_parse_peek_chunk_info (GstAiffParse * aiff, guint32 * tag,
   if (gst_adapter_available (aiff->adapter) < 8)
     return FALSE;
 
-  data = gst_adapter_peek (aiff->adapter, 8);
+  data = gst_adapter_map (aiff->adapter, 8);
   *tag = GST_READ_UINT32_LE (data);
   *size = GST_READ_UINT32_BE (data + 4);
+  gst_adapter_unmap (aiff->adapter);
 
   GST_DEBUG ("Next chunk size is %d bytes, type %" GST_FOURCC_FORMAT, *size,
       GST_FOURCC_ARGS (*tag));
@@ -567,7 +545,7 @@ gst_aiff_parse_peek_data (GstAiffParse * aiff, guint32 size,
   if (gst_adapter_available (aiff->adapter) < size)
     return FALSE;
 
-  *data = gst_adapter_peek (aiff->adapter, size);
+  *data = gst_adapter_map (aiff->adapter, size);
   return TRUE;
 }
 
@@ -646,31 +624,34 @@ gst_aiff_parse_read_IEEE80 (guint8 * buf)
 static gboolean
 gst_aiff_parse_parse_comm (GstAiffParse * aiff, GstBuffer * buf)
 {
-  guint8 *data;
   int size;
+  GstMapInfo info;
+  guint32 fourcc;
+
+  if (!gst_buffer_map (buf, &info, GST_MAP_READ)) {
+    GST_WARNING_OBJECT (aiff, "Can't map buffer");
+    gst_buffer_unref (buf);
+    return FALSE;
+  }
 
   if (aiff->is_aifc)
     size = 22;
   else
     size = 18;
 
-  if (GST_BUFFER_SIZE (buf) < size) {
-    GST_WARNING_OBJECT (aiff, "COMM chunk too short, cannot parse header");
-    return FALSE;
-  }
-
-  data = GST_BUFFER_DATA (buf);
+  if (info.size < size)
+    goto too_small;
 
-  aiff->channels = GST_READ_UINT16_BE (data);
-  aiff->total_frames = GST_READ_UINT32_BE (data + 2);
-  aiff->depth = GST_READ_UINT16_BE (data + 6);
+  aiff->channels = GST_READ_UINT16_BE (info.data);
+  aiff->total_frames = GST_READ_UINT32_BE (info.data + 2);
+  aiff->depth = GST_READ_UINT16_BE (info.data + 6);
   aiff->width = GST_ROUND_UP_8 (aiff->depth);
-  aiff->rate = (int) gst_aiff_parse_read_IEEE80 (data + 8);
+  aiff->rate = (int) gst_aiff_parse_read_IEEE80 (info.data + 8);
 
   aiff->floating_point = FALSE;
 
   if (aiff->is_aifc) {
-    guint32 fourcc = GST_READ_UINT32_LE (data + 18);
+    fourcc = GST_READ_UINT32_LE (info.data + 18);
 
     /* We only support the 'trivial' uncompressed AIFC, but it can be
      * either big or little endian */
@@ -693,16 +674,32 @@ gst_aiff_parse_parse_comm (GstAiffParse * aiff, GstBuffer * buf)
         aiff->endianness = G_BIG_ENDIAN;
         break;
       default:
-        GST_WARNING_OBJECT (aiff, "Unsupported compression in AIFC "
-            "file: %" GST_FOURCC_FORMAT,
-            GST_FOURCC_ARGS (GST_READ_UINT32_LE (data + 18)));
-        return FALSE;
-
+        goto unknown_compression;
     }
   } else
     aiff->endianness = G_BIG_ENDIAN;
 
+  gst_buffer_unmap (buf, &info);
+  gst_buffer_unref (buf);
+
   return TRUE;
+
+  /* ERRORS */
+too_small:
+  {
+    GST_WARNING_OBJECT (aiff, "COMM chunk too short, cannot parse header");
+    gst_buffer_unmap (buf, &info);
+    gst_buffer_unref (buf);
+    return FALSE;
+  }
+unknown_compression:
+  {
+    GST_WARNING_OBJECT (aiff, "Unsupported compression in AIFC "
+        "file: %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (fourcc));
+    gst_buffer_unmap (buf, &info);
+    gst_buffer_unref (buf);
+    return FALSE;
+  }
 }
 
 static GstFlowReturn
@@ -712,19 +709,23 @@ gst_aiff_parse_read_chunk (GstAiffParse * aiff, guint64 * offset, guint32 * tag,
   guint size;
   GstFlowReturn res;
   GstBuffer *buf;
+  GstMapInfo info;
 
   if ((res =
           gst_pad_pull_range (aiff->sinkpad, *offset, 8, &buf)) != GST_FLOW_OK)
     return res;
 
-  *tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
-  size = GST_READ_UINT32_BE (GST_BUFFER_DATA (buf) + 4);
+  gst_buffer_map (buf, &info, GST_MAP_READ);
+  *tag = GST_READ_UINT32_LE (info.data);
+  size = GST_READ_UINT32_BE (info.data + 4);
+  gst_buffer_unmap (buf, &info);
+  gst_buffer_unref (buf);
 
   if ((res =
           gst_pad_pull_range (aiff->sinkpad, (*offset) + 8, size,
               &buf)) != GST_FLOW_OK)
     return res;
-  else if (GST_BUFFER_SIZE (buf) < size)
+  else if (gst_buffer_get_size (buf) < size)
     goto too_small;
 
   *data = buf;
@@ -735,11 +736,12 @@ gst_aiff_parse_read_chunk (GstAiffParse * aiff, guint64 * offset, guint32 * tag,
   /* ERRORS */
 too_small:
   {
-    /* short read, we return UNEXPECTED to mark the EOS case */
-    GST_DEBUG_OBJECT (aiff, "not enough data (available=%u, needed=%u)",
-        GST_BUFFER_SIZE (buf), size);
+    /* short read, we return EOS to mark the EOS case */
+    GST_DEBUG_OBJECT (aiff,
+        "not enough data (available=%" G_GSIZE_FORMAT ", needed=%u)",
+        gst_buffer_get_size (buf), size);
     gst_buffer_unref (buf);
-    return GST_FLOW_UNEXPECTED;
+    return GST_FLOW_EOS;
   }
 
 }
@@ -747,24 +749,46 @@ too_small:
 static GstCaps *
 gst_aiff_parse_create_caps (GstAiffParse * aiff)
 {
-  GstCaps *caps;
+  GstCaps *caps = NULL;
+  const gchar *format = NULL;
 
   if (aiff->floating_point) {
-    caps = gst_caps_new_simple ("audio/x-raw-float",
-        "width", G_TYPE_INT, aiff->width,
-        "channels", G_TYPE_INT, aiff->channels,
-        "endianness", G_TYPE_INT, aiff->endianness,
-        "rate", G_TYPE_INT, aiff->rate, NULL);
+    if (aiff->endianness == G_BIG_ENDIAN) {
+      if (aiff->width == 32)
+        format = "F32BE";
+      else if (aiff->width == 32)
+        format = "F64BE";
+    }
   } else {
-    caps = gst_caps_new_simple ("audio/x-raw-int",
-        "width", G_TYPE_INT, aiff->width,
-        "depth", G_TYPE_INT, aiff->depth,
+    if (aiff->endianness == G_BIG_ENDIAN) {
+      if (aiff->width == 8)
+        format = "S8";
+      else if (aiff->width == 16)
+        format = "S16BE";
+      else if (aiff->width == 24)
+        format = "S24BE";
+      else if (aiff->width == 32)
+        format = "S32BE";
+    } else {
+      if (aiff->width == 8)
+        format = "S8";
+      else if (aiff->width == 16)
+        format = "S16LE";
+      else if (aiff->width == 24)
+        format = "S24LE";
+      else if (aiff->width == 32)
+        format = "S32LE";
+    }
+  }
+  if (format) {
+    caps = gst_caps_new_simple ("audio/x-raw",
+        "format", G_TYPE_STRING, format,
         "channels", G_TYPE_INT, aiff->channels,
-        "endianness", G_TYPE_INT, aiff->endianness,
-        "rate", G_TYPE_INT, aiff->rate, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+        "rate", G_TYPE_INT, aiff->rate, NULL);
   }
 
   GST_DEBUG_OBJECT (aiff, "Created caps: %" GST_PTR_FORMAT, caps);
+
   return caps;
 }
 
@@ -777,11 +801,9 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
   gboolean gotdata = FALSE;
   gboolean done = FALSE;
   GstEvent **event_p;
-  GstFormat bformat;
   gint64 upstream_size = 0;
 
-  bformat = GST_FORMAT_BYTES;
-  gst_pad_query_peer_duration (aiff->sinkpad, &bformat, &upstream_size);
+  gst_pad_peer_query_duration (aiff->sinkpad, GST_FORMAT_BYTES, &upstream_size);
   GST_DEBUG_OBJECT (aiff, "upstream size %" G_GUINT64_FORMAT, upstream_size);
 
   /* loop headers until we get data */
@@ -790,12 +812,17 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
       if (!gst_aiff_parse_peek_chunk_info (aiff, &tag, &size))
         return GST_FLOW_OK;
     } else {
+      GstMapInfo info;
+
       if ((res =
               gst_pad_pull_range (aiff->sinkpad, aiff->offset, 8,
                   &buf)) != GST_FLOW_OK)
         goto header_read_error;
-      tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
-      size = GST_READ_UINT32_BE (GST_BUFFER_DATA (buf) + 4);
+
+      gst_buffer_map (buf, &info, GST_MAP_READ);
+      tag = GST_READ_UINT32_LE (info.data);
+      size = GST_READ_UINT32_BE (info.data + 4);
+      gst_buffer_unmap (buf, &info);
     }
 
     GST_INFO_OBJECT (aiff,
@@ -806,6 +833,8 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
      */
     switch (tag) {
       case GST_MAKE_FOURCC ('C', 'O', 'M', 'M'):{
+        GstCaps *caps;
+
         if (aiff->streaming) {
           if (!gst_aiff_parse_peek_chunk (aiff, &tag, &size))
             return GST_FLOW_OK;
@@ -820,12 +849,8 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
             return res;
         }
 
-        if (!gst_aiff_parse_parse_comm (aiff, buf)) {
-          gst_buffer_unref (buf);
+        if (!gst_aiff_parse_parse_comm (aiff, buf))
           goto parse_header_error;
-        }
-
-        gst_buffer_unref (buf);
 
         /* do sanity checks of header fields */
         if (aiff->channels == 0)
@@ -835,11 +860,12 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
 
         GST_DEBUG_OBJECT (aiff, "creating the caps");
 
-        aiff->caps = gst_aiff_parse_create_caps (aiff);
-        if (!aiff->caps)
+        caps = gst_aiff_parse_create_caps (aiff);
+        if (caps == NULL)
           goto unknown_format;
 
-        gst_pad_set_caps (aiff->srcpad, aiff->caps);
+        gst_pad_push_event (aiff->srcpad, gst_event_new_caps (caps));
+        gst_caps_unref (caps);
 
         aiff->bytes_per_sample = aiff->channels * aiff->width / 8;
         aiff->bps = aiff->bytes_per_sample * aiff->rate;
@@ -851,37 +877,42 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
         break;
       }
       case GST_MAKE_FOURCC ('S', 'S', 'N', 'D'):{
-        GstBuffer *ssndbuf = NULL;
-        const guint8 *ssnddata = NULL;
         guint32 datasize;
 
         GST_DEBUG_OBJECT (aiff, "Got 'SSND' TAG, size : %d", size);
 
         /* Now, read the 8-byte header in the SSND chunk */
         if (aiff->streaming) {
+          const guint8 *ssnddata = NULL;
+
           if (!gst_aiff_parse_peek_data (aiff, 16, &ssnddata))
             return GST_FLOW_OK;
+
+          aiff->ssnd_offset = GST_READ_UINT32_BE (ssnddata + 8);
+          aiff->ssnd_blocksize = GST_READ_UINT32_BE (ssnddata + 12);
+          gst_adapter_unmap (aiff->adapter);
+          gst_adapter_flush (aiff->adapter, 16);
         } else {
+          GstBuffer *ssndbuf = NULL;
+          GstMapInfo info;
+
           gst_buffer_unref (buf);
           if ((res =
                   gst_pad_pull_range (aiff->sinkpad, aiff->offset, 16,
                       &ssndbuf)) != GST_FLOW_OK)
             goto header_read_error;
-          ssnddata = GST_BUFFER_DATA (ssndbuf);
-        }
-
-        aiff->ssnd_offset = GST_READ_UINT32_BE (ssnddata + 8);
-        aiff->ssnd_blocksize = GST_READ_UINT32_BE (ssnddata + 12);
 
-        gotdata = TRUE;
-        if (aiff->streaming) {
-          gst_adapter_flush (aiff->adapter, 16);
-        } else {
+          gst_buffer_map (ssndbuf, &info, GST_MAP_READ);
+          aiff->ssnd_offset = GST_READ_UINT32_BE (info.data + 8);
+          aiff->ssnd_blocksize = GST_READ_UINT32_BE (info.data + 12);
+          gst_buffer_unmap (ssndbuf, &info);
           gst_buffer_unref (ssndbuf);
         }
+
+        gotdata = TRUE;
+
         /* 8 byte chunk header, 8 byte SSND header */
         aiff->offset += 16;
-
         datasize = size - 16;
 
         aiff->datastart = aiff->offset + aiff->ssnd_offset;
@@ -920,7 +951,8 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
             return res;
         }
 
-        GST_LOG_OBJECT (aiff, "ID3 chunk of size %u", GST_BUFFER_SIZE (buf));
+        GST_LOG_OBJECT (aiff, "ID3 chunk of size %" G_GSIZE_FORMAT,
+            gst_buffer_get_size (buf));
 
         tags = gst_tag_list_from_id3v2_tag (buf);
         gst_buffer_unref (buf);
@@ -962,11 +994,11 @@ gst_aiff_parse_stream_headers (GstAiffParse * aiff)
 
   if (gst_aiff_parse_calculate_duration (aiff)) {
     gst_segment_init (&aiff->segment, GST_FORMAT_TIME);
-    gst_segment_set_duration (&aiff->segment, GST_FORMAT_TIME, aiff->duration);
+    aiff->segment.duration = aiff->duration;
   } else {
     /* no bitrate, let downstream peer do the math, we'll feed it bytes. */
     gst_segment_init (&aiff->segment, GST_FORMAT_BYTES);
-    gst_segment_set_duration (&aiff->segment, GST_FORMAT_BYTES, aiff->datasize);
+    aiff->segment.duration = aiff->datasize;
   }
 
   /* now we have all the info to perform a pending seek if any, if no
@@ -1127,7 +1159,7 @@ iterate_adapter:
    * amounts of data regardless of the playback rate */
   desired =
       MIN (gst_guint64_to_gdouble (aiff->dataleft),
-      MAX_BUFFER_SIZE * aiff->segment.abs_rate);
+      MAX_BUFFER_SIZE * ABS (aiff->segment.rate));
 
   if (desired >= aiff->bytes_per_sample && aiff->bytes_per_sample > 0)
     desired -= (desired % aiff->bytes_per_sample);
@@ -1161,12 +1193,11 @@ iterate_adapter:
     aiff->start_segment = NULL;
   }
   if (G_UNLIKELY (aiff->tags != NULL)) {
-    gst_element_found_tags_for_pad (GST_ELEMENT_CAST (aiff), aiff->srcpad,
-        aiff->tags);
+    gst_pad_push_event (aiff->srcpad, gst_event_new_tag (aiff->tags));
     aiff->tags = NULL;
   }
 
-  obtained = GST_BUFFER_SIZE (buf);
+  obtained = gst_buffer_get_size (buf);
 
   /* our positions in bytes */
   pos = aiff->offset - aiff->datastart;
@@ -1185,7 +1216,7 @@ iterate_adapter:
     duration = next_timestamp - timestamp;
 
     /* update current running segment position */
-    gst_segment_set_last_stop (&aiff->segment, GST_FORMAT_TIME, next_timestamp);
+    aiff->segment.position = next_timestamp;
   } else {
     /* no bitrate, all we know is that the first sample has timestamp 0, all
      * other positions and durations have unknown timestamp. */
@@ -1195,7 +1226,7 @@ iterate_adapter:
       timestamp = GST_CLOCK_TIME_NONE;
     duration = GST_CLOCK_TIME_NONE;
     /* update current running segment position with byte offset */
-    gst_segment_set_last_stop (&aiff->segment, GST_FORMAT_BYTES, nextpos);
+    aiff->segment.position = nextpos;
   }
   if (aiff->discont) {
     GST_DEBUG_OBJECT (aiff, "marking DISCONT");
@@ -1205,12 +1236,11 @@ iterate_adapter:
 
   GST_BUFFER_TIMESTAMP (buf) = timestamp;
   GST_BUFFER_DURATION (buf) = duration;
-  gst_buffer_set_caps (buf, aiff->caps);
 
   GST_LOG_OBJECT (aiff,
       "Got buffer. timestamp:%" GST_TIME_FORMAT " , duration:%" GST_TIME_FORMAT
-      ", size:%u", GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration),
-      GST_BUFFER_SIZE (buf));
+      ", size:%" G_GUINT64_FORMAT, GST_TIME_ARGS (timestamp),
+      GST_TIME_ARGS (duration), obtained);
 
   if ((res = gst_pad_push (aiff->srcpad, buf)) != GST_FLOW_OK)
     goto push_error;
@@ -1236,12 +1266,12 @@ iterate_adapter:
 found_eos:
   {
     GST_DEBUG_OBJECT (aiff, "found EOS");
-    return GST_FLOW_UNEXPECTED;
+    return GST_FLOW_EOS;
   }
 pull_error:
   {
     /* check if we got EOS */
-    if (res == GST_FLOW_UNEXPECTED)
+    if (res == GST_FLOW_EOS)
       goto found_eos;
 
     GST_WARNING_OBJECT (aiff,
@@ -1303,7 +1333,7 @@ pause:
     aiff->segment_running = FALSE;
     gst_pad_pause_task (pad);
 
-    if (ret == GST_FLOW_UNEXPECTED) {
+    if (ret == GST_FLOW_EOS) {
       /* perform EOS logic */
       if (aiff->segment.flags & GST_SEEK_FLAG_SEGMENT) {
         GstClockTime stop;
@@ -1315,11 +1345,11 @@ pause:
             gst_message_new_segment_done (GST_OBJECT_CAST (aiff),
                 aiff->segment.format, stop));
         gst_pad_push_event (aiff->srcpad,
-            gst_evnet_new_segment_done (aiff->segment.format, stop));
+            gst_event_new_segment_done (aiff->segment.format, stop));
       } else {
         gst_pad_push_event (aiff->srcpad, gst_event_new_eos ());
       }
-    } else if (ret < GST_FLOW_UNEXPECTED || ret == GST_FLOW_NOT_LINKED) {
+    } else if (ret < GST_FLOW_EOS || ret == GST_FLOW_NOT_LINKED) {
       /* for fatal errors we post an error message, post the error
        * first so the app knows about the error first. */
       GST_ELEMENT_ERROR (aiff, STREAM, FAILED,
@@ -1332,12 +1362,13 @@ pause:
 }
 
 static GstFlowReturn
-gst_aiff_parse_chain (GstPad * pad, GstBuffer * buf)
+gst_aiff_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
 {
   GstFlowReturn ret;
-  GstAiffParse *aiff = GST_AIFF_PARSE (GST_PAD_PARENT (pad));
+  GstAiffParse *aiff = GST_AIFF_PARSE (parent);
 
-  GST_LOG_OBJECT (aiff, "adapter_push %u bytes", GST_BUFFER_SIZE (buf));
+  GST_LOG_OBJECT (aiff, "adapter_push %" G_GSIZE_FORMAT " bytes",
+      gst_buffer_get_size (buf));
 
   gst_adapter_push (aiff->adapter, buf);
 
@@ -1459,29 +1490,15 @@ done:
 
 }
 
-static const GstQueryType *
-gst_aiff_parse_get_query_types (GstPad * pad)
-{
-  static const GstQueryType types[] = {
-    GST_QUERY_DURATION,
-    GST_QUERY_CONVERT,
-    GST_QUERY_SEEKING,
-    0
-  };
-
-  return types;
-}
-
 /* handle queries for location and length in requested format */
 static gboolean
-gst_aiff_parse_pad_query (GstPad * pad, GstQuery * query)
+gst_aiff_parse_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
 {
   gboolean res = TRUE;
-  GstAiffParse *aiff = GST_AIFF_PARSE (gst_pad_get_parent (pad));
+  GstAiffParse *aiff = GST_AIFF_PARSE (parent);
 
   /* only if we know */
   if (aiff->state != AIFF_PARSE_DATA) {
-    gst_object_unref (aiff);
     return FALSE;
   }
 
@@ -1538,17 +1555,16 @@ gst_aiff_parse_pad_query (GstPad * pad, GstQuery * query)
       break;
     }
     default:
-      res = gst_pad_query_default (pad, query);
+      res = gst_pad_query_default (pad, parent, query);
       break;
   }
-  gst_object_unref (aiff);
   return res;
 }
 
 static gboolean
-gst_aiff_parse_srcpad_event (GstPad * pad, GstEvent * event)
+gst_aiff_parse_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
 {
-  GstAiffParse *aiffparse = GST_AIFF_PARSE (gst_pad_get_parent (pad));
+  GstAiffParse *aiffparse = GST_AIFF_PARSE (parent);
   gboolean res = FALSE;
 
   GST_DEBUG_OBJECT (aiffparse, "%s event", GST_EVENT_TYPE_NAME (event));
@@ -1565,48 +1581,74 @@ gst_aiff_parse_srcpad_event (GstPad * pad, GstEvent * event)
       res = gst_pad_push_event (aiffparse->sinkpad, event);
       break;
   }
-  gst_object_unref (aiffparse);
   return res;
 }
 
 static gboolean
-gst_aiff_parse_sink_activate (GstPad * sinkpad)
+gst_aiff_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
 {
-  GstAiffParse *aiff = GST_AIFF_PARSE (gst_pad_get_parent (sinkpad));
-  gboolean res;
+  GstQuery *query;
+  gboolean pull_mode;
 
-  if (aiff->adapter)
-    g_object_unref (aiff->adapter);
+  query = gst_query_new_scheduling ();
 
-  if (gst_pad_check_pull_range (sinkpad)) {
-    GST_DEBUG ("going to pull mode");
-    aiff->streaming = FALSE;
-    aiff->adapter = NULL;
-    res = gst_pad_activate_pull (sinkpad, TRUE);
-  } else {
-    GST_DEBUG ("going to push (streaming) mode");
-    aiff->streaming = TRUE;
-    aiff->adapter = gst_adapter_new ();
-    res = gst_pad_activate_push (sinkpad, TRUE);
+  if (!gst_pad_peer_query (sinkpad, query)) {
+    gst_query_unref (query);
+    goto activate_push;
+  }
+
+  pull_mode = gst_query_has_scheduling_mode_with_flags (query,
+      GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
+  gst_query_unref (query);
+
+  if (!pull_mode)
+    goto activate_push;
+
+  GST_DEBUG_OBJECT (sinkpad, "going to pull mode");
+  return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
+
+activate_push:
+  {
+    GST_DEBUG_OBJECT (sinkpad, "going to push (streaming) mode");
+    return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
   }
-  gst_object_unref (aiff);
-  return res;
 }
 
 
 static gboolean
-gst_aiff_parse_sink_activate_pull (GstPad * sinkpad, gboolean active)
+gst_aiff_parse_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
+    GstPadMode mode, gboolean active)
 {
-  GstAiffParse *aiff = GST_AIFF_PARSE (GST_OBJECT_PARENT (sinkpad));
+  gboolean res;
+  GstAiffParse *aiff = GST_AIFF_PARSE (parent);
 
-  if (active) {
-    aiff->segment_running = TRUE;
-    return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_aiff_parse_loop,
-        sinkpad, NULL);
-  } else {
-    aiff->segment_running = FALSE;
-    return gst_pad_stop_task (sinkpad);
+  if (aiff->adapter)
+    g_object_unref (aiff->adapter);
+
+  switch (mode) {
+    case GST_PAD_MODE_PUSH:
+      aiff->streaming = TRUE;
+      aiff->adapter = gst_adapter_new ();
+      res = TRUE;
+      break;
+    case GST_PAD_MODE_PULL:
+      if (active) {
+        aiff->streaming = FALSE;
+        aiff->adapter = NULL;
+        aiff->segment_running = TRUE;
+        res =
+            gst_pad_start_task (sinkpad, (GstTaskFunction) gst_aiff_parse_loop,
+            sinkpad, NULL);
+      } else {
+        aiff->segment_running = FALSE;
+        res = gst_pad_stop_task (sinkpad);
+      }
+      break;
+    default:
+      res = FALSE;
+      break;
   }
+  return res;
 };
 
 static GstStateChangeReturn
index badc0ed4ea2d7fdaa938d6fe32fe4420f93d821e..2243ddc2990acf4390a9f955e6407b8e57735b34 100644 (file)
@@ -59,7 +59,6 @@ struct _GstAiffParse {
   GstPad      *sinkpad;
   GstPad      *srcpad;
 
-  GstCaps     *caps;
   GstEvent    *close_segment;
   GstEvent    *start_segment;