Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 9 Nov 2011 16:40:10 +0000 (17:40 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 9 Nov 2011 16:40:10 +0000 (17:40 +0100)
1  2 
gst/avi/gstavidemux.c

diff --combined gst/avi/gstavidemux.c
@@@ -72,6 -72,9 +72,6 @@@ static GstStaticPadTemplate sink_templ 
      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);
@@@ -87,6 -90,7 +87,6 @@@ static gboolean gst_avi_demux_push_even
  #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);
@@@ -114,50 -118,63 +114,50 @@@ static void gst_avi_demux_get_buffer_in
  
  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>, "
  }
  
  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");
@@@ -253,6 -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;
@@@ -416,6 -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)
  {
            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;
          }
@@@ -700,14 -754,22 +700,14 @@@ gst_avi_demux_handle_sink_event (GstPa
        "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 */
        }
  
        /* 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;
        }
          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];
            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;
              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];
  
  
          /* 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) {
            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)
          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);
@@@ -911,10 -970,9 +911,10 @@@ gst_avi_demux_peek_chunk_info (GstAviDe
    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;
  }
@@@ -1093,17 -1151,14 +1093,17 @@@ gst_avi_demux_parse_avih (GstAviDemux 
      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);
@@@ -1163,7 -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;
    }
@@@ -1190,20 -1245,16 +1190,20 @@@ gst_avi_demux_parse_superindex (GstAviD
    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). */
    indexes[i] = GST_BUFFER_OFFSET_NONE;
    *_indexes = indexes;
  
 +  gst_buffer_unmap (buf, data, size);
    gst_buffer_unref (buf);
  
    return TRUE;
@@@ -1244,18 -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;
    }
  }
@@@ -1460,16 -1508,19 +1460,16 @@@ gst_avi_demux_parse_subindex (GstAviDem
    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;
      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;
@@@ -1530,20 -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:
    {
          ("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;
    }
@@@ -1705,18 -1754,14 +1705,18 @@@ gst_avi_demux_riff_parse_vprp (GstEleme
  {
    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);
  
    /* 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);
@@@ -1804,7 -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;
    }
@@@ -1821,8 -1868,8 +1821,8 @@@ gst_avi_demux_expose_streams (GstAviDem
      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)
  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);
    }
  }
@@@ -2086,12 -2127,9 +2086,12 @@@ gst_avi_demux_parse_stream (GstAviDemu
        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 {
  
        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;
        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);
      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;
  #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
    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;
  
@@@ -2325,26 -2365,20 +2325,26 @@@ gst_avi_demux_parse_odml (GstAviDemux 
      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);
@@@ -2522,7 -2556,7 +2522,7 @@@ static gboolea
  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;
    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 ();
  
  
      n++;
    }
 +  gst_buffer_unmap (buf, data, size);
    gst_buffer_unref (buf);
  
    /* get stream stats now */
  empty_list:
    {
      GST_DEBUG_OBJECT (avi, "empty index");
 +    gst_buffer_unmap (buf, data, size);
      gst_buffer_unref (buf);
      return FALSE;
    }
@@@ -2621,7 -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;
    }
@@@ -2641,8 -2673,6 +2641,8 @@@ gst_avi_demux_stream_index (GstAviDemu
    GstBuffer *buf;
    guint32 tag;
    guint32 size;
 +  gsize bsize;
 +  guint8 *bdata;
  
    GST_DEBUG ("demux stream index at offset %" G_GUINT64_FORMAT, offset);
  
    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 */
      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);
  
@@@ -2722,7 -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;
    }
@@@ -2731,11 -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;
    }
  }
@@@ -2786,7 -2810,7 +2786,7 @@@ gst_avi_demux_stream_index_push (GstAvi
    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);
@@@ -2834,17 -2858,19 +2834,17 @@@ gst_avi_demux_peek_tag (GstAviDemux * a
  {
    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);
  
        *size, offset + 8, offset + 8 + (gint64) * size);
  
  done:
 +  gst_buffer_unmap (buf, bufdata, bufsize);
    gst_buffer_unref (buf);
  
    return res;
@@@ -2914,6 -2939,7 +2914,6 @@@ gst_avi_demux_stream_scan (GstAviDemux 
  {
    GstFlowReturn res;
    GstAviStream *stream;
 -  GstFormat format;
    guint64 pos = 0;
    guint64 length;
    gint64 tmplength;
    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;
  
@@@ -3044,7 -3071,7 +3044,7 @@@ gst_avi_demux_calculate_durations_from_
    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,
@@@ -3088,8 -3115,10 +3088,8 @@@ gst_avi_demux_check_seekability (GstAvi
  
    /* 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
@@@ -3120,9 -3149,9 +3120,9 @@@ gst_avi_demux_stream_header_push (GstAv
    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);
  
          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 */
  
            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;
                  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;
          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) {
@@@ -3336,9 -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);
  
@@@ -3406,7 -3438,7 +3406,7 @@@ gst_avi_demux_add_date_tag (GstAviDemu
    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);
@@@ -3493,11 -3525,10 +3493,11 @@@ gst_avi_demux_parse_idit_text (GstAviDe
  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
     */
  
    /* 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;
  
  non_parsable:
    GST_WARNING_OBJECT (avi, "IDIT tag has no parsable info");
 +  gst_buffer_unmap (buf, data, size);
  }
  
  /*
@@@ -3554,10 -3581,10 +3554,10 @@@ gst_avi_demux_stream_header_pull (GstAv
    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 ();
  
      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);
        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");
  
    /* 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),
              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) {
            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;
          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;
      }
    /* Now, find the data (i.e. skip all junk between header and data) */
    do {
      guint size;
 +    gsize bsize;
      guint8 *data;
      guint32 tag, ltag;
  
      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) {
                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));
                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) {
              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);
@@@ -3825,13 -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,
@@@ -3961,8 -3995,8 +3961,8 @@@ gst_avi_demux_do_seek (GstAviDemux * av
    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);
          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;
  
@@@ -4049,16 -4083,17 +4049,16 @@@ gst_avi_demux_handle_seek (GstAviDemux 
      /* 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 %"
  
    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 */
    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);
    }
@@@ -4182,28 -4241,29 +4182,28 @@@ avi_demux_handle_seek_push (GstAviDemu
        &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
@@@ -4390,9 -4450,7 +4390,9 @@@ gst_avi_demux_invert (GstAviStream * st
    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;
      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;
  
    h = stream->strf.vids->height;
    w = stream->strf.vids->width;
-   stride = w * (bpp / 8);
+   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;
  }
  
@@@ -4691,7 -4742,7 +4691,7 @@@ gst_avi_demux_loop_data (GstAviDemux * 
        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 */
  
      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);
@@@ -4778,7 -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;
@@@ -4796,6 -4849,7 +4796,6 @@@ gst_avi_demux_stream_data (GstAviDemux 
    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 */
          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;
          }
            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);
  
          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;
            /* 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;
              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
      }
    }
  
 -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;
 -  }
  }
  
  /*
@@@ -5035,19 -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;
  }
@@@ -5076,6 -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;
@@@ -5105,17 -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;
  
@@@ -5167,7 -5233,7 +5167,7 @@@ gst_avi_demux_chain (GstPad * pad, GstB
        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) {
        }
        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;
@@@ -5266,28 -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);
    }
  }
@@@ -5298,10 -5351,12 +5298,10 @@@ gst_avi_demux_sink_activate_pull (GstPa
    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);
    }
  }