Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / isomp4 / qtdemux.c
index 14d5413..b7511c5 100644 (file)
@@ -33,7 +33,7 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch filesrc location=test.mov ! qtdemux name=demux  demux.audio_00 ! decodebin ! audioconvert ! audioresample ! autoaudiosink   demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
+ * gst-launch filesrc location=test.mov ! qtdemux name=demux  demux.audio_0 ! decodebin ! audioconvert ! audioresample ! autoaudiosink   demux.video_0 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
  * ]| Play (parse and decode) a .mov file and try to output it to
  * an automatically detected soundcard and videosink. If the MOV file contains
  * compressed audio or video data, this will only work if you have the
@@ -55,6 +55,7 @@
 
 #include <glib/gprintf.h>
 #include <gst/tag/tag.h>
+#include <gst/audio/audio.h>
 
 #include "qtatomparser.h"
 #include "qtdemux_types.h"
@@ -370,24 +371,25 @@ static GstStaticPadTemplate gst_qtdemux_sink_template =
     );
 
 static GstStaticPadTemplate gst_qtdemux_videosrc_template =
-GST_STATIC_PAD_TEMPLATE ("video_%02d",
+GST_STATIC_PAD_TEMPLATE ("video_%u",
     GST_PAD_SRC,
     GST_PAD_SOMETIMES,
     GST_STATIC_CAPS_ANY);
 
 static GstStaticPadTemplate gst_qtdemux_audiosrc_template =
-GST_STATIC_PAD_TEMPLATE ("audio_%02d",
+GST_STATIC_PAD_TEMPLATE ("audio_%u",
     GST_PAD_SRC,
     GST_PAD_SOMETIMES,
     GST_STATIC_CAPS_ANY);
 
 static GstStaticPadTemplate gst_qtdemux_subsrc_template =
-GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
+GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
     GST_PAD_SRC,
     GST_PAD_SOMETIMES,
     GST_STATIC_CAPS_ANY);
 
-GST_BOILERPLATE (GstQTDemux, gst_qtdemux, GstQTDemux, GST_TYPE_ELEMENT);
+#define gst_qtdemux_parent_class parent_class
+G_DEFINE_TYPE (GstQTDemux, gst_qtdemux, GST_TYPE_ELEMENT);
 
 static void gst_qtdemux_dispose (GObject * object);
 
@@ -398,17 +400,21 @@ static guint32
 gst_qtdemux_find_index_for_given_media_offset_linear (GstQTDemux * qtdemux,
     QtDemuxStream * str, gint64 media_offset);
 
+#if 0
 static void gst_qtdemux_set_index (GstElement * element, GstIndex * index);
 static GstIndex *gst_qtdemux_get_index (GstElement * element);
+#endif
 static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element,
     GstStateChange transition);
-static gboolean qtdemux_sink_activate (GstPad * sinkpad);
-static gboolean qtdemux_sink_activate_pull (GstPad * sinkpad, gboolean active);
-static gboolean qtdemux_sink_activate_push (GstPad * sinkpad, gboolean active);
+static gboolean qtdemux_sink_activate (GstPad * sinkpad, GstObject * parent);
+static gboolean qtdemux_sink_activate_mode (GstPad * sinkpad,
+    GstObject * parent, GstPadMode mode, gboolean active);
 
 static void gst_qtdemux_loop (GstPad * pad);
-static GstFlowReturn gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf);
-static gboolean gst_qtdemux_handle_sink_event (GstPad * pad, GstEvent * event);
+static GstFlowReturn gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent,
+    GstBuffer * inbuf);
+static gboolean gst_qtdemux_handle_sink_event (GstPad * pad, GstObject * parent,
+    GstEvent * event);
 
 static gboolean qtdemux_parse_moov (GstQTDemux * qtdemux,
     const guint8 * buffer, guint length);
@@ -432,27 +438,6 @@ static gboolean qtdemux_parse_samples (GstQTDemux * qtdemux,
 static GstFlowReturn qtdemux_expose_streams (GstQTDemux * qtdemux);
 
 static void
-gst_qtdemux_base_init (gpointer klass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_static_pad_template (element_class,
-      &gst_qtdemux_sink_template);
-  gst_element_class_add_static_pad_template (element_class,
-      &gst_qtdemux_videosrc_template);
-  gst_element_class_add_static_pad_template (element_class,
-      &gst_qtdemux_audiosrc_template);
-  gst_element_class_add_static_pad_template (element_class,
-      &gst_qtdemux_subsrc_template);
-  gst_element_class_set_details_simple (element_class, "QuickTime demuxer",
-      "Codec/Demuxer",
-      "Demultiplex a QuickTime file into audio and video streams",
-      "David Schleef <ds@schleef.org>, Wim Taymans <wim@fluendo.com>");
-
-  GST_DEBUG_CATEGORY_INIT (qtdemux_debug, "qtdemux", 0, "qtdemux plugin");
-}
-
-static void
 gst_qtdemux_class_init (GstQTDemuxClass * klass)
 {
   GObjectClass *gobject_class;
@@ -466,23 +451,38 @@ gst_qtdemux_class_init (GstQTDemuxClass * klass)
   gobject_class->dispose = gst_qtdemux_dispose;
 
   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_qtdemux_change_state);
-
+#if 0
   gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_qtdemux_set_index);
   gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_qtdemux_get_index);
+#endif
 
   gst_tag_register_musicbrainz_tags ();
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_qtdemux_sink_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_qtdemux_videosrc_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_qtdemux_audiosrc_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_qtdemux_subsrc_template));
+  gst_element_class_set_details_simple (gstelement_class, "QuickTime demuxer",
+      "Codec/Demuxer",
+      "Demultiplex a QuickTime file into audio and video streams",
+      "David Schleef <ds@schleef.org>, Wim Taymans <wim@fluendo.com>");
+
+  GST_DEBUG_CATEGORY_INIT (qtdemux_debug, "qtdemux", 0, "qtdemux plugin");
+
 }
 
 static void
-gst_qtdemux_init (GstQTDemux * qtdemux, GstQTDemuxClass * klass)
+gst_qtdemux_init (GstQTDemux * qtdemux)
 {
   qtdemux->sinkpad =
       gst_pad_new_from_static_template (&gst_qtdemux_sink_template, "sink");
   gst_pad_set_activate_function (qtdemux->sinkpad, qtdemux_sink_activate);
-  gst_pad_set_activatepull_function (qtdemux->sinkpad,
-      qtdemux_sink_activate_pull);
-  gst_pad_set_activatepush_function (qtdemux->sinkpad,
-      qtdemux_sink_activate_push);
+  gst_pad_set_activatemode_function (qtdemux->sinkpad,
+      qtdemux_sink_activate_mode);
   gst_pad_set_chain_function (qtdemux->sinkpad, gst_qtdemux_chain);
   gst_pad_set_event_function (qtdemux->sinkpad, gst_qtdemux_handle_sink_event);
   gst_element_add_pad (GST_ELEMENT_CAST (qtdemux), qtdemux->sinkpad);
@@ -499,6 +499,8 @@ gst_qtdemux_init (GstQTDemux * qtdemux, GstQTDemuxClass * klass)
   qtdemux->mdatoffset = GST_CLOCK_TIME_NONE;
   qtdemux->mdatbuffer = NULL;
   gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
+
+  GST_OBJECT_FLAG_SET (qtdemux, GST_ELEMENT_FLAG_INDEXABLE);
 }
 
 static void
@@ -528,11 +530,43 @@ gst_qtdemux_post_no_playable_stream_error (GstQTDemux * qtdemux)
   }
 }
 
+static void
+_gst_buffer_copy_into_mem (GstBuffer * dest, const guint8 * src,
+    gsize offset, gsize size)
+{
+  guint8 *bdata;
+  gsize bsize;
+
+  g_return_if_fail (gst_buffer_is_writable (dest));
+
+  bsize = gst_buffer_get_size (dest);
+  g_return_if_fail (bsize >= offset + size);
+
+  bdata = gst_buffer_map (dest, &bsize, NULL, GST_MAP_WRITE);
+  memcpy (bdata + offset, src, size);
+  gst_buffer_unmap (dest, bdata, bsize);
+}
+
+static GstBuffer *
+_gst_buffer_new_wrapped (gpointer mem, gsize size, GFreeFunc free_func)
+{
+  GstBuffer *buf;
+
+  buf = gst_buffer_new ();
+  gst_buffer_take_memory (buf, -1,
+      gst_memory_new_wrapped (free_func ? 0 : GST_MEMORY_FLAG_READONLY,
+          mem, free_func, size, 0, size));
+
+  return buf;
+}
+
 static GstFlowReturn
 gst_qtdemux_pull_atom (GstQTDemux * qtdemux, guint64 offset, guint64 size,
     GstBuffer ** buf)
 {
   GstFlowReturn flow;
+  guint8 *bdata;
+  gsize bsize;
 
   if (G_UNLIKELY (size == 0)) {
     GstFlowReturn ret;
@@ -542,9 +576,11 @@ gst_qtdemux_pull_atom (GstQTDemux * qtdemux, guint64 offset, guint64 size,
     if (ret != GST_FLOW_OK)
       return ret;
 
-    size = QT_UINT32 (GST_BUFFER_DATA (tmp));
+    bdata = gst_buffer_map (tmp, &bsize, NULL, GST_MAP_READ);
+    size = QT_UINT32 (bdata);
     GST_DEBUG_OBJECT (qtdemux, "size 0x%08" G_GINT64_MODIFIER "x", size);
 
+    gst_buffer_unmap (tmp, bdata, bsize);
     gst_buffer_unref (tmp);
   }
 
@@ -555,7 +591,7 @@ gst_qtdemux_pull_atom (GstQTDemux * qtdemux, guint64 offset, guint64 size,
        * so never mind the rest (e.g. tags) (that much) */
       GST_WARNING_OBJECT (qtdemux, "atom has bogus size %" G_GUINT64_FORMAT,
           size);
-      return GST_FLOW_UNEXPECTED;
+      return GST_FLOW_EOS;
     } else {
       GST_ELEMENT_ERROR (qtdemux, STREAM, DEMUX,
           (_("This file is invalid and cannot be played.")),
@@ -569,13 +605,14 @@ gst_qtdemux_pull_atom (GstQTDemux * qtdemux, guint64 offset, guint64 size,
   if (G_UNLIKELY (flow != GST_FLOW_OK))
     return flow;
 
+  bsize = gst_buffer_get_size (*buf);
   /* Catch short reads - we don't want any partial atoms */
-  if (G_UNLIKELY (GST_BUFFER_SIZE (*buf) < size)) {
-    GST_WARNING_OBJECT (qtdemux, "short read: %u < %" G_GUINT64_FORMAT,
-        GST_BUFFER_SIZE (*buf), size);
+  if (G_UNLIKELY (bsize < size)) {
+    GST_WARNING_OBJECT (qtdemux,
+        "short read: %" G_GSIZE_FORMAT " < %" G_GUINT64_FORMAT, bsize, size);
     gst_buffer_unref (*buf);
     *buf = NULL;
-    return GST_FLOW_UNEXPECTED;
+    return GST_FLOW_EOS;
   }
 
   return flow;
@@ -650,21 +687,6 @@ done:
 }
 #endif
 
-static const GstQueryType *
-gst_qtdemux_get_src_query_types (GstPad * pad)
-{
-  static const GstQueryType src_types[] = {
-    GST_QUERY_POSITION,
-    GST_QUERY_DURATION,
-    GST_QUERY_CONVERT,
-    GST_QUERY_FORMATS,
-    GST_QUERY_SEEKING,
-    0
-  };
-
-  return src_types;
-}
-
 static gboolean
 gst_qtdemux_get_duration (GstQTDemux * qtdemux, gint64 * duration)
 {
@@ -682,18 +704,19 @@ gst_qtdemux_get_duration (GstQTDemux * qtdemux, gint64 * duration)
 }
 
 static gboolean
-gst_qtdemux_handle_src_query (GstPad * pad, GstQuery * query)
+gst_qtdemux_handle_src_query (GstPad * pad, GstObject * parent,
+    GstQuery * query)
 {
   gboolean res = FALSE;
-  GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad));
+  GstQTDemux *qtdemux = GST_QTDEMUX (parent);
 
   GST_LOG_OBJECT (pad, "%s query", GST_QUERY_TYPE_NAME (query));
 
   switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_POSITION:
-      if (GST_CLOCK_TIME_IS_VALID (qtdemux->segment.last_stop)) {
+      if (GST_CLOCK_TIME_IS_VALID (qtdemux->segment.position)) {
         gst_query_set_position (query, GST_FORMAT_TIME,
-            qtdemux->segment.last_stop);
+            qtdemux->segment.position);
         res = TRUE;
       }
       break;
@@ -758,12 +781,10 @@ gst_qtdemux_handle_src_query (GstPad * pad, GstQuery * query)
       break;
     }
     default:
-      res = gst_pad_query_default (pad, query);
+      res = gst_pad_query_default (pad, parent, query);
       break;
   }
 
-  gst_object_unref (qtdemux);
-
   return res;
 }
 
@@ -1159,7 +1180,6 @@ gst_qtdemux_convert_seek (GstPad * pad, GstFormat * format,
     GstSeekType cur_type, gint64 * cur, GstSeekType stop_type, gint64 * stop)
 {
   gboolean res;
-  GstFormat fmt;
 
   g_return_val_if_fail (format != NULL, FALSE);
   g_return_val_if_fail (cur != NULL, FALSE);
@@ -1168,12 +1188,11 @@ gst_qtdemux_convert_seek (GstPad * pad, GstFormat * format,
   if (*format == GST_FORMAT_TIME)
     return TRUE;
 
-  fmt = GST_FORMAT_TIME;
   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)
     *format = GST_FORMAT_TIME;
@@ -1282,7 +1301,7 @@ gst_qtdemux_perform_seek (GstQTDemux * qtdemux, GstSegment * segment)
   gint64 desired_offset;
   gint n;
 
-  desired_offset = segment->last_stop;
+  desired_offset = segment->position;
 
   GST_DEBUG_OBJECT (qtdemux, "seeking to %" GST_TIME_FORMAT,
       GST_TIME_ARGS (desired_offset));
@@ -1308,8 +1327,11 @@ gst_qtdemux_perform_seek (GstQTDemux * qtdemux, GstSegment * segment)
     stream->segment_index = -1;
     stream->last_ret = GST_FLOW_OK;
     stream->sent_eos = FALSE;
+
+    if (segment->flags & GST_SEEK_FLAG_FLUSH)
+      gst_segment_init (&stream->segment, GST_FORMAT_TIME);
   }
-  segment->last_stop = desired_offset;
+  segment->position = desired_offset;
   segment->time = desired_offset;
 
   /* we stop at the end */
@@ -1374,7 +1396,7 @@ gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event)
   if (event) {
     /* configure the segment with the seek variables */
     GST_DEBUG_OBJECT (qtdemux, "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);
   }
 
@@ -1383,32 +1405,8 @@ gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event)
 
   /* prepare for streaming again */
   if (flush) {
-    gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_stop ());
-    gst_qtdemux_push_event (qtdemux, gst_event_new_flush_stop ());
-  } else if (qtdemux->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 (qtdemux, "closing running segment %" G_GINT64_FORMAT
-        " to %" G_GINT64_FORMAT, qtdemux->segment.start,
-        qtdemux->segment.last_stop);
-
-    if (qtdemux->segment.rate >= 0) {
-      /* FIXME, rate is the product of the global rate and the (quicktime)
-       * segment rate. */
-      qtdemux->pending_newsegment = gst_event_new_new_segment (TRUE,
-          qtdemux->segment.rate, qtdemux->segment.format,
-          qtdemux->segment.start, qtdemux->segment.last_stop,
-          qtdemux->segment.time);
-    } else {                    /* For Reverse Playback */
-      guint64 stop;
-
-      if ((stop = qtdemux->segment.stop) == -1)
-        stop = qtdemux->segment.duration;
-      /* for reverse playback, we played from stop to last_stop. */
-      qtdemux->pending_newsegment = gst_event_new_new_segment (TRUE,
-          qtdemux->segment.rate, qtdemux->segment.format,
-          qtdemux->segment.last_stop, stop, qtdemux->segment.last_stop);
-    }
+    gst_pad_push_event (qtdemux->sinkpad, gst_event_new_flush_stop (TRUE));
+    gst_qtdemux_push_event (qtdemux, gst_event_new_flush_stop (TRUE));
   }
 
   /* commit the new segment */
@@ -1417,12 +1415,10 @@ gst_qtdemux_do_seek (GstQTDemux * qtdemux, GstPad * pad, GstEvent * event)
   if (qtdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
     gst_element_post_message (GST_ELEMENT_CAST (qtdemux),
         gst_message_new_segment_start (GST_OBJECT_CAST (qtdemux),
-            qtdemux->segment.format, qtdemux->segment.last_stop));
+            qtdemux->segment.format, qtdemux->segment.position));
   }
 
-  /* restart streaming, NEWSEGMENT will be sent from the streaming
-   * thread. */
-  qtdemux->segment_running = TRUE;
+  /* restart streaming, NEWSEGMENT will be sent from the streaming thread. */
   for (i = 0; i < qtdemux->n_streams; i++)
     qtdemux->streams[i]->last_ret = GST_FLOW_OK;
 
@@ -1467,10 +1463,11 @@ parse_error:
 }
 
 static gboolean
-gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event)
+gst_qtdemux_handle_src_event (GstPad * pad, GstObject * parent,
+    GstEvent * event)
 {
   gboolean res = TRUE;
-  GstQTDemux *qtdemux = GST_QTDEMUX (gst_pad_get_parent (pad));
+  GstQTDemux *qtdemux = GST_QTDEMUX (parent);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SEEK:
@@ -1507,12 +1504,10 @@ gst_qtdemux_handle_src_event (GstPad * pad, GstEvent * event)
       gst_event_unref (event);
       break;
     default:
-      res = gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, parent, event);
       break;
   }
 
-  gst_object_unref (qtdemux);
-
 done:
   return res;
 
@@ -1599,32 +1594,25 @@ gst_qtdemux_find_sample (GstQTDemux * qtdemux, gint64 byte_pos, gboolean fw,
 }
 
 static gboolean
-gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
+gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstObject * parent,
+    GstEvent * event)
 {
-  GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad));
+  GstQTDemux *demux = GST_QTDEMUX (parent);
   gboolean res;
 
   GST_LOG_OBJECT (demux, "handling %s event", GST_EVENT_TYPE_NAME (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;
+      gint64 offset = 0;
       QtDemuxStream *stream;
       gint idx;
-      gboolean update;
       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 (demux,
-          "received format %d newsegment %" GST_SEGMENT_FORMAT, format,
+      gst_event_copy_segment (event, &segment);
+      GST_DEBUG_OBJECT (demux, "received newsegment %" GST_SEGMENT_FORMAT,
           &segment);
 
       /* chain will send initial newsegment after pads have been added */
@@ -1634,12 +1622,12 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
       }
 
       /* we only expect a BYTE segment, e.g. following a seek */
-      if (format == GST_FORMAT_BYTES) {
-        if (start > 0) {
+      if (segment.format == GST_FORMAT_BYTES) {
+        if (GST_CLOCK_TIME_IS_VALID (segment.start)) {
           gint64 requested_seek_time;
           guint64 seek_offset;
 
-          offset = start;
+          offset = segment.start;
 
           GST_OBJECT_LOCK (demux);
           requested_seek_time = demux->requested_seek_time;
@@ -1649,19 +1637,20 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
           GST_OBJECT_UNLOCK (demux);
 
           if (offset == seek_offset) {
-            start = requested_seek_time;
+            segment.start = requested_seek_time;
           } else {
-            gst_qtdemux_find_sample (demux, start, TRUE, FALSE, NULL, NULL,
-                &start);
-            start = MAX (start, 0);
+            gst_qtdemux_find_sample (demux, segment.start, TRUE, FALSE, NULL,
+                NULL, (gint64 *) & segment.start);
+            if ((gint64) segment.start < 0)
+              segment.start = 0;
           }
         }
-        if (stop > 0) {
-          gst_qtdemux_find_sample (demux, stop, FALSE, FALSE, NULL, NULL,
-              &stop);
+        if (GST_CLOCK_TIME_IS_VALID (segment.stop)) {
+          gst_qtdemux_find_sample (demux, segment.stop, FALSE, FALSE, NULL,
+              NULL, (gint64 *) & segment.stop);
           /* keyframe seeking should already arrange for start >= stop,
            * but make sure in other rare cases */
-          stop = MAX (stop, start);
+          segment.stop = MAX (segment.stop, segment.start);
         }
       } else {
         GST_DEBUG_OBJECT (demux, "unsupported segment format, ignoring");
@@ -1669,16 +1658,14 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
       }
 
       /* accept upstream's notion of segment and distribute along */
-      gst_segment_set_newsegment_full (&demux->segment, update, rate, arate,
-          GST_FORMAT_TIME, start, stop, start);
-      GST_DEBUG_OBJECT (demux, "Pushing newseg update %d, rate %g, "
-          "applied rate %g, format %d, start %" GST_TIME_FORMAT ", "
-          "stop %" GST_TIME_FORMAT, update, rate, arate, GST_FORMAT_TIME,
-          GST_TIME_ARGS (start), GST_TIME_ARGS (stop));
+      segment.time = segment.start;
+      segment.duration = demux->segment.duration;
+      segment.base = gst_segment_to_running_time (&demux->segment,
+          GST_FORMAT_TIME, demux->segment.position);
 
-      gst_qtdemux_push_event (demux,
-          gst_event_new_new_segment_full (update, rate, arate, GST_FORMAT_TIME,
-              start, stop, start));
+      gst_segment_copy_into (&segment, &demux->segment);
+      GST_DEBUG_OBJECT (demux, "Pushing newseg %" GST_SEGMENT_FORMAT, &segment);
+      gst_qtdemux_push_event (demux, gst_event_new_segment (&segment));
 
       /* clear leftover in current segment, if any */
       gst_adapter_clear (demux->adapter);
@@ -1702,6 +1689,7 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
     case GST_EVENT_FLUSH_STOP:
     {
       gint i;
+      GstClockTime dur;
 
       /* clean up, force EOS if no more info follows */
       gst_adapter_clear (demux->adapter);
@@ -1712,6 +1700,9 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
         demux->streams[i]->last_ret = GST_FLOW_OK;
         demux->streams[i]->sent_eos = FALSE;
       }
+      dur = demux->segment.duration;
+      gst_segment_init (&demux->segment, GST_FORMAT_TIME);
+      demux->segment.duration = dur;
       break;
     }
     case GST_EVENT_EOS:
@@ -1734,12 +1725,13 @@ gst_qtdemux_handle_sink_event (GstPad * sinkpad, GstEvent * event)
       break;
   }
 
-  res = gst_pad_event_default (demux->sinkpad, event);
+  res = gst_pad_event_default (demux->sinkpad, parent, event);
 
 drop:
   return res;
 }
 
+#if 0
 static void
 gst_qtdemux_set_index (GstElement * element, GstIndex * index)
 {
@@ -1776,6 +1768,7 @@ gst_qtdemux_get_index (GstElement * element)
 
   return result;
 }
+#endif
 
 static void
 gst_qtdemux_stbl_free (QtDemuxStream * stream)
@@ -1855,9 +1848,11 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
       if (qtdemux->tag_list)
         gst_tag_list_free (qtdemux->tag_list);
       qtdemux->tag_list = NULL;
+#if 0
       if (qtdemux->element_index)
         gst_object_unref (qtdemux->element_index);
       qtdemux->element_index = NULL;
+#endif
       gst_adapter_clear (qtdemux->adapter);
       for (n = 0; n < qtdemux->n_streams; n++) {
         gst_qtdemux_stream_free (qtdemux, qtdemux->streams[n]);
@@ -1910,7 +1905,7 @@ qtdemux_parse_ftyp (GstQTDemux * qtdemux, const guint8 * buffer, gint length)
     GST_DEBUG_OBJECT (qtdemux, "major brand: %" GST_FOURCC_FORMAT,
         GST_FOURCC_ARGS (qtdemux->major_brand));
     buf = qtdemux->comp_brands = gst_buffer_new_and_alloc (length - 16);
-    memcpy (GST_BUFFER_DATA (buf), buffer + 16, GST_BUFFER_SIZE (buf));
+    _gst_buffer_copy_into_mem (buf, buffer + 16, 0, length - 16);
   }
 }
 
@@ -1956,10 +1951,8 @@ qtdemux_parse_uuid (GstQTDemux * qtdemux, const guint8 * buffer, gint length)
     GstBuffer *buf;
     GstTagList *taglist;
 
-    buf = gst_buffer_new ();
-    GST_BUFFER_DATA (buf) = (guint8 *) buffer + offset + 16;
-    GST_BUFFER_SIZE (buf) = length - offset - 16;
-
+    buf = _gst_buffer_new_wrapped ((guint8 *) buffer + offset + 16,
+        length - offset - 16, NULL);
     taglist = gst_tag_list_from_xmp_buffer (buf);
     gst_buffer_unref (buf);
 
@@ -2595,7 +2588,7 @@ qtdemux_parse_mfro (GstQTDemux * qtdemux, guint64 * mfra_offset,
   gint64 len;
   GstFormat fmt = GST_FORMAT_BYTES;
 
-  if (!gst_pad_query_peer_duration (qtdemux->sinkpad, &fmt, &len)) {
+  if (!gst_pad_peer_query_duration (qtdemux->sinkpad, &fmt, &len)) {
     GST_DEBUG_OBJECT (qtdemux, "upstream size not available; "
         "can not locate mfro");
     goto exit;
@@ -2657,13 +2650,16 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
   GstBuffer *buf = NULL;
   GstFlowReturn ret = GST_FLOW_OK;
   guint64 cur_offset = qtdemux->offset;
+  guint8 *data;
+  gsize size;
 
   ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, 16, &buf);
   if (G_UNLIKELY (ret != GST_FLOW_OK))
     goto beach;
-  if (G_LIKELY (GST_BUFFER_SIZE (buf) >= 8))
-    extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf),
-        GST_BUFFER_SIZE (buf), &length, &fourcc);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  if (G_LIKELY (size >= 8))
+    extract_initial_length_and_fourcc (data, size, &length, &fourcc);
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 
   /* maybe we already got most we needed, so only consider this eof */
@@ -2672,7 +2668,7 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
         (_("Invalid atom size.")),
         ("Header atom '%" GST_FOURCC_FORMAT "' has empty length",
             GST_FOURCC_ARGS (fourcc)));
-    ret = GST_FLOW_UNEXPECTED;
+    ret = GST_FLOW_EOS;
     goto beach;
   }
 
@@ -2708,51 +2704,49 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
       ret = gst_pad_pull_range (qtdemux->sinkpad, cur_offset, length, &moov);
       if (ret != GST_FLOW_OK)
         goto beach;
-      if (length != GST_BUFFER_SIZE (moov)) {
+      data = gst_buffer_map (moov, &size, NULL, GST_MAP_READ);
+      if (length != size) {
         /* Some files have a 'moov' atom at the end of the file which contains
          * a terminal 'free' atom where the body of the atom is missing.
          * Check for, and permit, this special case.
          */
-        if (GST_BUFFER_SIZE (moov) >= 8) {
-          guint8 *final_data = GST_BUFFER_DATA (moov) +
-              (GST_BUFFER_SIZE (moov) - 8);
+        if (size >= 8) {
+          guint8 *final_data = data + (size - 8);
           guint32 final_length = QT_UINT32 (final_data);
           guint32 final_fourcc = QT_FOURCC (final_data + 4);
-          if (final_fourcc == FOURCC_free &&
-              GST_BUFFER_SIZE (moov) + final_length - 8 == length) {
+          gst_buffer_unmap (moov, data, size);
+          if (final_fourcc == FOURCC_free && size + final_length - 8 == length) {
             /* Ok, we've found that special case. Allocate a new buffer with
              * that free atom actually present. */
             GstBuffer *newmoov = gst_buffer_new_and_alloc (length);
-            gst_buffer_copy_metadata (newmoov, moov,
-                GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
-                GST_BUFFER_COPY_CAPS);
-            memcpy (GST_BUFFER_DATA (newmoov), GST_BUFFER_DATA (moov),
-                GST_BUFFER_SIZE (moov));
-            memset (GST_BUFFER_DATA (newmoov) + GST_BUFFER_SIZE (moov), 0,
-                final_length - 8);
+            gst_buffer_copy_into (newmoov, moov, 0, 0, size);
+            data = gst_buffer_map (newmoov, &size, NULL, GST_MAP_WRITE);
+            memset (data + length - final_length + 8, 0, final_length - 8);
             gst_buffer_unref (moov);
             moov = newmoov;
           }
         }
       }
 
-      if (length != GST_BUFFER_SIZE (moov)) {
+      if (length != size) {
         GST_ELEMENT_ERROR (qtdemux, STREAM, DEMUX,
             (_("This file is incomplete and cannot be played.")),
-            ("We got less than expected (received %u, wanted %u, offset %"
-                G_GUINT64_FORMAT ")",
-                GST_BUFFER_SIZE (moov), (guint) length, cur_offset));
+            ("We got less than expected (received %" G_GSIZE_FORMAT
+                ", wanted %u, offset %" G_GUINT64_FORMAT ")", size,
+                (guint) length, cur_offset));
+        gst_buffer_unmap (moov, data, size);
         gst_buffer_unref (moov);
         ret = GST_FLOW_ERROR;
         goto beach;
       }
       qtdemux->offset += length;
 
-      qtdemux_parse_moov (qtdemux, GST_BUFFER_DATA (moov), length);
+      qtdemux_parse_moov (qtdemux, data, length);
       qtdemux_node_dump (qtdemux, qtdemux->moov_node);
 
       qtdemux_parse_tree (qtdemux);
       g_node_destroy (qtdemux->moov_node);
+      gst_buffer_unmap (moov, data, size);
       gst_buffer_unref (moov);
       qtdemux->moov_node = NULL;
       qtdemux->got_moov = TRUE;
@@ -2768,8 +2762,9 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
       if (ret != GST_FLOW_OK)
         goto beach;
       qtdemux->offset += length;
-      qtdemux_parse_ftyp (qtdemux, GST_BUFFER_DATA (ftyp),
-          GST_BUFFER_SIZE (ftyp));
+      data = gst_buffer_map (ftyp, &size, NULL, GST_MAP_READ);
+      qtdemux_parse_ftyp (qtdemux, data, size);
+      gst_buffer_unmap (ftyp, data, size);
       gst_buffer_unref (ftyp);
       break;
     }
@@ -2782,8 +2777,9 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
       if (ret != GST_FLOW_OK)
         goto beach;
       qtdemux->offset += length;
-      qtdemux_parse_uuid (qtdemux, GST_BUFFER_DATA (uuid),
-          GST_BUFFER_SIZE (uuid));
+      data = gst_buffer_map (uuid, &size, NULL, GST_MAP_READ);
+      qtdemux_parse_uuid (qtdemux, data, size);
+      gst_buffer_unmap (uuid, data, size);
       gst_buffer_unref (uuid);
       break;
     }
@@ -2798,8 +2794,9 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
       ret = gst_qtdemux_pull_atom (qtdemux, cur_offset, length, &unknown);
       if (ret != GST_FLOW_OK)
         goto beach;
-      GST_MEMDUMP ("Unknown tag", GST_BUFFER_DATA (unknown),
-          GST_BUFFER_SIZE (unknown));
+      data = gst_buffer_map (unknown, &size, NULL, GST_MAP_READ);
+      GST_MEMDUMP ("Unknown tag", data, size);
+      gst_buffer_unmap (unknown, data, size);
       gst_buffer_unref (unknown);
       qtdemux->offset += length;
       break;
@@ -2807,7 +2804,7 @@ gst_qtdemux_loop_state_header (GstQTDemux * qtdemux)
   }
 
 beach:
-  if (ret == GST_FLOW_UNEXPECTED && qtdemux->got_moov) {
+  if (ret == GST_FLOW_EOS && qtdemux->got_moov) {
     /* digested all data, show what we have */
     ret = qtdemux_expose_streams (qtdemux);
 
@@ -2844,7 +2841,7 @@ gst_qtdemux_seek_to_previous_keyframe (GstQTDemux * qtdemux)
     QtDemuxStream *str = qtdemux->streams[n];
 
     seg_idx = gst_qtdemux_find_segment (qtdemux, str,
-        qtdemux->segment.last_stop);
+        qtdemux->segment.position);
 
     /* segment not found, continue with normal flow */
     if (seg_idx == -1)
@@ -2920,7 +2917,7 @@ gst_qtdemux_seek_to_previous_keyframe (GstQTDemux * qtdemux)
       k_index, GST_TIME_ARGS (k_pos));
 
   /* Set last_stop with the keyframe timestamp we pushed of that stream */
-  gst_segment_set_last_stop (&qtdemux->segment, GST_FORMAT_TIME, last_stop);
+  qtdemux->segment.position = last_stop;
   GST_DEBUG_OBJECT (qtdemux, "last_stop now is %" GST_TIME_FORMAT,
       GST_TIME_ARGS (last_stop));
 
@@ -2987,7 +2984,7 @@ gst_qtdemux_seek_to_previous_keyframe (GstQTDemux * qtdemux)
   return GST_FLOW_OK;
 
 eos:
-  return GST_FLOW_UNEXPECTED;
+  return GST_FLOW_EOS;
 }
 
 /* activate the given segment number @seg_idx of @stream at time @offset.
@@ -3084,13 +3081,18 @@ gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
 
   /* update the segment values used for clipping */
   gst_segment_init (&stream->segment, GST_FORMAT_TIME);
-  gst_segment_set_newsegment (&stream->segment, FALSE, rate, GST_FORMAT_TIME,
-      start, stop, time);
+  /* accumulate previous segments */
+  if (GST_CLOCK_TIME_IS_VALID (stream->segment.stop))
+    stream->segment.base += (stream->segment.stop - stream->segment.start) /
+        ABS (stream->segment.rate);
+  stream->segment.rate = rate;
+  stream->segment.start = start;
+  stream->segment.stop = stop;
+  stream->segment.time = time;
 
   /* now prepare and send the segment */
   if (stream->pad) {
-    event = gst_event_new_new_segment (FALSE, rate, GST_FORMAT_TIME,
-        start, stop, time);
+    event = gst_event_new_segment (&stream->segment);
     gst_pad_push_event (stream->pad, event);
     /* assume we can send more data now */
     stream->last_ret = GST_FLOW_OK;
@@ -3352,8 +3354,8 @@ gst_qtdemux_sync_streams (GstQTDemux * demux)
     end_time = stream->segments[stream->n_segments - 1].stop_time;
     GST_LOG_OBJECT (demux, "current position: %" GST_TIME_FORMAT
         ", stream end: %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (demux->segment.last_stop), GST_TIME_ARGS (end_time));
-    if (end_time + 2 * GST_SECOND < demux->segment.last_stop) {
+        GST_TIME_ARGS (demux->segment.position), GST_TIME_ARGS (end_time));
+    if (end_time + 2 * GST_SECOND < demux->segment.position) {
       GST_DEBUG_OBJECT (demux, "sending EOS for stream %s",
           GST_PAD_NAME (stream->pad));
       stream->sent_eos = TRUE;
@@ -3362,10 +3364,10 @@ gst_qtdemux_sync_streams (GstQTDemux * demux)
   }
 }
 
-/* UNEXPECTED and NOT_LINKED need to be combined. This means that we return:
+/* EOS and NOT_LINKED need to be combined. This means that we return:
  *
  *  GST_FLOW_NOT_LINKED: when all pads NOT_LINKED.
- *  GST_FLOW_UNEXPECTED: when all pads UNEXPECTED or NOT_LINKED.
+ *  GST_FLOW_EOS: when all pads EOS or NOT_LINKED.
  */
 static GstFlowReturn
 gst_qtdemux_combine_flows (GstQTDemux * demux, QtDemuxStream * stream,
@@ -3380,7 +3382,7 @@ gst_qtdemux_combine_flows (GstQTDemux * demux, QtDemuxStream * stream,
   stream->last_ret = ret;
 
   /* any other error that is not-linked or eos can be returned right away */
-  if (G_LIKELY (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_NOT_LINKED))
+  if (G_LIKELY (ret != GST_FLOW_EOS && ret != GST_FLOW_NOT_LINKED))
     goto done;
 
   /* only return NOT_LINKED if all other pads returned NOT_LINKED */
@@ -3390,11 +3392,11 @@ gst_qtdemux_combine_flows (GstQTDemux * demux, QtDemuxStream * stream,
     ret = ostream->last_ret;
 
     /* no unexpected or unlinked, return */
-    if (G_LIKELY (ret != GST_FLOW_UNEXPECTED && ret != GST_FLOW_NOT_LINKED))
+    if (G_LIKELY (ret != GST_FLOW_EOS && ret != GST_FLOW_NOT_LINKED))
       goto done;
 
     /* we check to see if we have at least 1 unexpected or all unlinked */
-    unexpected |= (ret == GST_FLOW_UNEXPECTED);
+    unexpected |= (ret == GST_FLOW_EOS);
     not_linked &= (ret == GST_FLOW_NOT_LINKED);
   }
 
@@ -3402,7 +3404,7 @@ gst_qtdemux_combine_flows (GstQTDemux * demux, QtDemuxStream * stream,
   if (not_linked)
     ret = GST_FLOW_NOT_LINKED;
   else if (unexpected)
-    ret = GST_FLOW_UNEXPECTED;
+    ret = GST_FLOW_EOS;
 done:
   GST_LOG_OBJECT (demux, "combined flow return: %s", gst_flow_get_name (ret));
   return ret;
@@ -3414,16 +3416,16 @@ static GstBuffer *
 gst_qtdemux_clip_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
     GstBuffer * buf)
 {
-  gint64 start, stop, cstart, cstop, diff;
+  guint64 start, stop, cstart, cstop, diff;
   GstClockTime timestamp = GST_CLOCK_TIME_NONE, duration = GST_CLOCK_TIME_NONE;
-  guint8 *data;
   guint size;
   gint num_rate, denom_rate;
   gint frame_size;
   gboolean clip_data;
+  guint offset;
 
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
+  size = gst_buffer_get_size (buf);
+  offset = 0;
 
   /* depending on the type, setup the clip parameters */
   if (stream->subtype == FOURCC_soun) {
@@ -3473,7 +3475,7 @@ gst_qtdemux_clip_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
           "clipping start to %" GST_TIME_FORMAT " %"
           G_GUINT64_FORMAT " bytes", GST_TIME_ARGS (cstart), diff);
 
-      data += diff;
+      offset = diff;
       size -= diff;
     }
   }
@@ -3492,10 +3494,9 @@ gst_qtdemux_clip_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
     }
   }
 
+  gst_buffer_resize (buf, offset, size);
   GST_BUFFER_TIMESTAMP (buf) = timestamp;
   GST_BUFFER_DURATION (buf) = duration;
-  GST_BUFFER_SIZE (buf) = size;
-  GST_BUFFER_DATA (buf) = data;
 
   return buf;
 
@@ -3525,12 +3526,10 @@ gst_qtdemux_process_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
     GstBuffer * buf)
 {
   guint8 *data;
-  guint size, nsize = 0;
+  guint nsize = 0;
+  gsize size;
   gchar *str;
 
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
-
   /* not many cases for now */
   if (G_UNLIKELY (stream->fourcc == FOURCC_mp4s)) {
     /* send a one time dvd clut event */
@@ -3545,25 +3544,26 @@ gst_qtdemux_process_buffer (GstQTDemux * qtdemux, QtDemuxStream * stream,
     return buf;
   }
 
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+
   if (G_LIKELY (size >= 2)) {
     nsize = GST_READ_UINT16_BE (data);
     nsize = MIN (nsize, size - 2);
   }
 
-  GST_LOG_OBJECT (qtdemux, "3GPP timed text subtitle: %d/%d", nsize, size);
+  GST_LOG_OBJECT (qtdemux, "3GPP timed text subtitle: %d/%" G_GSIZE_FORMAT "",
+      nsize, size);
 
   /* takes care of UTF-8 validation or UTF-16 recognition,
    * no other encoding expected */
   str = gst_tag_freeform_string_to_utf8 ((gchar *) data + 2, nsize, NULL);
+  gst_buffer_unmap (buf, data, size);
   if (str) {
     gst_buffer_unref (buf);
-    buf = gst_buffer_new ();
-    GST_BUFFER_DATA (buf) = GST_BUFFER_MALLOCDATA (buf) = (guint8 *) str;
-    GST_BUFFER_SIZE (buf) = strlen (str);
+    buf = _gst_buffer_new_wrapped (str, strlen (str), g_free);
   } else {
     /* may be 0-size subtitle, which is also sent to keep pipeline going */
-    GST_BUFFER_DATA (buf) = data + 2;
-    GST_BUFFER_SIZE (buf) = nsize;
+    gst_buffer_resize (buf, 2, nsize);
   }
 
   /* FIXME ? convert optional subsequent style info to markup */
@@ -3585,8 +3585,12 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
 
   if (G_UNLIKELY (stream->fourcc == FOURCC_rtsp)) {
     gchar *url;
+    guint8 *bdata;
+    gsize bsize;
 
-    url = g_strndup ((gchar *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+    bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+    url = g_strndup ((gchar *) bdata, bsize);
+    gst_buffer_unmap (buf, bdata, bsize);
     if (url != NULL && strlen (url) != 0) {
       /* we have RTSP redirect now */
       gst_element_post_message (GST_ELEMENT_CAST (qtdemux),
@@ -3603,7 +3607,7 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
 
   /* position reporting */
   if (qtdemux->segment.rate >= 0) {
-    gst_segment_set_last_stop (&qtdemux->segment, GST_FORMAT_TIME, position);
+    qtdemux->segment.position = position;
     gst_qtdemux_sync_streams (qtdemux);
   }
 
@@ -3622,7 +3626,6 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
       stream->discont = FALSE;
     }
-    gst_buffer_set_caps (buffer, stream->caps);
 
     gst_pad_push (stream->pad, buffer);
 
@@ -3630,7 +3633,7 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
   }
 
   /* we're going to modify the metadata */
-  buf = gst_buffer_make_metadata_writable (buf);
+  buf = gst_buffer_make_writable (buf);
 
   if (G_UNLIKELY (stream->need_process))
     buf = gst_qtdemux_process_buffer (qtdemux, stream, buf);
@@ -3641,10 +3644,9 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
   GST_BUFFER_OFFSET_END (buf) = -1;
 
   if (G_UNLIKELY (stream->padding)) {
-    GST_BUFFER_DATA (buf) += stream->padding;
-    GST_BUFFER_SIZE (buf) -= stream->padding;
+    gst_buffer_resize (buf, stream->padding, -1);
   }
-
+#if 0
   if (G_UNLIKELY (qtdemux->element_index)) {
     GstClockTime stream_time;
 
@@ -3662,6 +3664,7 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
           GST_FORMAT_BYTES, byte_position, NULL);
     }
   }
+#endif
 
   if (stream->need_clip)
     buf = gst_qtdemux_clip_buffer (qtdemux, stream, buf);
@@ -3678,8 +3681,6 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
   if (!keyframe)
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
 
-  gst_buffer_set_caps (buf, stream->caps);
-
   GST_LOG_OBJECT (qtdemux,
       "Pushing buffer with time %" GST_TIME_FORMAT ", duration %"
       GST_TIME_FORMAT " on pad %s", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
@@ -3754,7 +3755,7 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
     goto next;
 
   /* last pushed sample was out of boundary, goto next sample */
-  if (G_UNLIKELY (stream->last_ret == GST_FLOW_UNEXPECTED))
+  if (G_UNLIKELY (stream->last_ret == GST_FLOW_EOS))
     goto next;
 
   GST_LOG_OBJECT (qtdemux, "reading %d bytes @ %" G_GUINT64_FORMAT, size,
@@ -3771,7 +3772,7 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
   ret = gst_qtdemux_combine_flows (qtdemux, stream, ret);
   /* ignore unlinked, we will not push on the pad anymore and we will EOS when
    * we have no more data for the pad to push */
-  if (ret == GST_FLOW_UNEXPECTED)
+  if (ret == GST_FLOW_EOS)
     ret = GST_FLOW_OK;
 
 next:
@@ -3784,7 +3785,7 @@ beach:
 eos:
   {
     GST_DEBUG_OBJECT (qtdemux, "No samples left for any streams - EOS");
-    ret = GST_FLOW_UNEXPECTED;
+    ret = GST_FLOW_EOS;
     goto beach;
   }
 eos_stream:
@@ -3816,7 +3817,7 @@ gst_qtdemux_loop (GstPad * pad)
       break;
     case QTDEMUX_STATE_MOVIE:
       ret = gst_qtdemux_loop_state_movie (qtdemux);
-      if (qtdemux->segment.rate < 0 && ret == GST_FLOW_UNEXPECTED) {
+      if (qtdemux->segment.rate < 0 && ret == GST_FLOW_EOS) {
         ret = gst_qtdemux_seek_to_previous_keyframe (qtdemux);
       }
       break;
@@ -3838,7 +3839,6 @@ invalid_state:
   {
     GST_ELEMENT_ERROR (qtdemux, STREAM, FAILED,
         (NULL), ("streaming stopped, invalid state"));
-    qtdemux->segment_running = FALSE;
     gst_pad_pause_task (pad);
     gst_qtdemux_push_event (qtdemux, gst_event_new_eos ());
     goto done;
@@ -3849,12 +3849,11 @@ pause:
 
     GST_LOG_OBJECT (qtdemux, "pausing task, reason %s", reason);
 
-    qtdemux->segment_running = FALSE;
     gst_pad_pause_task (pad);
 
     /* fatal errors need special actions */
     /* check EOS */
-    if (ret == GST_FLOW_UNEXPECTED) {
+    if (ret == GST_FLOW_EOS) {
       if (qtdemux->n_streams == 0) {
         /* we have no streams, post an error */
         gst_qtdemux_post_no_playable_stream_error (qtdemux);
@@ -3862,11 +3861,6 @@ pause:
       if (qtdemux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
         gint64 stop;
 
-        /* FIXME: I am not sure this is the right fix. If the sinks are
-         * supposed to detect the segment is complete and accumulate
-         * automatically, it does not seem to work here. Need more work */
-        qtdemux->segment_running = TRUE;
-
         if ((stop = qtdemux->segment.stop) == -1)
           stop = qtdemux->segment.duration;
 
@@ -3886,7 +3880,7 @@ pause:
         GST_LOG_OBJECT (qtdemux, "Sending EOS at end of segment");
         gst_qtdemux_push_event (qtdemux, gst_event_new_eos ());
       }
-    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_UNEXPECTED) {
+    } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
       GST_ELEMENT_ERROR (qtdemux, STREAM, FAILED,
           (NULL), ("streaming stopped, reason %s", reason));
       gst_qtdemux_push_event (qtdemux, gst_event_new_eos ());
@@ -4013,10 +4007,8 @@ gst_qtdemux_check_seekability (GstQTDemux * demux)
 
   /* 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 (demux, "doing duration query to fix up unset stop");
-    gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
+    gst_pad_peer_query_duration (demux->sinkpad, GST_FORMAT_BYTES, &stop);
   }
 
   /* if upstream doesn't know the size, it's likely that it's not seekable in
@@ -4037,12 +4029,12 @@ done:
 
 /* FIXME, unverified after edit list updates */
 static GstFlowReturn
-gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
+gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
 {
   GstQTDemux *demux;
   GstFlowReturn ret = GST_FLOW_OK;
 
-  demux = GST_QTDEMUX (gst_pad_get_parent (sinkpad));
+  demux = GST_QTDEMUX (parent);
 
   gst_adapter_push (demux->adapter, inbuf);
 
@@ -4050,8 +4042,9 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
   if (demux->neededbytes == -1)
     goto eos;
 
-  GST_DEBUG_OBJECT (demux, "pushing in inbuf %p, neededbytes:%u, available:%u",
-      inbuf, demux->neededbytes, gst_adapter_available (demux->adapter));
+  GST_DEBUG_OBJECT (demux,
+      "pushing in inbuf %p, neededbytes:%u, available:%" G_GSIZE_FORMAT, inbuf,
+      demux->neededbytes, gst_adapter_available (demux->adapter));
 
   while (((gst_adapter_available (demux->adapter)) >= demux->neededbytes) &&
       (ret == GST_FLOW_OK)) {
@@ -4068,11 +4061,13 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
 
         gst_qtdemux_check_seekability (demux);
 
-        data = gst_adapter_peek (demux->adapter, demux->neededbytes);
+        data = gst_adapter_map (demux->adapter, demux->neededbytes);
 
         /* get fourcc/length, set neededbytes */
         extract_initial_length_and_fourcc ((guint8 *) data, demux->neededbytes,
             &size, &fourcc);
+        gst_adapter_unmap (demux->adapter);
+        data = NULL;
         GST_DEBUG_OBJECT (demux, "Peeking found [%" GST_FOURCC_FORMAT "] "
             "size: %" G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc), size);
         if (size == 0) {
@@ -4134,7 +4129,7 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
               /* there may be multiple mdat (or alike) buffers */
               /* sanity check */
               if (demux->mdatbuffer)
-                bs = GST_BUFFER_SIZE (demux->mdatbuffer);
+                bs = gst_buffer_get_size (demux->mdatbuffer);
               else
                 bs = 0;
               if (size + bs > 10 * (1 << 20))
@@ -4168,7 +4163,7 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
 
         GST_DEBUG_OBJECT (demux, "In header");
 
-        data = gst_adapter_peek (demux->adapter, demux->neededbytes);
+        data = gst_adapter_map (demux->adapter, demux->neededbytes);
 
         /* parse the header */
         extract_initial_length_and_fourcc (data, demux->neededbytes, NULL,
@@ -4179,11 +4174,8 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
           demux->got_moov = TRUE;
 
           /* prepare newsegment to send when streaming actually starts */
-          if (!demux->pending_newsegment) {
-            demux->pending_newsegment =
-                gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
-                0, GST_CLOCK_TIME_NONE, 0);
-          }
+          if (!demux->pending_newsegment)
+            demux->pending_newsegment = gst_event_new_segment (&demux->segment);
 
           qtdemux_parse_moov (demux, data, demux->neededbytes);
           qtdemux_node_dump (demux, demux->moov_node);
@@ -4198,6 +4190,7 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
             GST_DEBUG_OBJECT (demux, "Parsing [moof]");
             if (!qtdemux_parse_moof (demux, data, demux->neededbytes,
                     demux->offset, NULL)) {
+              gst_adapter_unmap (demux->adapter);
               ret = GST_FLOW_ERROR;
               goto done;
             }
@@ -4216,6 +4209,8 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
               GST_FOURCC_ARGS (fourcc));
           /* Let's jump that one and go back to initial state */
         }
+        gst_adapter_unmap (demux->adapter);
+        data = NULL;
 
         if (demux->mdatbuffer && demux->n_streams) {
           /* the mdat was before the header */
@@ -4260,12 +4255,14 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
       }
       case QTDEMUX_STATE_BUFFER_MDAT:{
         GstBuffer *buf;
+        guint8 fourcc[4];
 
         GST_DEBUG_OBJECT (demux, "Got our buffer at offset %" G_GUINT64_FORMAT,
             demux->offset);
         buf = gst_adapter_take_buffer (demux->adapter, demux->neededbytes);
+        gst_buffer_extract (buf, 0, fourcc, 4);
         GST_DEBUG_OBJECT (demux, "mdatbuffer starts with %" GST_FOURCC_FORMAT,
-            GST_FOURCC_ARGS (QT_FOURCC (GST_BUFFER_DATA (buf) + 4)));
+            GST_FOURCC_ARGS (QT_FOURCC (fourcc)));
         if (demux->mdatbuffer)
           demux->mdatbuffer = gst_buffer_join (demux->mdatbuffer, buf);
         else
@@ -4405,7 +4402,6 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
         demux->neededbytes);
   }
 done:
-  gst_object_unref (demux);
 
   return ret;
 
@@ -4419,7 +4415,7 @@ unknown_stream:
 eos:
   {
     GST_DEBUG_OBJECT (demux, "no next entry, EOS");
-    ret = GST_FLOW_UNEXPECTED;
+    ret = GST_FLOW_EOS;
     goto done;
   }
 invalid_state:
@@ -4439,38 +4435,60 @@ no_moov:
 }
 
 static gboolean
-qtdemux_sink_activate (GstPad * sinkpad)
+qtdemux_sink_activate (GstPad * sinkpad, GstObject * parent)
 {
-  if (gst_pad_check_pull_range (sinkpad))
-    return gst_pad_activate_pull (sinkpad, TRUE);
-  else
-    return gst_pad_activate_push (sinkpad, TRUE);
-}
+  GstQuery *query;
+  gboolean pull_mode;
 
-static gboolean
-qtdemux_sink_activate_pull (GstPad * sinkpad, gboolean active)
-{
-  GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad));
+  query = gst_query_new_scheduling ();
 
-  if (active) {
-    demux->pullbased = TRUE;
-    demux->segment_running = TRUE;
-    return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_qtdemux_loop,
-        sinkpad);
-  } else {
-    demux->segment_running = FALSE;
-    return gst_pad_stop_task (sinkpad);
+  if (!gst_pad_peer_query (sinkpad, query)) {
+    gst_query_unref (query);
+    goto activate_push;
+  }
+
+  pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
+  gst_query_unref (query);
+
+  if (!pull_mode)
+    goto activate_push;
+
+  GST_DEBUG_OBJECT (sinkpad, "activating pull");
+  return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
+
+activate_push:
+  {
+    GST_DEBUG_OBJECT (sinkpad, "activating push");
+    return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
   }
 }
 
 static gboolean
-qtdemux_sink_activate_push (GstPad * sinkpad, gboolean active)
+qtdemux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
+    GstPadMode mode, gboolean active)
 {
-  GstQTDemux *demux = GST_QTDEMUX (GST_PAD_PARENT (sinkpad));
-
-  demux->pullbased = FALSE;
+  gboolean res;
+  GstQTDemux *demux = GST_QTDEMUX (parent);
 
-  return TRUE;
+  switch (mode) {
+    case GST_PAD_MODE_PUSH:
+      demux->pullbased = FALSE;
+      res = TRUE;
+      break;
+    case GST_PAD_MODE_PULL:
+      if (active) {
+        demux->pullbased = TRUE;
+        res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_qtdemux_loop,
+            sinkpad);
+      } else {
+        res = gst_pad_stop_task (sinkpad);
+      }
+      break;
+    default:
+      res = FALSE;
+      break;
+  }
+  return res;
 }
 
 #ifdef HAVE_ZLIB
@@ -4658,19 +4676,19 @@ qtdemux_parse_theora_extension (GstQTDemux * qtdemux, QtDemuxStream * stream,
     switch (type) {
       case FOURCC_tCtH:
         buffer = gst_buffer_new_and_alloc (size);
-        memcpy (GST_BUFFER_DATA (buffer), buf, size);
+        _gst_buffer_copy_into_mem (buffer, buf, 0, size);
         stream->buffers = g_slist_append (stream->buffers, buffer);
         GST_LOG_OBJECT (qtdemux, "parsing theora header");
         break;
       case FOURCC_tCt_:
         buffer = gst_buffer_new_and_alloc (size);
-        memcpy (GST_BUFFER_DATA (buffer), buf, size);
+        _gst_buffer_copy_into_mem (buffer, buf, 0, size);
         stream->buffers = g_slist_append (stream->buffers, buffer);
         GST_LOG_OBJECT (qtdemux, "parsing theora comment");
         break;
       case FOURCC_tCtC:
         buffer = gst_buffer_new_and_alloc (size);
-        memcpy (GST_BUFFER_DATA (buffer), buf, size);
+        _gst_buffer_copy_into_mem (buffer, buf, 0, size);
         stream->buffers = g_slist_append (stream->buffers, buffer);
         GST_LOG_OBJECT (qtdemux, "parsing theora codebook");
         break;
@@ -4979,11 +4997,9 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
 {
   /* consistent default for push based mode */
   gst_segment_init (&stream->segment, GST_FORMAT_TIME);
-  gst_segment_set_newsegment (&stream->segment, FALSE, 1.0, GST_FORMAT_TIME,
-      0, GST_CLOCK_TIME_NONE, 0);
 
   if (stream->subtype == FOURCC_vide) {
-    gchar *name = g_strdup_printf ("video_%02d", qtdemux->n_video_streams);
+    gchar *name = g_strdup_printf ("video_%u", qtdemux->n_video_streams);
 
     stream->pad =
         gst_pad_new_from_static_template (&gst_qtdemux_videosrc_template, name);
@@ -5083,10 +5099,8 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
 
         /* make sure it's not writable. We leave MALLOCDATA to NULL so that we
          * don't free any of the buffer data. */
-        palette = gst_buffer_new ();
-        GST_BUFFER_FLAG_SET (palette, GST_BUFFER_FLAG_READONLY);
-        GST_BUFFER_DATA (palette) = (guint8 *) palette_data;
-        GST_BUFFER_SIZE (palette) = sizeof (guint32) * palette_count;
+        palette = _gst_buffer_new_wrapped ((gpointer) palette_data,
+            palette_count, NULL);
 
         gst_caps_set_simple (stream->caps, "palette_data",
             GST_TYPE_BUFFER, palette, NULL);
@@ -5101,12 +5115,13 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
     }
     qtdemux->n_video_streams++;
   } else if (stream->subtype == FOURCC_soun) {
-    gchar *name = g_strdup_printf ("audio_%02d", qtdemux->n_audio_streams);
+    gchar *name = g_strdup_printf ("audio_%u", qtdemux->n_audio_streams);
 
     stream->pad =
         gst_pad_new_from_static_template (&gst_qtdemux_audiosrc_template, name);
     g_free (name);
     if (stream->caps) {
+      /* FIXME: Need to set channel-mask here and maybe reorder */
       gst_caps_set_simple (stream->caps,
           "rate", G_TYPE_INT, (int) stream->rate,
           "channels", G_TYPE_INT, stream->n_channels, NULL);
@@ -5115,7 +5130,7 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
   } else if (stream->subtype == FOURCC_strm) {
     GST_DEBUG_OBJECT (qtdemux, "stream type, not creating pad");
   } else if (stream->subtype == FOURCC_subp || stream->subtype == FOURCC_text) {
-    gchar *name = g_strdup_printf ("subtitle_%02d", qtdemux->n_sub_streams);
+    gchar *name = g_strdup_printf ("subtitle_%u", qtdemux->n_sub_streams);
 
     stream->pad =
         gst_pad_new_from_static_template (&gst_qtdemux_subsrc_template, name);
@@ -5131,27 +5146,19 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
 
     gst_pad_use_fixed_caps (stream->pad);
     gst_pad_set_event_function (stream->pad, gst_qtdemux_handle_src_event);
-    gst_pad_set_query_type_function (stream->pad,
-        gst_qtdemux_get_src_query_types);
     gst_pad_set_query_function (stream->pad, gst_qtdemux_handle_src_query);
+    gst_pad_set_active (stream->pad, TRUE);
 
     GST_DEBUG_OBJECT (qtdemux, "setting caps %" GST_PTR_FORMAT, stream->caps);
     gst_pad_set_caps (stream->pad, stream->caps);
 
     GST_DEBUG_OBJECT (qtdemux, "adding pad %s %p to qtdemux %p",
         GST_OBJECT_NAME (stream->pad), stream->pad, qtdemux);
-    gst_pad_set_active (stream->pad, TRUE);
     gst_element_add_pad (GST_ELEMENT_CAST (qtdemux), stream->pad);
+
     if (stream->pending_tags)
       gst_tag_list_free (stream->pending_tags);
     stream->pending_tags = list;
-    if (list) {
-      /* post now, send event on pad later */
-      GST_DEBUG_OBJECT (qtdemux, "Posting tags %" GST_PTR_FORMAT, list);
-      gst_element_post_message (GST_ELEMENT (qtdemux),
-          gst_message_new_tag_full (GST_OBJECT (qtdemux), stream->pad,
-              gst_tag_list_copy (list)));
-    }
     /* global tags go on each pad anyway */
     stream->send_global_tags = TRUE;
   }
@@ -5172,17 +5179,21 @@ qtdemux_find_atom (GstQTDemux * qtdemux, guint64 * offset,
       G_GUINT64_FORMAT, GST_FOURCC_ARGS (fourcc), *offset);
 
   while (TRUE) {
+    guint8 *bdata;
+    gsize bsize;
+
     ret = gst_pad_pull_range (qtdemux->sinkpad, *offset, 16, &buf);
     if (G_UNLIKELY (ret != GST_FLOW_OK))
       goto locate_failed;
-    if (G_LIKELY (GST_BUFFER_SIZE (buf) != 16)) {
+    if (G_UNLIKELY (gst_buffer_get_size (buf) != 16)) {
       /* likely EOF */
-      ret = GST_FLOW_UNEXPECTED;
+      ret = GST_FLOW_EOS;
       gst_buffer_unref (buf);
       goto locate_failed;
     }
-    extract_initial_length_and_fourcc (GST_BUFFER_DATA (buf), 16, length,
-        &lfourcc);
+    bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+    extract_initial_length_and_fourcc (bdata, 16, length, &lfourcc);
+    gst_buffer_unmap (buf, bdata, bsize);
     gst_buffer_unref (buf);
 
     if (G_UNLIKELY (*length == 0)) {
@@ -5222,13 +5233,15 @@ qtdemux_add_fragmented_samples (GstQTDemux * qtdemux)
   GstBuffer *buf = NULL;
   GstFlowReturn ret = GST_FLOW_OK;
   GstFlowReturn res = GST_FLOW_OK;
+  guint8 *bdata;
+  gsize bsize;
 
   offset = qtdemux->moof_offset;
   GST_DEBUG_OBJECT (qtdemux, "next moof at offset %" G_GUINT64_FORMAT, offset);
 
   if (!offset) {
     GST_DEBUG_OBJECT (qtdemux, "no next moof");
-    return GST_FLOW_UNEXPECTED;
+    return GST_FLOW_EOS;
   }
 
   /* best not do pull etc with lock held */
@@ -5241,13 +5254,15 @@ qtdemux_add_fragmented_samples (GstQTDemux * qtdemux)
   ret = gst_qtdemux_pull_atom (qtdemux, offset, length, &buf);
   if (G_UNLIKELY (ret != GST_FLOW_OK))
     goto flow_failed;
-  if (!qtdemux_parse_moof (qtdemux, GST_BUFFER_DATA (buf),
-          GST_BUFFER_SIZE (buf), offset, NULL)) {
+  bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
+  if (!qtdemux_parse_moof (qtdemux, bdata, bsize, offset, NULL)) {
+    gst_buffer_unmap (buf, bdata, bsize);
     gst_buffer_unref (buf);
     buf = NULL;
     goto parse_failed;
   }
 
+  gst_buffer_unmap (buf, bdata, bsize);
   gst_buffer_unref (buf);
   buf = NULL;
 
@@ -6091,7 +6106,7 @@ qtdemux_parse_svq3_stsd_data (GstQTDemux * qtdemux, GNode * stsd,
                 seqh_size = QT_UINT32 (data + 4);
                 if (seqh_size > 0) {
                   _seqh = gst_buffer_new_and_alloc (seqh_size);
-                  memcpy (GST_BUFFER_DATA (_seqh), data + 8, seqh_size);
+                  _gst_buffer_copy_into_mem (_seqh, data + 8, 0, seqh_size);
                 }
               }
             }
@@ -6248,12 +6263,14 @@ qtdemux_parse_amr_bitrate (GstBuffer * buf, gboolean wb)
   static const guint wb_bitrates[] = {
     6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850
   };
-  const guint8 *data = GST_BUFFER_DATA (buf);
-  guint size = QT_UINT32 (data), max_mode;
+  guint8 *data;
+  gsize size, max_mode;
   guint16 mode_set;
 
-  if (GST_BUFFER_SIZE (buf) != 0x11) {
-    GST_DEBUG ("Atom should have size 0x11, not %u", size);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+
+  if (size != 0x11) {
+    GST_DEBUG ("Atom should have size 0x11, not %" G_GSIZE_FORMAT, size);
     goto bad_data;
   }
 
@@ -6277,9 +6294,11 @@ qtdemux_parse_amr_bitrate (GstBuffer * buf, gboolean wb)
     goto bad_data;
   }
 
+  gst_buffer_unmap (buf, data, size);
   return wb ? wb_bitrates[max_mode] : nb_bitrates[max_mode];
 
 bad_data:
+  gst_buffer_unmap (buf, data, size);
   return 0;
 }
 
@@ -6484,7 +6503,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
     stream->caps =
         qtdemux_video_caps (qtdemux, stream, fourcc, stsd_data, &codec);
     if (codec) {
-      list = gst_tag_list_new ();
+      list = gst_tag_list_new_empty ();
       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
           GST_TAG_VIDEO_CODEC, codec, NULL);
       g_free (codec);
@@ -6547,7 +6566,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
                     avc_data + 8 + 1, size - 1);
 
                 buf = gst_buffer_new_and_alloc (size);
-                memcpy (GST_BUFFER_DATA (buf), avc_data + 0x8, size);
+                _gst_buffer_copy_into_mem (buf, avc_data + 0x8, 0, size);
                 gst_caps_set_simple (stream->caps,
                     "codec_data", GST_TYPE_BUFFER, buf, NULL);
                 gst_buffer_unref (buf);
@@ -6578,7 +6597,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
                 }
 
                 if (!list)
-                  list = gst_tag_list_new ();
+                  list = gst_tag_list_new_empty ();
 
                 if (max_bitrate > 0 && max_bitrate < G_MAXUINT32) {
                   gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
@@ -6626,7 +6645,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
             if (len > 0x8) {
               len -= 0x8;
               buf = gst_buffer_new_and_alloc (len);
-              memcpy (GST_BUFFER_DATA (buf), data + 8, len);
+              _gst_buffer_copy_into_mem (buf, data + 8, 0, len);
               gst_caps_set_simple (stream->caps,
                   "codec_data", GST_TYPE_BUFFER, buf, NULL);
               gst_buffer_unref (buf);
@@ -6639,7 +6658,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
           /* see annex I of the jpeg2000 spec */
           GNode *jp2h, *ihdr, *colr, *mjp2, *field, *prefix, *cmap, *cdef;
           const guint8 *data;
-          guint32 fourcc = 0;
+          const gchar *colorspace = NULL;
           gint ncomp = 0;
           guint32 ncomp_map = 0;
           gint32 *comp_map = NULL;
@@ -6670,21 +6689,22 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
           if (QT_UINT8 ((guint8 *) colr->data + 8) == 1) {
             switch (QT_UINT32 ((guint8 *) colr->data + 11)) {
               case 16:
-                fourcc = GST_MAKE_FOURCC ('s', 'R', 'G', 'B');
+                colorspace = "sRGB";
                 break;
               case 17:
-                fourcc = GST_MAKE_FOURCC ('G', 'R', 'A', 'Y');
+                colorspace = "GRAY";
                 break;
               case 18:
-                fourcc = GST_MAKE_FOURCC ('s', 'Y', 'U', 'V');
+                colorspace = "sYUV";
                 break;
               default:
+                colorspace = NULL;
                 break;
             }
           }
-          if (!fourcc)
+          if (!colorspace)
             /* colr is required, and only values 16, 17, and 18 are specified,
-               so error if we have no fourcc */
+               so error if we have no colorspace */
             break;
 
           /* extract component mapping */
@@ -6751,7 +6771,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
           gst_caps_set_simple (stream->caps,
               "num-components", G_TYPE_INT, ncomp, NULL);
           gst_caps_set_simple (stream->caps,
-              "fourcc", GST_TYPE_FOURCC, fourcc, NULL);
+              "colorspace", G_TYPE_STRING, colorspace, NULL);
 
           if (comp_map) {
             GValue arr = { 0, };
@@ -6809,7 +6829,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
             if (len > 0x8) {
               len -= 0x8;
               buf = gst_buffer_new_and_alloc (len);
-              memcpy (GST_BUFFER_DATA (buf), data + 8, len);
+              _gst_buffer_copy_into_mem (buf, data + 8, 0, len);
               gst_caps_set_simple (stream->caps,
                   "codec_data", GST_TYPE_BUFFER, buf, NULL);
               gst_buffer_unref (buf);
@@ -6839,7 +6859,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
 
           GST_DEBUG_OBJECT (qtdemux, "found codec_data in stsd");
           buf = gst_buffer_new_and_alloc (len);
-          memcpy (GST_BUFFER_DATA (buf), stsd_data, len);
+          _gst_buffer_copy_into_mem (buf, stsd_data, 0, len);
           gst_caps_set_simple (stream->caps,
               "codec_data", GST_TYPE_BUFFER, buf, NULL);
           gst_buffer_unref (buf);
@@ -6873,7 +6893,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
         case FOURCC_ovc1:
         {
           GNode *ovc1;
-          gchar *ovc1_data;
+          guint8 *ovc1_data;
           guint ovc1_len;
           GstBuffer *buf;
 
@@ -6888,7 +6908,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
             break;
           }
           buf = gst_buffer_new_and_alloc (ovc1_len - 198);
-          memcpy (GST_BUFFER_DATA (buf), ovc1_data + 198, ovc1_len - 198);
+          _gst_buffer_copy_into_mem (buf, ovc1_data + 198, 0, ovc1_len - 198);
           gst_caps_set_simple (stream->caps,
               "codec_data", GST_TYPE_BUFFER, buf, NULL);
           gst_buffer_unref (buf);
@@ -7063,14 +7083,15 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
         }
         if (enda) {
           gst_caps_set_simple (stream->caps,
-              "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, NULL);
+              "format", G_TYPE_STRING, "S24_3LE", NULL);
         }
         break;
       }
       case FOURCC_owma:
       {
         GNode *owma;
-        const gchar *owma_data, *codec_name = NULL;
+        const guint8 *owma_data;
+        const gchar *codec_name = NULL;
         guint owma_len;
         GstBuffer *buf;
         gint version = 1;
@@ -7101,7 +7122,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
         }
         wfex = (WAVEFORMATEX *) (owma_data + 36);
         buf = gst_buffer_new_and_alloc (owma_len - 54);
-        memcpy (GST_BUFFER_DATA (buf), owma_data + 54, owma_len - 54);
+        _gst_buffer_copy_into_mem (buf, owma_data + 54, 0, owma_len - 54);
         if (wfex->wFormatTag == 0x0161) {
           codec_name = "Windows Media Audio";
           version = 2;
@@ -7139,7 +7160,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
       GstStructure *s;
       gint bitrate = 0;
 
-      list = gst_tag_list_new ();
+      list = gst_tag_list_new_empty ();
       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
           GST_TAG_AUDIO_CODEC, codec, NULL);
       g_free (codec);
@@ -7199,15 +7220,15 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
               waveheader += 8;
               headerlen -= 8;
 
-              headerbuf = gst_buffer_new ();
-              GST_BUFFER_DATA (headerbuf) = (guint8 *) waveheader;
-              GST_BUFFER_SIZE (headerbuf) = headerlen;
+              headerbuf = gst_buffer_new_and_alloc (headerlen);
+              _gst_buffer_copy_into_mem (headerbuf, waveheader, 0, headerlen);
 
               if (gst_riff_parse_strf_auds (GST_ELEMENT_CAST (qtdemux),
                       headerbuf, &header, &extra)) {
                 gst_caps_unref (stream->caps);
+                /* FIXME: Need to do something with the channel reorder map */
                 stream->caps = gst_riff_create_audio_caps (header->format, NULL,
-                    header, extra, NULL, NULL);
+                    header, extra, NULL, NULL, NULL);
 
                 if (extra)
                   gst_buffer_unref (extra);
@@ -7239,7 +7260,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
           if (len > 0x4C) {
             GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x4C);
 
-            memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x4C, len - 0x4C);
+            _gst_buffer_copy_into_mem (buf, stsd_data + 0x4C, 0, len - 0x4C);
             gst_caps_set_simple (stream->caps,
                 "codec_data", GST_TYPE_BUFFER, buf, NULL);
             gst_buffer_unref (buf);
@@ -7274,7 +7295,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
               /* codec-data contains alac atom size and prefix,
                * ffmpeg likes it that way, not quite gst-ish though ...*/
               buf = gst_buffer_new_and_alloc (len);
-              memcpy (GST_BUFFER_DATA (buf), alac->data, len);
+              _gst_buffer_copy_into_mem (buf, alac->data, 0, len);
               gst_caps_set_simple (stream->caps,
                   "codec_data", GST_TYPE_BUFFER, buf, NULL);
               gst_buffer_unref (buf);
@@ -7295,14 +7316,14 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
             GstBuffer *buf = gst_buffer_new_and_alloc (len - 0x34);
             guint bitrate;
 
-            memcpy (GST_BUFFER_DATA (buf), stsd_data + 0x34, len - 0x34);
+            _gst_buffer_copy_into_mem (buf, stsd_data + 0x34, 0, len - 0x34);
 
             /* If we have enough data, let's try to get the 'damr' atom. See
              * the 3GPP container spec (26.244) for more details. */
             if ((len - 0x34) > 8 &&
                 (bitrate = qtdemux_parse_amr_bitrate (buf, amrwb))) {
               if (!list)
-                list = gst_tag_list_new ();
+                list = gst_tag_list_new_empty ();
               gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
                   GST_TAG_MAXIMUM_BITRATE, bitrate, NULL);
             }
@@ -7339,7 +7360,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
     stream->caps =
         qtdemux_sub_caps (qtdemux, stream, fourcc, stsd_data, &codec);
     if (codec) {
-      list = gst_tag_list_new ();
+      list = gst_tag_list_new_empty ();
       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
           GST_TAG_SUBTITLE_CODEC, codec, NULL);
       g_free (codec);
@@ -7451,7 +7472,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
     const gchar *lang_code;
 
     if (!list)
-      list = gst_tag_list_new ();
+      list = gst_tag_list_new_empty ();
 
     /* convert ISO 639-2 code to ISO 639-1 */
     lang_code = gst_tag_get_language_code (stream->lang_id);
@@ -7517,7 +7538,6 @@ too_many_streams:
 static void
 gst_qtdemux_guess_bitrate (GstQTDemux * qtdemux)
 {
-  GstFormat format = GST_FORMAT_BYTES;
   QtDemuxStream *stream = NULL;
   gint64 size, duration, sys_bitrate, sum_bitrate = 0;
   gint i;
@@ -7528,8 +7548,7 @@ gst_qtdemux_guess_bitrate (GstQTDemux * qtdemux)
 
   GST_DEBUG_OBJECT (qtdemux, "Looking for streams with unknown bitrate");
 
-  if (!gst_pad_query_peer_duration (qtdemux->sinkpad, &format, &size) ||
-      format != GST_FORMAT_BYTES) {
+  if (!gst_pad_peer_query_duration (qtdemux->sinkpad, GST_FORMAT_BYTES, &size)) {
     GST_DEBUG_OBJECT (qtdemux,
         "Size in bytes of the stream not known - bailing");
     return;
@@ -7596,7 +7615,7 @@ gst_qtdemux_guess_bitrate (GstQTDemux * qtdemux)
       ", Stream bitrate = %u", sys_bitrate, bitrate);
 
   if (!stream->pending_tags)
-    stream->pending_tags = gst_tag_list_new ();
+    stream->pending_tags = gst_tag_list_new_empty ();
 
   gst_tag_list_add (stream->pending_tags, GST_TAG_MERGE_REPLACE,
       GST_TAG_BITRATE, bitrate, NULL);
@@ -7709,16 +7728,18 @@ qtdemux_is_brand_3gp (GstQTDemux * qtdemux, gboolean major)
     return ((qtdemux->major_brand & GST_MAKE_FOURCC (255, 255, 0, 0)) ==
         GST_MAKE_FOURCC ('3', 'g', 0, 0));
   } else if (qtdemux->comp_brands != NULL) {
-    guint8 *data = GST_BUFFER_DATA (qtdemux->comp_brands);
-    guint size = GST_BUFFER_SIZE (qtdemux->comp_brands);
+    guint8 *data;
+    gsize size;
     gboolean res = FALSE;
 
+    data = gst_buffer_map (qtdemux->comp_brands, &size, NULL, GST_MAP_READ);
     while (size >= 4) {
       res = res || ((QT_FOURCC (data) & GST_MAKE_FOURCC (255, 255, 0, 0)) ==
           GST_MAKE_FOURCC ('3', 'g', 0, 0));
       data += 4;
       size -= 4;
     }
+    gst_buffer_unmap (qtdemux->comp_brands, data, size);
     return res;
   } else {
     return FALSE;
@@ -8131,7 +8152,7 @@ qtdemux_tag_add_covr (GstQTDemux * qtdemux, const char *tag1, const char *dummy,
   GNode *data;
   int len;
   int type;
-  GstBuffer *buf;
+  GstSample *sample;
 
   data = qtdemux_tree_get_child_by_type (node, FOURCC_data);
   if (data) {
@@ -8139,12 +8160,13 @@ qtdemux_tag_add_covr (GstQTDemux * qtdemux, const char *tag1, const char *dummy,
     type = QT_UINT32 ((guint8 *) data->data + 8);
     GST_DEBUG_OBJECT (qtdemux, "have covr tag, type=%d,len=%d", type, len);
     if ((type == 0x0000000d || type == 0x0000000e) && len > 16) {
-      if ((buf = gst_tag_image_data_to_image_buffer ((guint8 *) data->data + 16,
+      if ((sample =
+              gst_tag_image_data_to_image_sample ((guint8 *) data->data + 16,
                   len - 16, GST_TAG_IMAGE_TYPE_NONE))) {
         GST_DEBUG_OBJECT (qtdemux, "adding tag size %d", len - 16);
         gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_REPLACE,
-            tag1, buf, NULL);
-        gst_buffer_unref (buf);
+            tag1, sample, NULL);
+        gst_sample_unref (sample);
       }
     }
   }
@@ -8390,9 +8412,8 @@ qtdemux_tag_add_id32 (GstQTDemux * demux, const char *tag,
   if (len < 12 + 2)
     return;
 
-  buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = data + 14;
-  GST_BUFFER_SIZE (buf) = len - 14;
+  buf = gst_buffer_new_allocate (NULL, len - 14, 0);
+  gst_buffer_fill (buf, 0, data + 14, len - 14);
 
   taglist = gst_tag_list_from_id3v2_tag (buf);
   if (taglist) {
@@ -8497,7 +8518,7 @@ qtdemux_tag_add_blob (GNode * node, GstQTDemux * demux)
   data = node->data;
   len = QT_UINT32 (data);
   buf = gst_buffer_new_and_alloc (len);
-  memcpy (GST_BUFFER_DATA (buf), data, len);
+  _gst_buffer_copy_into_mem (buf, data, 0, len);
 
   /* heuristic to determine style of tag */
   if (QT_FOURCC (data + 4) == FOURCC_____ ||
@@ -8523,12 +8544,13 @@ qtdemux_tag_add_blob (GNode * node, GstQTDemux * demux)
   GST_DEBUG_OBJECT (demux, "media type %s", media_type);
 
   caps = gst_caps_new_simple (media_type, "style", G_TYPE_STRING, style, NULL);
-  gst_buffer_set_caps (buf, caps);
+  // TODO conver to metadata or ???
+//   gst_buffer_set_caps (buf, caps);
   gst_caps_unref (caps);
   g_free (media_type);
 
   GST_DEBUG_OBJECT (demux, "adding private tag; size %d, caps %" GST_PTR_FORMAT,
-      GST_BUFFER_SIZE (buf), caps);
+      len, caps);
 
   gst_tag_list_add (demux->tag_list, GST_TAG_MERGE_APPEND,
       GST_QT_DEMUX_PRIVATE_TAG, buf, NULL);
@@ -8558,7 +8580,7 @@ qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta)
 
   GST_DEBUG_OBJECT (qtdemux, "new tag list");
   if (!qtdemux->tag_list)
-    qtdemux->tag_list = gst_tag_list_new ();
+    qtdemux->tag_list = gst_tag_list_new_empty ();
 
   i = 0;
   while (i < G_N_ELEMENTS (add_funcs)) {
@@ -8590,10 +8612,8 @@ qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta)
     GstBuffer *buf;
     GstTagList *taglist;
 
-    buf = gst_buffer_new ();
-    GST_BUFFER_DATA (buf) = ((guint8 *) xmp_->data) + 8;
-    GST_BUFFER_SIZE (buf) = QT_UINT32 ((guint8 *) xmp_->data) - 8;
-
+    buf = _gst_buffer_new_wrapped (((guint8 *) xmp_->data) + 8,
+        QT_UINT32 ((guint8 *) xmp_->data) - 8, NULL);
     taglist = gst_tag_list_from_xmp_buffer (buf);
     gst_buffer_unref (buf);
 
@@ -8778,7 +8798,7 @@ qtdemux_add_container_format (GstQTDemux * qtdemux, GstTagList * tags)
   const gchar *fmt;
 
   if (tags == NULL)
-    tags = gst_tag_list_new ();
+    tags = gst_tag_list_new_empty ();
 
   if (qtdemux->major_brand == FOURCC_mjp2)
     fmt = "Motion JPEG 2000";
@@ -8856,7 +8876,7 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
   }
   if (datetime) {
     if (!qtdemux->tag_list)
-      qtdemux->tag_list = gst_tag_list_new ();
+      qtdemux->tag_list = gst_tag_list_new_empty ();
 
     /* Use KEEP as explicit tags should have a higher priority than mvhd tag */
     gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_KEEP, GST_TAG_DATE_TIME,
@@ -8885,7 +8905,7 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
   /* set duration in the segment info */
   gst_qtdemux_get_duration (qtdemux, &duration);
   if (duration) {
-    gst_segment_set_duration (&qtdemux->segment, GST_FORMAT_TIME, duration);
+    qtdemux->segment.duration = duration;
     /* also do not exceed duration; stop is set that way post seek anyway,
      * and segment activation falls back to duration,
      * whereas loop only checks stop, so let's align this here as well */
@@ -9090,11 +9110,11 @@ gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream,
           "systemstream", G_TYPE_BOOLEAN, FALSE, NULL);
       break;
     case 0x6C:                 /* MJPEG */
-      caps = gst_caps_new_simple ("image/jpeg", NULL);
+      caps = gst_caps_new_empty_simple ("image/jpeg");
       codec_name = "Motion-JPEG";
       break;
     case 0x6D:                 /* PNG */
-      caps = gst_caps_new_simple ("image/png", NULL);
+      caps = gst_caps_new_empty_simple ("image/png");
       codec_name = "PNG still images";
       break;
     case 0x6E:                 /* JPEG2000 */
@@ -9103,7 +9123,7 @@ gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream,
       break;
     case 0xA4:                 /* Dirac */
       codec_name = "Dirac";
-      caps = gst_caps_new_simple ("video/x-dirac", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-dirac");
       break;
     case 0xA5:                 /* AC3 */
       codec_name = "AC-3 audio";
@@ -9113,7 +9133,7 @@ gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream,
     case 0xE1:                 /* QCELP */
       /* QCELP, the codec_data is a riff tag (little endian) with
        * more info (http://ftp.3gpp2.org/TSGC/Working/2003/2003-05-SanDiego/TSG-C-2003-05-San%20Diego/WG1/SWG12/C12-20030512-006%20=%20C12-20030217-015_Draft_Baseline%20Text%20of%20FFMS_R2.doc). */
-      caps = gst_caps_new_simple ("audio/qcelp", NULL);
+      caps = gst_caps_new_empty_simple ("audio/qcelp");
       codec_name = "QCELP";
       break;
     default:
@@ -9135,7 +9155,7 @@ gst_qtdemux_handle_esds (GstQTDemux * qtdemux, QtDemuxStream * stream,
     GstBuffer *buffer;
 
     buffer = gst_buffer_new_and_alloc (data_len);
-    memcpy (GST_BUFFER_DATA (buffer), data_ptr, data_len);
+    _gst_buffer_copy_into_mem (buffer, data_ptr, 0, data_len);
 
     GST_DEBUG_OBJECT (qtdemux, "setting codec_data from esds");
     GST_MEMDUMP_OBJECT (qtdemux, "codec_data from esds", data_ptr, data_len);
@@ -9165,22 +9185,22 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
   switch (fourcc) {
     case GST_MAKE_FOURCC ('p', 'n', 'g', ' '):
       _codec ("PNG still images");
-      caps = gst_caps_new_simple ("image/png", NULL);
+      caps = gst_caps_new_empty_simple ("image/png");
       break;
     case GST_MAKE_FOURCC ('j', 'p', 'e', 'g'):
       _codec ("JPEG still images");
-      caps = gst_caps_new_simple ("image/jpeg", NULL);
+      caps = gst_caps_new_empty_simple ("image/jpeg");
       break;
     case GST_MAKE_FOURCC ('m', 'j', 'p', 'a'):
     case GST_MAKE_FOURCC ('A', 'V', 'D', 'J'):
     case GST_MAKE_FOURCC ('M', 'J', 'P', 'G'):
     case GST_MAKE_FOURCC ('d', 'm', 'b', '1'):
       _codec ("Motion-JPEG");
-      caps = gst_caps_new_simple ("image/jpeg", NULL);
+      caps = gst_caps_new_empty_simple ("image/jpeg");
       break;
     case GST_MAKE_FOURCC ('m', 'j', 'p', 'b'):
       _codec ("Motion-JPEG format B");
-      caps = gst_caps_new_simple ("video/x-mjpeg-b", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-mjpeg-b");
       break;
     case GST_MAKE_FOURCC ('m', 'j', 'p', '2'):
       _codec ("JPEG-2000");
@@ -9206,43 +9226,20 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
       _codec ("Raw RGB video");
       bps = QT_UINT16 (stsd_data + 98);
       /* set common stuff */
-      caps = gst_caps_new_simple ("video/x-raw-rgb",
-          "endianness", G_TYPE_INT, G_BYTE_ORDER, "depth", G_TYPE_INT, bps,
-          NULL);
+      caps = gst_caps_new_empty_simple ("video/x-raw");
 
       switch (bps) {
         case 15:
-          gst_caps_set_simple (caps,
-              "bpp", G_TYPE_INT, 16,
-              "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-              "red_mask", G_TYPE_INT, 0x7c00,
-              "green_mask", G_TYPE_INT, 0x03e0,
-              "blue_mask", G_TYPE_INT, 0x001f, NULL);
+          gst_caps_set_simple (caps, "format", G_TYPE_STRING, "RGB15", NULL);
           break;
         case 16:
-          gst_caps_set_simple (caps,
-              "bpp", G_TYPE_INT, 16,
-              "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-              "red_mask", G_TYPE_INT, 0xf800,
-              "green_mask", G_TYPE_INT, 0x07e0,
-              "blue_mask", G_TYPE_INT, 0x001f, NULL);
+          gst_caps_set_simple (caps, "format", G_TYPE_STRING, "RGB16", NULL);
           break;
         case 24:
-          gst_caps_set_simple (caps,
-              "bpp", G_TYPE_INT, 24,
-              "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-              "red_mask", G_TYPE_INT, 0xff0000,
-              "green_mask", G_TYPE_INT, 0x00ff00,
-              "blue_mask", G_TYPE_INT, 0x0000ff, NULL);
+          gst_caps_set_simple (caps, "format", G_TYPE_STRING, "RGB", NULL);
           break;
         case 32:
-          gst_caps_set_simple (caps,
-              "bpp", G_TYPE_INT, 32,
-              "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-              "alpha_mask", G_TYPE_INT, 0xff000000,
-              "red_mask", G_TYPE_INT, 0x00ff0000,
-              "green_mask", G_TYPE_INT, 0x0000ff00,
-              "blue_mask", G_TYPE_INT, 0x000000ff, NULL);
+          gst_caps_set_simple (caps, "format", G_TYPE_STRING, "ARGB", NULL);
           break;
         default:
           /* unknown */
@@ -9252,39 +9249,30 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
     }
     case GST_MAKE_FOURCC ('y', 'v', '1', '2'):
       _codec ("Raw planar YUV 4:2:0");
-      caps = gst_caps_new_simple ("video/x-raw-yuv",
-          "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
-          NULL);
+      caps = gst_caps_new_simple ("video/x-raw",
+          "format", G_TYPE_STRING, "I420", NULL);
       break;
     case GST_MAKE_FOURCC ('y', 'u', 'v', '2'):
     case GST_MAKE_FOURCC ('Y', 'u', 'v', '2'):
       _codec ("Raw packed YUV 4:2:2");
-      caps = gst_caps_new_simple ("video/x-raw-yuv",
-          "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
-          NULL);
+      caps = gst_caps_new_simple ("video/x-raw",
+          "format", G_TYPE_STRING, "YUY2", NULL);
       break;
     case GST_MAKE_FOURCC ('2', 'v', 'u', 'y'):
     case GST_MAKE_FOURCC ('2', 'V', 'u', 'y'):
       _codec ("Raw packed YUV 4:2:2");
-      caps = gst_caps_new_simple ("video/x-raw-yuv",
-          "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'),
-          NULL);
+      caps = gst_caps_new_simple ("video/x-raw",
+          "format", G_TYPE_STRING, "UYVY", NULL);
       break;
     case GST_MAKE_FOURCC ('v', '2', '1', '0'):
       _codec ("Raw packed YUV 10-bit 4:2:2");
-      caps = gst_caps_new_simple ("video/x-raw-yuv",
-          "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('v', '2', '1', '0'),
-          NULL);
+      caps = gst_caps_new_simple ("video/x-raw",
+          "format", G_TYPE_STRING, "v210", NULL);
       break;
     case GST_MAKE_FOURCC ('r', '2', '1', '0'):
       _codec ("Raw packed RGB 10-bit 4:4:4");
-      caps = gst_caps_new_simple ("video/x-raw-rgb",
-          "endianness", G_TYPE_INT, G_BIG_ENDIAN, "depth", G_TYPE_INT, 30,
-          "bpp", G_TYPE_INT, 32,
-          "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-          "red_mask", G_TYPE_INT, 0x3ff00000,
-          "green_mask", G_TYPE_INT, 0x000ffc00,
-          "blue_mask", G_TYPE_INT, 0x000003ff, NULL);
+      caps = gst_caps_new_simple ("video/x-raw",
+          "format", G_TYPE_STRING, "r210", NULL);
       break;
     case GST_MAKE_FOURCC ('m', 'p', 'e', 'g'):
     case GST_MAKE_FOURCC ('m', 'p', 'g', '1'):
@@ -9312,7 +9300,7 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
       break;
     case GST_MAKE_FOURCC ('g', 'i', 'f', ' '):
       _codec ("GIF still images");
-      caps = gst_caps_new_simple ("image/gif", NULL);
+      caps = gst_caps_new_empty_simple ("image/gif");
       break;
     case GST_MAKE_FOURCC ('h', '2', '6', '3'):
     case GST_MAKE_FOURCC ('H', '2', '6', '3'):
@@ -9320,7 +9308,7 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
     case GST_MAKE_FOURCC ('U', '2', '6', '3'):
       _codec ("H.263");
       /* ffmpeg uses the height/width props, don't know why */
-      caps = gst_caps_new_simple ("video/x-h263", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-h263");
       break;
     case GST_MAKE_FOURCC ('m', 'p', '4', 'v'):
     case GST_MAKE_FOURCC ('M', 'P', '4', 'V'):
@@ -9337,7 +9325,7 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
     case GST_MAKE_FOURCC ('3', 'I', 'V', '1'):
     case GST_MAKE_FOURCC ('3', 'I', 'V', '2'):
       _codec ("3ivX video");
-      caps = gst_caps_new_simple ("video/x-3ivx", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-3ivx");
       break;
     case GST_MAKE_FOURCC ('D', 'I', 'V', '3'):
       _codec ("DivX 3");
@@ -9358,7 +9346,7 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
     case GST_MAKE_FOURCC ('X', 'V', 'I', 'D'):
     case GST_MAKE_FOURCC ('x', 'v', 'i', 'd'):
       _codec ("XVID MPEG-4");
-      caps = gst_caps_new_simple ("video/x-xvid", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-xvid");
       break;
 
     case GST_MAKE_FOURCC ('F', 'M', 'P', '4'):
@@ -9371,15 +9359,15 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
 
     case GST_MAKE_FOURCC ('c', 'v', 'i', 'd'):
       _codec ("Cinepak");
-      caps = gst_caps_new_simple ("video/x-cinepak", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-cinepak");
       break;
     case GST_MAKE_FOURCC ('q', 'd', 'r', 'w'):
       _codec ("Apple QuickDraw");
-      caps = gst_caps_new_simple ("video/x-qdrw", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-qdrw");
       break;
     case GST_MAKE_FOURCC ('r', 'p', 'z', 'a'):
       _codec ("Apple video");
-      caps = gst_caps_new_simple ("video/x-apple-video", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-apple-video");
       break;
     case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):
       _codec ("H.264 / AVC");
@@ -9430,26 +9418,26 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
       break;
     case GST_MAKE_FOURCC ('s', 'm', 'c', ' '):
       _codec ("Apple Graphics (SMC)");
-      caps = gst_caps_new_simple ("video/x-smc", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-smc");
       break;
     case GST_MAKE_FOURCC ('V', 'P', '3', '1'):
       _codec ("VP3");
-      caps = gst_caps_new_simple ("video/x-vp3", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-vp3");
       break;
     case GST_MAKE_FOURCC ('X', 'i', 'T', 'h'):
       _codec ("Theora");
-      caps = gst_caps_new_simple ("video/x-theora", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-theora");
       /* theora uses one byte of padding in the data stream because it does not
        * allow 0 sized packets while theora does */
       stream->padding = 1;
       break;
     case GST_MAKE_FOURCC ('d', 'r', 'a', 'c'):
       _codec ("Dirac");
-      caps = gst_caps_new_simple ("video/x-dirac", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-dirac");
       break;
     case GST_MAKE_FOURCC ('t', 'i', 'f', 'f'):
       _codec ("TIFF still images");
-      caps = gst_caps_new_simple ("image/tiff", NULL);
+      caps = gst_caps_new_empty_simple ("image/tiff");
       break;
     case GST_MAKE_FOURCC ('i', 'c', 'o', 'd'):
       _codec ("Apple Intermediate Codec");
@@ -9466,9 +9454,7 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
     case FOURCC_ovc1:
       _codec ("VC-1");
       caps = gst_caps_new_simple ("video/x-wmv",
-          "wmvversion", G_TYPE_INT, 3,
-          "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'),
-          NULL);
+          "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL);
       break;
     case GST_MAKE_FOURCC ('k', 'p', 'c', 'd'):
     default:
@@ -9477,7 +9463,7 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
 
       s = g_strdup_printf ("video/x-gst-fourcc-%" GST_FOURCC_FORMAT,
           GST_FOURCC_ARGS (fourcc));
-      caps = gst_caps_new_simple (s, NULL);
+      caps = gst_caps_new_empty_simple (s);
       break;
     }
   }
@@ -9485,7 +9471,7 @@ qtdemux_video_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
   /* enable clipping for raw video streams */
   s = gst_caps_get_structure (caps, 0);
   name = gst_structure_get_name (s);
-  if (g_str_has_prefix (name, "video/x-raw-")) {
+  if (g_str_has_prefix (name, "video/x-raw")) {
     stream->need_clip = TRUE;
   }
   return caps;
@@ -9506,8 +9492,8 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
     case GST_MAKE_FOURCC ('N', 'O', 'N', 'E'):
     case GST_MAKE_FOURCC ('r', 'a', 'w', ' '):
       _codec ("Raw 8-bit PCM audio");
-      caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 8,
-          "depth", G_TYPE_INT, 8, "signed", G_TYPE_BOOLEAN, FALSE, NULL);
+      caps = gst_caps_new_simple ("audio/x-raw",
+          "format", G_TYPE_STRING, "U8", NULL);
       break;
     case GST_MAKE_FOURCC ('t', 'w', 'o', 's'):
       endian = G_BIG_ENDIAN;
@@ -9516,53 +9502,51 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
     {
       gchar *str;
       gint depth;
+      GstAudioFormat format;
 
       if (!endian)
         endian = G_LITTLE_ENDIAN;
 
       depth = stream->bytes_per_packet * 8;
+      format = gst_audio_format_build_integer (TRUE, endian, depth, depth);
+
       str = g_strdup_printf ("Raw %d-bit PCM audio", depth);
       _codec (str);
       g_free (str);
-      caps = gst_caps_new_simple ("audio/x-raw-int",
-          "width", G_TYPE_INT, depth, "depth", G_TYPE_INT, depth,
-          "endianness", G_TYPE_INT, endian,
-          "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+
+      caps = gst_caps_new_simple ("audio/x-raw",
+          "format", G_TYPE_STRING, gst_audio_format_to_string (format), NULL);
       break;
     }
     case GST_MAKE_FOURCC ('f', 'l', '6', '4'):
       _codec ("Raw 64-bit floating-point audio");
-      caps = gst_caps_new_simple ("audio/x-raw-float", "width", G_TYPE_INT, 64,
-          "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
+      caps = gst_caps_new_simple ("audio/x-raw",
+          "format", G_TYPE_STRING, "F64BE", NULL);
       break;
     case GST_MAKE_FOURCC ('f', 'l', '3', '2'):
       _codec ("Raw 32-bit floating-point audio");
-      caps = gst_caps_new_simple ("audio/x-raw-float", "width", G_TYPE_INT, 32,
-          "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
+      caps = gst_caps_new_simple ("audio/x-raw",
+          "format", G_TYPE_STRING, "F32BE", NULL);
       break;
     case FOURCC_in24:
       _codec ("Raw 24-bit PCM audio");
       /* we assume BIG ENDIAN, an enda box will tell us to change this to little
        * endian later */
-      caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 24,
-          "depth", G_TYPE_INT, 24,
-          "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-          "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+      caps = gst_caps_new_simple ("audio/x-raw",
+          "format", G_TYPE_STRING, "S24BE", NULL);
       break;
     case GST_MAKE_FOURCC ('i', 'n', '3', '2'):
       _codec ("Raw 32-bit PCM audio");
-      caps = gst_caps_new_simple ("audio/x-raw-int", "width", G_TYPE_INT, 32,
-          "depth", G_TYPE_INT, 32,
-          "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-          "signed", G_TYPE_BOOLEAN, TRUE, NULL);
+      caps = gst_caps_new_simple ("audio/x-raw",
+          "format", G_TYPE_STRING, "S32BE", NULL);
       break;
     case GST_MAKE_FOURCC ('u', 'l', 'a', 'w'):
       _codec ("Mu-law audio");
-      caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
+      caps = gst_caps_new_empty_simple ("audio/x-mulaw");
       break;
     case GST_MAKE_FOURCC ('a', 'l', 'a', 'w'):
       _codec ("A-law audio");
-      caps = gst_caps_new_simple ("audio/x-alaw", NULL);
+      caps = gst_caps_new_empty_simple ("audio/x-alaw");
       break;
     case 0x0200736d:
     case 0x6d730002:
@@ -9618,11 +9602,11 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
       break;
     case GST_MAKE_FOURCC ('O', 'g', 'g', 'V'):
       /* ogg/vorbis */
-      caps = gst_caps_new_simple ("application/ogg", NULL);
+      caps = gst_caps_new_empty_simple ("application/ogg");
       break;
     case GST_MAKE_FOURCC ('d', 'v', 'c', 'a'):
       _codec ("DV audio");
-      caps = gst_caps_new_simple ("audio/x-dv", NULL);
+      caps = gst_caps_new_empty_simple ("audio/x-dv");
       break;
     case GST_MAKE_FOURCC ('m', 'p', '4', 'a'):
       _codec ("MPEG-4 AAC audio");
@@ -9632,7 +9616,7 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
       break;
     case GST_MAKE_FOURCC ('Q', 'D', 'M', 'C'):
       _codec ("QDesign Music");
-      caps = gst_caps_new_simple ("audio/x-qdm", NULL);
+      caps = gst_caps_new_empty_simple ("audio/x-qdm");
       break;
     case GST_MAKE_FOURCC ('Q', 'D', 'M', '2'):
       _codec ("QDesign Music v.2");
@@ -9643,20 +9627,20 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
             "bitrate", G_TYPE_INT, QT_UINT32 (data + 40),
             "blocksize", G_TYPE_INT, QT_UINT32 (data + 44), NULL);
       } else {
-        caps = gst_caps_new_simple ("audio/x-qdm2", NULL);
+        caps = gst_caps_new_empty_simple ("audio/x-qdm2");
       }
       break;
     case GST_MAKE_FOURCC ('a', 'g', 's', 'm'):
       _codec ("GSM audio");
-      caps = gst_caps_new_simple ("audio/x-gsm", NULL);
+      caps = gst_caps_new_empty_simple ("audio/x-gsm");
       break;
     case GST_MAKE_FOURCC ('s', 'a', 'm', 'r'):
       _codec ("AMR audio");
-      caps = gst_caps_new_simple ("audio/AMR", NULL);
+      caps = gst_caps_new_empty_simple ("audio/AMR");
       break;
     case GST_MAKE_FOURCC ('s', 'a', 'w', 'b'):
       _codec ("AMR-WB audio");
-      caps = gst_caps_new_simple ("audio/AMR-WB", NULL);
+      caps = gst_caps_new_empty_simple ("audio/AMR-WB");
       break;
     case GST_MAKE_FOURCC ('i', 'm', 'a', '4'):
       _codec ("Quicktime IMA ADPCM");
@@ -9665,7 +9649,7 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
       break;
     case GST_MAKE_FOURCC ('a', 'l', 'a', 'c'):
       _codec ("Apple lossless audio");
-      caps = gst_caps_new_simple ("audio/x-alac", NULL);
+      caps = gst_caps_new_empty_simple ("audio/x-alac");
       break;
     case GST_MAKE_FOURCC ('Q', 'c', 'l', 'p'):
       _codec ("QualComm PureVoice");
@@ -9673,7 +9657,7 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
       break;
     case FOURCC_owma:
       _codec ("WMA");
-      caps = gst_caps_new_simple ("audio/x-wma", NULL);
+      caps = gst_caps_new_empty_simple ("audio/x-wma");
       break;
     case GST_MAKE_FOURCC ('q', 't', 'v', 'r'):
       /* ? */
@@ -9683,15 +9667,24 @@ qtdemux_audio_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
 
       s = g_strdup_printf ("audio/x-gst-fourcc-%" GST_FOURCC_FORMAT,
           GST_FOURCC_ARGS (fourcc));
-      caps = gst_caps_new_simple (s, NULL);
+      caps = gst_caps_new_empty_simple (s);
       break;
     }
   }
 
+  if (caps) {
+    GstCaps *templ_caps =
+        gst_static_pad_template_get_caps (&gst_qtdemux_audiosrc_template);
+    GstCaps *intersection = gst_caps_intersect (caps, templ_caps);
+    gst_caps_unref (caps);
+    gst_caps_unref (templ_caps);
+    caps = intersection;
+  }
+
   /* enable clipping for raw audio streams */
   s = gst_caps_get_structure (caps, 0);
   name = gst_structure_get_name (s);
-  if (g_str_has_prefix (name, "audio/x-raw-")) {
+  if (g_str_has_prefix (name, "audio/x-raw")) {
     stream->need_clip = TRUE;
   }
   return caps;
@@ -9708,7 +9701,7 @@ qtdemux_sub_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
   switch (fourcc) {
     case GST_MAKE_FOURCC ('m', 'p', '4', 's'):
       _codec ("DVD subtitle");
-      caps = gst_caps_new_simple ("video/x-dvd-subpicture", NULL);
+      caps = gst_caps_new_empty_simple ("video/x-dvd-subpicture");
       break;
     case GST_MAKE_FOURCC ('t', 'e', 'x', 't'):
       _codec ("Quicktime timed text");
@@ -9716,7 +9709,7 @@ qtdemux_sub_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
     case GST_MAKE_FOURCC ('t', 'x', '3', 'g'):
       _codec ("3GPP timed text");
     text:
-      caps = gst_caps_new_simple ("text/plain", NULL);
+      caps = gst_caps_new_empty_simple ("text/plain");
       /* actual text piece needs to be extracted */
       stream->need_process = TRUE;
       break;
@@ -9726,7 +9719,7 @@ qtdemux_sub_caps (GstQTDemux * qtdemux, QtDemuxStream * stream,
 
       s = g_strdup_printf ("text/x-gst-fourcc-%" GST_FOURCC_FORMAT,
           GST_FOURCC_ARGS (fourcc));
-      caps = gst_caps_new_simple (s, NULL);
+      caps = gst_caps_new_empty_simple (s);
       break;
     }
   }