Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / matroska / matroska-mux.c
index e6fb059..5fe25f9 100644 (file)
@@ -50,6 +50,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <gst/audio/audio.h>
 #include <gst/riff/riff-media.h>
 #include <gst/tag/tag.h>
 
@@ -96,7 +97,7 @@ static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
  */
 
 static GstStaticPadTemplate videosink_templ =
-    GST_STATIC_PAD_TEMPLATE ("video_%d",
+    GST_STATIC_PAD_TEMPLATE ("video_%u",
     GST_PAD_SINK,
     GST_PAD_REQUEST,
     GST_STATIC_CAPS ("video/mpeg, "
@@ -127,8 +128,8 @@ static GstStaticPadTemplate videosink_templ =
         COMMON_VIDEO_CAPS "; "
         "video/x-vp8, "
         COMMON_VIDEO_CAPS "; "
-        "video/x-raw-yuv, "
-        "format = (fourcc) { YUY2, I420, YV12, UYVY, AYUV }, "
+        "video/x-raw, "
+        "format = (string) { YUY2, I420, YV12, UYVY, AYUV }, "
         COMMON_VIDEO_CAPS "; "
         "video/x-wmv, " "wmvversion = (int) [ 1, 3 ], " COMMON_VIDEO_CAPS)
     );
@@ -141,7 +142,7 @@ static GstStaticPadTemplate videosink_templ =
  * * require codec data, etc as needed
  */
 static GstStaticPadTemplate audiosink_templ =
-    GST_STATIC_PAD_TEMPLATE ("audio_%d",
+    GST_STATIC_PAD_TEMPLATE ("audio_%u",
     GST_PAD_SINK,
     GST_PAD_REQUEST,
     GST_STATIC_CAPS ("audio/mpeg, "
@@ -164,32 +165,9 @@ static GstStaticPadTemplate audiosink_templ =
         COMMON_AUDIO_CAPS "; "
         "audio/x-speex, "
         COMMON_AUDIO_CAPS "; "
-        "audio/x-raw-int, "
-        "width = (int) 8, "
-        "depth = (int) 8, "
-        "signed = (boolean) false, "
-        COMMON_AUDIO_CAPS ";"
-        "audio/x-raw-int, "
-        "width = (int) 16, "
-        "depth = (int) 16, "
-        "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, "
-        "signed = (boolean) true, "
-        COMMON_AUDIO_CAPS ";"
-        "audio/x-raw-int, "
-        "width = (int) 24, "
-        "depth = (int) 24, "
-        "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, "
-        "signed = (boolean) true, "
-        COMMON_AUDIO_CAPS ";"
-        "audio/x-raw-int, "
-        "width = (int) 32, "
-        "depth = (int) 32, "
-        "endianness = (int) { BIG_ENDIAN, LITTLE_ENDIAN }, "
-        "signed = (boolean) true, "
-        COMMON_AUDIO_CAPS ";"
-        "audio/x-raw-float, "
-        "width = (int) [ 32, 64 ], "
-        "endianness = (int) LITTLE_ENDIAN, "
+        "audio/x-raw, "
+        "format = (string) { U8, S16BE, S16LE, S24BE, S24LE, S32BE, S32LE, F32LE, F64LE }, "
+        "layout = (string) interleaved, "
         COMMON_AUDIO_CAPS ";"
         "audio/x-tta, "
         "width = (int) { 8, 16, 24 }, "
@@ -218,10 +196,9 @@ static GstStaticPadTemplate subtitlesink_templ =
 static GArray *used_uids;
 G_LOCK_DEFINE_STATIC (used_uids);
 
-static void gst_matroska_mux_add_interfaces (GType type);
-
-GST_BOILERPLATE_FULL (GstMatroskaMux, gst_matroska_mux, GstElement,
-    GST_TYPE_ELEMENT, gst_matroska_mux_add_interfaces);
+#define parent_class gst_matroska_mux_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstMatroskaMux, gst_matroska_mux, GST_TYPE_ELEMENT,
+    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
 
 /* Matroska muxer destructor */
 static void gst_matroska_mux_finalize (GObject * object);
@@ -234,9 +211,9 @@ static gboolean gst_matroska_mux_handle_sink_event (GstCollectPads2 * pads,
 
 /* pad functions */
 static gboolean gst_matroska_mux_handle_src_event (GstPad * pad,
-    GstEvent * event);
+    GstObject * parent, GstEvent * event);
 static GstPad *gst_matroska_mux_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name);
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void gst_matroska_mux_release_pad (GstElement * element, GstPad * pad);
 
 /* gst internal change state handler */
@@ -270,19 +247,6 @@ gst_matroska_mux_write_simple_tag (const GstTagList * list, const gchar * tag,
     gpointer data);
 
 static void
-gst_matroska_mux_add_interfaces (GType type)
-{
-  static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
-
-  g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, &tag_setter_info);
-}
-
-static void
-gst_matroska_mux_base_init (gpointer g_class)
-{
-}
-
-static void
 gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
 {
   GObjectClass *gobject_class;
@@ -291,13 +255,14 @@ gst_matroska_mux_class_init (GstMatroskaMuxClass * klass)
   gobject_class = (GObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
 
-  gst_element_class_add_static_pad_template (gstelement_class,
-      &videosink_templ);
-  gst_element_class_add_static_pad_template (gstelement_class,
-      &audiosink_templ);
-  gst_element_class_add_static_pad_template (gstelement_class,
-      &subtitlesink_templ);
-  gst_element_class_add_static_pad_template (gstelement_class, &src_templ);
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&videosink_templ));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&audiosink_templ));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&subtitlesink_templ));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_templ));
   gst_element_class_set_details_simple (gstelement_class, "Matroska muxer",
       "Codec/Muxer",
       "Muxes video/audio/subtitle streams into a matroska stream",
@@ -446,12 +411,12 @@ gst_matroskamux_pad_init (GstMatroskamuxPad * pad)
  * Matroska muxer constructor.
  */
 static void
-gst_matroska_mux_init (GstMatroskaMux * mux, GstMatroskaMuxClass * g_class)
+gst_matroska_mux_init (GstMatroskaMux * mux)
 {
   GstPadTemplate *templ;
 
   templ =
-      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
+      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mux), "src");
   mux->srcpad = gst_pad_new_from_template (templ, "src");
 
   gst_pad_set_event_function (mux->srcpad, gst_matroska_mux_handle_src_event);
@@ -620,9 +585,9 @@ gst_matroska_pad_reset (GstMatroskaPad * collect_pad, gboolean full)
  * Release resources of a matroska collect pad.
  */
 static void
-gst_matroska_pad_free (GstMatroskaPad * collect_pad)
+gst_matroska_pad_free (GstPad * collect_pad)
 {
-  gst_matroska_pad_reset (collect_pad, TRUE);
+  gst_matroska_pad_reset ((GstMatroskaPad *) collect_pad, TRUE);
 }
 
 
@@ -685,7 +650,8 @@ gst_matroska_mux_reset (GstElement * element)
  * Returns: #TRUE on success.
  */
 static gboolean
-gst_matroska_mux_handle_src_event (GstPad * pad, GstEvent * event)
+gst_matroska_mux_handle_src_event (GstPad * pad, GstObject * parent,
+    GstEvent * event)
 {
   GstEventType type;
 
@@ -699,7 +665,7 @@ gst_matroska_mux_handle_src_event (GstPad * pad, GstEvent * event)
       break;
   }
 
-  return gst_pad_event_default (pad, event);
+  return gst_pad_event_default (pad, parent, event);
 }
 
 static void
@@ -753,11 +719,12 @@ static gboolean
 gst_matroska_mux_handle_sink_event (GstCollectPads2 * pads,
     GstCollectData2 * data, GstEvent * event, gpointer user_data)
 {
-  GstMatroskaTrackContext *context;
   GstMatroskaPad *collect_pad;
+  GstMatroskaTrackContext *context;
   GstMatroskaMux *mux;
   GstPad *pad;
   GstTagList *list;
+  gboolean ret = FALSE;
 
   mux = GST_MATROSKA_MUX (user_data);
   collect_pad = (GstMatroskaPad *) data;
@@ -766,6 +733,17 @@ gst_matroska_mux_handle_sink_event (GstCollectPads2 * pads,
   g_assert (context);
 
   switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CAPS:{
+      GstCaps *caps;
+
+      collect_pad = (GstMatroskaPad *) gst_pad_get_element_private (pad);
+      gst_event_parse_caps (event, &caps);
+
+      ret = collect_pad->capsfunc (pad, caps);
+      gst_event_unref (event);
+      event = NULL;
+      break;
+    }
     case GST_EVENT_TAG:{
       gchar *lang = NULL;
 
@@ -795,12 +773,11 @@ gst_matroska_mux_handle_sink_event (GstCollectPads2 * pads,
       event = NULL;
       break;
     }
-    case GST_EVENT_NEWSEGMENT:{
-      GstFormat format;
+    case GST_EVENT_SEGMENT:{
+      const GstSegment *segment;
 
-      gst_event_parse_new_segment (event, NULL, NULL, &format, NULL, NULL,
-          NULL);
-      if (format != GST_FORMAT_TIME) {
+      gst_event_parse_segment (event, &segment);
+      if (segment->format != GST_FORMAT_TIME) {
         gst_event_unref (event);
         event = NULL;
       }
@@ -847,10 +824,7 @@ gst_matroska_mux_handle_sink_event (GstCollectPads2 * pads,
   }
 
   /* now GstCollectPads2 can take care of the rest, e.g. EOS */
-  if (event)
-    return FALSE;
-  else
-    return TRUE;
+  return ret;
 }
 
 static void
@@ -882,7 +856,7 @@ gst_matroska_mux_video_pad_setcaps (GstPad * pad, GstCaps * caps)
   GstStructure *structure;
   const gchar *mimetype;
   const GValue *value = NULL;
-  const GstBuffer *codec_buf = NULL;
+  GstBuffer *codec_buf = NULL;
   gint width, height, pixel_width, pixel_height;
   gint fps_d, fps_n;
   gboolean interlaced = FALSE;
@@ -966,13 +940,18 @@ skip_details:
   /* extract codec_data, may turn out needed */
   value = gst_structure_get_value (structure, "codec_data");
   if (value)
-    codec_buf = gst_value_get_buffer (value);
+    codec_buf = (GstBuffer *) gst_value_get_buffer (value);
 
   /* find type */
-  if (!strcmp (mimetype, "video/x-raw-yuv")) {
+  if (!strcmp (mimetype, "video/x-raw")) {
+    const gchar *fstr;
     gst_matroska_mux_set_codec_id (context,
         GST_MATROSKA_CODEC_ID_VIDEO_UNCOMPRESSED);
-    gst_structure_get_fourcc (structure, "format", &videocontext->fourcc);
+    fstr = gst_structure_get_string (structure, "format");
+    if (fstr && strlen (fstr) == 4)
+      videocontext->fourcc = GST_STR_FOURCC (fstr);
+  } else if (!strcmp (mimetype, "image/jpeg")) {
+    gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_VIDEO_MJPEG);
   } else if (!strcmp (mimetype, "video/x-xvid") /* MS/VfW compatibility cases */
       ||!strcmp (mimetype, "video/x-huffyuv")
       || !strcmp (mimetype, "video/x-divx")
@@ -1025,9 +1004,11 @@ skip_details:
       }
     } else if (!strcmp (mimetype, "video/x-wmv")) {
       gint wmvversion;
-      guint32 format;
-      if (gst_structure_get_fourcc (structure, "format", &format)) {
-        fourcc = format;
+      const gchar *fstr;
+
+      fstr = gst_structure_get_string (structure, "format");
+      if (fstr && strlen (fstr) == 4) {
+        fourcc = GST_STR_FOURCC (fstr);
       } else if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
         if (wmvversion == 2) {
           fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '2');
@@ -1056,11 +1037,11 @@ skip_details:
 
     /* process codec private/initialization data, if any */
     if (codec_buf) {
-      size += GST_BUFFER_SIZE (codec_buf);
+      size += gst_buffer_get_size (codec_buf);
       bih = g_realloc (bih, size);
       GST_WRITE_UINT32_LE (&bih->size, size);
-      memcpy ((guint8 *) bih + sizeof (gst_riff_strf_vids),
-          GST_BUFFER_DATA (codec_buf), GST_BUFFER_SIZE (codec_buf));
+      gst_buffer_extract (codec_buf, 0,
+          (guint8 *) bih + sizeof (gst_riff_strf_vids), -1);
     }
 
     gst_matroska_mux_set_codec_id (context,
@@ -1079,10 +1060,9 @@ skip_details:
 
     /* Create avcC header */
     if (codec_buf != NULL) {
-      context->codec_priv_size = GST_BUFFER_SIZE (codec_buf);
+      context->codec_priv_size = gst_buffer_get_size (codec_buf);
       context->codec_priv = g_malloc0 (context->codec_priv_size);
-      memcpy (context->codec_priv, GST_BUFFER_DATA (codec_buf),
-          context->codec_priv_size);
+      gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
     }
   } else if (!strcmp (mimetype, "video/x-theora")) {
     const GValue *streamheader;
@@ -1128,10 +1108,9 @@ skip_details:
 
     /* global headers may be in codec data */
     if (codec_buf != NULL) {
-      context->codec_priv_size = GST_BUFFER_SIZE (codec_buf);
+      context->codec_priv_size = gst_buffer_get_size (codec_buf);
       context->codec_priv = g_malloc0 (context->codec_priv_size);
-      memcpy (context->codec_priv, GST_BUFFER_DATA (codec_buf),
-          context->codec_priv_size);
+      gst_buffer_extract (codec_buf, 0, context->codec_priv, -1);
     }
   } else if (!strcmp (mimetype, "video/x-msmpeg")) {
   msmpeg43:
@@ -1170,10 +1149,10 @@ skip_details:
 
       GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);
 
-      priv_data_size = GST_BUFFER_SIZE (codec_data_buf);
+      priv_data_size = gst_buffer_get_size (codec_data_buf);
       priv_data = g_malloc0 (priv_data_size);
 
-      memcpy (priv_data, GST_BUFFER_DATA (codec_data_buf), priv_data_size);
+      gst_buffer_extract (codec_data_buf, 0, priv_data, -1);
 
       context->codec_priv = priv_data;
       context->codec_priv_size = priv_data_size;
@@ -1231,12 +1210,12 @@ xiphN_streamheader_to_codecdata (const GValue * streamheader,
   priv_data_size = 1;
   if (bufarr->len > 0) {
     for (i = 0; i < bufarr->len - 1; i++) {
-      priv_data_size += GST_BUFFER_SIZE (buf[i]) / 0xff + 1;
+      priv_data_size += gst_buffer_get_size (buf[i]) / 0xff + 1;
     }
   }
 
   for (i = 0; i < bufarr->len; ++i) {
-    priv_data_size += GST_BUFFER_SIZE (buf[i]);
+    priv_data_size += gst_buffer_get_size (buf[i]);
   }
 
   priv_data = g_malloc0 (priv_data_size);
@@ -1246,17 +1225,16 @@ xiphN_streamheader_to_codecdata (const GValue * streamheader,
 
   if (bufarr->len > 0) {
     for (bufi = 0; bufi < bufarr->len - 1; bufi++) {
-      for (i = 0; i < GST_BUFFER_SIZE (buf[bufi]) / 0xff; ++i) {
+      for (i = 0; i < gst_buffer_get_size (buf[bufi]) / 0xff; ++i) {
         priv_data[offset++] = 0xff;
       }
-      priv_data[offset++] = GST_BUFFER_SIZE (buf[bufi]) % 0xff;
+      priv_data[offset++] = gst_buffer_get_size (buf[bufi]) % 0xff;
     }
   }
 
   for (i = 0; i < bufarr->len; ++i) {
-    memcpy (priv_data + offset, GST_BUFFER_DATA (buf[i]),
-        GST_BUFFER_SIZE (buf[i]));
-    offset += GST_BUFFER_SIZE (buf[i]);
+    gst_buffer_extract (buf[i], 0, priv_data + offset, -1);
+    offset += gst_buffer_get_size (buf[i]);
   }
 
   context->codec_priv = priv_data;
@@ -1302,17 +1280,19 @@ vorbis_streamheader_to_codecdata (const GValue * streamheader,
   if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, 3))
     return FALSE;
 
-  if (buf0 == NULL || GST_BUFFER_SIZE (buf0) < 1 + 6 + 4) {
+  if (buf0 == NULL || gst_buffer_get_size (buf0) < 1 + 6 + 4) {
     GST_WARNING ("First vorbis header too small, ignoring");
   } else {
-    if (memcmp (GST_BUFFER_DATA (buf0) + 1, "vorbis", 6) == 0) {
+    if (gst_buffer_memcmp (buf0, 1, "vorbis", 6) == 0) {
       GstMatroskaTrackAudioContext *audiocontext;
-      guint8 *hdr;
+      guint8 *data, *hdr;
 
-      hdr = GST_BUFFER_DATA (buf0) + 1 + 6 + 4;
+      data = gst_buffer_map (buf0, NULL, NULL, GST_MAP_READ);
+      hdr = data + 1 + 6 + 4;
       audiocontext = (GstMatroskaTrackAudioContext *) context;
       audiocontext->channels = GST_READ_UINT8 (hdr);
       audiocontext->samplerate = GST_READ_UINT32_LE (hdr + 1);
+      gst_buffer_unmap (buf0, data, -1);
     }
   }
 
@@ -1331,16 +1311,17 @@ theora_streamheader_to_codecdata (const GValue * streamheader,
   if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, 3))
     return FALSE;
 
-  if (buf0 == NULL || GST_BUFFER_SIZE (buf0) < 1 + 6 + 26) {
+  if (buf0 == NULL || gst_buffer_get_size (buf0) < 1 + 6 + 26) {
     GST_WARNING ("First theora header too small, ignoring");
-  } else if (memcmp (GST_BUFFER_DATA (buf0), "\200theora\003\002", 9) != 0) {
+  } else if (gst_buffer_memcmp (buf0, 0, "\200theora\003\002", 9) != 0) {
     GST_WARNING ("First header not a theora identification header, ignoring");
   } else {
     GstMatroskaTrackVideoContext *videocontext;
     guint fps_num, fps_denom, par_num, par_denom;
-    guint8 *hdr;
+    guint8 *data, *hdr;
 
-    hdr = GST_BUFFER_DATA (buf0) + 1 + 6 + 3 + 2 + 2;
+    data = gst_buffer_map (buf0, NULL, NULL, GST_MAP_READ);
+    hdr = data + 1 + 6 + 3 + 2 + 2;
 
     videocontext = (GstMatroskaTrackVideoContext *) context;
     videocontext->pixel_width = GST_READ_UINT32_BE (hdr) >> 8;
@@ -1371,6 +1352,8 @@ theora_streamheader_to_codecdata (const GValue * streamheader,
       videocontext->display_height = 0;
     }
     hdr += 3 + 3;
+
+    gst_buffer_unmap (buf0, data, -1);
   }
 
   if (buf0)
@@ -1388,9 +1371,9 @@ kate_streamheader_to_codecdata (const GValue * streamheader,
   if (!xiphN_streamheader_to_codecdata (streamheader, context, &buf0, -1))
     return FALSE;
 
-  if (buf0 == NULL || GST_BUFFER_SIZE (buf0) < 64) {    /* Kate ID header is 64 bytes */
+  if (buf0 == NULL || gst_buffer_get_size (buf0) < 64) {        /* Kate ID header is 64 bytes */
     GST_WARNING ("First kate header too small, ignoring");
-  } else if (memcmp (GST_BUFFER_DATA (buf0), "\200kate\0\0\0", 8) != 0) {
+  } else if (gst_buffer_memcmp (buf0, 0, "\200kate\0\0\0", 8) != 0) {
     GST_WARNING ("First header not a kate identification header, ignoring");
   }
 
@@ -1431,19 +1414,19 @@ flac_streamheader_to_codecdata (const GValue * streamheader,
   buffer = g_value_peek_pointer (bufval);
 
   /* Need at least OggFLAC mapping header, fLaC marker and STREAMINFO block */
-  if (GST_BUFFER_SIZE (buffer) < 9 + 4 + 4 + 34
-      || memcmp (GST_BUFFER_DATA (buffer) + 1, "FLAC", 4) != 0
-      || memcmp (GST_BUFFER_DATA (buffer) + 9, "fLaC", 4) != 0) {
+  if (gst_buffer_get_size (buffer) < 9 + 4 + 4 + 34
+      || gst_buffer_memcmp (buffer, 1, "FLAC", 4) != 0
+      || gst_buffer_memcmp (buffer, 9, "fLaC", 4) != 0) {
     GST_WARNING ("Invalid streamheader for FLAC");
     return FALSE;
   }
 
-  context->codec_priv = g_malloc (GST_BUFFER_SIZE (buffer) - 9);
-  context->codec_priv_size = GST_BUFFER_SIZE (buffer) - 9;
-  memcpy (context->codec_priv, GST_BUFFER_DATA (buffer) + 9,
-      GST_BUFFER_SIZE (buffer) - 9);
+  context->codec_priv_size = gst_buffer_get_size (buffer) - 9;
+  context->codec_priv = g_malloc (context->codec_priv_size);
+  gst_buffer_extract (buffer, 9, context->codec_priv, -1);
 
   for (i = 1; i < bufarr->len; i++) {
+    guint old_size;
     bufval = &g_array_index (bufarr, GValue, i);
 
     if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
@@ -1456,13 +1439,13 @@ flac_streamheader_to_codecdata (const GValue * streamheader,
 
     buffer = g_value_peek_pointer (bufval);
 
-    context->codec_priv =
-        g_realloc (context->codec_priv,
-        context->codec_priv_size + GST_BUFFER_SIZE (buffer));
-    memcpy ((guint8 *) context->codec_priv + context->codec_priv_size,
-        GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
-    context->codec_priv_size =
-        context->codec_priv_size + GST_BUFFER_SIZE (buffer);
+    old_size = context->codec_priv_size;
+    context->codec_priv_size += gst_buffer_get_size (buffer);
+
+    context->codec_priv = g_realloc (context->codec_priv,
+        context->codec_priv_size);
+    gst_buffer_extract (buffer, 0,
+        (guint8 *) context->codec_priv + old_size, -1);
   }
 
   return TRUE;
@@ -1475,6 +1458,7 @@ speex_streamheader_to_codecdata (const GValue * streamheader,
   GArray *bufarr;
   GValue *bufval;
   GstBuffer *buffer;
+  guint old_size;
 
   if (streamheader == NULL || G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY) {
     GST_WARNING ("No or invalid streamheader field in the caps");
@@ -1497,16 +1481,15 @@ speex_streamheader_to_codecdata (const GValue * streamheader,
 
   buffer = g_value_peek_pointer (bufval);
 
-  if (GST_BUFFER_SIZE (buffer) < 80
-      || memcmp (GST_BUFFER_DATA (buffer), "Speex   ", 8) != 0) {
+  if (gst_buffer_get_size (buffer) < 80
+      || gst_buffer_memcmp (buffer, 0, "Speex   ", 8) != 0) {
     GST_WARNING ("Invalid streamheader for Speex");
     return FALSE;
   }
 
-  context->codec_priv = g_malloc (GST_BUFFER_SIZE (buffer));
-  context->codec_priv_size = GST_BUFFER_SIZE (buffer);
-  memcpy (context->codec_priv, GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
+  context->codec_priv_size = gst_buffer_get_size (buffer);
+  context->codec_priv = g_malloc (context->codec_priv_size);
+  gst_buffer_extract (buffer, 0, context->codec_priv, -1);
 
   bufval = &g_array_index (bufarr, GValue, 1);
 
@@ -1520,28 +1503,26 @@ speex_streamheader_to_codecdata (const GValue * streamheader,
 
   buffer = g_value_peek_pointer (bufval);
 
-  context->codec_priv =
-      g_realloc (context->codec_priv,
-      context->codec_priv_size + GST_BUFFER_SIZE (buffer));
-  memcpy ((guint8 *) context->codec_priv + context->codec_priv_size,
-      GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
-  context->codec_priv_size =
-      context->codec_priv_size + GST_BUFFER_SIZE (buffer);
+  old_size = context->codec_priv_size;
+  context->codec_priv_size += gst_buffer_get_size (buffer);
+  context->codec_priv = g_realloc (context->codec_priv,
+      context->codec_priv_size);
+  gst_buffer_extract (buffer, 0, (guint8 *) context->codec_priv + old_size, -1);
 
   return TRUE;
 }
 
 static const gchar *
-aac_codec_data_to_codec_id (const GstBuffer * buf)
+aac_codec_data_to_codec_id (GstBuffer * buf)
 {
   const gchar *result;
-  gint profile;
+  guint8 profile;
 
   /* default to MAIN */
   profile = 1;
 
-  if (GST_BUFFER_SIZE (buf) >= 2) {
-    profile = GST_READ_UINT8 (GST_BUFFER_DATA (buf));
+  if (gst_buffer_get_size (buf) >= 2) {
+    gst_buffer_extract (buf, 0, &profile, 1);
     profile >>= 3;
   }
 
@@ -1587,7 +1568,7 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
   gint samplerate = 0, channels = 0;
   GstStructure *structure;
   const GValue *codec_data = NULL;
-  const GstBuffer *buf = NULL;
+  GstBuffer *buf = NULL;
   const gchar *stream_format = NULL;
 
   mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));
@@ -1702,55 +1683,47 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
       default:
         goto refuse_caps;
     }
-  } else if (!strcmp (mimetype, "audio/x-raw-int")) {
-    gint width, depth;
-    gint endianness = G_LITTLE_ENDIAN;
-    gboolean signedness = TRUE;
-
-    if (!gst_structure_get_int (structure, "width", &width) ||
-        !gst_structure_get_int (structure, "depth", &depth) ||
-        !gst_structure_get_boolean (structure, "signed", &signedness)) {
-      GST_DEBUG_OBJECT (mux, "broken caps, width/depth/signed field missing");
-      goto refuse_caps;
-    }
-
-    if (depth > 8 &&
-        !gst_structure_get_int (structure, "endianness", &endianness)) {
-      GST_DEBUG_OBJECT (mux, "broken caps, no endianness specified");
-      goto refuse_caps;
-    }
+  } else if (!strcmp (mimetype, "audio/x-raw")) {
+    GstAudioInfo info;
 
-    if (width != depth) {
-      GST_DEBUG_OBJECT (mux, "width must be same as depth!");
+    gst_audio_info_init (&info);
+    if (!gst_audio_info_from_caps (&info, caps)) {
+      GST_DEBUG_OBJECT (mux,
+          "broken caps, rejected by gst_audio_info_from_caps");
       goto refuse_caps;
     }
 
-    /* FIXME: where is this spec'ed out? (tpm) */
-    if ((width == 8 && signedness) || (width >= 16 && !signedness)) {
-      GST_DEBUG_OBJECT (mux, "8-bit PCM must be unsigned, 16-bit PCM signed");
-      goto refuse_caps;
-    }
-
-    audiocontext->bitdepth = depth;
-    if (endianness == G_BIG_ENDIAN)
-      gst_matroska_mux_set_codec_id (context,
-          GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE);
-    else
-      gst_matroska_mux_set_codec_id (context,
-          GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE);
-
-  } else if (!strcmp (mimetype, "audio/x-raw-float")) {
-    gint width;
+    switch (GST_AUDIO_INFO_FORMAT (&info)) {
+      case GST_AUDIO_FORMAT_U8:
+      case GST_AUDIO_FORMAT_S16BE:
+      case GST_AUDIO_FORMAT_S16LE:
+      case GST_AUDIO_FORMAT_S24BE:
+      case GST_AUDIO_FORMAT_S24LE:
+      case GST_AUDIO_FORMAT_S32BE:
+      case GST_AUDIO_FORMAT_S32LE:
+        if (GST_AUDIO_INFO_WIDTH (&info) != GST_AUDIO_INFO_DEPTH (&info)) {
+          GST_DEBUG_OBJECT (mux, "width must be same as depth!");
+          goto refuse_caps;
+        }
+        if (GST_AUDIO_INFO_IS_BIG_ENDIAN (&info))
+          gst_matroska_mux_set_codec_id (context,
+              GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_BE);
+        else
+          gst_matroska_mux_set_codec_id (context,
+              GST_MATROSKA_CODEC_ID_AUDIO_PCM_INT_LE);
+        break;
+      case GST_AUDIO_FORMAT_F32LE:
+      case GST_AUDIO_FORMAT_F64LE:
+        gst_matroska_mux_set_codec_id (context,
+            GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT);
+        break;
 
-    if (!gst_structure_get_int (structure, "width", &width)) {
-      GST_DEBUG_OBJECT (mux, "broken caps, width field missing");
-      goto refuse_caps;
+      default:
+        GST_DEBUG_OBJECT (mux, "wrong format in raw audio caps");
+        goto refuse_caps;
     }
 
-    audiocontext->bitdepth = width;
-    gst_matroska_mux_set_codec_id (context,
-        GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT);
-
+    audiocontext->bitdepth = GST_AUDIO_INFO_WIDTH (&info);
   } else if (!strcmp (mimetype, "audio/x-vorbis")) {
     const GValue *streamheader;
 
@@ -1845,10 +1818,10 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
 
       GstBuffer *codec_data_buf = g_value_peek_pointer (mdpr_data);
 
-      priv_data_size = GST_BUFFER_SIZE (codec_data_buf);
+      priv_data_size = gst_buffer_get_size (codec_data_buf);
       priv_data = g_malloc0 (priv_data_size);
 
-      memcpy (priv_data, GST_BUFFER_DATA (codec_data_buf), priv_data_size);
+      gst_buffer_extract (codec_data_buf, 0, priv_data, -1);
 
       context->codec_priv = priv_data;
       context->codec_priv_size = priv_data_size;
@@ -1912,7 +1885,7 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
 
     codec_priv_size = WAVEFORMATEX_SIZE;
     if (buf)
-      codec_priv_size += GST_BUFFER_SIZE (buf);
+      codec_priv_size += gst_buffer_get_size (buf);
 
     /* serialize waveformatex structure */
     codec_priv = g_malloc0 (codec_priv_size);
@@ -1923,14 +1896,14 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
     GST_WRITE_UINT16_LE (codec_priv + 12, block_align);
     GST_WRITE_UINT16_LE (codec_priv + 14, 0);
     if (buf)
-      GST_WRITE_UINT16_LE (codec_priv + 16, GST_BUFFER_SIZE (buf));
+      GST_WRITE_UINT16_LE (codec_priv + 16, gst_buffer_get_size (buf));
     else
       GST_WRITE_UINT16_LE (codec_priv + 16, 0);
 
     /* process codec private/initialization data, if any */
     if (buf) {
-      memcpy ((guint8 *) codec_priv + WAVEFORMATEX_SIZE,
-          GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+      gst_buffer_extract (buf, 0,
+          (guint8 *) codec_priv + WAVEFORMATEX_SIZE, -1);
     }
 
     gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_ACM);
@@ -1977,7 +1950,7 @@ gst_matroska_mux_subtitle_pad_setcaps (GstPad * pad, GstCaps * caps)
   const gchar *mimetype;
   GstStructure *structure;
   const GValue *value = NULL;
-  const GstBuffer *buf = NULL;
+  GstBuffer *buf = NULL;
   gchar *id = NULL;
   gboolean ret = TRUE;
 
@@ -2044,14 +2017,16 @@ gst_matroska_mux_subtitle_pad_setcaps (GstPad * pad, GstCaps * caps)
   if (value)
     buf = gst_value_get_buffer (value);
   if (buf != NULL) {
-    guint8 *priv_data = NULL;
-    guint priv_data_size = 0;
+    guint8 *priv_data = NULL, *priv_buffer_data;
+    gsize priv_data_size = 0;
 
-    priv_data_size = GST_BUFFER_SIZE (buf);
+    priv_buffer_data =
+        gst_buffer_map (buf, &priv_data_size, NULL, GST_MAP_READ);
     if (priv_data_size > SUBTITLE_MAX_CODEC_PRIVATE) {
       GST_WARNING_OBJECT (mux, "pad %" GST_PTR_FORMAT " subtitle private data"
           " exceeded maximum (%d); discarding", pad,
           SUBTITLE_MAX_CODEC_PRIVATE);
+      gst_buffer_unmap (buf, priv_data, priv_data_size);
       return TRUE;
     }
 
@@ -2059,9 +2034,10 @@ gst_matroska_mux_subtitle_pad_setcaps (GstPad * pad, GstCaps * caps)
       g_free (context->codec_priv);
 
     priv_data = g_malloc0 (priv_data_size);
-    memcpy (priv_data, GST_BUFFER_DATA (buf), priv_data_size);
+    memcpy (priv_data, priv_buffer_data, priv_data_size);
     context->codec_priv = priv_data;
     context->codec_priv_size = priv_data_size;
+    gst_buffer_unmap (buf, priv_buffer_data, priv_data_size);
   }
 
   GST_DEBUG_OBJECT (pad, "codec_id %s, codec data size %u",
@@ -2088,7 +2064,7 @@ exit:
  */
 static GstPad *
 gst_matroska_mux_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * req_name)
+    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
 {
   GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
   GstMatroskaMux *mux = GST_MATROSKA_MUX (element);
@@ -2096,50 +2072,50 @@ gst_matroska_mux_request_new_pad (GstElement * element,
   GstMatroskamuxPad *newpad;
   gchar *name = NULL;
   const gchar *pad_name = NULL;
-  GstPadSetCapsFunction setcapsfunc = NULL;
+  GstMatroskaCapsFunc capsfunc = NULL;
   GstMatroskaTrackContext *context = NULL;
   gint pad_id;
   gboolean locked = TRUE;
   gchar *id = NULL;
 
-  if (templ == gst_element_class_get_pad_template (klass, "audio_%d")) {
+  if (templ == gst_element_class_get_pad_template (klass, "audio_%u")) {
     /* don't mix named and unnamed pads, if the pad already exists we fail when
      * trying to add it */
-    if (req_name != NULL && sscanf (req_name, "audio_%d", &pad_id) == 1) {
+    if (req_name != NULL && sscanf (req_name, "audio_%u", &pad_id) == 1) {
       pad_name = req_name;
     } else {
-      name = g_strdup_printf ("audio_%d", mux->num_a_streams++);
+      name = g_strdup_printf ("audio_%u", mux->num_a_streams++);
       pad_name = name;
     }
-    setcapsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_audio_pad_setcaps);
+    capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_audio_pad_setcaps);
     context = (GstMatroskaTrackContext *)
         g_new0 (GstMatroskaTrackAudioContext, 1);
     context->type = GST_MATROSKA_TRACK_TYPE_AUDIO;
     context->name = g_strdup ("Audio");
-  } else if (templ == gst_element_class_get_pad_template (klass, "video_%d")) {
+  } else if (templ == gst_element_class_get_pad_template (klass, "video_%u")) {
     /* don't mix named and unnamed pads, if the pad already exists we fail when
      * trying to add it */
-    if (req_name != NULL && sscanf (req_name, "video_%d", &pad_id) == 1) {
+    if (req_name != NULL && sscanf (req_name, "video_%u", &pad_id) == 1) {
       pad_name = req_name;
     } else {
-      name = g_strdup_printf ("video_%d", mux->num_v_streams++);
+      name = g_strdup_printf ("video_%u", mux->num_v_streams++);
       pad_name = name;
     }
-    setcapsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_video_pad_setcaps);
+    capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_video_pad_setcaps);
     context = (GstMatroskaTrackContext *)
         g_new0 (GstMatroskaTrackVideoContext, 1);
     context->type = GST_MATROSKA_TRACK_TYPE_VIDEO;
     context->name = g_strdup ("Video");
-  } else if (templ == gst_element_class_get_pad_template (klass, "subtitle_%d")) {
+  } else if (templ == gst_element_class_get_pad_template (klass, "subtitle_%u")) {
     /* don't mix named and unnamed pads, if the pad already exists we fail when
      * trying to add it */
-    if (req_name != NULL && sscanf (req_name, "subtitle_%d", &pad_id) == 1) {
+    if (req_name != NULL && sscanf (req_name, "subtitle_%u", &pad_id) == 1) {
       pad_name = req_name;
     } else {
-      name = g_strdup_printf ("subtitle_%d", mux->num_t_streams++);
+      name = g_strdup_printf ("subtitle_%u", mux->num_t_streams++);
       pad_name = name;
     }
-    setcapsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_subtitle_pad_setcaps);
+    capsfunc = GST_DEBUG_FUNCPTR (gst_matroska_mux_subtitle_pad_setcaps);
     context = (GstMatroskaTrackContext *)
         g_new0 (GstMatroskaTrackSubtitleContext, 1);
     context->type = GST_MATROSKA_TRACK_TYPE_SUBTITLE;
@@ -2166,7 +2142,7 @@ gst_matroska_mux_request_new_pad (GstElement * element,
   gst_matroska_pad_reset (collect_pad, FALSE);
   collect_pad->track->codec_id = id;
 
-  gst_pad_set_setcaps_function (GST_PAD (newpad), setcapsfunc);
+  collect_pad->capsfunc = capsfunc;
   gst_pad_set_active (GST_PAD (newpad), TRUE);
   if (!gst_element_add_pad (element, GST_PAD (newpad)))
     goto pad_add_failed;
@@ -2374,9 +2350,9 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
   GTimeVal time = { 0, 0 };
 
   if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) {
-    ebml->caps = gst_caps_new_simple ("video/webm", NULL);
+    ebml->caps = gst_caps_new_empty_simple ("video/webm");
   } else {
-    ebml->caps = gst_caps_new_simple ("video/x-matroska", NULL);
+    ebml->caps = gst_caps_new_empty_simple ("video/x-matroska");
   }
   /* we start with a EBML header */
   doctype = mux->doctype;
@@ -2441,7 +2417,6 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
     for (collected = mux->collect->data; collected;
         collected = g_slist_next (collected)) {
       GstMatroskaPad *collect_pad;
-      GstFormat format = GST_FORMAT_TIME;
       GstPad *thepad;
       gint64 trackduration;
 
@@ -2450,7 +2425,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
 
       /* Query the total length of the track. */
       GST_DEBUG_OBJECT (thepad, "querying peer duration");
-      if (gst_pad_query_peer_duration (thepad, &format, &trackduration)) {
+      if (gst_pad_peer_query_duration (thepad, GST_FORMAT_TIME, &trackduration)) {
         GST_DEBUG_OBJECT (thepad, "duration: %" GST_TIME_FORMAT,
             GST_TIME_ARGS (trackduration));
         if (trackduration != GST_CLOCK_TIME_NONE && trackduration > duration) {
@@ -2774,15 +2749,16 @@ gst_matroska_mux_create_buffer_header (GstMatroskaTrackContext * track,
     gint16 relative_timestamp, int flags)
 {
   GstBuffer *hdr;
+  guint8 *data = g_malloc (4);
 
-  hdr = gst_buffer_new_and_alloc (4);
+  hdr = gst_buffer_new_wrapped (data, 4);
   /* track num - FIXME: what if num >= 0x80 (unlikely)? */
-  GST_BUFFER_DATA (hdr)[0] = track->num | 0x80;
+  data[0] = track->num | 0x80;
   /* time relative to clustertime */
-  GST_WRITE_UINT16_BE (GST_BUFFER_DATA (hdr) + 1, relative_timestamp);
+  GST_WRITE_UINT16_BE (data + 1, relative_timestamp);
 
   /* flags */
-  GST_BUFFER_DATA (hdr)[3] = flags;
+  data[3] = flags;
 
   return hdr;
 }
@@ -2797,14 +2773,18 @@ gst_matroska_mux_handle_dirac_packet (GstMatroskaMux * mux,
 {
   GstMatroskaTrackVideoContext *ctx =
       (GstMatroskaTrackVideoContext *) collect_pad->track;
-  const guint8 *data = GST_BUFFER_DATA (buf);
-  guint size = GST_BUFFER_SIZE (buf);
+  guint8 *buf_data, *data;
+  gsize size;
   guint8 parse_code;
   guint32 next_parse_offset;
   GstBuffer *ret = NULL;
   gboolean is_muxing_unit = FALSE;
 
-  if (GST_BUFFER_SIZE (buf) < 13) {
+  buf_data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  data = buf_data;
+
+  if (size < 13) {
+    gst_buffer_unmap (buf, buf_data, -1);
     gst_buffer_unref (buf);
     return ret;
   }
@@ -2812,6 +2792,7 @@ gst_matroska_mux_handle_dirac_packet (GstMatroskaMux * mux,
   /* Check if this buffer contains a picture or end-of-sequence packet */
   while (size >= 13) {
     if (GST_READ_UINT32_BE (data) != 0x42424344 /* 'BBCD' */ ) {
+      gst_buffer_unmap (buf, buf_data, -1);
       gst_buffer_unref (buf);
       return ret;
     }
@@ -2842,12 +2823,13 @@ gst_matroska_mux_handle_dirac_packet (GstMatroskaMux * mux,
   else
     ctx->dirac_unit = gst_buffer_ref (buf);
 
+  gst_buffer_unmap (buf, buf_data, -1);
+
   if (is_muxing_unit) {
-    ret = gst_buffer_make_metadata_writable (ctx->dirac_unit);
+    ret = gst_buffer_make_writable (ctx->dirac_unit);
     ctx->dirac_unit = NULL;
-    gst_buffer_copy_metadata (ret, buf,
-        GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS |
-        GST_BUFFER_COPY_CAPS);
+    gst_buffer_copy_into (ret, buf,
+        GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
     gst_buffer_unref (buf);
   } else {
     gst_buffer_unref (buf);
@@ -2869,9 +2851,9 @@ gst_matroska_mux_stop_streamheader (GstMatroskaMux * mux)
 
   streamheader_buffer = gst_ebml_stop_streamheader (ebml);
   if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) {
-    caps = gst_caps_new_simple ("video/webm", NULL);
+    caps = gst_caps_new_empty_simple ("video/webm");
   } else {
-    caps = gst_caps_new_simple ("video/x-matroska", NULL);
+    caps = gst_caps_new_empty_simple ("video/x-matroska");
   }
   s = gst_caps_get_structure (caps, 0);
   g_value_init (&streamheader, GST_TYPE_ARRAY);
@@ -3072,14 +3054,14 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad,
         relative_timestamp, flags);
     gst_ebml_write_set_cache (ebml, 0x40);
     gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_SIMPLEBLOCK,
-        GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
+        gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
     gst_ebml_write_buffer (ebml, hdr);
     gst_ebml_write_flush_cache (ebml, FALSE, GST_BUFFER_TIMESTAMP (buf));
     gst_ebml_write_buffer (ebml, buf);
 
     return gst_ebml_last_write_result (ebml);
   } else {
-    gst_ebml_write_set_cache (ebml, GST_BUFFER_SIZE (buf) * 2);
+    gst_ebml_write_set_cache (ebml, gst_buffer_get_size (buf) * 2);
     /* write and call order slightly unnatural,
      * but avoids seek and minizes pushing */
     blockgroup = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_BLOCKGROUP);
@@ -3089,9 +3071,10 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad,
     if (write_duration)
       gst_ebml_write_uint (ebml, GST_MATROSKA_ID_BLOCKDURATION, block_duration);
     gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_BLOCK,
-        GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr));
+        gst_buffer_get_size (buf) + gst_buffer_get_size (hdr));
     gst_ebml_write_buffer (ebml, hdr);
-    gst_ebml_write_master_finish_full (ebml, blockgroup, GST_BUFFER_SIZE (buf));
+    gst_ebml_write_master_finish_full (ebml, blockgroup,
+        gst_buffer_get_size (buf));
     gst_ebml_write_flush_cache (ebml, FALSE, GST_BUFFER_TIMESTAMP (buf));
     gst_ebml_write_buffer (ebml, buf);
 
@@ -3145,7 +3128,7 @@ gst_matroska_mux_handle_buffer (GstCollectPads2 * pads, GstCollectData2 * data,
       GST_DEBUG_OBJECT (mux, "... but streamable, nothing to finish");
     }
     gst_pad_push_event (mux->srcpad, gst_event_new_eos ());
-    ret = GST_FLOW_UNEXPECTED;
+    ret = GST_FLOW_EOS;
     goto exit;
   }