Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / avi / gstavidemux.c
index 8ada527..604ae1e 100644 (file)
@@ -72,9 +72,6 @@ static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS ("video/x-msvideo")
     );
 
-static void gst_avi_demux_base_init (GstAviDemuxClass * klass);
-static void gst_avi_demux_class_init (GstAviDemuxClass * klass);
-static void gst_avi_demux_init (GstAviDemux * avi);
 static void gst_avi_demux_finalize (GObject * object);
 
 static void gst_avi_demux_reset (GstAviDemux * avi);
@@ -90,7 +87,6 @@ static gboolean gst_avi_demux_push_event (GstAviDemux * avi, GstEvent * event);
 #if 0
 static const GstFormat *gst_avi_demux_get_src_formats (GstPad * pad);
 #endif
-static const GstQueryType *gst_avi_demux_get_src_query_types (GstPad * pad);
 static gboolean gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query);
 static gboolean gst_avi_demux_src_convert (GstPad * pad, GstFormat src_format,
     gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
@@ -118,63 +114,50 @@ static void gst_avi_demux_get_buffer_info (GstAviDemux * avi,
 
 static void gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf);
 
-static GstElementClass *parent_class = NULL;
-
 /* GObject methods */
 
-GType
-gst_avi_demux_get_type (void)
-{
-  static GType avi_demux_type = 0;
-
-  if (!avi_demux_type) {
-    static const GTypeInfo avi_demux_info = {
-      sizeof (GstAviDemuxClass),
-      (GBaseInitFunc) gst_avi_demux_base_init,
-      NULL,
-      (GClassInitFunc) gst_avi_demux_class_init,
-      NULL,
-      NULL,
-      sizeof (GstAviDemux),
-      0,
-      (GInstanceInitFunc) gst_avi_demux_init,
-    };
-
-    avi_demux_type =
-        g_type_register_static (GST_TYPE_ELEMENT,
-        "GstAviDemux", &avi_demux_info, 0);
-  }
-
-  return avi_demux_type;
-}
+#define gst_avi_demux_parent_class parent_class
+G_DEFINE_TYPE (GstAviDemux, gst_avi_demux, GST_TYPE_ELEMENT);
 
 static void
-gst_avi_demux_base_init (GstAviDemuxClass * klass)
+gst_avi_demux_class_init (GstAviDemuxClass * klass)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+  GObjectClass *gobject_class = (GObjectClass *) klass;
   GstPadTemplate *videosrctempl, *audiosrctempl, *subsrctempl;
   GstCaps *audcaps, *vidcaps, *subcaps;
 
+  GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux",
+      0, "Demuxer for AVI streams");
+
+  gobject_class->finalize = gst_avi_demux_finalize;
+
+  gstelement_class->change_state =
+      GST_DEBUG_FUNCPTR (gst_avi_demux_change_state);
+  gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_avi_demux_set_index);
+  gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_avi_demux_get_index);
+
   audcaps = gst_riff_create_audio_template_caps ();
-  gst_caps_append (audcaps, gst_caps_new_simple ("audio/x-avi-unknown", NULL));
-  audiosrctempl = gst_pad_template_new ("audio_%02d",
+  gst_caps_append (audcaps, gst_caps_new_empty_simple ("audio/x-avi-unknown"));
+  audiosrctempl = gst_pad_template_new ("audio_%u",
       GST_PAD_SRC, GST_PAD_SOMETIMES, audcaps);
 
   vidcaps = gst_riff_create_video_template_caps ();
   gst_caps_append (vidcaps, gst_riff_create_iavs_template_caps ());
-  gst_caps_append (vidcaps, gst_caps_new_simple ("video/x-avi-unknown", NULL));
-  videosrctempl = gst_pad_template_new ("video_%02d",
+  gst_caps_append (vidcaps, gst_caps_new_empty_simple ("video/x-avi-unknown"));
+  videosrctempl = gst_pad_template_new ("video_%u",
       GST_PAD_SRC, GST_PAD_SOMETIMES, vidcaps);
 
-  subcaps = gst_caps_new_simple ("application/x-subtitle-avi", NULL);
-  subsrctempl = gst_pad_template_new ("subtitle_%02d",
+  subcaps = gst_caps_new_empty_simple ("application/x-subtitle-avi");
+  subsrctempl = gst_pad_template_new ("subtitle_%u",
       GST_PAD_SRC, GST_PAD_SOMETIMES, subcaps);
-  gst_element_class_add_pad_template (element_class, audiosrctempl);
-  gst_element_class_add_pad_template (element_class, videosrctempl);
-  gst_element_class_add_pad_template (element_class, subsrctempl);
-  gst_element_class_add_pad_template (element_class,
+  gst_element_class_add_pad_template (gstelement_class, audiosrctempl);
+  gst_element_class_add_pad_template (gstelement_class, videosrctempl);
+  gst_element_class_add_pad_template (gstelement_class, subsrctempl);
+  gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&sink_templ));
-  gst_element_class_set_details_simple (element_class, "Avi demuxer",
+
+  gst_element_class_set_details_simple (gstelement_class, "Avi demuxer",
       "Codec/Demuxer",
       "Demultiplex an avi file into audio and video",
       "Erik Walthinsen <omega@cse.ogi.edu>, "
@@ -183,25 +166,6 @@ gst_avi_demux_base_init (GstAviDemuxClass * klass)
 }
 
 static void
-gst_avi_demux_class_init (GstAviDemuxClass * klass)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
-  GObjectClass *gobject_class = (GObjectClass *) klass;
-
-  GST_DEBUG_CATEGORY_INIT (avidemux_debug, "avidemux",
-      0, "Demuxer for AVI streams");
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  gobject_class->finalize = gst_avi_demux_finalize;
-  gstelement_class->change_state =
-      GST_DEBUG_FUNCPTR (gst_avi_demux_change_state);
-
-  gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_avi_demux_set_index);
-  gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_avi_demux_get_index);
-}
-
-static void
 gst_avi_demux_init (GstAviDemux * avi)
 {
   avi->sinkpad = gst_pad_new_from_static_template (&sink_templ, "sink");
@@ -289,10 +253,6 @@ gst_avi_demux_reset (GstAviDemux * avi)
     gst_object_unref (avi->element_index);
   avi->element_index = NULL;
 
-  if (avi->close_seg_event) {
-    gst_event_unref (avi->close_seg_event);
-    avi->close_seg_event = NULL;
-  }
   if (avi->seg_event) {
     gst_event_unref (avi->seg_event);
     avi->seg_event = NULL;
@@ -456,20 +416,6 @@ done:
   return res;
 }
 
-static const GstQueryType *
-gst_avi_demux_get_src_query_types (GstPad * pad)
-{
-  static const GstQueryType src_types[] = {
-    GST_QUERY_POSITION,
-    GST_QUERY_DURATION,
-    GST_QUERY_SEEKING,
-    GST_QUERY_CONVERT,
-    0
-  };
-
-  return src_types;
-}
-
 static gboolean
 gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
 {
@@ -570,7 +516,7 @@ gst_avi_demux_handle_src_query (GstPad * pad, GstQuery * query)
           if (stream->idx_n >= 0)
             gst_query_set_duration (query, fmt, stream->idx_n);
           else if (gst_pad_query_convert (pad, GST_FORMAT_TIME,
-                  duration, &fmt, &dur))
+                  duration, fmt, &dur))
             gst_query_set_duration (query, fmt, dur);
           break;
         }
@@ -754,22 +700,14 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
       "have event type %s: %p on sink pad", GST_EVENT_TYPE_NAME (event), event);
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time, offset = 0;
-      gboolean update;
+      gint64 boffset, offset = 0;
       GstSegment segment;
 
       /* some debug output */
-      gst_segment_init (&segment, GST_FORMAT_UNDEFINED);
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-      gst_segment_set_newsegment_full (&segment, update, rate, arate, format,
-          start, stop, time);
-      GST_DEBUG_OBJECT (avi,
-          "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
+      gst_event_copy_segment (event, &segment);
+      GST_DEBUG_OBJECT (avi, "received newsegment %" GST_SEGMENT_FORMAT,
           &segment);
 
       /* chain will send initial newsegment after pads have been added */
@@ -779,7 +717,7 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
       }
 
       /* we only expect a BYTE segment, e.g. following a seek */
-      if (format != GST_FORMAT_BYTES) {
+      if (segment.format != GST_FORMAT_BYTES) {
         GST_DEBUG_OBJECT (avi, "unsupported segment format, ignoring");
         goto exit;
       }
@@ -790,7 +728,7 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
         GstAviStream *stream;
 
         /* compensate chunk header, stored index offset points after header */
-        start += 8;
+        boffset = segment.start + 8;
         /* find which stream we're on */
         do {
           stream = &avi->stream[i];
@@ -799,7 +737,7 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
           entry = gst_util_array_binary_search (stream->index,
               stream->idx_n, sizeof (GstAviIndexEntry),
               (GCompareDataFunc) gst_avi_demux_index_entry_offset_search,
-              GST_SEARCH_MODE_AFTER, &start, NULL);
+              GST_SEARCH_MODE_AFTER, &boffset, NULL);
 
           if (entry == NULL)
             continue;
@@ -811,10 +749,10 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
             k = i;
           }
           /* exact match needs no further searching */
-          if (stream->index[index].offset == start)
+          if (stream->index[index].offset == segment.start)
             break;
         } while (++i < avi->num_streams);
-        start -= 8;
+        boffset -= 8;
         offset -= 8;
         stream = &avi->stream[k];
 
@@ -826,14 +764,14 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
 
         /* get the ts corresponding to start offset bytes for the stream */
         gst_avi_demux_get_buffer_info (avi, stream, index,
-            (GstClockTime *) & time, NULL, NULL, NULL);
+            (GstClockTime *) & segment.time, NULL, NULL, NULL);
       } else if (avi->element_index) {
         GstIndexEntry *entry;
 
         /* Let's check if we have an index entry for this position */
         entry = gst_index_get_assoc_entry (avi->element_index, avi->index_id,
             GST_INDEX_LOOKUP_AFTER, GST_ASSOCIATION_FLAG_NONE,
-            GST_FORMAT_BYTES, start);
+            GST_FORMAT_BYTES, segment.start);
 
         /* we can not go where we have not yet been before ... */
         if (!entry) {
@@ -841,27 +779,30 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
           goto eos;
         }
 
-        gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time);
+        gst_index_entry_assoc_map (entry, GST_FORMAT_TIME,
+            (gint64 *) & segment.time);
         gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &offset);
       } else {
         GST_WARNING_OBJECT (avi, "no index data, forcing EOS");
         goto eos;
       }
 
-      stop = GST_CLOCK_TIME_NONE;
+      segment.format = GST_FORMAT_TIME;
+      segment.start = segment.time;
+      segment.stop = GST_CLOCK_TIME_NONE;
+      segment.position = segment.start;
+
+      /* rescue duration */
+      segment.duration = avi->segment.duration;
 
       /* set up segment and send downstream */
-      gst_segment_set_newsegment_full (&avi->segment, update, rate, arate,
-          GST_FORMAT_TIME, time, stop, time);
-      GST_DEBUG_OBJECT (avi, "Pushing newseg update %d, rate %g, "
-          "applied rate %g, format %d, start %" G_GINT64_FORMAT ", "
-          "stop %" G_GINT64_FORMAT, update, rate, arate, GST_FORMAT_TIME,
-          time, stop);
-      gst_avi_demux_push_event (avi,
-          gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME,
-              time, stop, time));
-
-      GST_DEBUG_OBJECT (avi, "next chunk expected at %" G_GINT64_FORMAT, start);
+      gst_segment_copy_into (&segment, &avi->segment);
+
+      GST_DEBUG_OBJECT (avi, "Pushing newseg %" GST_SEGMENT_FORMAT, &segment);
+      gst_avi_demux_push_event (avi, gst_event_new_segment (&segment));
+
+      GST_DEBUG_OBJECT (avi, "next chunk expected at %" G_GINT64_FORMAT,
+          boffset);
 
       /* adjust state for streaming thread accordingly */
       if (avi->have_index)
@@ -870,9 +811,9 @@ gst_avi_demux_handle_sink_event (GstPad * pad, GstEvent * event)
         gst_avi_demux_seek_streams (avi, offset, FALSE);
 
       /* set up streaming thread */
-      g_assert (offset >= start);
-      avi->offset = start;
-      avi->todrop = offset - start;
+      g_assert (offset >= boffset);
+      avi->offset = boffset;
+      avi->todrop = offset - boffset;
 
     exit:
       gst_event_unref (event);
@@ -970,9 +911,10 @@ gst_avi_demux_peek_chunk_info (GstAviDemux * avi, guint32 * tag, guint32 * size)
   if (gst_adapter_available (avi->adapter) < 8)
     return FALSE;
 
-  data = gst_adapter_peek (avi->adapter, 8);
+  data = gst_adapter_map (avi->adapter, 8);
   *tag = GST_READ_UINT32_LE (data);
   *size = GST_READ_UINT32_LE (data + 4);
+  gst_adapter_unmap (avi->adapter, 0);
 
   return TRUE;
 }
@@ -1151,14 +1093,17 @@ gst_avi_demux_parse_avih (GstAviDemux * avi,
     GstBuffer * buf, gst_riff_avih ** _avih)
 {
   gst_riff_avih *avih;
+  gsize size;
 
   if (buf == NULL)
     goto no_buffer;
 
-  if (GST_BUFFER_SIZE (buf) < sizeof (gst_riff_avih))
+  size = gst_buffer_get_size (buf);
+  if (size < sizeof (gst_riff_avih))
     goto avih_too_small;
 
-  avih = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  avih = g_malloc (size);
+  gst_buffer_extract (buf, 0, avih, size);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
   avih->us_frame = GUINT32_FROM_LE (avih->us_frame);
@@ -1218,7 +1163,7 @@ avih_too_small:
   {
     GST_ELEMENT_ERROR (avi, STREAM, DEMUX, (NULL),
         ("Too small avih (%d available, %d needed)",
-            GST_BUFFER_SIZE (buf), (int) sizeof (gst_riff_avih)));
+            size, (int) sizeof (gst_riff_avih)));
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -1245,16 +1190,20 @@ gst_avi_demux_parse_superindex (GstAviDemux * avi,
   guint16 bpe = 16;
   guint32 num, i;
   guint64 *indexes;
-  guint size;
+  gsize size;
 
   *_indexes = NULL;
 
-  size = buf ? GST_BUFFER_SIZE (buf) : 0;
+  if (buf) {
+    data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  } else {
+    data = NULL;
+    size = 0;
+  }
+
   if (size < 24)
     goto too_small;
 
-  data = GST_BUFFER_DATA (buf);
-
   /* check type of index. The opendml2 specs state that
    * there should be 4 dwords per array entry. Type can be
    * either frame or field (and we don't care). */
@@ -1285,6 +1234,7 @@ gst_avi_demux_parse_superindex (GstAviDemux * avi,
   indexes[i] = GST_BUFFER_OFFSET_NONE;
   *_indexes = indexes;
 
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 
   return TRUE;
@@ -1294,16 +1244,18 @@ too_small:
   {
     GST_ERROR_OBJECT (avi,
         "Not enough data to parse superindex (%d available, 24 needed)", size);
-    if (buf)
+    if (buf) {
+      gst_buffer_unmap (buf, data, size);
       gst_buffer_unref (buf);
+    }
     return FALSE;
   }
 invalid_params:
   {
     GST_ERROR_OBJECT (avi, "invalid index parameters (num = %d, bpe = %d)",
         num, bpe);
-    if (buf)
-      gst_buffer_unref (buf);
+    gst_buffer_unmap (buf, data, size);
+    gst_buffer_unref (buf);
     return FALSE;
   }
 }
@@ -1508,19 +1460,16 @@ gst_avi_demux_parse_subindex (GstAviDemux * avi, GstAviStream * stream,
   guint16 bpe;
   guint32 num, i;
   guint64 baseoff;
-  guint size;
+  gsize size;
 
-  if (!buf)
+  if (buf == NULL)
     return TRUE;
 
-  size = GST_BUFFER_SIZE (buf);
-
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
   /* check size */
   if (size < 24)
     goto too_small;
 
-  data = GST_BUFFER_DATA (buf);
-
   /* We don't support index-data yet */
   if (data[3] & 0x80)
     goto not_implemented;
@@ -1570,6 +1519,8 @@ gst_avi_demux_parse_subindex (GstAviDemux * avi, GstAviStream * stream,
     if (G_UNLIKELY (!gst_avi_demux_add_index (avi, stream, num, &entry)))
       goto out_of_mem;
   }
+done:
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 
   return TRUE;
@@ -1579,21 +1530,20 @@ too_small:
   {
     GST_ERROR_OBJECT (avi,
         "Not enough data to parse subindex (%d available, 24 needed)", size);
-    gst_buffer_unref (buf);
-    return TRUE;                /* continue */
+    goto done;                  /* continue */
   }
 not_implemented:
   {
     GST_ELEMENT_ERROR (avi, STREAM, NOT_IMPLEMENTED, (NULL),
         ("Subindex-is-data is not implemented"));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
 empty_index:
   {
     GST_DEBUG_OBJECT (avi, "the index is empty");
-    gst_buffer_unref (buf);
-    return TRUE;
+    goto done;                  /* continue */
   }
 out_of_mem:
   {
@@ -1601,6 +1551,7 @@ out_of_mem:
         ("Cannot allocate memory for %u*%u=%u bytes",
             (guint) sizeof (GstAviIndexEntry), num,
             (guint) sizeof (GstAviIndexEntry) * num));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -1754,14 +1705,18 @@ gst_avi_demux_riff_parse_vprp (GstElement * element,
 {
   gst_riff_vprp *vprp;
   gint k;
+  gsize size;
 
   g_return_val_if_fail (buf != NULL, FALSE);
   g_return_val_if_fail (_vprp != NULL, FALSE);
 
-  if (GST_BUFFER_SIZE (buf) < G_STRUCT_OFFSET (gst_riff_vprp, field_info))
+  size = gst_buffer_get_size (buf);
+
+  if (size < G_STRUCT_OFFSET (gst_riff_vprp, field_info))
     goto too_small;
 
-  vprp = g_memdup (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  vprp = g_malloc (size);
+  gst_buffer_extract (buf, 0, vprp, size);
 
 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
   vprp->format_token = GUINT32_FROM_LE (vprp->format_token);
@@ -1777,8 +1732,7 @@ gst_avi_demux_riff_parse_vprp (GstElement * element,
 
   /* size checking */
   /* calculate fields based on size */
-  k = (GST_BUFFER_SIZE (buf) - G_STRUCT_OFFSET (gst_riff_vprp, field_info)) /
-      vprp->fields;
+  k = (size - G_STRUCT_OFFSET (gst_riff_vprp, field_info)) / vprp->fields;
   if (vprp->fields > k) {
     GST_WARNING_OBJECT (element,
         "vprp header indicated %d fields, only %d available", vprp->fields, k);
@@ -1850,8 +1804,7 @@ too_small:
   {
     GST_ERROR_OBJECT (element,
         "Too small vprp (%d available, at least %d needed)",
-        GST_BUFFER_SIZE (buf),
-        (int) G_STRUCT_OFFSET (gst_riff_vprp, field_info));
+        size, (int) G_STRUCT_OFFSET (gst_riff_vprp, field_info));
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -1868,8 +1821,8 @@ gst_avi_demux_expose_streams (GstAviDemux * avi, gboolean force)
     GstAviStream *stream = &avi->stream[i];
 
     if (force || stream->idx_n != 0) {
-      GST_LOG_OBJECT (avi, "Added pad %s with caps %" GST_PTR_FORMAT,
-          GST_PAD_NAME (stream->pad), GST_PAD_CAPS (stream->pad));
+      GST_LOG_OBJECT (avi, "Adding pad %s" GST_PTR_FORMAT,
+          GST_PAD_NAME (stream->pad));
       gst_element_add_pad ((GstElement *) avi, stream->pad);
 
       if (avi->element_index)
@@ -1893,16 +1846,22 @@ gst_avi_demux_expose_streams (GstAviDemux * avi, gboolean force)
 static inline void
 gst_avi_demux_roundup_list (GstAviDemux * avi, GstBuffer ** buf)
 {
-  gint size = GST_BUFFER_SIZE (*buf);
+  gsize size;
+
+  size = gst_buffer_get_size (*buf);
 
   if (G_UNLIKELY (size & 1)) {
     GstBuffer *obuf;
+    guint8 *data;
 
     GST_DEBUG_OBJECT (avi, "rounding up dubious list size %d", size);
     obuf = gst_buffer_new_and_alloc (size + 1);
-    memcpy (GST_BUFFER_DATA (obuf), GST_BUFFER_DATA (*buf), size);
+
+    data = gst_buffer_map (obuf, NULL, NULL, GST_MAP_WRITE);
+    gst_buffer_extract (*buf, 0, data, size);
     /* assume 0 padding, at least makes outcome deterministic */
-    (GST_BUFFER_DATA (obuf))[size] = 0;
+    data[size] = 0;
+    gst_buffer_unmap (obuf, data, size + 1);
     gst_buffer_replace (buf, obuf);
   }
 }
@@ -2127,9 +2086,12 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
       case GST_RIFF_TAG_strn:
         g_free (stream->name);
         if (sub != NULL) {
-          stream->name =
-              g_strndup ((gchar *) GST_BUFFER_DATA (sub),
-              (gsize) GST_BUFFER_SIZE (sub));
+          gchar *bdata;
+          gsize bsize;
+
+          bdata = gst_buffer_map (sub, &bsize, NULL, GST_MAP_READ);
+          stream->name = g_strndup (bdata, bsize);
+          gst_buffer_unmap (sub, bdata, bsize);
           gst_buffer_unref (sub);
           sub = NULL;
         } else {
@@ -2185,13 +2147,13 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
 
       fourcc = (stream->strf.vids->compression) ?
           stream->strf.vids->compression : stream->strh->fcc_handler;
-      padname = g_strdup_printf ("video_%02d", avi->num_v_streams);
-      templ = gst_element_class_get_pad_template (klass, "video_%02d");
+      padname = g_strdup_printf ("video_%u", avi->num_v_streams);
+      templ = gst_element_class_get_pad_template (klass, "video_%u");
       caps = gst_riff_create_video_caps (fourcc, stream->strh,
           stream->strf.vids, stream->extradata, stream->initdata, &codec_name);
       if (!caps) {
         caps = gst_caps_new_simple ("video/x-avi-unknown", "fourcc",
-            GST_TYPE_FOURCC, fourcc, NULL);
+            G_TYPE_INT, fourcc, NULL);
       } else if (got_vprp && vprp) {
         guint32 aspect_n, aspect_d;
         gint n, d;
@@ -2213,8 +2175,8 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
       break;
     }
     case GST_RIFF_FCC_auds:{
-      padname = g_strdup_printf ("audio_%02d", avi->num_a_streams);
-      templ = gst_element_class_get_pad_template (klass, "audio_%02d");
+      padname = g_strdup_printf ("audio_%u", avi->num_a_streams);
+      templ = gst_element_class_get_pad_template (klass, "audio_%u");
       caps = gst_riff_create_audio_caps (stream->strf.auds->format,
           stream->strh, stream->strf.auds, stream->extradata,
           stream->initdata, &codec_name);
@@ -2229,22 +2191,22 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
     case GST_RIFF_FCC_iavs:{
       guint32 fourcc = stream->strh->fcc_handler;
 
-      padname = g_strdup_printf ("video_%02d", avi->num_v_streams);
-      templ = gst_element_class_get_pad_template (klass, "video_%02d");
+      padname = g_strdup_printf ("video_%u", avi->num_v_streams);
+      templ = gst_element_class_get_pad_template (klass, "video_%u");
       caps = gst_riff_create_iavs_caps (fourcc, stream->strh,
           stream->strf.iavs, stream->extradata, stream->initdata, &codec_name);
       if (!caps) {
         caps = gst_caps_new_simple ("video/x-avi-unknown", "fourcc",
-            GST_TYPE_FOURCC, fourcc, NULL);
+            G_TYPE_INT, fourcc, NULL);
       }
       tag_name = GST_TAG_VIDEO_CODEC;
       avi->num_v_streams++;
       break;
     }
     case GST_RIFF_FCC_txts:{
-      padname = g_strdup_printf ("subtitle_%02d", avi->num_t_streams);
-      templ = gst_element_class_get_pad_template (klass, "subtitle_%02d");
-      caps = gst_caps_new_simple ("application/x-subtitle-avi", NULL);
+      padname = g_strdup_printf ("subtitle_%u", avi->num_t_streams);
+      templ = gst_element_class_get_pad_template (klass, "subtitle_%u");
+      caps = gst_caps_new_empty_simple ("application/x-subtitle-avi");
       tag_name = NULL;
       avi->num_t_streams++;
       break;
@@ -2278,8 +2240,6 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
 #endif
   gst_pad_set_event_function (pad,
       GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_event));
-  gst_pad_set_query_type_function (pad,
-      GST_DEBUG_FUNCPTR (gst_avi_demux_get_src_query_types));
   gst_pad_set_query_function (pad,
       GST_DEBUG_FUNCPTR (gst_avi_demux_handle_src_query));
 #if 0
@@ -2309,14 +2269,14 @@ gst_avi_demux_parse_stream (GstAviDemux * avi, GstBuffer * buf)
   gst_pad_set_element_private (pad, stream);
   avi->num_streams++;
 
-  gst_pad_set_caps (pad, caps);
   gst_pad_set_active (pad, TRUE);
+  gst_pad_push_event (pad, gst_event_new_caps (caps));
   gst_caps_unref (caps);
 
   /* make tags */
   if (codec_name) {
     if (!stream->taglist)
-      stream->taglist = gst_tag_list_new ();
+      stream->taglist = gst_tag_list_new_empty ();
 
     avi->got_tags = TRUE;
 
@@ -2365,20 +2325,26 @@ gst_avi_demux_parse_odml (GstAviDemux * avi, GstBuffer * buf)
     switch (tag) {
       case GST_RIFF_TAG_dmlh:{
         gst_riff_dmlh dmlh, *_dmlh;
-        guint size;
+        gsize size;
+        guint8 *data;
 
         /* sub == NULL is possible and means an empty buffer */
-        size = sub ? GST_BUFFER_SIZE (sub) : 0;
+        if (sub == NULL)
+          goto next;
+
+        data = gst_buffer_map (sub, &size, NULL, GST_MAP_READ);
 
         /* check size */
         if (size < sizeof (gst_riff_dmlh)) {
           GST_ERROR_OBJECT (avi,
               "DMLH entry is too small (%d bytes, %d needed)",
               size, (int) sizeof (gst_riff_dmlh));
+          gst_buffer_unmap (sub, data, size);
           goto next;
         }
-        _dmlh = (gst_riff_dmlh *) GST_BUFFER_DATA (sub);
+        _dmlh = (gst_riff_dmlh *) data;
         dmlh.totalframes = GST_READ_UINT32_LE (&_dmlh->totalframes);
+        gst_buffer_unmap (sub, data, size);
 
         GST_INFO_OBJECT (avi, "dmlh tag found: totalframes: %u",
             dmlh.totalframes);
@@ -2556,7 +2522,7 @@ static gboolean
 gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
 {
   guint8 *data;
-  guint size;
+  gsize size;
   guint i, num, n;
   gst_riff_index_entry *index;
   GstClockTime stamp;
@@ -2567,8 +2533,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
   if (!buf)
     return FALSE;
 
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
 
   stamp = gst_util_get_timestamp ();
 
@@ -2630,6 +2595,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
 
     n++;
   }
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 
   /* get stream stats now */
@@ -2645,6 +2611,7 @@ gst_avi_demux_parse_index (GstAviDemux * avi, GstBuffer * buf)
 empty_list:
   {
     GST_DEBUG_OBJECT (avi, "empty index");
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -2654,6 +2621,7 @@ out_of_mem:
         ("Cannot allocate memory for %u*%u=%u bytes",
             (guint) sizeof (GstAviIndexEntry), num,
             (guint) sizeof (GstAviIndexEntry) * num));
+    gst_buffer_unmap (buf, data, size);
     gst_buffer_unref (buf);
     return FALSE;
   }
@@ -2673,6 +2641,8 @@ gst_avi_demux_stream_index (GstAviDemux * avi)
   GstBuffer *buf;
   guint32 tag;
   guint32 size;
+  gsize bsize;
+  guint8 *bdata;
 
   GST_DEBUG ("demux stream index at offset %" G_GUINT64_FORMAT, offset);
 
@@ -2680,34 +2650,41 @@ gst_avi_demux_stream_index (GstAviDemux * avi)
   res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
   if (res != GST_FLOW_OK)
     goto pull_failed;
-  else if (GST_BUFFER_SIZE (buf) < 8)
+
+  bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  if (bsize < 8)
     goto too_small;
 
   /* check tag first before blindy trying to read 'size' bytes */
-  tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
-  size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+  tag = GST_READ_UINT32_LE (bdata);
+  size = GST_READ_UINT32_LE (bdata + 4);
   if (tag == GST_RIFF_TAG_LIST) {
     /* this is the movi tag */
     GST_DEBUG_OBJECT (avi, "skip LIST chunk, size %" G_GUINT32_FORMAT,
         (8 + GST_ROUND_UP_2 (size)));
     offset += 8 + GST_ROUND_UP_2 (size);
+    gst_buffer_unmap (buf, bdata, bsize);
     gst_buffer_unref (buf);
+
     res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
     if (res != GST_FLOW_OK)
       goto pull_failed;
-    else if (GST_BUFFER_SIZE (buf) < 8)
+
+    bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+    if (bsize < 8)
       goto too_small;
-    tag = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf));
-    size = GST_READ_UINT32_LE (GST_BUFFER_DATA (buf) + 4);
+
+    tag = GST_READ_UINT32_LE (bdata);
+    size = GST_READ_UINT32_LE (bdata + 4);
   }
+  gst_buffer_unmap (buf, bdata, bsize);
+  gst_buffer_unref (buf);
 
   if (tag != GST_RIFF_TAG_idx1)
     goto no_index;
   if (!size)
     goto zero_index;
 
-  gst_buffer_unref (buf);
-
   GST_DEBUG ("index found at offset %" G_GUINT64_FORMAT, offset);
 
   /* read chunk, advance offset */
@@ -2716,7 +2693,7 @@ gst_avi_demux_stream_index (GstAviDemux * avi)
     return;
 
   GST_DEBUG ("will parse index chunk size %u for tag %"
-      GST_FOURCC_FORMAT, GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag));
+      GST_FOURCC_FORMAT, gst_buffer_get_size (buf), GST_FOURCC_ARGS (tag));
 
   gst_avi_demux_parse_index (avi, buf);
 
@@ -2745,6 +2722,7 @@ pull_failed:
 too_small:
   {
     GST_DEBUG_OBJECT (avi, "Buffer is too small");
+    gst_buffer_unmap (buf, bdata, bsize);
     gst_buffer_unref (buf);
     return;
   }
@@ -2753,13 +2731,11 @@ no_index:
     GST_WARNING_OBJECT (avi,
         "No index data (idx1) after movi chunk, but %" GST_FOURCC_FORMAT,
         GST_FOURCC_ARGS (tag));
-    gst_buffer_unref (buf);
     return;
   }
 zero_index:
   {
     GST_WARNING_OBJECT (avi, "Empty index data (idx1) after movi chunk");
-    gst_buffer_unref (buf);
     return;
   }
 }
@@ -2810,7 +2786,7 @@ gst_avi_demux_stream_index_push (GstAviDemux * avi)
   offset += 8 + GST_ROUND_UP_2 (size);
 
   GST_DEBUG ("will parse index chunk size %u for tag %"
-      GST_FOURCC_FORMAT, GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag));
+      GST_FOURCC_FORMAT, gst_buffer_get_size (buf), GST_FOURCC_ARGS (tag));
 
   avi->offset = avi->first_movi_offset;
   gst_avi_demux_parse_index (avi, buf);
@@ -2858,19 +2834,17 @@ gst_avi_demux_peek_tag (GstAviDemux * avi, guint64 offset, guint32 * tag,
 {
   GstFlowReturn res = GST_FLOW_OK;
   GstBuffer *buf = NULL;
-  guint bufsize;
+  gsize bufsize;
   guint8 *bufdata;
 
   res = gst_pad_pull_range (avi->sinkpad, offset, 8, &buf);
   if (res != GST_FLOW_OK)
     goto pull_failed;
 
-  bufsize = GST_BUFFER_SIZE (buf);
+  bufdata = gst_buffer_map (buf, &bufsize, NULL, GST_MAP_READ);
   if (bufsize != 8)
     goto wrong_size;
 
-  bufdata = GST_BUFFER_DATA (buf);
-
   *tag = GST_READ_UINT32_LE (bufdata);
   *size = GST_READ_UINT32_LE (bufdata + 4);
 
@@ -2879,6 +2853,7 @@ gst_avi_demux_peek_tag (GstAviDemux * avi, guint64 offset, guint32 * tag,
       *size, offset + 8, offset + 8 + (gint64) * size);
 
 done:
+  gst_buffer_unmap (buf, bufdata, bufsize);
   gst_buffer_unref (buf);
 
   return res;
@@ -2939,7 +2914,6 @@ gst_avi_demux_stream_scan (GstAviDemux * avi)
 {
   GstFlowReturn res;
   GstAviStream *stream;
-  GstFormat format;
   guint64 pos = 0;
   guint64 length;
   gint64 tmplength;
@@ -2952,8 +2926,7 @@ gst_avi_demux_stream_scan (GstAviDemux * avi)
   GST_DEBUG_OBJECT (avi, "Creating index");
 
   /* get the size of the file */
-  format = GST_FORMAT_BYTES;
-  if (!gst_pad_query_peer_duration (avi->sinkpad, &format, &tmplength))
+  if (!gst_pad_query_peer_duration (avi->sinkpad, GST_FORMAT_BYTES, &tmplength))
     return FALSE;
   length = tmplength;
 
@@ -3071,7 +3044,7 @@ gst_avi_demux_calculate_durations_from_index (GstAviDemux * avi)
   GST_INFO ("Setting total duration to: %" GST_TIME_FORMAT,
       GST_TIME_ARGS (total));
 
-  gst_segment_set_duration (&avi->segment, GST_FORMAT_TIME, total);
+  avi->segment.duration = total;
 }
 
 /* returns FALSE if there are no pads to deliver event to,
@@ -3115,10 +3088,8 @@ gst_avi_demux_check_seekability (GstAviDemux * avi)
 
   /* try harder to query upstream size if we didn't get it the first time */
   if (seekable && stop == -1) {
-    GstFormat fmt = GST_FORMAT_BYTES;
-
     GST_DEBUG_OBJECT (avi, "doing duration query to fix up unset stop");
-    gst_pad_query_peer_duration (avi->sinkpad, &fmt, &stop);
+    gst_pad_query_peer_duration (avi->sinkpad, GST_FORMAT_BYTES, &stop);
   }
 
   /* if upstream doesn't know the size, it's likely that it's not seekable in
@@ -3149,9 +3120,9 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
   const guint8 *data;
   GstBuffer *buf = NULL, *sub = NULL;
   guint offset = 4;
-  gint64 stop;
   gint i;
   GstTagList *tags = NULL;
+  guint8 fourcc[4];
 
   GST_DEBUG ("Reading and parsing avi headers: %d", avi->header_state);
 
@@ -3167,7 +3138,9 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
         GST_DEBUG ("Reading %d bytes", size);
         buf = gst_adapter_take_buffer (avi->adapter, size);
 
-        if (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl)
+        gst_buffer_extract (buf, 0, fourcc, 4);
+
+        if (GST_READ_UINT32_LE (fourcc) != GST_RIFF_LIST_hdrl)
           goto header_no_hdrl;
 
         /* mind padding */
@@ -3200,10 +3173,12 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
 
           switch (tag) {
             case GST_RIFF_TAG_LIST:
-              if (GST_BUFFER_SIZE (sub) < 4)
+              if (gst_buffer_get_size (sub) < 4)
                 goto next;
 
-              switch (GST_READ_UINT32_LE (GST_BUFFER_DATA (sub))) {
+              gst_buffer_extract (sub, 0, fourcc, 4);
+
+              switch (GST_READ_UINT32_LE (fourcc)) {
                 case GST_RIFF_LIST_strl:
                   if (!(gst_avi_demux_parse_stream (avi, sub))) {
                     sub = NULL;
@@ -3220,14 +3195,13 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
                 default:
                   GST_WARNING_OBJECT (avi,
                       "Unknown list %" GST_FOURCC_FORMAT " in AVI header",
-                      GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA
-                              (sub))));
+                      GST_FOURCC_ARGS (GST_READ_UINT32_LE (fourcc)));
                   /* fall-through */
                 case GST_RIFF_TAG_JUNQ:
                 case GST_RIFF_TAG_JUNK:
                   goto next;
+                  break;
               }
-              break;
             case GST_RIFF_IDIT:
               gst_avi_demux_parse_idit (avi, sub);
               goto next;
@@ -3270,10 +3244,11 @@ gst_avi_demux_stream_header_push (GstAviDemux * avi)
         if (gst_adapter_available (avi->adapter) < 12)
           return GST_FLOW_OK;
 
-        data = gst_adapter_peek (avi->adapter, 12);
+        data = gst_adapter_map (avi->adapter, 12);
         tag = GST_READ_UINT32_LE (data);
         size = GST_READ_UINT32_LE (data + 4);
         ltag = GST_READ_UINT32_LE (data + 8);
+        gst_adapter_unmap (avi->adapter, 0);
 
         if (tag == GST_RIFF_TAG_LIST) {
           switch (ltag) {
@@ -3361,16 +3336,9 @@ skipping_done:
     avi->stream[i].current_entry = 0;
 
   /* create initial NEWSEGMENT event */
-  if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
-    stop = avi->segment.duration;
-
-  GST_DEBUG_OBJECT (avi, "segment stop %" G_GINT64_FORMAT, stop);
-
   if (avi->seg_event)
     gst_event_unref (avi->seg_event);
-  avi->seg_event = gst_event_new_new_segment_full
-      (FALSE, avi->segment.rate, avi->segment.applied_rate, GST_FORMAT_TIME,
-      avi->segment.start, stop, avi->segment.time);
+  avi->seg_event = gst_event_new_segment (&avi->segment);
 
   gst_avi_demux_check_seekability (avi);
 
@@ -3438,7 +3406,7 @@ gst_avi_demux_add_date_tag (GstAviDemux * avi, gint y, gint m, gint d,
   dt = gst_date_time_new_local_time (y, m, d, h, min, s);
 
   if (avi->globaltags == NULL)
-    avi->globaltags = gst_tag_list_new ();
+    avi->globaltags = gst_tag_list_new_empty ();
 
   gst_tag_list_add (avi->globaltags, GST_TAG_MERGE_REPLACE, GST_TAG_DATE, date,
       NULL);
@@ -3525,10 +3493,11 @@ gst_avi_demux_parse_idit_text (GstAviDemux * avi, gchar * data)
 static void
 gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
 {
-  gchar *data = (gchar *) GST_BUFFER_DATA (buf);
-  guint size = GST_BUFFER_SIZE (buf);
+  gchar *data, *ptr;
+  gsize size, left;
   gchar *safedata = NULL;
 
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
   /*
    * According to:
    * http://www.eden-foundation.org/products/code/film_date_stamp/index.html
@@ -3542,24 +3511,27 @@ gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
    */
 
   /* skip eventual initial whitespace */
-  while (size > 0 && g_ascii_isspace (data[0])) {
-    data++;
-    size--;
+  ptr = data;
+  left = size;
+
+  while (left > 0 && g_ascii_isspace (ptr[0])) {
+    ptr++;
+    left--;
   }
 
-  if (size == 0) {
+  if (left == 0) {
     goto non_parsable;
   }
 
   /* make a safe copy to add a \0 to the end of the string */
-  safedata = g_strndup (data, size);
+  safedata = g_strndup (ptr, left);
 
   /* test if the first char is a alpha or a number */
-  if (g_ascii_isdigit (data[0])) {
+  if (g_ascii_isdigit (ptr[0])) {
     gst_avi_demux_parse_idit_nums_only (avi, safedata);
     g_free (safedata);
     return;
-  } else if (g_ascii_isalpha (data[0])) {
+  } else if (g_ascii_isalpha (ptr[0])) {
     gst_avi_demux_parse_idit_text (avi, safedata);
     g_free (safedata);
     return;
@@ -3569,6 +3541,7 @@ gst_avi_demux_parse_idit (GstAviDemux * avi, GstBuffer * buf)
 
 non_parsable:
   GST_WARNING_OBJECT (avi, "IDIT tag has no parsable info");
+  gst_buffer_unmap (buf, data, size);
 }
 
 /*
@@ -3581,10 +3554,10 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
   GstBuffer *buf, *sub = NULL;
   guint32 tag;
   guint offset = 4;
-  gint64 stop;
   GstElement *element = GST_ELEMENT_CAST (avi);
   GstClockTime stamp;
   GstTagList *tags = NULL;
+  guint8 fourcc[4];
 
   stamp = gst_util_get_timestamp ();
 
@@ -3594,15 +3567,16 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
     goto pull_range_failed;
   else if (tag != GST_RIFF_TAG_LIST)
     goto no_list;
-  else if (GST_BUFFER_SIZE (buf) < 4)
+  else if (gst_buffer_get_size (buf) < 4)
     goto no_header;
 
   GST_DEBUG_OBJECT (avi, "parsing headers");
 
   /* Find the 'hdrl' LIST tag */
-  while (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) != GST_RIFF_LIST_hdrl) {
+  gst_buffer_extract (buf, 0, fourcc, 4);
+  while (GST_READ_UINT32_LE (fourcc) != GST_RIFF_LIST_hdrl) {
     GST_LOG_OBJECT (avi, "buffer contains %" GST_FOURCC_FORMAT,
-        GST_FOURCC_ARGS (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf))));
+        GST_FOURCC_ARGS (GST_READ_UINT32_LE (fourcc)));
 
     /* Eat up */
     gst_buffer_unref (buf);
@@ -3613,8 +3587,9 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
       goto pull_range_failed;
     else if (tag != GST_RIFF_TAG_LIST)
       goto no_list;
-    else if (GST_BUFFER_SIZE (buf) < 4)
+    else if (gst_buffer_get_size (buf) < 4)
       goto no_header;
+    gst_buffer_extract (buf, 0, fourcc, 4);
   }
 
   GST_DEBUG_OBJECT (avi, "hdrl LIST tag found");
@@ -3633,23 +3608,21 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
 
   /* now, read the elements from the header until the end */
   while (gst_riff_parse_chunk (element, buf, &offset, &tag, &sub)) {
+    gsize size;
+    guint8 *data;
+
     /* sub can be NULL on empty tags */
     if (!sub)
       continue;
 
+    data = gst_buffer_map (sub, &size, NULL, GST_MAP_READ);
+
     switch (tag) {
       case GST_RIFF_TAG_LIST:
-      {
-        guint8 *data;
-        guint32 fourcc;
-
-        if (GST_BUFFER_SIZE (sub) < 4)
+        if (size < 4)
           goto next;
 
-        data = GST_BUFFER_DATA (sub);
-        fourcc = GST_READ_UINT32_LE (data);
-
-        switch (fourcc) {
+        switch (GST_READ_UINT32_LE (data)) {
           case GST_RIFF_LIST_strl:
             if (!(gst_avi_demux_parse_stream (avi, sub))) {
               GST_ELEMENT_WARNING (avi, STREAM, DEMUX, (NULL),
@@ -3663,8 +3636,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
             sub = NULL;
             break;
           case GST_RIFF_LIST_INFO:
-            GST_BUFFER_DATA (sub) = data + 4;
-            GST_BUFFER_SIZE (sub) -= 4;
+            gst_buffer_resize (sub, 4, -1);
             gst_riff_parse_info (element, sub, &tags);
             if (tags) {
               if (avi->globaltags) {
@@ -3679,16 +3651,14 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
           default:
             GST_WARNING_OBJECT (avi,
                 "Unknown list %" GST_FOURCC_FORMAT " in AVI header",
-                GST_FOURCC_ARGS (fourcc));
-            GST_MEMDUMP_OBJECT (avi, "Unknown list", GST_BUFFER_DATA (sub),
-                GST_BUFFER_SIZE (sub));
+                GST_FOURCC_ARGS (GST_READ_UINT32_LE (data)));
+            GST_MEMDUMP_OBJECT (avi, "Unknown list", data, size);
             /* fall-through */
           case GST_RIFF_TAG_JUNQ:
           case GST_RIFF_TAG_JUNK:
             goto next;
         }
         break;
-      }
       case GST_RIFF_IDIT:
         gst_avi_demux_parse_idit (avi, sub);
         goto next;
@@ -3696,14 +3666,15 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
         GST_WARNING_OBJECT (avi,
             "Unknown tag %" GST_FOURCC_FORMAT " in AVI header at off %d",
             GST_FOURCC_ARGS (tag), offset);
-        GST_MEMDUMP_OBJECT (avi, "Unknown tag", GST_BUFFER_DATA (sub),
-            GST_BUFFER_SIZE (sub));
+        GST_MEMDUMP_OBJECT (avi, "Unknown tag", data, size);
         /* fall-through */
       case GST_RIFF_TAG_JUNQ:
       case GST_RIFF_TAG_JUNK:
       next:
-        if (sub)
+        if (sub) {
+          gst_buffer_unmap (sub, data, size);
           gst_buffer_unref (sub);
+        }
         sub = NULL;
         break;
     }
@@ -3726,6 +3697,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
   /* Now, find the data (i.e. skip all junk between header and data) */
   do {
     guint size;
+    gsize bsize;
     guint8 *data;
     guint32 tag, ltag;
 
@@ -3733,22 +3705,22 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
     if (res != GST_FLOW_OK) {
       GST_DEBUG_OBJECT (avi, "pull_range failure while looking for tags");
       goto pull_range_failed;
-    } else if (GST_BUFFER_SIZE (buf) < 12) {
+    } else if (gst_buffer_get_size (buf) < 12) {
       GST_DEBUG_OBJECT (avi, "got %d bytes which is less than 12 bytes",
-          GST_BUFFER_SIZE (buf));
+          gst_buffer_get_size (buf));
       gst_buffer_unref (buf);
       return GST_FLOW_ERROR;
     }
 
-    data = GST_BUFFER_DATA (buf);
-
+    data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
     tag = GST_READ_UINT32_LE (data);
     size = GST_READ_UINT32_LE (data + 4);
     ltag = GST_READ_UINT32_LE (data + 8);
 
     GST_DEBUG ("tag %" GST_FOURCC_FORMAT ", size %u",
         GST_FOURCC_ARGS (tag), size);
-    GST_MEMDUMP ("Tag content", data, GST_BUFFER_SIZE (buf));
+    GST_MEMDUMP ("Tag content", data, bsize);
+    gst_buffer_unmap (buf, data, bsize);
     gst_buffer_unref (buf);
 
     switch (tag) {
@@ -3766,7 +3738,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
               GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
               goto pull_range_failed;
             }
-            GST_DEBUG ("got size %u", GST_BUFFER_SIZE (buf));
+            GST_DEBUG ("got size %u", gst_buffer_get_size (buf));
             if (size < 4) {
               GST_DEBUG ("skipping INFO LIST prefix");
               avi->offset += (4 - GST_ROUND_UP_2 (size));
@@ -3774,7 +3746,7 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
               continue;
             }
 
-            sub = gst_buffer_create_sub (buf, 4, GST_BUFFER_SIZE (buf) - 4);
+            sub = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, 4, -1);
             gst_riff_parse_info (element, sub, &tags);
             if (tags) {
               if (avi->globaltags) {
@@ -3814,7 +3786,9 @@ gst_avi_demux_stream_header_pull (GstAviDemux * avi)
             GST_DEBUG_OBJECT (avi, "couldn't read INFO chunk");
             goto pull_range_failed;
           }
-          GST_MEMDUMP ("Junk", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+          data = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+          GST_MEMDUMP ("Junk", data, bsize);
+          gst_buffer_unmap (buf, data, bsize);
           gst_buffer_unref (buf);
         }
         avi->offset += 8 + GST_ROUND_UP_2 (size);
@@ -3851,21 +3825,13 @@ skipping_done:
 
   gst_avi_demux_expose_streams (avi, FALSE);
 
-  /* create initial NEWSEGMENT event */
-  if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
-    stop = avi->segment.duration;
-
-  GST_DEBUG_OBJECT (avi, "segment stop %" G_GINT64_FORMAT, stop);
-
   /* do initial seek to the default segment values */
   gst_avi_demux_do_seek (avi, &avi->segment);
 
-  /* prepare initial segment */
+  /* create initial NEWSEGMENT event */
   if (avi->seg_event)
     gst_event_unref (avi->seg_event);
-  avi->seg_event = gst_event_new_new_segment_full
-      (FALSE, avi->segment.rate, avi->segment.applied_rate, GST_FORMAT_TIME,
-      avi->segment.start, stop, avi->segment.time);
+  avi->seg_event = gst_event_new_segment (&avi->segment);
 
   stamp = gst_util_get_timestamp () - stamp;
   GST_DEBUG_OBJECT (avi, "pulling header took %" GST_TIME_FORMAT,
@@ -3995,8 +3961,8 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
   guint i, index;
   GstAviStream *stream;
 
-  seek_time = segment->last_stop;
-  keyframe = !!(segment->flags & GST_SEEK_FLAG_KEY_UNIT);
+  seek_time = segment->position;
+  keyframe = ! !(segment->flags & GST_SEEK_FLAG_KEY_UNIT);
 
   GST_DEBUG_OBJECT (avi, "seek to: %" GST_TIME_FORMAT
       " keyframe seeking:%d", GST_TIME_ARGS (seek_time), keyframe);
@@ -4029,9 +3995,9 @@ gst_avi_demux_do_seek (GstAviDemux * avi, GstSegment * segment)
         GST_TIME_ARGS (seek_time));
   }
 
-  /* the seek time is also the last_stop and stream time when going
+  /* the seek time is also the position and stream time when going
    * forwards */
-  segment->last_stop = seek_time;
+  segment->position = seek_time;
   if (segment->rate > 0.0)
     segment->time = seek_time;
 
@@ -4083,17 +4049,16 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
     /* we have to have a format as the segment format. Try to convert
      * if not. */
     if (format != GST_FORMAT_TIME) {
-      GstFormat fmt = GST_FORMAT_TIME;
       gboolean res = TRUE;
 
       if (cur_type != GST_SEEK_TYPE_NONE)
-        res = gst_pad_query_convert (pad, format, cur, &fmt, &cur);
+        res = gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &cur);
       if (res && stop_type != GST_SEEK_TYPE_NONE)
-        res = gst_pad_query_convert (pad, format, stop, &fmt, &stop);
+        res = gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME, &stop);
       if (!res)
         goto no_format;
 
-      format = fmt;
+      format = GST_FORMAT_TIME;
     }
     GST_DEBUG_OBJECT (avi,
         "seek requested: rate %g cur %" GST_TIME_FORMAT " stop %"
@@ -4134,28 +4099,19 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
 
   if (event) {
     GST_DEBUG_OBJECT (avi, "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);
   }
-  /* do the seek, seeksegment.last_stop contains the new position, this
+  /* do the seek, seeksegment.position contains the new position, this
    * actually never fails. */
   gst_avi_demux_do_seek (avi, &seeksegment);
 
-  gst_event_replace (&avi->close_seg_event, NULL);
   if (flush) {
-    GstEvent *fevent = gst_event_new_flush_stop ();
+    GstEvent *fevent = gst_event_new_flush_stop (TRUE);
 
     GST_DEBUG_OBJECT (avi, "sending flush stop");
     gst_avi_demux_push_event (avi, gst_event_ref (fevent));
     gst_pad_push_event (avi->sinkpad, fevent);
-  } else if (avi->segment_running) {
-    /* we are running the current segment and doing a non-flushing seek,
-     * close the segment first based on the last_stop. */
-    GST_DEBUG_OBJECT (avi, "closing running segment %" G_GINT64_FORMAT
-        " to %" G_GINT64_FORMAT, avi->segment.start, avi->segment.last_stop);
-    avi->close_seg_event = gst_event_new_new_segment_full (TRUE,
-        avi->segment.rate, avi->segment.applied_rate, avi->segment.format,
-        avi->segment.start, avi->segment.last_stop, avi->segment.time);
   }
 
   /* now update the real segment info */
@@ -4165,30 +4121,15 @@ gst_avi_demux_handle_seek (GstAviDemux * avi, GstPad * pad, GstEvent * event)
   if (avi->segment.flags & GST_SEEK_FLAG_SEGMENT) {
     gst_element_post_message (GST_ELEMENT_CAST (avi),
         gst_message_new_segment_start (GST_OBJECT_CAST (avi),
-            avi->segment.format, avi->segment.last_stop));
+            avi->segment.format, avi->segment.position));
   }
 
-  /* prepare for streaming again */
-  if ((stop = avi->segment.stop) == GST_CLOCK_TIME_NONE)
-    stop = avi->segment.duration;
-
   /* queue the segment event for the streaming thread. */
   if (avi->seg_event)
     gst_event_unref (avi->seg_event);
-  if (avi->segment.rate > 0.0) {
-    /* forwards goes from last_stop to stop */
-    avi->seg_event = gst_event_new_new_segment_full (FALSE,
-        avi->segment.rate, avi->segment.applied_rate, avi->segment.format,
-        avi->segment.last_stop, stop, avi->segment.time);
-  } else {
-    /* reverse goes from start to last_stop */
-    avi->seg_event = gst_event_new_new_segment_full (FALSE,
-        avi->segment.rate, avi->segment.applied_rate, avi->segment.format,
-        avi->segment.start, avi->segment.last_stop, avi->segment.time);
-  }
+  avi->seg_event = gst_event_new_segment (&avi->segment);
 
   if (!avi->streaming) {
-    avi->segment_running = TRUE;
     gst_pad_start_task (avi->sinkpad, (GstTaskFunction) gst_avi_demux_loop,
         avi->sinkpad);
   }
@@ -4241,29 +4182,28 @@ avi_demux_handle_seek_push (GstAviDemux * avi, GstPad * pad, GstEvent * event)
       &cur_type, &cur, &stop_type, &stop);
 
   if (format != GST_FORMAT_TIME) {
-    GstFormat fmt = GST_FORMAT_TIME;
     gboolean res = TRUE;
 
     if (cur_type != GST_SEEK_TYPE_NONE)
-      res = gst_pad_query_convert (pad, format, cur, &fmt, &cur);
+      res = gst_pad_query_convert (pad, format, cur, GST_FORMAT_TIME, &cur);
     if (res && stop_type != GST_SEEK_TYPE_NONE)
-      res = gst_pad_query_convert (pad, format, stop, &fmt, &stop);
+      res = gst_pad_query_convert (pad, format, stop, GST_FORMAT_TIME, &stop);
     if (!res) {
       GST_DEBUG_OBJECT (avi, "unsupported format given, seek aborted.");
       return FALSE;
     }
 
-    format = fmt;
+    format = GST_FORMAT_TIME;
   }
 
   /* let gst_segment handle any tricky stuff */
   GST_DEBUG_OBJECT (avi, "configuring seek");
   memcpy (&seeksegment, &avi->segment, sizeof (GstSegment));
-  gst_segment_set_seek (&seeksegment, rate, format, flags,
+  gst_segment_do_seek (&seeksegment, rate, format, flags,
       cur_type, cur, stop_type, stop, &update);
 
-  keyframe = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
-  cur = seeksegment.last_stop;
+  keyframe = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
+  cur = seeksegment.position;
 
   GST_DEBUG_OBJECT (avi,
       "Seek requested: ts %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT
@@ -4450,7 +4390,9 @@ gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
   GstStructure *s;
   gint y, w, h;
   gint bpp, stride;
-  guint8 *tmp = NULL;
+  guint8 *tmp = NULL, *data;
+  gsize size;
+  GstCaps *caps;
 
   if (stream->strh->type != GST_RIFF_FCC_vids)
     return buf;
@@ -4459,7 +4401,10 @@ gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
     return buf;                 /* Ignore non DIB buffers */
   }
 
-  s = gst_caps_get_structure (GST_PAD_CAPS (stream->pad), 0);
+  caps = gst_pad_get_current_caps (stream->pad);
+  s = gst_caps_get_structure (caps, 0);
+  gst_caps_unref (caps);
+
   if (!gst_structure_get_int (s, "bpp", &bpp)) {
     GST_WARNING ("Failed to retrieve depth from caps");
     return buf;
@@ -4475,20 +4420,24 @@ gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
   stride = GST_ROUND_UP_4 (w * (bpp / 8));
 
   buf = gst_buffer_make_writable (buf);
-  if (GST_BUFFER_SIZE (buf) < (stride * h)) {
+
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
+  if (size < (stride * h)) {
     GST_WARNING ("Buffer is smaller than reported Width x Height x Depth");
+    gst_buffer_unmap (buf, data, size);
     return buf;
   }
 
   tmp = g_malloc (stride);
 
   for (y = 0; y < h / 2; y++) {
-    swap_line (GST_BUFFER_DATA (buf) + stride * y,
-        GST_BUFFER_DATA (buf) + stride * (h - 1 - y), tmp, stride);
+    swap_line (data + stride * y, data + stride * (h - 1 - y), tmp, stride);
   }
 
   g_free (tmp);
 
+  gst_buffer_unmap (buf, data, size);
+
   return buf;
 }
 
@@ -4742,7 +4691,7 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
       goto pull_failed;
 
     /* check for short buffers, this is EOS as well */
-    if (GST_BUFFER_SIZE (buf) < size)
+    if (gst_buffer_get_size (buf) < size)
       goto short_buffer;
 
     /* invert the picture if needed */
@@ -4768,15 +4717,13 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
 
     gst_avi_demux_add_assoc (avi, stream, timestamp, offset, keyframe);
 
-    gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
-
     /* update current position in the segment */
-    gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, timestamp);
+    avi->segment.position = timestamp;
 
     GST_DEBUG_OBJECT (avi, "Pushing buffer of size %u, ts %"
         GST_TIME_FORMAT ", dur %" GST_TIME_FORMAT ", off %" G_GUINT64_FORMAT
         ", off_end %" G_GUINT64_FORMAT,
-        GST_BUFFER_SIZE (buf), GST_TIME_ARGS (timestamp),
+        gst_buffer_get_size (buf), GST_TIME_ARGS (timestamp),
         GST_TIME_ARGS (duration), out_offset, out_offset_end);
 
     ret = gst_pad_push (stream->pad, buf);
@@ -4831,7 +4778,7 @@ short_buffer:
   {
     GST_WARNING_OBJECT (avi, "Short read at offset %" G_GUINT64_FORMAT
         ", only got %d/%" G_GUINT64_FORMAT " bytes (truncated file?)", offset,
-        GST_BUFFER_SIZE (buf), size);
+        gst_buffer_get_size (buf), size);
     gst_buffer_unref (buf);
     ret = GST_FLOW_UNEXPECTED;
     goto beach;
@@ -4849,7 +4796,6 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
   guint32 size = 0;
   gint stream_nr = 0;
   GstFlowReturn res = GST_FLOW_OK;
-  GstFormat format = GST_FORMAT_TIME;
 
   if (G_UNLIKELY (avi->have_eos)) {
     /* Clean adapter, we're done */
@@ -4976,7 +4922,7 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
         if (size) {
           buf = gst_adapter_take_buffer (avi->adapter, GST_ROUND_UP_2 (size));
           /* patch the size */
-          GST_BUFFER_SIZE (buf) = size;
+          gst_buffer_resize (buf, 0, size);
         } else {
           buf = NULL;
         }
@@ -5005,9 +4951,8 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
           gst_buffer_unref (buf);
       } else {
         /* get time of this buffer */
-        gst_pad_query_position (stream->pad, &format, (gint64 *) & next_ts);
-        if (G_UNLIKELY (format != GST_FORMAT_TIME))
-          goto wrong_format;
+        gst_pad_query_position (stream->pad, GST_FORMAT_TIME,
+            (gint64 *) & next_ts);
 
         gst_avi_demux_add_assoc (avi, stream, next_ts, offset, FALSE);
 
@@ -5016,7 +4961,7 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
         stream->current_total += size;
 
         /* update current position in the segment */
-        gst_segment_set_last_stop (&avi->segment, GST_FORMAT_TIME, next_ts);
+        avi->segment.position = next_ts;
 
         if (saw_desired_kf && buf) {
           GstClockTime dur_ts = 0;
@@ -5024,9 +4969,8 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
           /* invert the picture if needed */
           buf = gst_avi_demux_invert (stream, buf);
 
-          gst_pad_query_position (stream->pad, &format, (gint64 *) & dur_ts);
-          if (G_UNLIKELY (format != GST_FORMAT_TIME))
-            goto wrong_format;
+          gst_pad_query_position (stream->pad, GST_FORMAT_TIME,
+              (gint64 *) & dur_ts);
 
           GST_BUFFER_TIMESTAMP (buf) = next_ts;
           GST_BUFFER_DURATION (buf) = dur_ts - next_ts;
@@ -5038,7 +4982,6 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
             GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
           }
 
-          gst_buffer_set_caps (buf, GST_PAD_CAPS (stream->pad));
           GST_DEBUG_OBJECT (avi,
               "Pushing buffer with time=%" GST_TIME_FORMAT ", duration %"
               GST_TIME_FORMAT ", offset %" G_GUINT64_FORMAT
@@ -5066,17 +5009,7 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
     }
   }
 
-done:
   return res;
-
-  /* ERRORS */
-wrong_format:
-  {
-    GST_DEBUG_OBJECT (avi, "format %s != GST_FORMAT_TIME",
-        gst_format_get_name (format));
-    res = GST_FLOW_ERROR;
-    goto done;
-  }
 }
 
 /*
@@ -5102,19 +5035,19 @@ push_tag_lists (GstAviDemux * avi)
     if (pad && tags) {
       GST_DEBUG_OBJECT (pad, "Tags: %" GST_PTR_FORMAT, tags);
 
-      gst_element_found_tags_for_pad (GST_ELEMENT_CAST (avi), pad, tags);
+      gst_pad_push_event (pad, gst_event_new_tag (tags));
       stream->taglist = NULL;
     }
   }
 
   if (!(tags = avi->globaltags))
-    tags = gst_tag_list_new ();
+    tags = gst_tag_list_new_empty ();
 
   gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE,
       GST_TAG_CONTAINER_FORMAT, "AVI", NULL);
 
   GST_DEBUG_OBJECT (avi, "Global tags: %" GST_PTR_FORMAT, tags);
-  gst_element_found_tags (GST_ELEMENT_CAST (avi), tags);
+  gst_avi_demux_push_event (avi, gst_event_new_tag (tags));
   avi->globaltags = NULL;
   avi->got_tags = FALSE;
 }
@@ -5143,10 +5076,6 @@ gst_avi_demux_loop (GstPad * pad)
       avi->state = GST_AVI_DEMUX_MOVI;
       break;
     case GST_AVI_DEMUX_MOVI:
-      if (G_UNLIKELY (avi->close_seg_event)) {
-        gst_avi_demux_push_event (avi, avi->close_seg_event);
-        avi->close_seg_event = NULL;
-      }
       if (G_UNLIKELY (avi->seg_event)) {
         gst_avi_demux_push_event (avi, avi->seg_event);
         avi->seg_event = NULL;
@@ -5176,12 +5105,17 @@ pause:{
 
     gboolean push_eos = FALSE;
     GST_LOG_OBJECT (avi, "pausing task, reason %s", gst_flow_get_name (res));
-    avi->segment_running = FALSE;
     gst_pad_pause_task (avi->sinkpad);
 
-
     if (res == GST_FLOW_UNEXPECTED) {
       /* handle end-of-stream/segment */
+      /* so align our position with the end of it, if there is one
+       * this ensures a subsequent will arrive at correct base/acc time */
+      if (avi->segment.rate > 0.0 &&
+          GST_CLOCK_TIME_IS_VALID (avi->segment.stop))
+        avi->segment.position = avi->segment.stop;
+      else if (avi->segment.rate < 0.0)
+        avi->segment.position = avi->segment.start;
       if (avi->segment.flags & GST_SEEK_FLAG_SEGMENT) {
         gint64 stop;
 
@@ -5233,7 +5167,7 @@ gst_avi_demux_chain (GstPad * pad, GstBuffer * buf)
       avi->stream[i].discont = TRUE;
   }
 
-  GST_DEBUG ("Store %d bytes in adapter", GST_BUFFER_SIZE (buf));
+  GST_DEBUG ("Store %d bytes in adapter", gst_buffer_get_size (buf));
   gst_adapter_push (avi->adapter, buf);
 
   switch (avi->state) {
@@ -5250,10 +5184,6 @@ gst_avi_demux_chain (GstPad * pad, GstBuffer * buf)
       }
       break;
     case GST_AVI_DEMUX_MOVI:
-      if (G_UNLIKELY (avi->close_seg_event)) {
-        gst_avi_demux_push_event (avi, avi->close_seg_event);
-        avi->close_seg_event = NULL;
-      }
       if (G_UNLIKELY (avi->seg_event)) {
         gst_avi_demux_push_event (avi, avi->seg_event);
         avi->seg_event = NULL;
@@ -5336,11 +5266,28 @@ abort_buffering:
 static gboolean
 gst_avi_demux_sink_activate (GstPad * sinkpad)
 {
-  if (gst_pad_check_pull_range (sinkpad)) {
-    GST_DEBUG ("going to pull mode");
-    return gst_pad_activate_pull (sinkpad, TRUE);
-  } else {
-    GST_DEBUG ("going to push (streaming) mode");
+  GstQuery *query;
+  gboolean pull_mode;
+
+  query = gst_query_new_scheduling ();
+
+  if (!gst_pad_peer_query (sinkpad, query)) {
+    gst_query_unref (query);
+    goto activate_push;
+  }
+
+  gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+  gst_query_unref (query);
+
+  if (!pull_mode)
+    goto activate_push;
+
+  GST_DEBUG_OBJECT (sinkpad, "activating pull");
+  return gst_pad_activate_pull (sinkpad, TRUE);
+
+activate_push:
+  {
+    GST_DEBUG_OBJECT (sinkpad, "activating push");
     return gst_pad_activate_push (sinkpad, TRUE);
   }
 }
@@ -5351,12 +5298,10 @@ gst_avi_demux_sink_activate_pull (GstPad * sinkpad, gboolean active)
   GstAviDemux *avi = GST_AVI_DEMUX (GST_OBJECT_PARENT (sinkpad));
 
   if (active) {
-    avi->segment_running = TRUE;
     avi->streaming = FALSE;
     return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_avi_demux_loop,
         sinkpad);
   } else {
-    avi->segment_running = FALSE;
     return gst_pad_stop_task (sinkpad);
   }
 }