dvdsub: port to 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Thu, 6 Oct 2011 15:24:22 +0000 (17:24 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Thu, 6 Oct 2011 15:24:22 +0000 (17:24 +0200)
configure.ac
gst/dvdsub/Makefile.am
gst/dvdsub/gstdvdsubdec.c
gst/dvdsub/gstdvdsubdec.h
gst/dvdsub/gstdvdsubparse.c

index 10bc7a1..6c4bba8 100644 (file)
@@ -210,7 +210,7 @@ dnl *** plug-ins to include ***
 
 dnl Non ported plugins (non-dependant, then dependant)
 dnl Make sure you have a space before and after all plugins
-GST_PLUGINS_NONPORTED=" dvdsub iec958 synaesthesia xingmux \
+GST_PLUGINS_NONPORTED=" iec958 synaesthesia xingmux \
  mpegstream realmedia cdio dvdread twolame "
 AC_SUBST(GST_PLUGINS_NONPORTED)
 
index 8042b75..2a71a2d 100644 (file)
@@ -1,8 +1,8 @@
 plugin_LTLIBRARIES = libgstdvdsub.la
 
 libgstdvdsub_la_SOURCES = gstdvdsubdec.c gstdvdsubparse.c
-libgstdvdsub_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_CFLAGS)
-libgstdvdsub_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS)
+libgstdvdsub_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
+libgstdvdsub_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) $(GST_LIBS)
 libgstdvdsub_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstdvdsub_la_LIBTOOLFLAGS = --tag=disable-static
 
index 868d5b3..328c419 100644 (file)
@@ -28,7 +28,8 @@
 #include "gstdvdsubparse.h"
 #include <string.h>
 
-GST_BOILERPLATE (GstDvdSubDec, gst_dvd_sub_dec, GstElement, GST_TYPE_ELEMENT);
+#define gst_dvd_sub_dec_parent_class parent_class
+G_DEFINE_TYPE (GstDvdSubDec, gst_dvd_sub_dec, GST_TYPE_ELEMENT);
 
 static gboolean gst_dvd_sub_dec_src_event (GstPad * srcpad, GstEvent * event);
 static GstFlowReturn gst_dvd_sub_dec_chain (GstPad * pad, GstBuffer * buf);
@@ -37,7 +38,8 @@ static gboolean gst_dvd_sub_dec_handle_dvd_event (GstDvdSubDec * dec,
     GstEvent * event);
 static void gst_dvd_sub_dec_finalize (GObject * gobject);
 static void gst_setup_palette (GstDvdSubDec * dec);
-static void gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec, GstBuffer * buf);
+static void gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec,
+    GstVideoFrame * frame);
 static GstClockTime gst_dvd_sub_dec_get_event_delay (GstDvdSubDec * dec);
 static gboolean gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event);
 static gboolean gst_dvd_sub_dec_sink_setcaps (GstPad * pad, GstCaps * caps);
@@ -48,13 +50,8 @@ static GstFlowReturn gst_send_subtitle_frame (GstDvdSubDec * dec,
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw-yuv, format = (fourcc) AYUV, "
-        "width = (int) 720, height = (int) 576, framerate = (fraction) 0/1; "
-        "video/x-raw-rgb, "
-        "width = (int) 720, height = (int) 576, framerate = (fraction) 0/1, "
-        "bpp = (int) 32, endianness = (int) 4321, red_mask = (int) 16711680, "
-        "green_mask = (int) 65280, blue_mask = (int) 255, "
-        " alpha_mask = (int) -16777216, depth = (int) 32")
+    GST_STATIC_CAPS ("video/x-raw, format = (string) { AYUV, ARGB },"
+        "width = (int) 720, height = (int) 576, framerate = (fraction) 0/1")
     );
 
 static GstStaticPadTemplate subtitle_template = GST_STATIC_PAD_TEMPLATE ("sink",
@@ -101,33 +98,30 @@ typedef struct RLE_state
 RLE_state;
 
 static void
-gst_dvd_sub_dec_base_init (gpointer klass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&subtitle_template));
-
-  gst_element_class_set_details_simple (element_class, "DVD subtitle decoder",
-      "Codec/Decoder/Video", "Decodes DVD subtitles into AYUV video frames",
-      "Wim Taymans <wim.taymans@gmail.com>, "
-      "Jan Schmidt <thaytan@mad.scientist.com>");
-}
-
-static void
 gst_dvd_sub_dec_class_init (GstDvdSubDecClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
 
   gobject_class->finalize = gst_dvd_sub_dec_finalize;
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&subtitle_template));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "DVD subtitle decoder", "Codec/Decoder/Video",
+      "Decodes DVD subtitles into AYUV video frames",
+      "Wim Taymans <wim.taymans@gmail.com>, "
+      "Jan Schmidt <thaytan@mad.scientist.com>");
 }
 
 static void
-gst_dvd_sub_dec_init (GstDvdSubDec * dec, GstDvdSubDecClass * klass)
+gst_dvd_sub_dec_init (GstDvdSubDec * dec)
 {
   GstPadTemplate *tmpl;
 
@@ -137,7 +131,6 @@ gst_dvd_sub_dec_init (GstDvdSubDec * dec, GstDvdSubDecClass * klass)
   gst_pad_set_event_function (dec->sinkpad,
       GST_DEBUG_FUNCPTR (gst_dvd_sub_dec_sink_event));
   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
-  gst_pad_set_setcaps_function (dec->sinkpad, gst_dvd_sub_dec_sink_setcaps);
 
   tmpl = gst_static_pad_template_get (&src_template);
   dec->srcpad = gst_pad_new_from_template (tmpl, "src");
@@ -152,6 +145,7 @@ gst_dvd_sub_dec_init (GstDvdSubDec * dec, GstDvdSubDecClass * klass)
   dec->in_height = 576;
 
   dec->partialbuf = NULL;
+  dec->partialdata = NULL;
   dec->have_title = FALSE;
   dec->parse_pos = NULL;
   dec->forced_display = FALSE;
@@ -174,6 +168,7 @@ gst_dvd_sub_dec_finalize (GObject * gobject)
   GstDvdSubDec *dec = GST_DVD_SUB_DEC (gobject);
 
   if (dec->partialbuf) {
+    gst_buffer_unmap (dec->partialbuf, dec->partialdata, dec->partialsize);
     gst_buffer_unref (dec->partialbuf);
     dec->partialbuf = NULL;
   }
@@ -200,13 +195,12 @@ gst_dvd_sub_dec_src_event (GstPad * pad, GstEvent * event)
 static GstClockTime
 gst_dvd_sub_dec_get_event_delay (GstDvdSubDec * dec)
 {
-  guchar *start = GST_BUFFER_DATA (dec->partialbuf);
   guchar *buf;
   guint16 ticks;
   GstClockTime event_delay;
 
   /* If starting a new buffer, follow the first DCSQ ptr */
-  if (dec->parse_pos == start) {
+  if (dec->parse_pos == dec->partialdata) {
     buf = dec->parse_pos + dec->data_size;
   } else {
     buf = dec->parse_pos;
@@ -232,7 +226,7 @@ gst_dvd_sub_dec_parse_subpic (GstDvdSubDec * dec)
   { GST_WARNING("Subtitle stream broken parsing %c", *buf); \
     broken = TRUE; break; }
 
-  guchar *start = GST_BUFFER_DATA (dec->partialbuf);
+  guchar *start = dec->partialdata;
   guchar *buf;
   guchar *end;
   gboolean broken = FALSE;
@@ -568,18 +562,20 @@ gst_draw_rle_line (GstDvdSubDec * dec, guchar * buffer, RLE_state * state)
  * frame buffer.
  */
 static void
-gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec, GstBuffer * buf)
+gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec, GstVideoFrame * frame)
 {
   gint y;
-  gint Y_stride = 4 * dec->in_width;
-  guchar *buffer = GST_BUFFER_DATA (dec->partialbuf);
-
+  gint Y_stride;
+  guchar *buffer = dec->partialdata;
   gint hl_top, hl_bottom;
   gint last_y;
   RLE_state state;
+  guint8 *Y_data;;
 
-  GST_DEBUG_OBJECT (dec, "Merging subtitle on frame at time %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
+  GST_DEBUG_OBJECT (dec, "Merging subtitle on frame");
+
+  Y_data = GST_VIDEO_FRAME_PLANE_DATA (frame, 0);
+  Y_stride = GST_VIDEO_FRAME_PLANE_STRIDE (frame, 0);
 
   state.id = 0;
   state.aligned = 1;
@@ -641,7 +637,7 @@ gst_dvd_sub_dec_merge_title (GstDvdSubDec * dec, GstBuffer * buf)
   last_y = MIN (dec->bottom, dec->in_height);
 
   y = dec->top;
-  state.target = GST_BUFFER_DATA (buf) + 4 * dec->left + (y * Y_stride);
+  state.target = Y_data + 4 * dec->left + (y * Y_stride);
 
   /* Now draw scanlines until we hit last_y or end of RLE data */
   for (; ((state.offset[1] < dec->data_size + 2) && (y <= last_y)); y++) {
@@ -668,11 +664,16 @@ static void
 gst_send_empty_fill (GstDvdSubDec * dec, GstClockTime ts)
 {
   if (dec->next_ts < ts) {
+    GstSegment seg;
+
     GST_LOG_OBJECT (dec, "Sending newsegment update to advance time to %"
         GST_TIME_FORMAT, GST_TIME_ARGS (ts));
 
-    gst_pad_push_event (dec->srcpad,
-        gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, ts, -1, ts));
+    gst_segment_init (&seg, GST_FORMAT_TIME);
+    seg.start = ts;
+    seg.time = ts;
+
+    gst_pad_push_event (dec->srcpad, gst_event_new_segment (&seg));
   }
   dec->next_ts = ts;
 }
@@ -682,6 +683,8 @@ gst_send_subtitle_frame (GstDvdSubDec * dec, GstClockTime end_ts)
 {
   GstFlowReturn flow;
   GstBuffer *out_buf;
+  GstVideoFrame frame;
+  guint8 *data;
   gint x, y;
 
   g_assert (dec->have_title);
@@ -693,19 +696,16 @@ gst_send_subtitle_frame (GstDvdSubDec * dec, GstClockTime end_ts)
     goto out;
   }
 
-  flow = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, 0,
-      4 * dec->in_width * dec->in_height, GST_PAD_CAPS (dec->srcpad), &out_buf);
+  out_buf =
+      gst_buffer_new_allocate (NULL, 4 * GST_VIDEO_INFO_SIZE (&dec->info), 3);
+  gst_video_frame_map (&frame, &dec->info, out_buf, GST_MAP_READWRITE);
 
-  if (flow != GST_FLOW_OK) {
-    GST_DEBUG_OBJECT (dec, "alloc buffer failed: flow = %s",
-        gst_flow_get_name (flow));
-    goto out;
-  }
+  data = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
 
   /* Clear the buffer */
   /* FIXME - move this into the buffer rendering code */
   for (y = 0; y < dec->in_height; y++) {
-    guchar *line = GST_BUFFER_DATA (out_buf) + 4 * dec->in_width * y;
+    guchar *line = data + 4 * dec->in_width * y;
 
     for (x = 0; x < dec->in_width; x++) {
       line[0] = 0;              /* A */
@@ -726,9 +726,11 @@ gst_send_subtitle_frame (GstDvdSubDec * dec, GstClockTime end_ts)
   /* FIXME: do we really want to honour the forced_display flag
    * for subtitles streans? */
   if (dec->visible || dec->forced_display) {
-    gst_dvd_sub_dec_merge_title (dec, out_buf);
+    gst_dvd_sub_dec_merge_title (dec, &frame);
   }
 
+  gst_video_frame_unmap (&frame);
+
   dec->buf_dirty = FALSE;
 
   GST_BUFFER_TIMESTAMP (out_buf) = dec->next_ts;
@@ -744,8 +746,6 @@ gst_send_subtitle_frame (GstDvdSubDec * dec, GstClockTime end_ts)
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (out_buf)),
       GST_BUFFER_DURATION (out_buf));
 
-  gst_buffer_set_caps (out_buf, GST_PAD_CAPS (dec->srcpad));
-
   flow = gst_pad_push (dec->srcpad, out_buf);
 
 out:
@@ -807,7 +807,7 @@ gst_dvd_sub_dec_chain (GstPad * pad, GstBuffer * buf)
   dec = GST_DVD_SUB_DEC (GST_PAD_PARENT (pad));
 
   GST_DEBUG_OBJECT (dec, "Have buffer of size %d, ts %"
-      GST_TIME_FORMAT ", dur %" G_GINT64_FORMAT, GST_BUFFER_SIZE (buf),
+      GST_TIME_FORMAT ", dur %" G_GINT64_FORMAT, gst_buffer_get_size (buf),
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_DURATION (buf));
 
   if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
@@ -820,6 +820,7 @@ gst_dvd_sub_dec_chain (GstPad * pad, GstBuffer * buf)
   }
 
   if (dec->have_title) {
+    gst_buffer_unmap (dec->partialbuf, dec->partialdata, dec->partialsize);
     gst_buffer_unref (dec->partialbuf);
     dec->partialbuf = NULL;
     dec->have_title = FALSE;
@@ -832,14 +833,18 @@ gst_dvd_sub_dec_chain (GstPad * pad, GstBuffer * buf)
   if (dec->partialbuf) {
     GstBuffer *merge;
 
+    gst_buffer_unmap (dec->partialbuf, dec->partialdata, dec->partialsize);
     merge = gst_buffer_join (dec->partialbuf, buf);
     dec->partialbuf = merge;
   } else {
     dec->partialbuf = buf;
   }
 
-  data = GST_BUFFER_DATA (dec->partialbuf);
-  size = GST_BUFFER_SIZE (dec->partialbuf);
+  dec->partialdata =
+      gst_buffer_map (dec->partialbuf, &dec->partialsize, NULL, GST_MAP_READ);
+
+  data = dec->partialdata;
+  size = dec->partialsize;
 
   if (size > 4) {
     dec->packet_size = GST_READ_UINT16_BE (data);
@@ -873,21 +878,20 @@ gst_dvd_sub_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
 {
   GstDvdSubDec *dec = GST_DVD_SUB_DEC (gst_pad_get_parent (pad));
   gboolean ret = FALSE;
-  guint32 fourcc = GST_MAKE_FOURCC ('A', 'Y', 'U', 'V');
   GstCaps *out_caps = NULL, *peer_caps = NULL;
 
   GST_DEBUG_OBJECT (dec, "setcaps called with %" GST_PTR_FORMAT, caps);
 
-  dec->out_fourcc = fourcc;
-  out_caps = gst_caps_new_simple ("video/x-raw-yuv",
+  out_caps = gst_caps_new_simple ("video/x-raw",
+      "format", G_TYPE_STRING, "AYUV",
       "width", G_TYPE_INT, dec->in_width,
       "height", G_TYPE_INT, dec->in_height,
-      "format", GST_TYPE_FOURCC, dec->out_fourcc,
       "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
 
   peer_caps = gst_pad_get_allowed_caps (dec->srcpad);
   if (G_LIKELY (peer_caps)) {
     guint i = 0, n = 0;
+
     n = gst_caps_get_size (peer_caps);
     GST_DEBUG_OBJECT (dec, "peer allowed caps (%u structure(s)) are %"
         GST_PTR_FORMAT, n, peer_caps);
@@ -895,25 +899,18 @@ gst_dvd_sub_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
     for (i = 0; i < n; i++) {
       GstStructure *s = gst_caps_get_structure (peer_caps, i);
       /* Check if the peer pad support ARGB format, if yes change caps */
-      if (gst_structure_has_name (s, "video/x-raw-rgb") &&
-          gst_structure_has_field (s, "alpha_mask")) {
+      if (gst_structure_has_name (s, "video/x-raw")) {
         gst_caps_unref (out_caps);
-        GST_DEBUG_OBJECT (dec, "trying with fourcc %" GST_FOURCC_FORMAT,
-            GST_FOURCC_ARGS (fourcc));
-        out_caps = gst_caps_new_simple ("video/x-raw-rgb",
+        GST_DEBUG_OBJECT (dec, "trying with ARGB");
+
+        out_caps = gst_caps_new_simple ("video/x-raw",
+            "format", G_TYPE_STRING, "ARGB",
             "width", G_TYPE_INT, dec->in_width,
             "height", G_TYPE_INT, dec->in_height,
-            "framerate", GST_TYPE_FRACTION, 0, 1,
-            "bpp", G_TYPE_INT, 32,
-            "depth", G_TYPE_INT, 32,
-            "red_mask", G_TYPE_INT, 16711680,
-            "green_mask", G_TYPE_INT, 65280,
-            "blue_mask", G_TYPE_INT, 255,
-            "alpha_mask", G_TYPE_INT, -16777216,
-            "endianness", G_TYPE_INT, G_BIG_ENDIAN, NULL);
+            "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
+
         if (gst_pad_peer_accept_caps (dec->srcpad, out_caps)) {
-          GST_DEBUG_OBJECT (dec, "peer accepted format %" GST_FOURCC_FORMAT,
-              GST_FOURCC_ARGS (fourcc));
+          GST_DEBUG_OBJECT (dec, "peer accepted ARGB");
           /* If ARGB format then set the flag */
           dec->use_ARGB = TRUE;
           break;
@@ -925,7 +922,7 @@ gst_dvd_sub_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
   GST_DEBUG_OBJECT (dec, "setting caps downstream to %" GST_PTR_FORMAT,
       out_caps);
   if (gst_pad_set_caps (dec->srcpad, out_caps)) {
-    dec->out_fourcc = fourcc;
+    gst_video_info_from_caps (&dec->info, out_caps);
   } else {
     GST_WARNING_OBJECT (dec, "failed setting downstream caps");
     gst_caps_unref (out_caps);
@@ -949,12 +946,19 @@ gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event)
   GST_LOG_OBJECT (dec, "%s event", GST_EVENT_TYPE_NAME (event));
 
   switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CAPS:
+    {
+      GstCaps *caps;
+
+      gst_event_parse_caps (event, &caps);
+      ret = gst_dvd_sub_dec_sink_setcaps (pad, caps);
+      gst_event_unref (event);
+      break;
+    }
     case GST_EVENT_CUSTOM_DOWNSTREAM:{
       GstClockTime ts = GST_EVENT_TIMESTAMP (event);
 
-      if (event->structure != NULL &&
-          gst_structure_has_name (event->structure, "application/x-gst-dvd")) {
-
+      if (gst_event_has_name (event, "application/x-gst-dvd")) {
         if (GST_CLOCK_TIME_IS_VALID (ts))
           gst_dvd_sub_dec_advance_time (dec, ts);
 
@@ -969,14 +973,13 @@ gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event)
       ret = gst_pad_event_default (pad, event);
       break;
     }
-    case GST_EVENT_NEWSEGMENT:{
-      gboolean update;
-      GstFormat format;
-      gint64 start, stop, pos;
+    case GST_EVENT_SEGMENT:
+    {
+      GstSegment seg;
 
-      gst_event_parse_new_segment (event, &update, NULL, &format, &start,
-          &stop, &pos);
+      gst_event_copy_segment (event, &seg);
 
+#if 0
       if (update) {
         /* update ... advance time */
         if (GST_CLOCK_TIME_IS_VALID (pos)) {
@@ -990,20 +993,24 @@ gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event)
         }
         gst_event_unref (event);
         ret = TRUE;
-      } else {
+      } else
+#endif
+      {
         /* not just an update ... */
 
         /* Turn off forced highlight display */
         // dec->forced_display = 0;
         // dec->current_button = 0;
         if (dec->partialbuf) {
+          gst_buffer_unmap (dec->partialbuf, dec->partialdata,
+              dec->partialsize);
           gst_buffer_unref (dec->partialbuf);
           dec->partialbuf = NULL;
           dec->have_title = FALSE;
         }
 
-        if (GST_CLOCK_TIME_IS_VALID (pos))
-          dec->next_ts = pos;
+        if (GST_CLOCK_TIME_IS_VALID (seg.time))
+          dec->next_ts = seg.time;
         else
           dec->next_ts = GST_CLOCK_TIME_NONE;
 
@@ -1020,6 +1027,7 @@ gst_dvd_sub_dec_sink_event (GstPad * pad, GstEvent * event)
       dec->current_button = 0;
 
       if (dec->partialbuf) {
+        gst_buffer_unmap (dec->partialbuf, dec->partialdata, dec->partialsize);
         gst_buffer_unref (dec->partialbuf);
         dec->partialbuf = NULL;
         dec->have_title = FALSE;
index 52ea126..2780580 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <gst/gst.h>
+#include <gst/video/video.h>
 
 #define GST_TYPE_DVD_SUB_DEC             (gst_dvd_sub_dec_get_type())
 #define GST_DVD_SUB_DEC(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DVD_SUB_DEC,GstDvdSubDec))
@@ -50,6 +51,8 @@ struct _GstDvdSubDec
 
   /* Collect together subtitle buffers until we have a full control sequence */
   GstBuffer *partialbuf;
+  guint8 *partialdata;
+  gsize partialsize;
   gboolean have_title;
 
   guchar subtitle_index[4];
@@ -64,8 +67,8 @@ struct _GstDvdSubDec
   Color_val palette_cache_rgb[4];
   Color_val hl_palette_cache_rgb[4];
 
+  GstVideoInfo info;
   gboolean use_ARGB;
-  guint32 out_fourcc;
   GstClockTime next_ts;
 
   /*
index e922d56..adf3a6a 100644 (file)
@@ -49,23 +49,9 @@ static GstFlowReturn gst_dvd_sub_parse_chain (GstPad * pad, GstBuffer * buf);
 
 static GstStateChangeReturn gst_dvd_sub_parse_change_state (GstElement *
     element, GstStateChange transition);
-GST_BOILERPLATE (GstDvdSubParse, gst_dvd_sub_parse, GstElement,
-    GST_TYPE_ELEMENT);
 
-static void
-gst_dvd_sub_parse_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&src_template));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_template));
-
-  gst_element_class_set_details_simple (element_class, "DVD subtitle parser",
-      "Codec/Parser/Subtitle", "Parses and packetizes DVD subtitle streams",
-      "Mark Nauwelaerts <mnauw@users.sourceforge.net>");
-}
+#define gst_dvd_sub_parse_parent_class parent_class
+G_DEFINE_TYPE (GstDvdSubParse, gst_dvd_sub_parse, GST_TYPE_ELEMENT);
 
 static void
 gst_dvd_sub_parse_class_init (GstDvdSubParseClass * klass)
@@ -83,6 +69,15 @@ gst_dvd_sub_parse_class_init (GstDvdSubParseClass * klass)
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_dvd_sub_parse_change_state);
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&src_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_template));
+
+  gst_element_class_set_details_simple (gstelement_class, "DVD subtitle parser",
+      "Codec/Parser/Subtitle", "Parses and packetizes DVD subtitle streams",
+      "Mark Nauwelaerts <mnauw@users.sourceforge.net>");
 }
 
 static void
@@ -97,7 +92,7 @@ gst_dvd_sub_parse_finalize (GObject * object)
 }
 
 static void
-gst_dvd_sub_parse_init (GstDvdSubParse * parse, GstDvdSubParseClass * klass)
+gst_dvd_sub_parse_init (GstDvdSubParse * parse)
 {
   parse->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
   gst_pad_set_chain_function (parse->sinkpad,
@@ -159,14 +154,14 @@ gst_dvd_sub_parse_chain (GstPad * pad, GstBuffer * buf)
   adapter = parse->adapter;
 
   GST_LOG_OBJECT (parse, "%4u bytes, ts: %" GST_TIME_FORMAT,
-      GST_BUFFER_SIZE (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
+      gst_buffer_get_size (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
 
   gst_adapter_push (adapter, buf);
 
   if (!parse->needed) {
-    const guint8 *data;
+    guint8 data[2];
 
-    data = gst_adapter_peek (adapter, 2);
+    gst_adapter_copy (adapter, data, 0, 2);
     parse->needed = GST_READ_UINT16_BE (data);
   }
 
@@ -190,7 +185,6 @@ gst_dvd_sub_parse_chain (GstPad * pad, GstBuffer * buf)
       }
       outbuf = gst_adapter_take_buffer (adapter, parse->needed);
       /* decorate buffer */
-      gst_buffer_set_caps (outbuf, GST_PAD_CAPS (parse->srcpad));
       GST_BUFFER_TIMESTAMP (outbuf) = parse->stamp;
       /* reset state */
       parse->stamp = GST_CLOCK_TIME_NONE;