git diff 9194b36eb20e2112f5dd05cc62eee99a30475d55 b61aec17d4dcc163ce3df22be56774b1758fdea4

diff --git a/.gitignore b/.gitignore
index ddb619a..7d6b7cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,5 @@ tests/examples/shapewipe/shapewipe-example
 /m4
 Makefile.in
 Makefile
+sys/dxr3/dxr3marshal.h
+
diff --git a/configure.ac b/configure.ac
index 9d02d9e..62c3872 100644
--- a/configure.ac
+++ b/configure.ac
@@ -349,6 +349,20 @@ fi
 
 dnl *** sys plug-ins ***
 
+dnl *** DXR3 card ***
+translit(dnm, m, l) AM_CONDITIONAL(USE_DXR3, true)
+AG_GST_CHECK_FEATURE(DXR3, [DXR3 hardware MPEG DVD decoder],
+  dxr3videosink dxr3audiosink dxr3spusink, [
+  HAVE_DXR3=yes
+  AC_CHECK_HEADER(linux/em8300.h, ,
+                  [ AC_MSG_WARN([DXR3/em8300 header file not found]) &&
+                    HAVE_DXR3=no ] )
+  AC_CHECK_HEADER(linux/soundcard.h, ,
+                  [ AC_MSG_WARN([Generic sound header file not found]) &&
+                    HAVE_DXR3=no ] )
+])
+
+
 dnl DirectSound
 translit(dnm, m, l) AM_CONDITIONAL(USE_DIRECTSOUND, true)
 AG_GST_CHECK_FEATURE(DIRECTSOUND, [DirectSound], directsoundsrc, [
@@ -1683,6 +1697,7 @@ sys/directsound/Makefile
 sys/dshowsrcwrapper/Makefile
 sys/dshowvideosink/Makefile
 sys/dvb/Makefile
+sys/dxr3/Makefile
 sys/fbdev/Makefile
 sys/oss4/Makefile
 sys/osxvideo/Makefile
diff --git a/sys/Makefile.am b/sys/Makefile.am
index 5608a8e..1c4b815 100644
--- a/sys/Makefile.am
+++ b/sys/Makefile.am
@@ -1,8 +1,8 @@
-# if USE_DXR3
-# DXR3_DIR=dxr3
-# else
-# DXR3_DIR=
-# endif
+if USE_DXR3
+DXR3_DIR=dxr3
+else
+DXR3_DIR=
+endif
 
 # if USE_QCAM
 # QCAM_DIR=qcam
@@ -82,7 +82,7 @@ else
 VDPAU_DIR=
 endif
 
-SUBDIRS = $(ACM_DIR) $(DIRECTDRAW_DIR) $(DIRECTSOUND_DIR) $(DVB_DIR) $(FBDEV_DIR) $(OSS4_DIR) $(OSX_VIDEO_DIR) $(QT_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR)
+SUBDIRS = $(ACM_DIR) $(DIRECTDRAW_DIR) $(DIRECTSOUND_DIR) $(DVB_DIR) $(DXR3_DIR) $(FBDEV_DIR) $(OSS4_DIR) $(OSX_VIDEO_DIR) $(QT_DIR) $(VCD_DIR) $(VDPAU_DIR) $(WININET_DIR)
 
 DIST_SUBDIRS = acmenc acmmp3dec directdraw directsound dvb fbdev dshowdecwrapper dshowsrcwrapper dshowvideosink \
 			   oss4 osxvideo qtwrapper vcd vdpau wasapi wininet winks winscreencap
diff --git a/sys/dxr3/Makefile.am b/sys/dxr3/Makefile.am
index ae1ad50..00210cf 100644
--- a/sys/dxr3/Makefile.am
+++ b/sys/dxr3/Makefile.am
@@ -4,8 +4,8 @@ plugin_LTLIBRARIES = libgstdxr3.la
 libgstdxr3_la_SOURCES = dxr3videosink.c dxr3audiosink.c dxr3spusink.c \
 			dxr3init.c ac3_padder.c 
 nodist_libgstdxr3_la_SOURCES = dxr3marshal.c
-libgstdxr3_la_CFLAGS = $(GST_CFLAGS)
-libgstdxr3_la_LIBADD =
+libgstdxr3_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS)
+libgstdxr3_la_LIBADD = $(GST_BASE_LIBS)
 libgstdxr3_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstdxr3_la_LIBTOOLFLAGS = --tag=disable-static
 
diff --git a/sys/dxr3/dxr3audiosink.c b/sys/dxr3/dxr3audiosink.c
index 284ced2..8cca8bd 100644
--- a/sys/dxr3/dxr3audiosink.c
+++ b/sys/dxr3/dxr3audiosink.c
@@ -103,15 +103,14 @@ static gboolean dxr3audiosink_open (Dxr3AudioSink * sink);
 static gboolean dxr3audiosink_set_mode_pcm (Dxr3AudioSink * sink);
 static gboolean dxr3audiosink_set_mode_ac3 (Dxr3AudioSink * sink);
 static void dxr3audiosink_close (Dxr3AudioSink * sink);
-static void dxr3audiosink_set_clock (GstElement * element, GstClock * clock);
+static gboolean dxr3audiosink_set_clock (GstElement * element, GstClock * clock);
 
-static GstPadLinkReturn dxr3audiosink_pcm_sinklink (GstPad * pad,
-    const GstCaps * caps);
+static GstPadLinkReturn dxr3audiosink_pcm_sinklink (GstPad * pad, GstPad * peer);
 static void dxr3audiosink_set_scr (Dxr3AudioSink * sink, guint32 scr);
 
 static gboolean dxr3audiosink_handle_event (GstPad * pad, GstEvent * event);
-static void dxr3audiosink_chain_pcm (GstPad * pad, GstData * buf);
-static void dxr3audiosink_chain_ac3 (GstPad * pad, GstData * buf);
+static GstFlowReturn dxr3audiosink_chain_pcm (GstPad * pad, GstBuffer * buf);
+static GstFlowReturn dxr3audiosink_chain_ac3 (GstPad * pad, GstBuffer * buf);
 
 /* static void  dxr3audiosink_wait              (Dxr3AudioSink *sink, */
 /*                                                  GstClockTime time); */
@@ -214,7 +213,7 @@ dxr3audiosink_init (Dxr3AudioSink * sink)
   gst_pad_set_chain_function (sink->ac3_sinkpad, dxr3audiosink_chain_ac3);
   gst_element_add_pad (GST_ELEMENT (sink), sink->ac3_sinkpad);
 
-  GST_OBJECT_FLAG_SET (GST_ELEMENT (sink), GST_ELEMENT_EVENT_AWARE);
+//  GST_OBJECT_FLAG_SET (GST_ELEMENT (sink), GST_ELEMENT_EVENT_AWARE);
 
   sink->card_number = 0;
 
@@ -447,24 +446,26 @@ dxr3audiosink_close (Dxr3AudioSink * sink)
 }
 
 
-static void
+static gboolean
 dxr3audiosink_set_clock (GstElement * element, GstClock * clock)
 {
   Dxr3AudioSink *src = DXR3AUDIOSINK (element);
 
   src->clock = clock;
+  return TRUE;
 }
 
 
 static GstPadLinkReturn
-dxr3audiosink_pcm_sinklink (GstPad * pad, const GstCaps * caps)
+dxr3audiosink_pcm_sinklink (GstPad * pad, GstPad  * peer)
 {
+  GstCaps* caps = gst_pad_get_caps(peer);
   Dxr3AudioSink *sink = DXR3AUDIOSINK (gst_pad_get_parent (pad));
   GstStructure *structure = gst_caps_get_structure (caps, 0);
   gint rate;
 
   if (!gst_caps_is_fixed (caps)) {
-    return GST_PAD_LINK_DELAYED;
+    return GST_PAD_LINK_NOSCHED;
   }
 
   gst_structure_get_int (structure, "rate", &rate);
@@ -494,7 +495,8 @@ dxr3audiosink_handle_event (GstPad * pad, GstEvent * event)
   type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
 
   switch (type) {
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_FLUSH_START:
+    case GST_EVENT_FLUSH_STOP:
       if (sink->control_fd >= 0) {
         unsigned audiomode;
 
@@ -519,26 +521,22 @@ dxr3audiosink_handle_event (GstPad * pad, GstEvent * event)
 }
 
 
-static void
-dxr3audiosink_chain_pcm (GstPad * pad, GstData * _data)
+static GstFlowReturn
+dxr3audiosink_chain_pcm (GstPad * pad, GstBuffer * buf)
 {
   Dxr3AudioSink *sink;
   gint bytes_written = 0;
-  GstBuffer *buf;
-
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (_data != NULL);
+  g_return_val_if_fail (pad != NULL, GST_FLOW_CUSTOM_ERROR);
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_CUSTOM_ERROR);
+  g_return_val_if_fail (buf != NULL, GST_FLOW_CUSTOM_ERROR);
 
   sink = DXR3AUDIOSINK (gst_pad_get_parent (pad));
 
-  if (GST_IS_EVENT (_data)) {
-    dxr3audiosink_handle_event (pad, GST_EVENT (_data));
-    return;
+  if (GST_IS_EVENT (buf)) {
+    dxr3audiosink_handle_event (pad, GST_EVENT (buf));
+    return GST_FLOW_OK;
   }
 
-  buf = GST_BUFFER (_data);
-
   if (sink->mode != DXR3AUDIOSINK_MODE_PCM) {
     /* Switch to PCM mode. */
     dxr3audiosink_set_mode_pcm (sink);
@@ -581,29 +579,27 @@ dxr3audiosink_chain_pcm (GstPad * pad, GstData * _data)
   }
 
   gst_buffer_unref (buf);
+  return GST_FLOW_OK;
 }
 
 
-static void
-dxr3audiosink_chain_ac3 (GstPad * pad, GstData * _data)
+static GstFlowReturn
+dxr3audiosink_chain_ac3 (GstPad * pad, GstBuffer * buf)
 {
   Dxr3AudioSink *sink;
   gint bytes_written = 0;
-  GstBuffer *buf;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (_data != NULL);
+  g_return_val_if_fail (pad != NULL, GST_FLOW_CUSTOM_ERROR);
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_CUSTOM_ERROR);
+  g_return_val_if_fail (buf != NULL, GST_FLOW_CUSTOM_ERROR);
 
   sink = DXR3AUDIOSINK (gst_pad_get_parent (pad));
 
-  if (GST_IS_EVENT (_data)) {
-    dxr3audiosink_handle_event (pad, GST_EVENT (_data));
-    return;
+  if (GST_IS_EVENT (buf)) {
+    dxr3audiosink_handle_event (pad, GST_EVENT (buf));
+    return GST_FLOW_OK;
   }
 
-  buf = GST_BUFFER (_data);
-
   if (sink->mode != DXR3AUDIOSINK_MODE_AC3) {
     /* Switch to AC3 mode. */
     dxr3audiosink_set_mode_ac3 (sink);
@@ -669,6 +665,7 @@ dxr3audiosink_chain_ac3 (GstPad * pad, GstData * _data)
   }
 
   gst_buffer_unref (buf);
+  return GST_FLOW_OK;
 }
 
 #if 0
diff --git a/sys/dxr3/dxr3spusink.c b/sys/dxr3/dxr3spusink.c
index 0b220f8..0906bca 100644
--- a/sys/dxr3/dxr3spusink.c
+++ b/sys/dxr3/dxr3spusink.c
@@ -82,10 +82,10 @@ static void dxr3spusink_get_property (GObject * object,
 
 static gboolean dxr3spusink_open (Dxr3SpuSink * sink);
 static void dxr3spusink_close (Dxr3SpuSink * sink);
-static void dxr3spusink_set_clock (GstElement * element, GstClock * clock);
+static gboolean dxr3spusink_set_clock (GstElement * element, GstClock * clock);
 
 static gboolean dxr3spusink_handle_event (GstPad * pad, GstEvent * event);
-static void dxr3spusink_chain (GstPad * pad, GstData * _data);
+static GstFlowReturn dxr3spusink_chain (GstPad * pad, GstBuffer * _data);
 
 static GstStateChangeReturn dxr3spusink_change_state (GstElement * element,
     GstStateChange transition);
@@ -205,7 +205,7 @@ dxr3spusink_init (Dxr3SpuSink * sink)
   gst_element_add_pad (GST_ELEMENT (sink), pad);
   gst_pad_set_chain_function (pad, dxr3spusink_chain);
 
-  GST_OBJECT_FLAG_SET (GST_ELEMENT (sink), GST_ELEMENT_EVENT_AWARE);
+//  GST_OBJECT_FLAG_SET (GST_ELEMENT (sink), GST_ELEMENT_EVENT_AWARE);
 
   sink->card_number = 0;
 
@@ -312,12 +312,13 @@ dxr3spusink_close (Dxr3SpuSink * sink)
 }
 
 
-static void
+static gboolean
 dxr3spusink_set_clock (GstElement * element, GstClock * clock)
 {
   Dxr3SpuSink *src = DXR3SPUSINK (element);
 
   src->clock = clock;
+  return TRUE;
 }
 
 
@@ -332,7 +333,8 @@ dxr3spusink_handle_event (GstPad * pad, GstEvent * event)
   type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
 
   switch (type) {
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_FLUSH_START:
+    case GST_EVENT_FLUSH_STOP:
       if (sink->control_fd >= 0) {
         int subdevice;
 
@@ -358,22 +360,21 @@ dxr3spusink_handle_event (GstPad * pad, GstEvent * event)
 }
 
 
-static void
-dxr3spusink_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+dxr3spusink_chain (GstPad * pad, GstBuffer * buf)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   Dxr3SpuSink *sink;
   gint bytes_written = 0;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
+  g_return_val_if_fail (pad != NULL, GST_FLOW_CUSTOM_ERROR);
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_CUSTOM_ERROR);
+  g_return_val_if_fail (buf != NULL, GST_FLOW_CUSTOM_ERROR);
 
   sink = DXR3SPUSINK (gst_pad_get_parent (pad));
 
   if (GST_IS_EVENT (buf)) {
     dxr3spusink_handle_event (pad, GST_EVENT (buf));
-    return;
+    return GST_FLOW_OK;
   }
 
   if (GST_OBJECT_FLAG_IS_SET (sink, DXR3SPUSINK_OPEN)) {
@@ -394,6 +395,7 @@ dxr3spusink_chain (GstPad * pad, GstData * _data)
   }
 
   gst_buffer_unref (buf);
+  return GST_FLOW_OK;
 }
 
 
diff --git a/sys/dxr3/dxr3videosink.c b/sys/dxr3/dxr3videosink.c
index 475cfbd..1e4369f 100644
--- a/sys/dxr3/dxr3videosink.c
+++ b/sys/dxr3/dxr3videosink.c
@@ -32,6 +32,7 @@
 
 #include <gst/gst-i18n-plugin.h>
 #include <gst/gst.h>
+#include <gstreamer-0.10/gst/base/gstbasesink.h>
 
 #include "dxr3videosink.h"
 #include "dxr3marshal.h"
@@ -42,7 +43,7 @@
 /* ElementFactory information. */
 static GstElementDetails dxr3videosink_details = {
   "dxr3/Hollywood+ mpeg decoder board video element",
-  "Sink/Video",
+  "Sink/DXR3",
   "Feeds MPEG2 video to Sigma Designs em8300 based boards",
   "Martin Soto <martinsoto@users.sourceforge.net>"
 };
@@ -96,17 +97,19 @@ GST_STATIC_PAD_TEMPLATE ("sink",
 
 
 static void dxr3videosink_class_init (Dxr3VideoSinkClass * klass);
-static void dxr3videosink_base_init (Dxr3VideoSinkClass * klass);
-static void dxr3videosink_init (Dxr3VideoSink * dxr3videosink);
+static void dxr3videosink_base_init (gpointer g_class);
+static void dxr3videosink_init (Dxr3VideoSink * dxr3videosink,
+    Dxr3VideoSinkClass * dxr3class);
 
 static void dxr3videosink_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec);
 static void dxr3videosink_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
-static gboolean dxr3videosink_open (Dxr3VideoSink * sink);
-static void dxr3videosink_close (Dxr3VideoSink * sink);
-static void dxr3videosink_set_clock (GstElement * element, GstClock * clock);
+static gboolean dxr3videosink_open (GstBaseSink * basesink);
+static gboolean dxr3videosink_close (GstBaseSink * basesink);
+static gboolean dxr3videosink_set_clock (GstElement * element,
+    GstClock * clock);
 
 static void dxr3videosink_reset_parser (Dxr3VideoSink * sink);
 static int dxr3videosink_next_start_code (Dxr3VideoSink * sink);
@@ -114,8 +117,10 @@ static void dxr3videosink_discard_data (Dxr3VideoSink * sink, guint cut);
 static void dxr3videosink_write_data (Dxr3VideoSink * sink, guint cut);
 static void dxr3videosink_parse_data (Dxr3VideoSink * sink);
 
-static gboolean dxr3videosink_handle_event (GstPad * pad, GstEvent * event);
-static void dxr3videosink_chain (GstPad * pad, GstData * _data);
+static gboolean dxr3videosink_handle_event (GstBaseSink * sink,
+    GstEvent * event);
+static GstFlowReturn dxr3videosink_render (GstBaseSink * basesink,
+    GstBuffer * _data);
 
 static GstStateChangeReturn dxr3videosink_change_state (GstElement * element,
     GstStateChange transition);
@@ -126,44 +131,30 @@ static int dxr3videosink_mvcommand (Dxr3VideoSink * sink, int command);
 
 static void dxr3videosink_flushed (Dxr3VideoSink * sink);
 
-static GstElementClass *parent_class = NULL;
 static guint dxr3videosink_signals[LAST_SIGNAL] = { 0 };
 
+GST_DEBUG_CATEGORY_STATIC (dxr3videosink_debug);
 
-extern GType
-dxr3videosink_get_type (void)
+static void
+_do_init (GType dxr3_type)
 {
-  static GType dxr3videosink_type = 0;
-
-  if (!dxr3videosink_type) {
-    static const GTypeInfo dxr3videosink_info = {
-      sizeof (Dxr3VideoSinkClass),
-      (GBaseInitFunc) dxr3videosink_base_init,
-      NULL,
-      (GClassInitFunc) dxr3videosink_class_init,
-      NULL,
-      NULL,
-      sizeof (Dxr3VideoSink),
-      0,
-      (GInstanceInitFunc) dxr3videosink_init,
-    };
-
-    dxr3videosink_type = g_type_register_static (GST_TYPE_ELEMENT,
-        "Dxr3VideoSink", &dxr3videosink_info, 0);
-  }
-
-  return dxr3videosink_type;
+  GST_DEBUG_CATEGORY_INIT (dxr3videosink_debug, "dxr3videosink", 0,
+      "DXR3 sink element");
 }
 
+GST_BOILERPLATE_FULL (Dxr3VideoSink, dxr3videosink, GstBaseSink,
+    GST_TYPE_BASE_SINK, _do_init);
 
 static void
-dxr3videosink_base_init (Dxr3VideoSinkClass * klass)
+dxr3videosink_base_init (gpointer g_class)
 {
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
 
+  printf ("base_init\n");
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&dxr3videosink_sink_factory));
   gst_element_class_set_details (element_class, &dxr3videosink_details);
+  printf ("end of base_init\n");
 }
 
 static void
@@ -171,11 +162,11 @@ dxr3videosink_class_init (Dxr3VideoSinkClass * klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *gstelement_class;
-
+  GstBaseSinkClass *gstbasesink_class;
+  printf ("class_init\n");
   gobject_class = (GObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
-
-  parent_class = g_type_class_peek_parent (klass);
+  gstbasesink_class = GST_BASE_SINK_CLASS (klass);
 
   dxr3videosink_signals[SIGNAL_FLUSHED] =
       g_signal_new ("flushed", G_TYPE_FROM_CLASS (klass),
@@ -190,19 +181,30 @@ dxr3videosink_class_init (Dxr3VideoSinkClass * klass)
 
   gstelement_class->change_state = dxr3videosink_change_state;
   gstelement_class->set_clock = dxr3videosink_set_clock;
+
+  gstbasesink_class->get_times = NULL;
+  gstbasesink_class->start = GST_DEBUG_FUNCPTR (dxr3videosink_open);
+  gstbasesink_class->stop = GST_DEBUG_FUNCPTR (dxr3videosink_close);
+  gstbasesink_class->render = GST_DEBUG_FUNCPTR (dxr3videosink_render);
+  gstbasesink_class->event = GST_DEBUG_FUNCPTR (dxr3videosink_handle_event);
+  printf ("end of class_init\n");
 }
 
 
 static void
-dxr3videosink_init (Dxr3VideoSink * sink)
+dxr3videosink_init (Dxr3VideoSink * sink, Dxr3VideoSinkClass * dxr3class)
 {
   GstPad *pad;
 
-  pad = gst_pad_new_from_static_template (&dxr3videosink_sink_factory, "sink");
-  gst_element_add_pad (GST_ELEMENT (sink), pad);
-  gst_pad_set_chain_function (pad, dxr3videosink_chain);
+  printf ("init\n");
+  pad = GST_BASE_SINK_PAD (sink);
+  /*
+     pad = gst_pad_new_from_static_template (&dxr3videosink_sink_factory, "sink");
+     gst_element_add_pad (GST_ELEMENT (sink), pad);
+     gst_pad_set_render_function (pad, dxr3videosink_chain);
+     gst_pad_set_event_function(pad, dxr3videosink_handle_event);
+   */
 
-  GST_OBJECT_FLAG_SET (GST_ELEMENT (sink), GST_ELEMENT_EVENT_AWARE);
 
   sink->card_number = 0;
 
@@ -217,6 +219,7 @@ dxr3videosink_init (Dxr3VideoSink * sink)
 
   sink->cur_buf = NULL;
   dxr3videosink_reset_parser (sink);
+  printf ("end of init\n");
 }
 
 
@@ -254,8 +257,10 @@ dxr3videosink_get_property (GObject * object, guint prop_id,
 
 
 static gboolean
-dxr3videosink_open (Dxr3VideoSink * sink)
+dxr3videosink_open (GstBaseSink * basesink)
 {
+  Dxr3VideoSink *sink = DXR3VIDEOSINK (basesink);
+  printf ("Dxr3VideoSink open\n");
   g_return_val_if_fail (!GST_OBJECT_FLAG_IS_SET (sink, DXR3VIDEOSINK_OPEN),
       FALSE);
 
@@ -284,43 +289,48 @@ dxr3videosink_open (Dxr3VideoSink * sink)
   }
 
   GST_OBJECT_FLAG_SET (sink, DXR3VIDEOSINK_OPEN);
-
+  printf ("Sink Open\n");
   return TRUE;
 }
 
 
-static void
-dxr3videosink_close (Dxr3VideoSink * sink)
+static gboolean
+dxr3videosink_close (GstBaseSink * basesink)
 {
-  g_return_if_fail (GST_OBJECT_FLAG_IS_SET (sink, DXR3VIDEOSINK_OPEN));
+  Dxr3VideoSink *sink = DXR3VIDEOSINK (basesink);
+  printf ("close\n");
+  g_return_val_if_fail (GST_OBJECT_FLAG_IS_SET (sink, DXR3VIDEOSINK_OPEN),
+      FALSE);
 
   if (close (sink->video_fd) != 0) {
     GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
         (_("Could not close video device \"%s\"."), sink->video_filename),
         GST_ERROR_SYSTEM);
-    return;
+    return FALSE;
   }
 
   if (close (sink->control_fd) != 0) {
     GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE,
         (_("Could not close control device \"%s\"."), sink->control_filename),
         GST_ERROR_SYSTEM);
-    return;
+    return FALSE;
   }
 
   GST_OBJECT_FLAG_UNSET (sink, DXR3VIDEOSINK_OPEN);
 
   free (sink->video_filename);
   sink->video_filename = NULL;
+  return TRUE;
 }
 
 
-static void
+static gboolean
 dxr3videosink_set_clock (GstElement * element, GstClock * clock)
 {
   Dxr3VideoSink *src = DXR3VIDEOSINK (element);
 
   src->clock = clock;
+  return TRUE;
 }
 
 
@@ -330,6 +340,7 @@ dxr3videosink_reset_parser (Dxr3VideoSink * sink)
   if (sink->cur_buf != NULL) {
     gst_buffer_unref (sink->cur_buf);
     sink->cur_buf = NULL;
+    printf ("reset_parser\n");
   }
   sink->cur_ts = GST_CLOCK_TIME_NONE;
 
@@ -398,6 +409,7 @@ dxr3videosink_discard_data (Dxr3VideoSink * sink, guint cut)
 
   if (GST_BUFFER_SIZE (sink->cur_buf) == size) {
     gst_buffer_unref (sink->cur_buf);
+    printf ("discard_data\n");
     sink->cur_buf = NULL;
   } else {
     sub = gst_buffer_create_sub (sink->cur_buf, size,
@@ -527,19 +539,20 @@ dxr3videosink_parse_data (Dxr3VideoSink * sink)
 
 
 static gboolean
-dxr3videosink_handle_event (GstPad * pad, GstEvent * event)
+dxr3videosink_handle_event (GstBaseSink * basesink, GstEvent * event)
 {
   GstEventType type;
   Dxr3VideoSink *sink;
 
-  sink = DXR3VIDEOSINK (gst_pad_get_parent (pad));
+  sink = DXR3VIDEOSINK (basesink);
 
   type = event ? GST_EVENT_TYPE (event) : GST_EVENT_UNKNOWN;
-
+  printf ("event %d\n", type);
   switch (type) {
-    case GST_EVENT_EMPTY:
+    case GST_EVENT_EOS:
       //fprintf (stderr, "++++++ Video empty event\n");
     {
+      printf ("eos\n");
       /* FIXME: Handle this with a discontinuity or something. */
       /* Write an MPEG2 sequence end code, to ensure that the card
          actually displays the last picture.  Apparently some DVDs are
@@ -553,15 +566,27 @@ dxr3videosink_handle_event (GstPad * pad, GstEvent * event)
       write (sink->video_fd, &sec, 4);
     }
       break;
+    case 102:
+    {
+      gint32 em_speed;
+      gint32 pts;
+      em_speed = 0x900LL;
+      ioctl (sink->control_fd, EM8300_IOCTL_SCR_GET, &pts);
+      printf ("pts %d\n", pts);
+      ioctl (sink->control_fd, EM8300_IOCTL_SCR_SETSPEED, &em_speed);
+    }
+      break;
 
-    case GST_EVENT_DISCONTINUOUS:
+    case GST_EVENT_SEEK:
       //fprintf (stderr, "++++++ Video discont event\n");
     {
+      printf ("seek\n");
       gint64 time;
       gboolean has_time;
       unsigned cur_scr, mpeg_scr, diff;
 
-      has_time = gst_event_discont_get_value (event, GST_FORMAT_TIME, &time);
+      has_time = TRUE;
+      time = GST_EVENT_TIMESTAMP (event);
       if (has_time) {
 /*         fprintf (stderr, "^^^^^^ Discontinuous event has time %.4f\n", */
 /*                  (double) time / GST_SECOND); */
@@ -585,12 +610,15 @@ dxr3videosink_handle_event (GstPad * pad, GstEvent * event)
     }
       break;
 
-    case GST_EVENT_FLUSH:
+    case GST_EVENT_FLUSH_START:
+    case GST_EVENT_FLUSH_STOP:
+      printf ("flush\n");
       dxr3videosink_reset_parser (sink);
       break;
 
     default:
-      gst_pad_event_default (pad, event);
+      printf ("default\n");
+//      gst_pad_event_default (pad, event);
       break;
   }
 
@@ -598,55 +626,44 @@ dxr3videosink_handle_event (GstPad * pad, GstEvent * event)
 }
 
 
-static void
-dxr3videosink_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+dxr3videosink_render (GstBaseSink * basesink, GstBuffer * _data)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
+  GstBuffer *buf;
   Dxr3VideoSink *sink;
   GstBuffer *merged;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
+  buf = GST_BUFFER (_data);
 
-  sink = DXR3VIDEOSINK (gst_pad_get_parent (pad));
-
-  if (GST_IS_EVENT (buf)) {
-    dxr3videosink_handle_event (pad, GST_EVENT (buf));
-    return;
-  }
+  g_return_val_if_fail (basesink != NULL, GST_FLOW_CUSTOM_ERROR);
+  g_return_val_if_fail (buf != NULL, GST_FLOW_CUSTOM_ERROR);
 
-/*   fprintf (stderr, "^^^^^^ Video block\n"); */
+  sink = DXR3VIDEOSINK (basesink);
 
   if (sink->cur_buf == NULL) {
-    sink->cur_buf = buf;
-  } else {
-    merged = gst_buffer_merge (sink->cur_buf, buf);
-    gst_buffer_unref (sink->cur_buf);
-    gst_buffer_unref (buf);
-    sink->cur_buf = merged;
+    sink->cur_buf = gst_buffer_new_and_alloc (0);
+    printf ("^^^^^^ Video block\n");
   }
 
+  merged = gst_buffer_merge (sink->cur_buf, buf);
+  gst_buffer_unref (sink->cur_buf);
+  sink->cur_buf = merged;
+
   sink->last_ts = GST_BUFFER_TIMESTAMP (buf);
 
   dxr3videosink_parse_data (sink);
+  return GST_FLOW_OK;
 }
 
 
 static GstStateChangeReturn
 dxr3videosink_change_state (GstElement * element, GstStateChange transition)
 {
+  printf ("change state %d\n", transition);
   g_return_val_if_fail (GST_IS_DXR3VIDEOSINK (element),
       GST_STATE_CHANGE_FAILURE);
 
   switch (transition) {
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      if (!GST_OBJECT_FLAG_IS_SET (element, DXR3VIDEOSINK_OPEN)) {
-        if (!dxr3videosink_open (DXR3VIDEOSINK (element))) {
-          return GST_STATE_CHANGE_FAILURE;
-        }
-      }
-      break;
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       dxr3videosink_mvcommand (DXR3VIDEOSINK (element), MVCOMMAND_PAUSE);
       break;
@@ -659,10 +676,7 @@ dxr3videosink_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       dxr3videosink_mvcommand (DXR3VIDEOSINK (element), MVCOMMAND_STOP);
       break;
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      if (GST_OBJECT_FLAG_IS_SET (element, DXR3VIDEOSINK_OPEN)) {
-        dxr3videosink_close (DXR3VIDEOSINK (element));
-      }
+    default:
       break;
   }
 
diff --git a/sys/dxr3/dxr3videosink.h b/sys/dxr3/dxr3videosink.h
index f63a824..d76f4cd 100644
--- a/sys/dxr3/dxr3videosink.h
+++ b/sys/dxr3/dxr3videosink.h
@@ -22,7 +22,10 @@
 #ifndef __DXR3VIDEOSINK_H__
 #define __DXR3VIDEOSINK_H__
 
+#include <stdio.h>
+
 #include <gst/gst.h>
+#include <gst/base/gstbasesink.h>
 
 G_BEGIN_DECLS
 
@@ -50,7 +53,7 @@ typedef enum {
 
 
 struct _Dxr3VideoSink {
-  GstElement element;
+  GstBaseSink parent;
 
   int card_number;              /* The number of the card to open. */
 
@@ -82,7 +85,7 @@ struct _Dxr3VideoSink {
 
 
 struct _Dxr3VideoSinkClass {
-  GstElementClass parent_class;
+  GstBaseSinkClass parent_class;
 
   /* signals */
   void (*flushed) (Dxr3VideoSink *sink);
