Merge branch 'master' of ssh://uraeus@git.freedesktop.org/git/gstreamer/gst-plugins-bad
diff --git a/configure.ac b/configure.ac
index 06e5758..438b2cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -124,7 +124,6 @@
 AC_CHECK_LIBM
 AC_SUBST(LIBM)
 
-dnl needed for gst/xdgmime
 AC_FUNC_MMAP
 
 dnl *** checks for header files ***
@@ -298,7 +297,6 @@
 AG_GST_CHECK_PLUGIN(valve)
 AG_GST_CHECK_PLUGIN(videosignal)
 AG_GST_CHECK_PLUGIN(vmnc)
-AG_GST_CHECK_PLUGIN(xdgmime)
 
 dnl *** plug-ins to exclude ***
 
@@ -312,7 +310,6 @@
 #if test "x$BUILD_EXPERIMENTAL" != "xyes"; then
 #fi
 
-# For xdgmime, to use g_content_type_guess()
 # This will always succeed because we depend on GLib >= 2.16
 PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.16, HAVE_GIO=yes, HAVE_GIO=no)
 AC_SUBST(GIO_CFLAGS)
@@ -1749,7 +1746,6 @@
 gst/valve/Makefile
 gst/videosignal/Makefile
 gst/vmnc/Makefile
-gst/xdgmime/Makefile
 gst-libs/Makefile
 gst-libs/gst/Makefile
 gst-libs/gst/interfaces/Makefile
diff --git a/docs/plugins/inspect/plugin-xdgmime.xml b/docs/plugins/inspect/plugin-xdgmime.xml
deleted file mode 100644
index aecd94d..0000000
--- a/docs/plugins/inspect/plugin-xdgmime.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<plugin>
-  <name>xdgmime</name>
-  <description>XDG-MIME</description>
-  <filename>../../gst/xdgmime/.libs/libgstxdgmime.so</filename>
-  <basename>libgstxdgmime.so</basename>
-  <version>0.10.14.1</version>
-  <license>LGPL</license>
-  <source>gst-plugins-bad</source>
-  <package>GStreamer Bad Plug-ins git/prerelease</package>
-  <origin>Unknown package origin</origin>
-  <elements>
-
-  </elements>
-</plugin>
\ No newline at end of file
diff --git a/ext/neon/gstneonhttpsrc.c b/ext/neon/gstneonhttpsrc.c
index 1af733d..cceb268 100644
--- a/ext/neon/gstneonhttpsrc.c
+++ b/ext/neon/gstneonhttpsrc.c
@@ -27,12 +27,14 @@
 
 #include <ne_redirect.h>
 
+#define STATUS_IS_REDIRECTION(status)     ((status) >= 300 && (status) < 400)
+
 GST_DEBUG_CATEGORY_STATIC (neonhttpsrc_debug);
 #define GST_CAT_DEFAULT neonhttpsrc_debug
 
 #define MAX_READ_SIZE (4 * 1024)
 
-/* max number of HTTP redirects, when iterating over a sequence of HTTP 302/303 status code */
+/* max number of HTTP redirects, when iterating over a sequence of HTTP 3xx status code */
 #define MAX_HTTP_REDIRECTS_NUMBER 5
 
 static const GstElementDetails gst_neonhttp_src_details =
@@ -199,7 +201,7 @@
   g_object_class_install_property
       (gobject_class, PROP_AUTOMATIC_REDIRECT,
       g_param_spec_boolean ("automatic-redirect", "automatic-redirect",
-          "Automatically follow HTTP redirects (HTTP Status Code 302/303)",
+          "Automatically follow HTTP redirects (HTTP Status Code 3xx)",
           TRUE, G_PARAM_READWRITE));
 
   g_object_class_install_property
@@ -816,7 +818,7 @@
 }
 
 /* Try to send the HTTP request to the Icecast server, and if possible deals with
- * all the probable redirections (HTTP status code == 302/303)
+ * all the probable redirections (HTTP status code == 3xx)
  */
 static gint
 gst_neonhttp_src_send_request_and_redirect (GstNeonhttpSrc * src,
@@ -862,10 +864,10 @@
     res = ne_begin_request (request);
 
     if (res == NE_OK) {
-      /* When the HTTP status code is 302/303, it is not the SHOUTcast streaming content yet;
+      /* When the HTTP status code is 3xx, it is not the SHOUTcast streaming content yet;
        * Reload the HTTP request with a new URI value */
       http_status = ne_get_status (request)->code;
-      if ((http_status == 302 || http_status == 303) && do_redir) {
+      if (STATUS_IS_REDIRECTION (http_status) && do_redir) {
         const gchar *redir;
 
         /* the new URI value to go when redirecting can be found on the 'Location' HTTP header */
@@ -881,21 +883,21 @@
 
     if ((res != NE_OK) ||
         (offset == 0 && http_status != 200) ||
-        (offset > 0 && http_status != 206 && http_status != 302
-            && http_status != 303)) {
+        (offset > 0 && http_status != 206 &&
+            !STATUS_IS_REDIRECTION (http_status))) {
       ne_request_destroy (request);
       request = NULL;
       ne_close_connection (session);
       ne_session_destroy (session);
       session = NULL;
-      if (offset > 0 && http_status != 206 && http_status != 302
-          && http_status != 303) {
+      if (offset > 0 && http_status != 206 &&
+          !STATUS_IS_REDIRECTION (http_status)) {
         src->seekable = FALSE;
       }
     }
 
     /* if - NE_OK */
-    if ((http_status == 302 || http_status == 303) && do_redir) {
+    if (STATUS_IS_REDIRECTION (http_status) && do_redir) {
       ++request_count;
       GST_LOG_OBJECT (src, "redirect request_count is now %d", request_count);
       if (request_count < MAX_HTTP_REDIRECTS_NUMBER && do_redir) {
@@ -909,7 +911,7 @@
     }
     /* do the redirect, go back to send another HTTP request now using the 'Location' */
   } while (do_redir && (request_count < MAX_HTTP_REDIRECTS_NUMBER)
-      && (http_status == 302 || http_status == 303));
+      && STATUS_IS_REDIRECTION (http_status));
 
   if (session) {
     *ses = session;
diff --git a/gst-plugins-bad.spec.in b/gst-plugins-bad.spec.in
index f2f9109..b57186f 100644
--- a/gst-plugins-bad.spec.in
+++ b/gst-plugins-bad.spec.in
@@ -121,7 +121,6 @@
 %{_libdir}/gstreamer-%{majorminor}/libgstliveadder.so
 %{_libdir}/gstreamer-%{majorminor}/libgstrtpmux.so
 %{_libdir}/gstreamer-%{majorminor}/libgstsiren.so
-%{_libdir}/gstreamer-%{majorminor}/libgstxdgmime.so
 %{_libdir}/gstreamer-%{majorminor}/libgstadpcmdec.so
 %{_libdir}/gstreamer-%{majorminor}/libgstid3tag.so
 %{_libdir}/gstreamer-%{majorminor}/libgsthdvparse.so
diff --git a/gst/dvdspu/gstspu-vobsub-render.c b/gst/dvdspu/gstspu-vobsub-render.c
index 3709d82..30de0eb 100644
--- a/gst/dvdspu/gstspu-vobsub-render.c
+++ b/gst/dvdspu/gstspu-vobsub-render.c
@@ -172,7 +172,7 @@
       x++;
     }
     /* Update the compositing buffer so we know how much to blend later */
-    *(state->vobsub.comp_last_x_ptr) = end;
+    *(state->vobsub.comp_last_x_ptr) = end - 1; /* end is the start of the *next* run */
   }
 }
 
@@ -194,7 +194,7 @@
 gstspu_vobsub_render_line (SpuState * state, guint8 * planes[3],
     guint16 * rle_offset)
 {
-  gint16 x, next_x, end, rle_code;
+  gint16 x, next_x, end, rle_code, next_draw_x;
   SpuColour *colour;
 
   /* Check for special case of chg_col info to use (either highlight or
@@ -226,8 +226,11 @@
     rle_code = gstspu_vobsub_get_rle_code (state, rle_offset);
     colour = &state->vobsub.main_pal[rle_code & 3];
     next_x = rle_end_x (rle_code, x, end);
+    next_draw_x = next_x;
+    if (next_draw_x > state->vobsub.clip_rect.right)
+      next_draw_x = state->vobsub.clip_rect.right;      /* ensure no overflow */
     /* Now draw the run between [x,next_x) */
-    gstspu_vobsub_draw_rle_run (state, x, next_x, colour);
+    gstspu_vobsub_draw_rle_run (state, x, next_draw_x, colour);
     x = next_x;
   }
 }
@@ -265,7 +268,7 @@
 {
   SpuVobsubLineCtrlI *chg_col = state->vobsub.cur_chg_col;
 
-  gint16 x, next_x, disp_end, rle_code, run_end;
+  gint16 x, next_x, disp_end, rle_code, run_end, run_draw_end;
   SpuColour *colour;
   SpuVobsubPixCtrlI *cur_pix_ctrl;
   SpuVobsubPixCtrlI *next_pix_ctrl;
@@ -313,9 +316,13 @@
     while (x < next_x) {
       run_end = MIN (next_x, cur_reg_end);
 
+      run_draw_end = run_end;
+      if (run_draw_end > state->vobsub.clip_rect.right)
+        run_draw_end = state->vobsub.clip_rect.right;   /* ensure no overflow */
+
       if (G_LIKELY (x < run_end)) {
         colour = &cur_pix_ctrl->pal_cache[rle_code & 3];
-        gstspu_vobsub_draw_rle_run (state, x, run_end, colour);
+        gstspu_vobsub_draw_rle_run (state, x, run_draw_end, colour);
         x = run_end;
       }
 
@@ -340,14 +347,17 @@
   state->comp_right =
       MAX (state->vobsub.comp_last_x[0], state->vobsub.comp_last_x[1]);
 
+  state->comp_left = MAX (state->comp_left, state->vobsub.clip_rect.left);
+  state->comp_right = MIN (state->comp_right, state->vobsub.clip_rect.right);
+
   gstspu_blend_comp_buffers (state, planes);
 }
 
 static void
 gstspu_vobsub_clear_comp_buffers (SpuState * state)
 {
-  state->comp_left = state->vobsub.disp_rect.left;
-  state->comp_right = state->vobsub.disp_rect.right;
+  state->comp_left = state->vobsub.clip_rect.left;
+  state->comp_right = state->vobsub.clip_rect.right;
 
   gstspu_clear_comp_buffers (state);
 
@@ -375,13 +385,15 @@
   g_return_if_fail (planes[2] + (state->UV_height * state->UV_stride) <=
       GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf));
 
-  GST_DEBUG ("Rendering SPU. disp_rect %d,%d to %d,%d. hl_rect %d,%d to %d,%d",
+  GST_DEBUG_OBJECT (dvdspu,
+      "Rendering SPU. disp_rect %d,%d to %d,%d. hl_rect %d,%d to %d,%d",
       state->vobsub.disp_rect.left, state->vobsub.disp_rect.top,
       state->vobsub.disp_rect.right, state->vobsub.disp_rect.bottom,
       state->vobsub.hl_rect.left, state->vobsub.hl_rect.top,
       state->vobsub.hl_rect.right, state->vobsub.hl_rect.bottom);
 
-  GST_DEBUG ("vid_disp %d,%d", state->vid_width, state->vid_height);
+  GST_DEBUG_OBJECT (dvdspu, "video size %d,%d", state->vid_width,
+      state->vid_height);
 
   /* When reading RLE data, we track the offset in nibbles... */
   state->vobsub.cur_offsets[0] = state->vobsub.pix_data[0] * 2;
@@ -402,6 +414,74 @@
   } else
     state->vobsub.cur_chg_col = NULL;
 
+  state->vobsub.clip_rect.left = state->vobsub.disp_rect.left;
+  state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;
+
+  /* center the image when display rectangle exceeds the video width */
+  if (state->vid_width <= state->vobsub.disp_rect.right) {
+    gint left, disp_width;
+
+    disp_width = state->vobsub.disp_rect.right - state->vobsub.disp_rect.left
+        + 1;
+    left = (state->vid_width - disp_width) / 2;
+    state->vobsub.disp_rect.left = left;
+    state->vobsub.disp_rect.right = left + disp_width - 1;
+
+    /* if it clips to the right, shift it left, but only till zero */
+    if (state->vobsub.disp_rect.right >= state->vid_width) {
+      gint shift = state->vobsub.disp_rect.right - state->vid_width - 1;
+      if (shift > state->vobsub.disp_rect.left)
+        shift = state->vobsub.disp_rect.left;
+      state->vobsub.disp_rect.left -= shift;
+      state->vobsub.disp_rect.right -= shift;
+    }
+
+    /* init clip to disp */
+    state->vobsub.clip_rect.left = state->vobsub.disp_rect.left;
+    state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;
+
+    /* clip right after the shift */
+    if (state->vobsub.clip_rect.right >= state->vid_width)
+      state->vobsub.clip_rect.right = state->vid_width - 1;
+
+    GST_DEBUG_OBJECT (dvdspu,
+        "clipping width to %d,%d", state->vobsub.clip_rect.left,
+        state->vobsub.clip_rect.right);
+  }
+
+  /* for the height, bring it up till it fits as well as it can. We
+   * assume the picture is in the lower part. We should better check where it
+   * is and do something more clever. */
+  state->vobsub.clip_rect.top = state->vobsub.disp_rect.top;
+  state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;
+  if (state->vid_height <= state->vobsub.disp_rect.bottom) {
+
+    /* shift it up, but only till zero */
+    gint shift = state->vobsub.disp_rect.bottom - state->vid_height - 1;
+    if (shift > state->vobsub.disp_rect.top)
+      shift = state->vobsub.disp_rect.top;
+    state->vobsub.disp_rect.top -= shift;
+    state->vobsub.disp_rect.bottom -= shift;
+
+    /* start on even line */
+    if (state->vobsub.disp_rect.top & 1) {
+      state->vobsub.disp_rect.top--;
+      state->vobsub.disp_rect.bottom--;
+    }
+
+    /* init clip to disp */
+    state->vobsub.clip_rect.top = state->vobsub.disp_rect.top;
+    state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;
+
+    /* clip right after the shift */
+    if (state->vobsub.clip_rect.bottom >= state->vid_height)
+      state->vobsub.clip_rect.bottom = state->vid_height - 1;
+
+    GST_DEBUG_OBJECT (dvdspu,
+        "clipping height to %d,%d", state->vobsub.clip_rect.top,
+        state->vobsub.clip_rect.bottom);
+  }
+
   /* We start rendering from the first line of the display rect */
   y = state->vobsub.disp_rect.top;
   /* start_y is always an even number and we render lines in pairs from there,
@@ -409,40 +489,10 @@
    * single line at the end if the display rect ends on an even line too. */
   last_y = (state->vobsub.disp_rect.bottom - 1) & ~(0x01);
 
-  /* center the image when display rectangle exceeds the video width */
-  if (state->vid_width < state->vobsub.disp_rect.right) {
-    gint diff, disp_width;
-
-    disp_width = state->vobsub.disp_rect.left - state->vobsub.disp_rect.right;
-    diff = (disp_width - state->vid_width) / 2;
-
-    /* fixme, this is not used yet */
-    state->vobsub.clip_rect.left = state->vobsub.disp_rect.left + diff;
-    state->vobsub.clip_rect.right = state->vobsub.disp_rect.right - diff;
-
-    GST_DEBUG ("clipping width to %d,%d", state->vobsub.clip_rect.left,
-        state->vobsub.clip_rect.right);
-  } else {
-    state->vobsub.clip_rect.left = state->vobsub.disp_rect.left;
-    state->vobsub.clip_rect.right = state->vobsub.disp_rect.right;
-  }
-
-  /* for the height, chop off the bottom bits of the diplay rectangle because we
-   * assume the picture is in the lower part. We should better check where it
-   * is and do something more clever. */
-  state->vobsub.clip_rect.bottom = state->vobsub.disp_rect.bottom;
-  if (state->vid_height < state->vobsub.disp_rect.bottom) {
-    state->vobsub.clip_rect.top =
-        state->vobsub.disp_rect.bottom - state->vid_height;
-    GST_DEBUG ("clipping height to %d,%d", state->vobsub.clip_rect.top,
-        state->vobsub.clip_rect.bottom);
-  } else {
-    state->vobsub.clip_rect.top = state->vobsub.disp_rect.top;
-    /* Update our plane references to the first line of the disp_rect */
-    planes[0] += state->Y_stride * y;
-    planes[1] += state->UV_stride * (y / 2);
-    planes[2] += state->UV_stride * (y / 2);
-  }
+  /* Update our plane references to the first line of the disp_rect */
+  planes[0] += state->Y_stride * y;
+  planes[1] += state->UV_stride * (y / 2);
+  planes[2] += state->UV_stride * (y / 2);
 
   for (state->vobsub.cur_Y = y; state->vobsub.cur_Y <= last_y;
       state->vobsub.cur_Y++) {
@@ -476,14 +526,21 @@
     }
   }
   if (state->vobsub.cur_Y == state->vobsub.disp_rect.bottom) {
+    gboolean clip;
+
+    clip = (state->vobsub.cur_Y < state->vobsub.clip_rect.top
+        || state->vobsub.cur_Y > state->vobsub.clip_rect.bottom);
+
     g_assert ((state->vobsub.disp_rect.bottom & 0x01) == 0);
 
-    /* Render a remaining lone last even line. y already has the correct value
-     * after the above loop exited. */
-    gstspu_vobsub_clear_comp_buffers (state);
-    state->vobsub.comp_last_x_ptr = state->vobsub.comp_last_x;
-    gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[0]);
-    gstspu_vobsub_blend_comp_buffers (state, planes);
+    if (!clip) {
+      /* Render a remaining lone last even line. y already has the correct value
+       * after the above loop exited. */
+      gstspu_vobsub_clear_comp_buffers (state);
+      state->vobsub.comp_last_x_ptr = state->vobsub.comp_last_x;
+      gstspu_vobsub_render_line (state, planes, &state->vobsub.cur_offsets[0]);
+      gstspu_vobsub_blend_comp_buffers (state, planes);
+    }
   }
 
   /* for debugging purposes, draw a faint rectangle at the edges of the disp_rect */
diff --git a/gst/mpegdemux/gstmpegdefs.h b/gst/mpegdemux/gstmpegdefs.h
index 4055113..ef2bd46 100644
--- a/gst/mpegdemux/gstmpegdefs.h
+++ b/gst/mpegdemux/gstmpegdefs.h
@@ -178,14 +178,15 @@
 #define ST_BD_AUDIO_AC3_TRUE_HD         0x83
 #define ST_BD_AUDIO_AC3_PLUS            0x84
 #define ST_BD_AUDIO_DTS_HD              0x85
+#define ST_BD_AUDIO_EAC3                0x87
 #define ST_BD_PGS_SUBPICTURE            0x90
 #define ST_BD_IGS                       0x91
 #define ST_BD_SUBTITLE                  0x92
 #define ST_BD_SECONDARY_AC3_PLUS        0xa1
 #define ST_BD_SECONDARY_DTS_HD          0xa2
 
-/* VC1 extension */
-#define ST_VIDEO_VC1                    0xea
+/* defined for VC1 extension in RP227 */
+#define ST_PRIVATE_EA                   0xea
 
 /* HDV AUX stream mapping
  * 0xA0      ISO/IEC 61834-11
diff --git a/gst/mpegdemux/gstmpegdemux.c b/gst/mpegdemux/gstmpegdemux.c
index 5fe2771..e4be205 100644
--- a/gst/mpegdemux/gstmpegdemux.c
+++ b/gst/mpegdemux/gstmpegdemux.c
@@ -1037,6 +1037,12 @@
   guint64 scr_rate_n = demux->last_scr_offset - demux->first_scr_offset;
   guint64 scr_rate_d = demux->last_scr - demux->first_scr;
 
+  /* In some clips the PTS values are completely unaligned with SCR values.
+   * To improve the seek in that situation we apply a factor considering the
+   * relationship between last PTS and last SCR */
+  if (demux->last_scr > demux->last_pts)
+    scr = gst_util_uint64_scale (scr, demux->last_scr, demux->last_pts);
+
   scr = MIN (demux->last_scr, scr);
   scr = MAX (demux->first_scr, scr);
   fscr = scr;
diff --git a/gst/mpegdemux/gstmpegdesc.h b/gst/mpegdemux/gstmpegdesc.h
index 71b74aa..09a9a7c 100644
--- a/gst/mpegdemux/gstmpegdesc.h
+++ b/gst/mpegdemux/gstmpegdesc.h
@@ -319,6 +319,10 @@
 /* DVB Carousel Identifier Descriptor */
 #define DESC_DVB_CAROUSEL_IDENTIFIER_carousel_id(desc)		(GST_READ_UINT32_BE((desc) + 2))
 
+/* registration_descriptor format IDs */
+#define DRF_ID_HDMV       0x48444d56
+#define DRF_ID_VC1        0x56432D31   /* defined in RP227 */
+
 typedef struct {
   guint    n_desc;
   guint8   data_length;
diff --git a/gst/mpegdemux/gstmpegtsdemux.c b/gst/mpegdemux/gstmpegtsdemux.c
index 2ab639b..e7226f0 100644
--- a/gst/mpegdemux/gstmpegtsdemux.c
+++ b/gst/mpegdemux/gstmpegtsdemux.c
@@ -103,7 +103,6 @@
   PROP_PROGRAM_NUMBER,
   PROP_PAT_INFO,
   PROP_PMT_INFO,
-  PROP_M2TS
 };
 
 #define GSTTIME_TO_BYTES(time) \
@@ -138,7 +137,7 @@
       "mute = (boolean) { FALSE, TRUE }; " \
     "audio/x-ac3; audio/x-eac3;" \
     "audio/x-dts;" \
-    "audio/x-private1-lpcm" \
+    "audio/x-private-ts-lpcm" \
   )
 
 /* Can also use the subpicture pads for text subtitles? */
@@ -206,6 +205,9 @@
 
 static GstElementClass *parent_class = NULL;
 
+static FORCE_INLINE GstMpegTSStream
+    * gst_mpegts_demux_get_stream_for_PID (GstMpegTSDemux * demux, guint16 PID);
+
 /*static guint gst_mpegts_demux_signals[LAST_SIGNAL] = { 0 };*/
 
 GType
@@ -304,11 +306,6 @@
           "about the currently selected program and its streams",
           MPEGTS_TYPE_PMT_INFO, G_PARAM_READABLE));
 
-  g_object_class_install_property (gobject_class, PROP_M2TS,
-      g_param_spec_boolean ("m2ts_mode", "M2TS(192 bytes) Mode",
-          "Defines if the input is normal TS ie .ts(188 bytes)"
-          "or Blue-Ray Format ie .m2ts(192 bytes).", FALSE, G_PARAM_READWRITE));
-
   gstelement_class->change_state = gst_mpegts_demux_change_state;
   gstelement_class->provide_clock = gst_mpegts_demux_provide_clock;
 }
@@ -330,8 +327,6 @@
   demux->nb_elementary_pids = 0;
   demux->check_crc = DEFAULT_PROP_CHECK_CRC;
   demux->program_number = DEFAULT_PROP_PROGRAM_NUMBER;
-  demux->packetsize = MPEGTS_NORMAL_TS_PACKETSIZE;
-  demux->m2ts_mode = FALSE;
   demux->sync_lut = NULL;
   demux->sync_lut_len = 0;
   demux->bitrate = -1;
@@ -484,34 +479,18 @@
 gst_mpegts_demux_sink_setcaps (GstPad * pad, GstCaps * caps)
 {
   GstMpegTSDemux *demux = GST_MPEGTS_DEMUX (gst_pad_get_parent (pad));
-  gboolean ret = FALSE;
   GstStructure *structure = NULL;
-  gint expected_packetsize =
-      (demux->m2ts_mode ? MPEGTS_M2TS_TS_PACKETSIZE :
-      MPEGTS_NORMAL_TS_PACKETSIZE);
-  gint packetsize = expected_packetsize;
 
   structure = gst_caps_get_structure (caps, 0);
 
   GST_DEBUG_OBJECT (demux, "setcaps called with %" GST_PTR_FORMAT, caps);
 
-  if (!gst_structure_get_int (structure, "packetsize", &packetsize)) {
+  if (!gst_structure_get_int (structure, "packetsize", &demux->packetsize)) {
     GST_DEBUG_OBJECT (demux, "packetsize parameter not found in sink caps");
   }
 
-  if (packetsize < expected_packetsize) {
-    GST_WARNING_OBJECT (demux, "packetsize = %" G_GINT32_FORMAT "is less then"
-        "expected packetsize of %d bytes", packetsize, expected_packetsize);
-    goto beach;
-  }
-
-  /* here we my have a correct value for packet size */
-  demux->packetsize = packetsize;
-  ret = TRUE;
-
-beach:
   gst_object_unref (demux);
-  return ret;
+  return TRUE;
 }
 
 static FORCE_INLINE guint32
@@ -563,7 +542,6 @@
     case ST_VIDEO_MPEG2:
     case ST_VIDEO_MPEG4:
     case ST_VIDEO_H264:
-    case ST_VIDEO_VC1:
       return TRUE;
     case ST_VIDEO_DIRAC:
       return gst_mpegts_is_dirac_stream (stream);
@@ -660,7 +638,16 @@
         caps = gst_caps_new_simple ("video/x-dirac", NULL);
       }
       break;
-    case ST_VIDEO_VC1:
+    case ST_PRIVATE_EA:        /* Try to detect a VC1 stream */
+    {
+      guint8 *desc = NULL;
+
+      if (stream->ES_info)
+        desc = gst_mpeg_descriptor_find (stream->ES_info, DESC_REGISTRATION);
+      if (!(desc && DESC_REGISTRATION_format_identifier (desc) == DRF_ID_VC1)) {
+        GST_WARNING ("0xea private stream type found but no descriptor "
+            "for VC1. Assuming plain VC1.");
+      }
       template = klass->video_template;
       name = g_strdup_printf ("video_%04x", stream->PID);
       caps = gst_caps_new_simple ("video/x-wmv",
@@ -668,10 +655,42 @@
           "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('W', 'V', 'C', '1'),
           NULL);
       break;
+    }
     case ST_BD_AUDIO_AC3:
+    {
+      GstMpegTSStream *PMT_stream =
+          gst_mpegts_demux_get_stream_for_PID (stream->demux, stream->PMT_pid);
+      GstMPEGDescriptor *program_info = PMT_stream->PMT.program_info;
+      guint8 *desc = NULL;
+
+      if (program_info)
+        desc = gst_mpeg_descriptor_find (program_info, DESC_REGISTRATION);
+
+      if (desc && DESC_REGISTRATION_format_identifier (desc) == DRF_ID_HDMV) {
+        template = klass->audio_template;
+        name = g_strdup_printf ("audio_%04x", stream->PID);
+        caps = gst_caps_new_simple ("audio/x-eac3", NULL);
+      } else if (gst_mpeg_descriptor_find (stream->ES_info,
+              DESC_DVB_ENHANCED_AC3)) {
+        template = klass->audio_template;
+        name = g_strdup_printf ("audio_%04x", stream->PID);
+        caps = gst_caps_new_simple ("audio/x-eac3", NULL);
+      } else {
+        if (!gst_mpeg_descriptor_find (stream->ES_info, DESC_DVB_AC3)) {
+          GST_WARNING ("AC3 stream type found but no corresponding "
+              "descriptor to differentiate between AC3 and EAC3. "
+              "Assuming plain AC3.");
+        }
+        template = klass->audio_template;
+        name = g_strdup_printf ("audio_%04x", stream->PID);
+        caps = gst_caps_new_simple ("audio/x-ac3", NULL);
+      }
+      break;
+    }
+    case ST_BD_AUDIO_EAC3:
       template = klass->audio_template;
       name = g_strdup_printf ("audio_%04x", stream->PID);
-      caps = gst_caps_new_simple ("audio/x-ac3", NULL);
+      caps = gst_caps_new_simple ("audio/x-eac3", NULL);
       break;
     case ST_PS_AUDIO_DTS:
       template = klass->audio_template;
@@ -686,7 +705,7 @@
     case ST_BD_AUDIO_LPCM:
       template = klass->audio_template;
       name = g_strdup_printf ("audio_%04x", stream->PID);
-      caps = gst_caps_new_simple ("audio/x-private1-lpcm", NULL);
+      caps = gst_caps_new_simple ("audio/x-private-ts-lpcm", NULL);
       break;
     case ST_PS_DVD_SUBPICTURE:
       template = klass->subpicture_template;
@@ -2833,7 +2852,6 @@
   return res;
 }
 
-
 static FORCE_INLINE gint
 is_mpegts_sync (const guint8 * in_data, const guint8 * end_data,
     guint packetsize)
@@ -2859,6 +2877,26 @@
   return ret;
 }
 
+static inline void
+gst_mpegts_demux_detect_packet_size (GstMpegTSDemux * demux, guint len)
+{
+  guint i, packetsize;
+
+  for (i = 1; i < len; i++) {
+    packetsize = demux->sync_lut[i] - demux->sync_lut[i - 1];
+    if (packetsize == MPEGTS_NORMAL_TS_PACKETSIZE ||
+        packetsize == MPEGTS_M2TS_TS_PACKETSIZE ||
+        packetsize == MPEGTS_DVB_ASI_TS_PACKETSIZE ||
+        packetsize == MPEGTS_ATSC_TS_PACKETSIZE)
+      goto done;
+    else
+      packetsize = 0;
+  }
+
+done:
+  demux->packetsize = (packetsize ? packetsize : MPEGTS_NORMAL_TS_PACKETSIZE);
+  GST_DEBUG_OBJECT (demux, "packet_size set to %d bytes", demux->packetsize);
+}
 
 static FORCE_INLINE guint
 gst_mpegts_demux_sync_scan (GstMpegTSDemux * demux, const guint8 * in_data,
@@ -2867,10 +2905,12 @@
   guint sync_count = 0;
   const guint8 *end_scan = in_data + size - demux->packetsize;
   guint8 *ptr_data = (guint8 *) in_data;
+  guint packetsize =
+      (demux->packetsize ? demux->packetsize : MPEGTS_NORMAL_TS_PACKETSIZE);
 
   /* Check if the LUT table is big enough */
-  if (G_UNLIKELY (demux->sync_lut_len < (size / MPEGTS_NORMAL_TS_PACKETSIZE))) {
-    demux->sync_lut_len = size / MPEGTS_NORMAL_TS_PACKETSIZE;
+  if (G_UNLIKELY (demux->sync_lut_len < (size / packetsize))) {
+    demux->sync_lut_len = size / packetsize;
     if (demux->sync_lut)
       g_free (demux->sync_lut);
     demux->sync_lut = g_new0 (guint8 *, demux->sync_lut_len);
@@ -2880,22 +2920,24 @@
 
   while (ptr_data <= end_scan && sync_count < demux->sync_lut_len) {
     /* if sync code is found try to store it in the LUT */
-    guint chance = is_mpegts_sync (ptr_data, end_scan, demux->packetsize);
+    guint chance = is_mpegts_sync (ptr_data, end_scan, packetsize);
     if (G_LIKELY (chance > 50)) {
       /* skip paketsize bytes and try find next */
-      guint8 *next_sync = ptr_data + demux->packetsize;
+      guint8 *next_sync = ptr_data + packetsize;
       if (next_sync < end_scan) {
         demux->sync_lut[sync_count] = ptr_data;
         sync_count++;
-        ptr_data += demux->packetsize;
+        ptr_data += packetsize;
       } else
         goto done;
-
     } else {
       ptr_data++;
     }
   }
 done:
+  if (G_UNLIKELY (!demux->packetsize))
+    gst_mpegts_demux_detect_packet_size (demux, sync_count);
+
   *flush = ptr_data - in_data;
 
   return sync_count;
@@ -3105,9 +3147,6 @@
     case PROP_PROGRAM_NUMBER:
       demux->program_number = g_value_get_int (value);
       break;
-    case PROP_M2TS:
-      demux->m2ts_mode = g_value_get_boolean (value);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3158,9 +3197,6 @@
       }
       break;
     }
-    case PROP_M2TS:
-      g_value_set_boolean (value, demux->m2ts_mode);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
diff --git a/gst/mpegdemux/gstmpegtsdemux.h b/gst/mpegdemux/gstmpegtsdemux.h
index fde6892..693ece1 100644
--- a/gst/mpegdemux/gstmpegtsdemux.h
+++ b/gst/mpegdemux/gstmpegtsdemux.h
@@ -59,6 +59,8 @@
 #define MPEGTS_MAX_PID 0x1fff
 #define MPEGTS_NORMAL_TS_PACKETSIZE  188
 #define MPEGTS_M2TS_TS_PACKETSIZE    192
+#define MPEGTS_DVB_ASI_TS_PACKETSIZE 204
+#define MPEGTS_ATSC_TS_PACKETSIZE    208
 
 #define IS_MPEGTS_SYNC(data) (((data)[0] == 0x47) && \
                                     (((data)[1] & 0x80) == 0x00) && \
@@ -200,7 +202,7 @@
   /* indicates that we need to close our pad group, because we've added
    * at least one pad */
   gboolean          need_no_more_pads;
-  guint16           packetsize;
+  gint              packetsize;
   gboolean          m2ts_mode;
   /* clocking */
   GstClock          * clock;
diff --git a/gst/mpegpsmux/mpegpsmux.c b/gst/mpegpsmux/mpegpsmux.c
index da31f28..59c19aa 100644
--- a/gst/mpegpsmux/mpegpsmux.c
+++ b/gst/mpegpsmux/mpegpsmux.c
@@ -484,14 +484,13 @@
   if (best != NULL) {
     /* @*buf : the buffer to be processed */
     GstBuffer *buf = best->queued_buf;
-    GstCollectData *c_data = (GstCollectData *) best;
     gint64 pts = -1;
 
     g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
 
     GST_DEBUG_OBJECT (mux,
         "Chose stream from pad %" GST_PTR_FORMAT " for output (PID: 0x%04x)",
-        c_data->pad, best->stream_id);
+        best->collect.pad, best->stream_id);
 
     /* set timestamp */
     if (GST_CLOCK_TIME_IS_VALID (best->cur_ts)) {
diff --git a/gst/mpegtsmux/mpegtsmux.c b/gst/mpegtsmux/mpegtsmux.c
index 4ad22e7..d0d02fa 100644
--- a/gst/mpegtsmux/mpegtsmux.c
+++ b/gst/mpegtsmux/mpegtsmux.c
@@ -630,11 +630,10 @@
 
     if (G_UNLIKELY (prog->pcr_stream == NULL)) {
       if (best) {
-        MpegTsPadData *ts_data = (MpegTsPadData *) best;
         /* Take the first data stream for the PCR */
         GST_DEBUG_OBJECT (COLLECT_DATA_PAD (best),
             "Use stream (pid=%d) from pad as PCR for program (prog_id = %d)",
-            ts_data->pid, ts_data->prog_id);
+            MPEG_TS_PAD_DATA (best)->pid, MPEG_TS_PAD_DATA (best)->prog_id);
 
         /* Set the chosen PCR stream */
         tsmux_program_set_pcr_stream (prog, best->stream);
diff --git a/gst/mpegtsmux/mpegtsmux.h b/gst/mpegtsmux/mpegtsmux.h
index 2ebb725..81668ba 100644
--- a/gst/mpegtsmux/mpegtsmux.h
+++ b/gst/mpegtsmux/mpegtsmux.h
@@ -126,6 +126,8 @@
   GstElementClass parent_class;
 };
 
+#define MPEG_TS_PAD_DATA(data)  ((MpegTsPadData *)(data))
+
 struct MpegTsPadData {
   GstCollectData collect; /* Parent */
 
diff --git a/gst/pcapparse/gstpcapparse.c b/gst/pcapparse/gstpcapparse.c
index 546ffbe..6e20212 100644
--- a/gst/pcapparse/gstpcapparse.c
+++ b/gst/pcapparse/gstpcapparse.c
@@ -87,6 +87,7 @@
 static void gst_pcap_parse_reset (GstPcapParse * self);
 
 static GstFlowReturn gst_pcap_parse_chain (GstPad * pad, GstBuffer * buffer);
+static gboolean gst_pcap_sink_event (GstPad * pad, GstEvent * event);
 
 GST_BOILERPLATE (GstPcapParse, gst_pcap_parse, GstElement, GST_TYPE_ELEMENT);
 
@@ -146,6 +147,8 @@
   gst_pad_set_chain_function (self->sink_pad,
       GST_DEBUG_FUNCPTR (gst_pcap_parse_chain));
   gst_pad_use_fixed_caps (self->sink_pad);
+  gst_pad_set_event_function (self->sink_pad,
+      GST_DEBUG_FUNCPTR (gst_pcap_sink_event));
   gst_element_add_pad (GST_ELEMENT (self), self->sink_pad);
 
   self->src_pad = gst_pad_new_from_static_template (&src_template, "src");
@@ -261,6 +264,8 @@
   self->swap_endian = FALSE;
   self->cur_packet_size = -1;
   self->buffer_offset = 0;
+  self->cur_ts = GST_CLOCK_TIME_NONE;
+  self->newsegment_sent = FALSE;
 
   gst_adapter_clear (self->adapter);
 }
@@ -402,7 +407,18 @@
                 GST_PAD_CAPS (self->src_pad), &out_buf);
 
             if (ret == GST_FLOW_OK) {
+
               memcpy (GST_BUFFER_DATA (out_buf), payload_data, payload_size);
+              GST_BUFFER_TIMESTAMP (out_buf) = self->cur_ts;
+
+              if (!self->newsegment_sent &&
+                  GST_CLOCK_TIME_IS_VALID (self->cur_ts)) {
+                GstEvent *newsegment =
+                    gst_event_new_new_segment (FALSE, 1, GST_FORMAT_TIME,
+                    self->cur_ts, -1, 0);
+                gst_pad_push_event (self->src_pad, newsegment);
+                self->newsegment_sent = TRUE;
+              }
 
               ret = gst_pad_push (self->src_pad, out_buf);
 
@@ -432,6 +448,7 @@
 
         gst_adapter_flush (self->adapter, 16);
 
+        self->cur_ts = ts_sec * GST_SECOND + ts_usec * GST_USECOND;
         self->cur_packet_size = incl_len;
       }
     } else {
@@ -465,6 +482,26 @@
 }
 
 static gboolean
+gst_pcap_sink_event (GstPad * pad, GstEvent * event)
+{
+  gboolean ret = TRUE;
+  GstPcapParse *self = GST_PCAP_PARSE (gst_pad_get_parent (pad));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_NEWSEGMENT:
+      /* Drop it, we'll replace it with our own */
+      break;
+    default:
+      ret = gst_pad_push_event (self->src_pad, event);
+  }
+
+  gst_object_unref (self);
+
+  return ret;
+}
+
+
+static gboolean
 plugin_init (GstPlugin * plugin)
 {
   return gst_element_register (plugin, "pcapparse",
diff --git a/gst/pcapparse/gstpcapparse.h b/gst/pcapparse/gstpcapparse.h
index cc1b55f..caaa52e 100644
--- a/gst/pcapparse/gstpcapparse.h
+++ b/gst/pcapparse/gstpcapparse.h
@@ -70,6 +70,10 @@
   gboolean initialized;
   gboolean swap_endian;
   gint64 cur_packet_size;
+  GstClockTime cur_ts;
+
+  gboolean newsegment_sent;
+
   gint64 buffer_offset;
 };
 
diff --git a/gst/siren/gstsirendec.c b/gst/siren/gstsirendec.c
index edf728f..d6eb35e 100644
--- a/gst/siren/gstsirendec.c
+++ b/gst/siren/gstsirendec.c
@@ -40,6 +40,8 @@
 GST_DEBUG_CATEGORY (sirendec_debug);
 #define GST_CAT_DEFAULT (sirendec_debug)
 
+#define FRAME_DURATION  (20 * GST_MSECOND)
+
 /* elementfactory information */
 static const GstElementDetails gst_siren_dec_details =
 GST_ELEMENT_DETAILS ("Siren Decoder element",
@@ -75,11 +77,15 @@
   ARG_0,
 };
 
+static void gst_siren_dec_finalize (GObject * object);
 
+static GstStateChangeReturn
+gst_siren_change_state (GstElement * element, GstStateChange transition);
+
+static gboolean gst_siren_dec_sink_setcaps (GstPad * pad, GstCaps * caps);
+static gboolean gst_siren_dec_sink_event (GstPad * pad, GstEvent * event);
 static GstFlowReturn gst_siren_dec_chain (GstPad * pad, GstBuffer * buf);
 
-static void gst_siren_dec_dispose (GObject * object);
-
 static void
 _do_init (GType type)
 {
@@ -113,7 +119,9 @@
 
   GST_DEBUG ("Initializing Class");
 
-  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_siren_dec_dispose);
+  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_siren_dec_finalize);
+
+  gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_siren_change_state);
 
   GST_DEBUG ("Class Init done");
 }
@@ -128,102 +136,215 @@
   dec->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
   dec->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
 
+  gst_pad_set_setcaps_function (dec->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_siren_dec_sink_setcaps));
+  gst_pad_set_event_function (dec->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_siren_dec_sink_event));
   gst_pad_set_chain_function (dec->sinkpad,
       GST_DEBUG_FUNCPTR (gst_siren_dec_chain));
 
   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
   gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
 
-  dec->srccaps = gst_static_pad_template_get_caps (&srctemplate);
+  dec->adapter = gst_adapter_new ();
 
   GST_DEBUG_OBJECT (dec, "Init done");
 }
 
 static void
-gst_siren_dec_dispose (GObject * object)
+gst_siren_dec_finalize (GObject * object)
 {
   GstSirenDec *dec = GST_SIREN_DEC (object);
 
-  GST_DEBUG_OBJECT (dec, "Disposing");
+  GST_DEBUG_OBJECT (dec, "Finalize");
 
-  if (dec->decoder) {
-    Siren7_CloseDecoder (dec->decoder);
-    dec->decoder = NULL;
+  Siren7_CloseDecoder (dec->decoder);
+  g_object_unref (dec->adapter);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gboolean
+gst_siren_dec_sink_setcaps (GstPad * pad, GstCaps * caps)
+{
+  GstSirenDec *dec;
+  gboolean res;
+  GstCaps *outcaps;
+
+  dec = GST_SIREN_DEC (GST_PAD_PARENT (pad));
+
+  outcaps = gst_static_pad_template_get_caps (&srctemplate);
+  res = gst_pad_set_caps (dec->srcpad, outcaps);
+  gst_caps_unref (outcaps);
+
+  return res;
+}
+
+static gboolean
+gst_siren_dec_sink_event (GstPad * pad, GstEvent * event)
+{
+  GstSirenDec *dec;
+  gboolean res;
+
+  dec = GST_SIREN_DEC (GST_PAD_PARENT (pad));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_EOS:
+      gst_adapter_clear (dec->adapter);
+      res = gst_pad_push_event (dec->srcpad, event);
+      break;
+    case GST_EVENT_FLUSH_STOP:
+      gst_adapter_clear (dec->adapter);
+      res = gst_pad_push_event (dec->srcpad, event);
+      break;
+    default:
+      res = gst_pad_push_event (dec->srcpad, event);
+      break;
   }
-
-  if (dec->srccaps) {
-    gst_caps_unref (dec->srccaps);
-    dec->srccaps = NULL;
-  }
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
+  return res;
 }
 
 static GstFlowReturn
 gst_siren_dec_chain (GstPad * pad, GstBuffer * buf)
 {
-  GstSirenDec *dec = GST_SIREN_DEC (gst_pad_get_parent_element (pad));
+  GstSirenDec *dec;
   GstFlowReturn ret = GST_FLOW_OK;
-  GstBuffer *decoded = NULL;
-  guint in_offset = 0;
-  guint out_offset = 0;
-  gint decode_ret = 0;
-  guint size = 0;
+  GstBuffer *out_buf;
+  guint8 *in_data, *out_data;
+  guint8 *to_free = NULL;
+  guint i, size, num_frames;
+  gint out_size, in_size;
+  gint decode_ret;
+  gboolean discont;
+  GstClockTime timestamp;
+  guint64 distance;
 
-  GST_LOG_OBJECT (dec, "Decoding buffer of size %d", GST_BUFFER_SIZE (buf));
+  dec = GST_SIREN_DEC (GST_PAD_PARENT (pad));
 
-  size = GST_BUFFER_SIZE (buf) * 16;
-  size -= size % 640;
-
-  if (size == 0) {
-    GST_LOG_OBJECT (dec, "Got buffer smaller than framesize: %u < 40",
-        GST_BUFFER_SIZE (buf));
-    return GST_FLOW_OK;
+  discont = GST_BUFFER_IS_DISCONT (buf);
+  if (discont) {
+    GST_DEBUG_OBJECT (dec, "received DISCONT, flush adapter");
+    gst_adapter_clear (dec->adapter);
+    dec->discont = TRUE;
   }
 
-  if (GST_BUFFER_SIZE (buf) % 40 != 0)
-    GST_LOG_OBJECT (dec, "Got buffer with size not a multiple for frame size,"
-        " ignoring last %u bytes", GST_BUFFER_SIZE (buf) % 40);
+  gst_adapter_push (dec->adapter, buf);
 
-  ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad,
-      GST_BUFFER_OFFSET (buf) * 16, size, dec->srccaps, &decoded);
+  size = gst_adapter_available (dec->adapter);
+
+  GST_LOG_OBJECT (dec, "Received buffer of size %u with adapter of size : %u",
+      GST_BUFFER_SIZE (buf), size);
+
+  /* process 40 input bytes into 640 output bytes */
+  num_frames = size / 40;
+
+  if (num_frames == 0)
+    goto done;
+
+  /* this is the input/output size */
+  in_size = num_frames * 40;
+  out_size = num_frames * 640;
+
+  GST_LOG_OBJECT (dec, "we have %u frames, %u in, %u out", num_frames, in_size,
+      out_size);
+
+  /* get a buffer */
+  ret = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, -1,
+      out_size, GST_PAD_CAPS (dec->srcpad), &out_buf);
   if (ret != GST_FLOW_OK)
-    return ret;
+    goto alloc_failed;
 
-  GST_BUFFER_TIMESTAMP (decoded) = GST_BUFFER_TIMESTAMP (buf);
+  /* get the timestamp for the output buffer */
+  timestamp = gst_adapter_prev_timestamp (dec->adapter, &distance);
 
-  while ((in_offset + 40 <= GST_BUFFER_SIZE (buf)) && ret == GST_FLOW_OK) {
+  /* add the amount of time taken by the distance, each frame is 20ms */
+  if (timestamp != -1)
+    timestamp += (distance / 40) * FRAME_DURATION;
 
-    GST_LOG_OBJECT (dec, "Decoding frame");
+  GST_LOG_OBJECT (dec,
+      "timestamp %" GST_TIME_FORMAT ", distance %" G_GUINT64_FORMAT,
+      GST_TIME_ARGS (timestamp), distance);
 
-    decode_ret = Siren7_DecodeFrame (dec->decoder,
-        GST_BUFFER_DATA (buf) + in_offset,
-        GST_BUFFER_DATA (decoded) + out_offset);
-    if (decode_ret != 0) {
-      GST_ERROR_OBJECT (dec, "Siren7_DecodeFrame returned %d", decode_ret);
-      ret = GST_FLOW_ERROR;
-    }
+  /* get the input data for all the frames */
+  to_free = in_data = gst_adapter_take (dec->adapter, in_size);
+  out_data = GST_BUFFER_DATA (out_buf);
 
-    in_offset += 40;
-    out_offset += 640;
+  for (i = 0; i < num_frames; i++) {
+    GST_LOG_OBJECT (dec, "Decoding frame %u/%u", i, num_frames);
+
+    /* decode 40 input bytes to 640 output bytes */
+    decode_ret = Siren7_DecodeFrame (dec->decoder, in_data, out_data);
+    if (decode_ret != 0)
+      goto decode_error;
+
+    /* move to next frame */
+    out_data += 640;
+    in_data += 40;
   }
 
-  GST_LOG_OBJECT (dec, "Finished decoding : %d", out_offset);
-  if (out_offset != GST_BUFFER_SIZE (decoded)) {
-    GST_ERROR_OBJECT (dec,
-        "didn't decode enough : offfset (%d) != BUFFER_SIZE (%d)",
-        out_offset, GST_BUFFER_SIZE (decoded));
-    return GST_FLOW_ERROR;
+  GST_LOG_OBJECT (dec, "Finished decoding");
+
+  /* mark discont */
+  if (dec->discont) {
+    GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DISCONT);
+    dec->discont = FALSE;
   }
 
-  ret = gst_pad_push (dec->srcpad, decoded);
+  GST_BUFFER_TIMESTAMP (out_buf) = timestamp;
+  GST_BUFFER_DURATION (out_buf) = num_frames * FRAME_DURATION;
 
-  gst_object_unref (dec);
+  ret = gst_pad_push (dec->srcpad, out_buf);
+
+done:
+  if (to_free)
+    g_free (to_free);
+
+  return ret;
+
+  /* ERRORS */
+alloc_failed:
+  {
+    GST_DEBUG_OBJECT (dec, "failed to pad_alloc buffer: %d (%d)", ret,
+        gst_flow_get_name (ret));
+    goto done;
+  }
+decode_error:
+  {
+    GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
+        ("Error decoding frame: %d", decode_ret));
+    ret = GST_FLOW_ERROR;
+    gst_buffer_unref (out_buf);
+    goto done;
+  }
+}
+
+static GstStateChangeReturn
+gst_siren_change_state (GstElement * element, GstStateChange transition)
+{
+  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+  GstSirenDec *dec = GST_SIREN_DEC (element);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      dec->discont = FALSE;
+      break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+  switch (transition) {
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      gst_adapter_clear (dec->adapter);
+      break;
+    default:
+      break;
+  }
 
   return ret;
 }
 
-
 gboolean
 gst_siren_dec_plugin_init (GstPlugin * plugin)
 {
diff --git a/gst/siren/gstsirendec.h b/gst/siren/gstsirendec.h
index 90321cf..7c02089 100644
--- a/gst/siren/gstsirendec.h
+++ b/gst/siren/gstsirendec.h
@@ -53,10 +53,11 @@
   /* Protected by stream lock */
   SirenDecoder decoder;
 
+  GstAdapter *adapter;
+  gboolean discont;
+
   GstPad *sinkpad;
   GstPad *srcpad;
-
-  GstCaps *srccaps;
 };
 
 struct _GstSirenDecClass
diff --git a/gst/siren/gstsirenenc.c b/gst/siren/gstsirenenc.c
index fbf2b6e..9b6a2a8 100644
--- a/gst/siren/gstsirenenc.c
+++ b/gst/siren/gstsirenenc.c
@@ -40,6 +40,8 @@
 GST_DEBUG_CATEGORY (sirenenc_debug);
 #define GST_CAT_DEFAULT (sirenenc_debug)
 
+#define FRAME_DURATION  (20 * GST_MSECOND)
+
 /* elementfactory information */
 static const GstElementDetails gst_siren_enc_details =
 GST_ELEMENT_DETAILS ("Siren Encoder element",
@@ -77,7 +79,10 @@
 
 
 
-static void gst_siren_enc_dispose (GObject * object);
+static void gst_siren_enc_finalize (GObject * object);
+
+static gboolean gst_siren_enc_sink_setcaps (GstPad * pad, GstCaps * caps);
+static gboolean gst_siren_enc_sink_event (GstPad * pad, GstEvent * event);
 
 static GstFlowReturn gst_siren_enc_chain (GstPad * pad, GstBuffer * buf);
 static GstStateChangeReturn
@@ -117,7 +122,7 @@
 
   GST_DEBUG ("Initializing Class");
 
-  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_siren_enc_dispose);
+  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_siren_enc_finalize);
 
   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_siren_change_state);
 
@@ -135,106 +140,185 @@
   enc->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
   enc->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
 
+  gst_pad_set_setcaps_function (enc->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_siren_enc_sink_setcaps));
+  gst_pad_set_event_function (enc->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_siren_enc_sink_event));
   gst_pad_set_chain_function (enc->sinkpad,
       GST_DEBUG_FUNCPTR (gst_siren_enc_chain));
 
   gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad);
   gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad);
 
-  enc->srccaps = gst_static_pad_template_get_caps (&srctemplate);
-
   GST_DEBUG_OBJECT (enc, "Init done");
 }
 
 static void
-gst_siren_enc_dispose (GObject * object)
+gst_siren_enc_finalize (GObject * object)
 {
   GstSirenEnc *enc = GST_SIREN_ENC (object);
 
   GST_DEBUG_OBJECT (object, "Disposing");
 
-  if (enc->encoder) {
-    Siren7_CloseEncoder (enc->encoder);
-    enc->encoder = NULL;
-  }
-
-  if (enc->adapter) {
-    g_object_unref (enc->adapter);
-    enc->adapter = NULL;
-  }
-
-  if (enc->srccaps) {
-    gst_caps_unref (enc->srccaps);
-    enc->srccaps = NULL;
-  }
+  Siren7_CloseEncoder (enc->encoder);
+  g_object_unref (enc->adapter);
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
+static gboolean
+gst_siren_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
+{
+  GstSirenEnc *enc;
+  gboolean res;
+  GstCaps *outcaps;
+
+  enc = GST_SIREN_ENC (GST_PAD_PARENT (pad));
+
+  outcaps = gst_static_pad_template_get_caps (&srctemplate);
+  res = gst_pad_set_caps (enc->srcpad, outcaps);
+  gst_caps_unref (outcaps);
+
+  return res;
+}
+
+static gboolean
+gst_siren_enc_sink_event (GstPad * pad, GstEvent * event)
+{
+  GstSirenEnc *enc;
+  gboolean res;
+
+  enc = GST_SIREN_ENC (GST_PAD_PARENT (pad));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_EOS:
+      gst_adapter_clear (enc->adapter);
+      res = gst_pad_push_event (enc->srcpad, event);
+      break;
+    case GST_EVENT_FLUSH_STOP:
+      gst_adapter_clear (enc->adapter);
+      res = gst_pad_push_event (enc->srcpad, event);
+      break;
+    default:
+      res = gst_pad_push_event (enc->srcpad, event);
+      break;
+  }
+  return res;
+}
+
 static GstFlowReturn
 gst_siren_enc_chain (GstPad * pad, GstBuffer * buf)
 {
-  GstSirenEnc *enc = GST_SIREN_ENC (gst_pad_get_parent_element (pad));
+  GstSirenEnc *enc;
   GstFlowReturn ret = GST_FLOW_OK;
-  GstBuffer *encoded = NULL;
-  guint8 *data = NULL;
-  gint out_offset = 0;
-  gint encode_ret = 0;
-  gint size = 0;
-  guint in_offset = 0;
+  GstBuffer *out_buf;
+  guint8 *in_data, *out_data;
+  guint8 *to_free = NULL;
+  guint i, size, num_frames;
+  gint out_size, in_size;
+  gint encode_ret;
+  gboolean discont;
+  GstClockTime timestamp;
+  guint64 distance;
 
-  GST_OBJECT_LOCK (enc);
+  enc = GST_SIREN_ENC (GST_PAD_PARENT (pad));
+
+  discont = GST_BUFFER_IS_DISCONT (buf);
+  if (discont) {
+    GST_DEBUG_OBJECT (enc, "received DISCONT, flush adapter");
+    gst_adapter_clear (enc->adapter);
+    enc->discont = TRUE;
+  }
 
   gst_adapter_push (enc->adapter, buf);
 
-  GST_LOG_OBJECT (enc, "Received buffer of size %d with adapter of size : %d",
-      GST_BUFFER_SIZE (buf), gst_adapter_available (enc->adapter));
-
   size = gst_adapter_available (enc->adapter);
-  size /= 16;
-  size -= size % 40;
 
-  if (size == 0) {
-    GST_OBJECT_UNLOCK (enc);
-    goto out;
-  }
+  GST_LOG_OBJECT (enc, "Received buffer of size %d with adapter of size : %d",
+      GST_BUFFER_SIZE (buf), size);
 
-  data = gst_adapter_take (enc->adapter, size * 16);
+  /* we need to process 640 input bytes to produce 40 output bytes */
+  /* calculate the amount of frames we will handle */
+  num_frames = size / 640;
 
-  GST_OBJECT_UNLOCK (enc);
+  /* no frames, wait some more */
+  if (num_frames == 0)
+    goto done;
 
-  ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
-      GST_BUFFER_OFFSET (buf) / 16, size, enc->srccaps, &encoded);
+  /* this is the input/output size */
+  in_size = num_frames * 640;
+  out_size = num_frames * 40;
 
+  GST_LOG_OBJECT (enc, "we have %u frames, %u in, %u out", num_frames, in_size,
+      out_size);
+
+  /* get a buffer */
+  ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad, -1,
+      out_size, GST_PAD_CAPS (enc->srcpad), &out_buf);
   if (ret != GST_FLOW_OK)
-    goto out;
+    goto alloc_failed;
 
-  while (out_offset < size && ret == GST_FLOW_OK) {
-    GST_LOG_OBJECT (enc, "Encoding frame");
+  /* get the timestamp for the output buffer */
+  timestamp = gst_adapter_prev_timestamp (enc->adapter, &distance);
 
-    encode_ret = Siren7_EncodeFrame (enc->encoder,
-        data + in_offset, GST_BUFFER_DATA (encoded) + out_offset);
-    if (encode_ret != 0) {
-      GST_ERROR_OBJECT (enc, "Siren7_EncodeFrame returned %d", encode_ret);
-      ret = GST_FLOW_ERROR;
-      gst_buffer_unref (encoded);
-      goto out;
-    }
+  /* add the amount of time taken by the distance */
+  if (timestamp != -1)
+    timestamp += gst_util_uint64_scale_int (distance / 2, GST_SECOND, 16000);
 
-    out_offset += 40;
-    in_offset += 640;
+  GST_LOG_OBJECT (enc,
+      "timestamp %" GST_TIME_FORMAT ", distance %" G_GUINT64_FORMAT,
+      GST_TIME_ARGS (timestamp), distance);
+
+  /* get the input data for all the frames */
+  to_free = in_data = gst_adapter_take (enc->adapter, in_size);
+  out_data = GST_BUFFER_DATA (out_buf);
+
+  for (i = 0; i < num_frames; i++) {
+    GST_LOG_OBJECT (enc, "Encoding frame %u/%u", i, num_frames);
+
+    /* encode 640 input bytes to 40 output bytes */
+    encode_ret = Siren7_EncodeFrame (enc->encoder, in_data, out_data);
+    if (encode_ret != 0)
+      goto encode_error;
+
+    /* move to next frame */
+    out_data += 40;
+    in_data += 640;
   }
 
-  GST_LOG_OBJECT (enc, "Finished encoding : %d", out_offset);
+  GST_LOG_OBJECT (enc, "Finished encoding");
 
-  ret = gst_pad_push (enc->srcpad, encoded);
+  /* mark discont */
+  if (enc->discont) {
+    GST_BUFFER_FLAG_SET (out_buf, GST_BUFFER_FLAG_DISCONT);
+    enc->discont = FALSE;
+  }
+  GST_BUFFER_TIMESTAMP (out_buf) = timestamp;
+  GST_BUFFER_DURATION (out_buf) = num_frames * FRAME_DURATION;
 
-out:
-  if (data)
-    g_free (data);
+  ret = gst_pad_push (enc->srcpad, out_buf);
 
-  gst_object_unref (enc);
+done:
+  if (to_free)
+    g_free (to_free);
+
   return ret;
+
+  /* ERRORS */
+alloc_failed:
+  {
+    GST_DEBUG_OBJECT (enc, "failed to pad_alloc buffer: %d (%d)", ret,
+        gst_flow_get_name (ret));
+    goto done;
+  }
+encode_error:
+  {
+    GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
+        ("Error encoding frame: %d", encode_ret));
+    ret = GST_FLOW_ERROR;
+    gst_buffer_unref (out_buf);
+    goto done;
+  }
 }
 
 static GstStateChangeReturn
@@ -243,16 +327,19 @@
   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
   GstSirenEnc *enc = GST_SIREN_ENC (element);
 
-  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  switch (transition) {
+    case GST_STATE_CHANGE_READY_TO_PAUSED:
+      enc->discont = FALSE;
+      break;
+    default:
+      break;
+  }
 
-  if (ret == GST_STATE_CHANGE_FAILURE)
-    return ret;
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
   switch (transition) {
     case GST_STATE_CHANGE_PAUSED_TO_READY:
-      GST_OBJECT_LOCK (element);
       gst_adapter_clear (enc->adapter);
-      GST_OBJECT_UNLOCK (element);
       break;
     default:
       break;
diff --git a/gst/siren/gstsirenenc.h b/gst/siren/gstsirenenc.h
index 47e05bc..1d63628 100644
--- a/gst/siren/gstsirenenc.h
+++ b/gst/siren/gstsirenenc.h
@@ -52,13 +52,12 @@
 
   /* protected by the stream lock */
   SirenEncoder encoder;
-  /* protected by the object lock */
   GstAdapter *adapter;
 
+  gboolean discont;
+
   GstPad *srcpad;
   GstPad *sinkpad;
-
-  GstCaps *srccaps;
 };
 
 struct _GstSirenEncClass
diff --git a/gst/xdgmime/Makefile.am b/gst/xdgmime/Makefile.am
deleted file mode 100644
index f338a85..0000000
--- a/gst/xdgmime/Makefile.am
+++ /dev/null
@@ -1,9 +0,0 @@
-plugin_LTLIBRARIES = libgstxdgmime.la
-
-libgstxdgmime_la_SOURCES = gstxdgmime.c
-
-libgstxdgmime_la_CFLAGS = $(GIO_CFLAGS) $(GST_CFLAGS)
-libgstxdgmime_la_LIBADD = $(GIO_LIBS) $(GST_LIBS)
-libgstxdgmime_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstxdgmime_la_LIBTOOLFLAGS = --tag=disable-static
-
diff --git a/gst/xdgmime/gstxdgmime.c b/gst/xdgmime/gstxdgmime.c
deleted file mode 100644
index 2bc9d02..0000000
--- a/gst/xdgmime/gstxdgmime.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/* GStreamer
- * Copyright (C) <2009> Sebastian Dröge <sebastian.droege@collabora.co.uk>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gst/gst.h>
-
-GST_DEBUG_CATEGORY (xdgmime_debug);
-#define GST_CAT_DEFAULT xdgmime_debug
-
-#include <gio/gio.h>
-
-static void
-xdgmime_typefind (GstTypeFind * find, gpointer user_data)
-{
-  gchar *mimetype;
-  gsize length = 16384;
-  guint64 tf_length;
-  guint8 *data;
-  gchar *tmp;
-
-  if ((tf_length = gst_type_find_get_length (find)) > 0)
-    length = MIN (length, tf_length);
-
-  if ((data = gst_type_find_peek (find, 0, length)) == NULL)
-    return;
-
-
-  tmp = g_content_type_guess (NULL, data, length, NULL);
-  if (tmp == NULL || g_content_type_is_unknown (tmp)) {
-    g_free (tmp);
-    return;
-  }
-
-  mimetype = g_content_type_get_mime_type (tmp);
-  g_free (tmp);
-
-  if (mimetype == NULL)
-    return;
-
-  GST_DEBUG ("Got mimetype '%s'", mimetype);
-
-  /* Ignore audio/video types:
-   *  - our own typefinders in -base are likely to be better at this
-   *    (and if they're not, we really want to fix them, that's why we don't
-   *    report xdg-detected audio/video types at all, not even with a low
-   *    probability)
-   *  - we want to detect GStreamer media types and not MIME types
-   *  - the purpose of this xdg mime finder is mainly to prevent false
-   *    positives of non-media formats, not to typefind audio/video formats */
-  if (g_str_has_prefix (mimetype, "audio/") ||
-      g_str_has_prefix (mimetype, "video/")) {
-    GST_LOG ("Ignoring audio/video mime type");
-    g_free (mimetype);
-    return;
-  }
-
-  /* Again, we mainly want the xdg typefinding to prevent false-positives on
-   * non-media formats, so suggest the type with a probability that trumps
-   * uncertain results of our typefinders, but not more than that. */
-  GST_LOG ("Suggesting '%s' with probability POSSIBLE", mimetype);
-  gst_type_find_suggest_simple (find, GST_TYPE_FIND_POSSIBLE, mimetype, NULL);
-  g_free (mimetype);
-}
-
-static gboolean
-plugin_init (GstPlugin * plugin)
-{
-  gboolean ret;
-
-  GST_DEBUG_CATEGORY_INIT (xdgmime_debug, "xdgmime", 0, "XDG-MIME");
-
-  ret = gst_type_find_register (plugin,
-      "xdgmime", GST_RANK_MARGINAL, xdgmime_typefind, NULL, NULL, NULL, NULL);
-
-  return ret;
-}
-
-GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
-    GST_VERSION_MINOR,
-    "xdgmime",
-    "XDG-MIME",
-    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
diff --git a/sys/dshowsrcwrapper/gstdshow.cpp b/sys/dshowsrcwrapper/gstdshow.cpp
old mode 100644
new mode 100755
index 8b77b58..d542543
--- a/sys/dshowsrcwrapper/gstdshow.cpp
+++ b/sys/dshowsrcwrapper/gstdshow.cpp
@@ -321,3 +321,67 @@
   }
   return ret;
 }
+
+GstCaps *gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar* name, 
+  const VIDEO_STREAM_CONFIG_CAPS * vscc, GstCapturePinMediaType *pin_mediatype)
+{
+  GstCaps *video_caps = NULL;
+  GstStructure *video_structure = NULL;
+  VIDEOINFOHEADER *video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
+  
+  pin_mediatype->defaultWidth = video_info->bmiHeader.biWidth;
+  pin_mediatype->defaultHeight = video_info->bmiHeader.biHeight;
+  pin_mediatype->defaultFPS = (gint) (10000000 / video_info->AvgTimePerFrame);
+  pin_mediatype->granularityWidth = vscc->OutputGranularityX;
+  pin_mediatype->granularityHeight = vscc->OutputGranularityY;
+
+  /* raw video format */
+  switch (video_format) {
+    case GST_VIDEO_FORMAT_BGR:
+      video_caps = gst_caps_from_string (GST_VIDEO_CAPS_BGR);
+      break;
+    case GST_VIDEO_FORMAT_I420:
+      video_caps = gst_caps_from_string (GST_VIDEO_CAPS_YUV ("I420"));
+    default:
+      break;
+  }
+
+  /* other video format */
+  if (!video_caps){
+    if (g_strcasecmp (name, "video/x-dv, systemstream=FALSE") == 0) {
+      video_caps = gst_caps_new_simple ("video/x-dv", 
+        "systemstream", G_TYPE_BOOLEAN, FALSE,
+        "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'),
+        NULL);
+    } else if (g_strcasecmp (name, "video/x-dv, systemstream=TRUE") == 0) {
+      video_caps = gst_caps_new_simple ("video/x-dv", 
+        "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
+      return video_caps;
+    }
+  }
+
+  if (!video_caps)
+    return NULL;
+
+  video_structure = gst_caps_get_structure (video_caps, 0);
+
+  /* Hope GST_TYPE_INT_RANGE_STEP will exits in future gstreamer releases  */
+  /* because we could use :  */
+  /* "width", GST_TYPE_INT_RANGE_STEP, video_default->minWidth, video_default->maxWidth,  video_default->granularityWidth */
+  /* instead of : */
+  /* "width", GST_TYPE_INT_RANGE, video_default->minWidth, video_default->maxWidth */
+
+  /* For framerate we do not need a step (granularity) because  */
+  /* "The IAMStreamConfig::SetFormat method will set the frame rate to the closest  */
+  /* value that the filter supports" as it said in the VIDEO_STREAM_CONFIG_CAPS dshwo doc */

+  

+  gst_structure_set (video_structure,

+      "width", GST_TYPE_INT_RANGE, vscc->MinOutputSize.cx, vscc->MaxOutputSize.cx,

+      "height", GST_TYPE_INT_RANGE, vscc->MinOutputSize.cy, vscc->MaxOutputSize.cy,
+      "framerate", GST_TYPE_FRACTION_RANGE, 
+          (gint) (10000000 / vscc->MaxFrameInterval), 1,
+          (gint) (10000000 / vscc->MinFrameInterval), 1,
+       NULL);
+
+  return video_caps;
+}
diff --git a/sys/dshowsrcwrapper/gstdshow.h b/sys/dshowsrcwrapper/gstdshow.h
old mode 100644
new mode 100755
index 4491e50..3b91109
--- a/sys/dshowsrcwrapper/gstdshow.h
+++ b/sys/dshowsrcwrapper/gstdshow.h
@@ -22,29 +22,29 @@
 #ifndef _GSTDSHOW_
 #define _GSTDSHOW_
 
-#ifdef __cplusplus
 #include <streams.h>
-#endif
 #include <windows.h>
 #include <objbase.h>
 #include <dshow.h>
 #include <Rpc.h>
 
-#include <glib.h>
+#include <gst/gst.h>
+#include <gst/video/video.h>
 
 typedef struct _GstCapturePinMediaType
 {
   AM_MEDIA_TYPE *mediatype;
   IPin *capture_pin;
+
+  //default caps
+  gint defaultWidth;
+  gint defaultHeight;
+  gint defaultFPS;
+
+  gint granularityWidth; //will be removed when GST_TYPE_INT_RANGE_STEP exits
+  gint granularityHeight; //will be removed when GST_TYPE_INT_RANGE_STEP exits
 } GstCapturePinMediaType;
 
-#ifdef  __cplusplus

-extern "C" {

-#endif
-
-/* register fake filters as COM object and as Direct Show filters in the registry */
-//HRESULT gst_dshow_register_fakefilters ();
-
 /* free memory of the input pin mediatype */
 void gst_dshow_free_pin_mediatype (gpointer pt);
 
@@ -71,9 +71,9 @@
 
 /* show the capture filter property page (generally used to setup the device). the page is modal*/
 gboolean gst_dshow_show_propertypage (IBaseFilter *base_filter);
-

-#ifdef  __cplusplus

-}

-#endif
+
+/* transform a dshow video caps to a gstreamer video caps */ 
+GstCaps *gst_dshow_new_video_caps (GstVideoFormat video_format, const gchar* name, 
+  const VIDEO_STREAM_CONFIG_CAPS * vscc, GstCapturePinMediaType *pin_mediatype);
 
 #endif /* _GSTDSHOW_ */
\ No newline at end of file
diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp
old mode 100644
new mode 100755
index 1f4ff4a..726b1d0
--- a/sys/dshowsrcwrapper/gstdshowvideosrc.cpp
+++ b/sys/dshowsrcwrapper/gstdshowvideosrc.cpp
@@ -203,7 +203,6 @@
   src->media_filter = NULL;
   src->filter_graph = NULL;
   src->caps = NULL;
-  src->video_defaults = NULL;
   src->pins_mediatypes = NULL;
   src->is_rgb = FALSE;
 
@@ -237,12 +236,12 @@
   }
 
   if (res != -1) {
-    GList *type_video_default = g_list_nth (src->video_defaults, res);
-    if (type_video_default) {
-      GstCaptureVideoDefault *video_default = (GstCaptureVideoDefault *) type_video_default->data;
-      gst_structure_fixate_field_nearest_int (structure, "width", video_default->defaultWidth);
-      gst_structure_fixate_field_nearest_int (structure, "height", video_default->defaultHeight);
-      gst_structure_fixate_field_nearest_fraction (structure, "framerate", video_default->defaultFPS, 1);
+    GList *type_pin_mediatype = g_list_nth (src->pins_mediatypes, res);
+    if (type_pin_mediatype) {
+      GstCapturePinMediaType *pin_mediatype = (GstCapturePinMediaType *) type_pin_mediatype->data;
+      gst_structure_fixate_field_nearest_int (structure, "width", pin_mediatype->defaultWidth);
+      gst_structure_fixate_field_nearest_int (structure, "height", pin_mediatype->defaultHeight);
+      gst_structure_fixate_field_nearest_fraction (structure, "framerate", pin_mediatype->defaultFPS, 1);
     }
   }
 }
@@ -267,11 +266,6 @@
     src->caps = NULL;
   }
 
-  if (src->video_defaults) {
-    g_list_free (src->video_defaults);
-    src->video_defaults = NULL;
-  }
-
   if (src->pins_mediatypes) {
     gst_dshow_free_pins_mediatypes (src->pins_mediatypes);
     src->pins_mediatypes = NULL;
@@ -551,6 +545,7 @@
               GstCaps *caps =
                   gst_dshowvideosrc_getcaps_from_streamcaps (src, capture_pin,
                   streamcaps);
+              g_print ("caps: %s\n", gst_caps_to_string(caps));
 
               if (caps) {
                 gst_caps_append (src->caps, caps);
@@ -573,7 +568,6 @@
   }
 
   if (src->caps) {
-    GST_LOG ("getcaps returned %s", gst_caps_to_string (src->caps));
     return gst_caps_ref (src->caps);
   }
 
@@ -695,15 +689,10 @@
 
     if (res != -1 && src->pins_mediatypes) {
       /* get the corresponding media type and build the dshow graph */
-      GList *type = g_list_nth (src->pins_mediatypes, res);
+      GList *type_pin_mediatype = g_list_nth (src->pins_mediatypes, res);
 
-      //will be removed when GST_TYPE_INT_RANGE_STEP exits
-      GList *type_video_default = g_list_nth (src->video_defaults, res);
-
-      if (type && type_video_default) {
-        //will be removed when GST_TYPE_INT_RANGE_STEP exits
-        GstCaptureVideoDefault *video_default = (GstCaptureVideoDefault *) type_video_default->data;
-        GstCapturePinMediaType *pin_mediatype = NULL;
+      if (type_pin_mediatype) {
+        GstCapturePinMediaType *pin_mediatype = (GstCapturePinMediaType *) type_pin_mediatype->data;
         gchar *caps_string = NULL;
         gchar *src_caps_string = NULL;
 
@@ -720,17 +709,10 @@
         /* check if the desired video size is valid about granularity  */
 		    /* This check will be removed when GST_TYPE_INT_RANGE_STEP exits */
         /* See remarks in gst_dshowvideosrc_getcaps_from_streamcaps function */
-        if (video_default->granularityWidth != 0 && width % video_default->granularityWidth != 0)
-          g_warning ("your desired video size is not valid : %d mod %d !=0\n", width, video_default->granularityWidth) ;
-        if (video_default->granularityHeight !=0 && height % video_default->granularityHeight != 0)
-          g_warning ("your desired video size is not valid : %d mod %d !=0\n", height, video_default->granularityHeight) ;
-
-        /* display all capabilities when using --gst-debug-level=3 */
-        src_caps_string = gst_caps_to_string (src->caps);
-        GST_LOG (src_caps_string);
-        g_free (src_caps_string);
-
-        pin_mediatype = (GstCapturePinMediaType *) type->data;
+        if (pin_mediatype->granularityWidth != 0 && width % pin_mediatype->granularityWidth != 0)
+          g_warning ("your desired video size is not valid : %d mod %d !=0\n", width, pin_mediatype->granularityWidth) ;
+        if (pin_mediatype->granularityHeight !=0 && height % pin_mediatype->granularityHeight != 0)
+          g_warning ("your desired video size is not valid : %d mod %d !=0\n", height, pin_mediatype->granularityHeight) ;
 
         /* update mediatype */
         video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
@@ -896,161 +878,46 @@
   if (isize != sizeof (vscc))
     return NULL;
 
+  caps = gst_caps_new_empty ();
+
   for (; i < icount; i++) {
     GstCapturePinMediaType *pin_mediatype = g_new0 (GstCapturePinMediaType, 1);
-    GstCaptureVideoDefault *video_default = g_new0 (GstCaptureVideoDefault, 1);
 
     pin->AddRef();
     pin_mediatype->capture_pin = pin;
 
     hres = streamcaps->GetStreamCaps(i, &pin_mediatype->mediatype, (BYTE *) & vscc);
-    if (hres == S_OK && pin_mediatype->mediatype) {
-      VIDEOINFOHEADER *video_info;
+    if (FAILED (hres) || !pin_mediatype->mediatype) {
+      gst_dshow_free_pin_mediatype (pin_mediatype);
+    } else {
       GstCaps *mediacaps = NULL;
 
-      if (!caps)
-        caps = gst_caps_new_empty ();
-
-      /* some remarks: */
-      /* Hope GST_TYPE_INT_RANGE_STEP will exits in future gstreamer releases  */
-      /* because we could use :  */
-      /* "width", GST_TYPE_INT_RANGE_STEP, video_default->minWidth, video_default->maxWidth,  video_default->granularityWidth */
-      /* instead of : */
-      /* "width", GST_TYPE_INT_RANGE, video_default->minWidth, video_default->maxWidth */
-
-      /* For framerate we do not need a step (granularity) because  */
-      /* "The IAMStreamConfig::SetFormat method will set the frame rate to the closest  */
-      /* value that the filter supports" as it said in the VIDEO_STREAM_CONFIG_CAPS dshwo doc */
-
-      /* I420 */
       if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_I420, FORMAT_VideoInfo)) {
-        video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
+        mediacaps = gst_dshow_new_video_caps (GST_VIDEO_FORMAT_I420, NULL, &vscc, pin_mediatype);
 
-        video_default->defaultWidth = video_info->bmiHeader.biWidth;
-        video_default->defaultHeight = video_info->bmiHeader.biHeight;
-        video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame);
-        video_default->granularityWidth = vscc.OutputGranularityX;
-        video_default->granularityHeight = vscc.OutputGranularityY;
+      } else if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo)) {
+        mediacaps = gst_dshow_new_video_caps (GST_VIDEO_FORMAT_BGR, NULL, &vscc, pin_mediatype);
 
-        mediacaps = gst_caps_new_simple ("video/x-raw-yuv",
-          "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx,
-          "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy,
-          "framerate", GST_TYPE_FRACTION_RANGE,
-          (int) (10000000 / vscc.MaxFrameInterval), 1,
-          (int) (10000000 / vscc.MinFrameInterval), 1,
-          "format", GST_TYPE_FOURCC, MAKEFOURCC ('I', '4', '2', '0'), NULL);
+      } else if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_VideoInfo)) {
+        mediacaps = gst_dshow_new_video_caps (GST_VIDEO_FORMAT_UNKNOWN,
+          "video/x-dv, systemstream=FALSE", &vscc, pin_mediatype);
 
-        if (mediacaps) {
-          src->pins_mediatypes =
-              g_list_append (src->pins_mediatypes, pin_mediatype);
-          src->video_defaults =
-            g_list_append (src->video_defaults, video_default);
-          gst_caps_append (caps, mediacaps);
-        } else {
-          gst_dshow_free_pin_mediatype (pin_mediatype);
-          g_free (video_default);
-        }
-        continue;
+      } else if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_DvInfo)) { 
+        mediacaps = gst_dshow_new_video_caps (GST_VIDEO_FORMAT_UNKNOWN,
+          "video/x-dv, systemstream=TRUE", &vscc, pin_mediatype);
+
+        pin_mediatype->granularityWidth = 0;
+        pin_mediatype->granularityHeight = 0;
       }
 
-      /* BGR */
-      if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo)) {
-        video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
-
-        video_default->defaultWidth = video_info->bmiHeader.biWidth;
-        video_default->defaultHeight = video_info->bmiHeader.biHeight;
-        video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame);
-        video_default->granularityWidth = vscc.OutputGranularityX;
-        video_default->granularityHeight = vscc.OutputGranularityY;
-
-        /* ffmpegcolorspace handles RGB24 in BIG_ENDIAN */
-        mediacaps = gst_caps_new_simple ("video/x-raw-rgb",
-          "bpp", G_TYPE_INT, 24,
-          "depth", G_TYPE_INT, 24,
-          "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx,
-          "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy,
-          "framerate", GST_TYPE_FRACTION_RANGE,
-          (int) (10000000 / vscc.MaxFrameInterval), 1,
-          (int) (10000000 / vscc.MinFrameInterval), 1,
-          "endianness", G_TYPE_INT, G_BIG_ENDIAN,
-          "red_mask", G_TYPE_INT, 255,
-          "green_mask", G_TYPE_INT, 65280,
-          "blue_mask", G_TYPE_INT, 16711680, NULL);
-
-        if (mediacaps) {
-          src->pins_mediatypes =
-              g_list_append (src->pins_mediatypes, pin_mediatype);
-          src->video_defaults =
-            g_list_append (src->video_defaults, video_default);
-          gst_caps_append (caps, mediacaps);
-        } else {
-          gst_dshow_free_pin_mediatype (pin_mediatype);
-          g_free (video_default);
-        }
-        continue;
+      if (mediacaps) {
+        src->pins_mediatypes =
+          g_list_append (src->pins_mediatypes, pin_mediatype);
+        gst_caps_append (caps, mediacaps);
+      } else {
+        gst_dshow_free_pin_mediatype (pin_mediatype);
       }
 
-      /* DVSD */
-      if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_VideoInfo)) {
-        video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
-
-        video_default->defaultWidth = video_info->bmiHeader.biWidth;
-        video_default->defaultHeight = video_info->bmiHeader.biHeight;
-        video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame);
-        video_default->granularityWidth = vscc.OutputGranularityX;
-        video_default->granularityHeight = vscc.OutputGranularityY;
-
-        mediacaps = gst_caps_new_simple ("video/x-dv",
-          "systemstream", G_TYPE_BOOLEAN, FALSE,
-          "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'),
-          "framerate", GST_TYPE_FRACTION_RANGE,
-          (int) (10000000 / vscc.MaxFrameInterval), 1,
-          (int) (10000000 / vscc.MinFrameInterval), 1,
-          "width", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cx, vscc.MaxOutputSize.cx,
-          "height", GST_TYPE_INT_RANGE, vscc.MinOutputSize.cy, vscc.MaxOutputSize.cy, NULL);
-
-        if (mediacaps) {
-          src->pins_mediatypes =
-              g_list_append (src->pins_mediatypes, pin_mediatype);
-          src->video_defaults =
-            g_list_append (src->video_defaults, video_default);
-          gst_caps_append (caps, mediacaps);
-        } else {
-          gst_dshow_free_pin_mediatype (pin_mediatype);
-          g_free (video_default);
-        }
-        continue;
-      }
-
-      /* DV stream */
-      if (gst_dshow_check_mediatype (pin_mediatype->mediatype, MEDIASUBTYPE_dvsd, FORMAT_DvInfo)) {
-        video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat;
-
-        //No video size in caps when stream ? I do know if the following fields exist
-        video_default->defaultWidth = video_info->bmiHeader.biWidth;
-        video_default->defaultHeight = video_info->bmiHeader.biHeight;
-        video_default->defaultFPS = (int) (10000000 / video_info->AvgTimePerFrame);
-        video_default->granularityWidth = vscc.OutputGranularityX;
-        video_default->granularityHeight = vscc.OutputGranularityY;
-
-        mediacaps = gst_caps_new_simple ("video/x-dv",
-            "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
-
-        if (mediacaps) {
-          src->pins_mediatypes =
-              g_list_append (src->pins_mediatypes, pin_mediatype);
-          src->video_defaults =
-            g_list_append (src->video_defaults, video_default);
-          gst_caps_append (caps, mediacaps);
-        } else {
-          gst_dshow_free_pin_mediatype (pin_mediatype);
-          g_free (video_default);
-        }
-        continue;
-      }
-    } else {
-      gst_dshow_free_pin_mediatype (pin_mediatype);
-      g_free (video_default);
     }
   }
 
diff --git a/sys/dshowsrcwrapper/gstdshowvideosrc.h b/sys/dshowsrcwrapper/gstdshowvideosrc.h
old mode 100644
new mode 100755
index 4158307..9fe0f45
--- a/sys/dshowsrcwrapper/gstdshowvideosrc.h
+++ b/sys/dshowsrcwrapper/gstdshowvideosrc.h
@@ -42,17 +42,6 @@
 typedef struct _GstDshowVideoSrc GstDshowVideoSrc;
 typedef struct _GstDshowVideoSrcClass GstDshowVideoSrcClass;
 
-/* video default properties associated to a video format (YUY2, I420, RGB24 ...) */
-typedef struct _GstCaptureVideoDefault
-{
-  gint defaultWidth;
-  gint defaultHeight;
-  gint defaultFPS;
-
-  gint granularityWidth; //will be removed when GST_TYPE_INT_RANGE_STEP exits
-  gint granularityHeight; //will be removed when GST_TYPE_INT_RANGE_STEP exits
-
-} GstCaptureVideoDefault;
 
 struct _GstDshowVideoSrc
 {
@@ -67,9 +56,6 @@
   /* list of caps created from the list of supported media types of the dshow capture filter */
   GstCaps *caps;
 
-  /* list of dshow default video properties from filter's capture pins */
-  GList *video_defaults;
-
   /* list of dshow media types from the filter's capture pins */
   GList *pins_mediatypes;