diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
index 04a3924..cc91700 100644
--- a/gst/playback/gstplaybin2.c
+++ b/gst/playback/gstplaybin2.c
@@ -296,6 +296,8 @@ struct _GstSourceGroup
   GstElement *suburidecodebin;
   gint pending;
 
+  gdouble video_fps;
+
   gulong pad_added_id;
   gulong pad_removed_id;
   gulong no_more_pads_id;
@@ -526,6 +528,9 @@ static void no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group);
 static void pad_removed_cb (GstElement * decodebin, GstPad * pad,
     GstSourceGroup * group);
 
+static void check_video_fps_for_subs (GstSourceGroup * group, GstCaps * caps);
+static void set_video_fps_for_subs (GstSourceGroup * group);
+
 static GstElementClass *parent_class;
 
 static guint gst_play_bin_signals[LAST_SIGNAL] = { 0 };
@@ -1071,6 +1076,8 @@ init_group (GstPlayBin * playbin, GstSourceGroup * group)
   group->selector[5].media_list[0] = "text/";
   group->selector[5].type = GST_PLAY_SINK_TYPE_TEXT;
   group->selector[5].channels = group->text_channels;
+
+  group->video_fps = 0.0;
 }
 
 static void
@@ -2315,6 +2322,9 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group)
      * signal the other waiters. */
     GST_LOG_OBJECT (playbin, "last group complete");
     configure = TRUE;
+    if (group->suburi && group->suburidecodebin && group->video_fps > 0.0) {
+      set_video_fps_for_subs (group);
+    }
   } else {
     GST_LOG_OBJECT (playbin, "have more pending groups");
     configure = FALSE;
@@ -2472,6 +2482,12 @@ autoplug_select_cb (GstElement * decodebin, GstPad * pad,
   GST_DEBUG_OBJECT (playbin, "checking factory %s",
       GST_PLUGIN_FEATURE_NAME (factory));
 
+  klass = gst_element_factory_get_klass (factory);
+
+  /* Check the framerate from the video decoder caps */
+  if (!strcmp (klass, "Codec/Decoder/Video"))
+    check_video_fps_for_subs (group, caps);
+
   /* if it's not a sink, we just make decodebin try it */
   if (!gst_factory_list_is_type (factory, GST_FACTORY_LIST_SINK))
     return GST_AUTOPLUG_SELECT_TRY;
@@ -2479,8 +2495,6 @@ autoplug_select_cb (GstElement * decodebin, GstPad * pad,
   /* it's a sink, see if an instance of it actually works */
   GST_DEBUG_OBJECT (playbin, "we found a sink");
 
-  klass = gst_element_factory_get_klass (factory);
-
   /* figure out the klass */
   if (strstr (klass, "Audio")) {
     GST_DEBUG_OBJECT (playbin, "we found an audio sink");
@@ -2762,6 +2776,7 @@ deactivate_group (GstPlayBin * playbin, GstSourceGroup * group)
   GST_DEBUG_OBJECT (playbin, "unlinking group %p", group);
 
   GST_SOURCE_GROUP_LOCK (group);
+  group->video_fps = 0.0;
   group->active = FALSE;
   for (i = 0; i < GST_PLAY_SINK_TYPE_LAST; i++) {
     GstSourceSelect *select = &group->selector[i];
@@ -3026,3 +3041,59 @@ gst_play_bin2_plugin_init (GstPlugin * plugin)
   return gst_element_register (plugin, "playbin2", GST_RANK_NONE,
       GST_TYPE_PLAY_BIN);
 }
+
+static void
+check_video_fps_for_subs (GstSourceGroup * group, GstCaps * caps)
+{
+  GstStructure *s;
+  gint fps_n = 0, fps_d = 0;
+  if (!caps || !gst_caps_is_fixed (caps)) {
+    GST_DEBUG ("Caps are not fixed, cannot get framerate for subtitles: %s",
+        gst_caps_to_string (caps));
+    return;
+  }
+
+  s = gst_caps_get_structure (caps, 0);
+  if (!s || !gst_structure_get_fraction (s, "framerate", &fps_n, &fps_d) ||
+      fps_d == 0) {
+    GST_DEBUG ("No framerate information.");
+    return;
+  }
+
+  group->video_fps = (gdouble) fps_n / (gdouble) fps_d;
+  GST_DEBUG ("Video framerate: %.2f fps", group->video_fps);
+}
+
+static void
+set_video_fps_for_subs (GstSourceGroup * group)
+{
+  GstIterator *it;
+  gboolean done = FALSE;
+  GstElement *element;
+
+  it = gst_bin_iterate_recurse (GST_BIN (group->suburidecodebin));
+  while (!done) {
+    switch (gst_iterator_next (it, (gpointer) & element)) {
+      case GST_ITERATOR_OK:
+        if (g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT
+                    (element)), "video-fps")) {
+          GST_DEBUG ("Setting video framerate property for subtitle decoder.");
+          g_object_set (G_OBJECT (element), "video-fps", group->video_fps,
+              NULL);
+          done = TRUE;
+        }
+        gst_object_unref (element);
+        break;
+      case GST_ITERATOR_RESYNC:
+        gst_iterator_resync (it);
+        break;
+      case GST_ITERATOR_ERROR:
+        done = TRUE;
+        break;
+      case GST_ITERATOR_DONE:
+        done = TRUE;
+        break;
+    }
+  }
+  gst_iterator_free (it);
+}
diff --git a/gst/subparse/gstsubparse.c b/gst/subparse/gstsubparse.c
index 8b4a24c..5151966 100644
--- a/gst/subparse/gstsubparse.c
+++ b/gst/subparse/gstsubparse.c
@@ -42,7 +42,8 @@ GST_DEBUG_CATEGORY (sub_parse_debug);
 enum
 {
   PROP_0,
-  PROP_ENCODING
+  PROP_ENCODING,
+  PROP_VIDEOFPS
 };
 
 static void
@@ -188,6 +189,13 @@ gst_sub_parse_class_init (GstSubParseClass * klass)
           "variable will be checked for an encoding to use. If that is not set "
           "either, ISO-8859-15 will be assumed.", DEFAULT_ENCODING,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (object_class, PROP_VIDEOFPS,
+      g_param_spec_double ("video-fps", "Video framerate",
+          "Framerate of the video stream. This is needed by some subtitle "
+          "formats to synchronize subtitles and video properly. If not set "
+          "and the subtitle format requires it subtitles may be out of sync.",
+          0.0, 100.0, 0.0, G_PARAM_READWRITE));
 }
 
 static void
@@ -348,6 +356,12 @@ gst_sub_parse_set_property (GObject * object, guint prop_id,
       GST_LOG_OBJECT (object, "subtitle encoding set to %s",
           GST_STR_NULL (subparse->encoding));
       break;
+    case PROP_VIDEOFPS:
+    {
+      subparse->fps = g_value_get_double (value);
+      GST_DEBUG_OBJECT (object, "video framerate set to %.2f", subparse->fps);
+      break;
+    }
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -366,6 +380,9 @@ gst_sub_parse_get_property (GObject * object, guint prop_id,
     case PROP_ENCODING:
       g_value_set_string (value, subparse->encoding);
       break;
+    case PROP_VIDEOFPS:
+      g_value_set_double (value, subparse->fps);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1415,6 +1432,7 @@ handle_buffer (GstSubParse * self, GstBuffer * buf)
         detect_encoding ((gchar *) GST_BUFFER_DATA (buf),
         GST_BUFFER_SIZE (buf));
     self->first_buffer = FALSE;
+    self->state.fps = self->fps;
   }
 
   feed_textbuf (self, buf);
diff --git a/gst/subparse/gstsubparse.h b/gst/subparse/gstsubparse.h
index 92884dc..25a8b37 100644
--- a/gst/subparse/gstsubparse.h
+++ b/gst/subparse/gstsubparse.h
@@ -65,7 +65,7 @@ typedef struct {
   guint64  max_duration; /* to clamp duration, 0 = no limit (used by tmplayer parser) */
   GstSegment *segment;
   gpointer user_data;
-  gdouble  fps;          /* used by microdvd parser */
+  gdouble  fps;          /* used by frame based parsers */
 } ParserState;
 
 typedef gchar* (*Parser) (ParserState *state, const gchar *line);
@@ -102,6 +102,9 @@ struct _GstSubParse {
   gchar   *encoding;
 
   gboolean first_buffer;
+
+  /* used by frame based parsers */
+  gdouble  fps;          
 };
 
 struct _GstSubParseClass {
