diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
index 54b9c1d..27f3262 100644
--- a/gst/playback/gstplaybin2.c
+++ b/gst/playback/gstplaybin2.c
@@ -371,6 +371,8 @@ struct _GstPlayBin
   guint64 buffer_duration;      /* When buffering, the max buffer duration (ns) */
   guint buffer_size;            /* When buffering, the max buffer size (bytes) */
 
+  gboolean autoplug_sinkside;   /* Use only the ranks in auto-plugging */
+
   /* our play sink */
   GstPlaySink *playsink;
 
@@ -461,6 +463,7 @@ struct _GstPlayBinClass
 #define DEFAULT_BUFFER_DURATION   -1
 #define DEFAULT_BUFFER_SIZE       -1
 #define DEFAULT_RING_BUFFER_MAX_SIZE 0
+#define DEFAULT_AUTOPLUG_SINKSIDE TRUE
 
 enum
 {
@@ -489,6 +492,7 @@ enum
   PROP_BUFFER_DURATION,
   PROP_AV_OFFSET,
   PROP_RING_BUFFER_MAX_SIZE,
+  PROP_AUTOPLUG_SINKSIDE,
   PROP_LAST
 };
 
@@ -810,6 +814,22 @@ gst_play_bin_class_init (GstPlayBinClass * klass)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   /**
+   * GstPlayBin2:autoplug-sinkside
+   *
+   * If set to TRUE, instead of using only the ranks of elements
+   * in auto-plugging, which is the behavior of the previous version,
+   * prefer the direct connecivity of elements' sink pads to the final
+   * sink elements over the elements' ranks.  Default TRUE.
+   */
+  g_object_class_install_property (gobject_klass, PROP_AUTOPLUG_SINKSIDE,
+      g_param_spec_boolean ("autoplug-sinkside",
+          "Enable sink-side connectivity criteria",
+          "Prefer the direct connectivity to the video/audio-sink"
+          " over the ranks in auto-plugging, instead of just the ranks.",
+          DEFAULT_AUTOPLUG_SINKSIDE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  /**
    * GstPlayBin2::about-to-finish
    * @playbin: a #GstPlayBin2
    *
@@ -1206,6 +1226,7 @@ gst_play_bin_init (GstPlayBin * playbin)
   playbin->buffer_duration = DEFAULT_BUFFER_DURATION;
   playbin->buffer_size = DEFAULT_BUFFER_SIZE;
   playbin->ring_buffer_max_size = DEFAULT_RING_BUFFER_MAX_SIZE;
+  playbin->autoplug_sinkside = DEFAULT_AUTOPLUG_SINKSIDE;
 }
 
 static void
@@ -1834,6 +1855,9 @@ gst_play_bin_set_property (GObject * object, guint prop_id,
     case PROP_RING_BUFFER_MAX_SIZE:
       playbin->ring_buffer_max_size = g_value_get_uint64 (value);
       break;
+    case PROP_AUTOPLUG_SINKSIDE:
+      playbin->autoplug_sinkside = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2009,6 +2033,9 @@ gst_play_bin_get_property (GObject * object, guint prop_id, GValue * value,
     case PROP_RING_BUFFER_MAX_SIZE:
       g_value_set_uint64 (value, playbin->ring_buffer_max_size);
       break;
+    case PROP_AUTOPLUG_SINKSIDE:
+      g_value_set_boolean (value, playbin->autoplug_sinkside);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2876,6 +2903,119 @@ drained_cb (GstElement * decodebin, GstSourceGroup * group)
   setup_next_source (playbin, GST_STATE_PAUSED);
 }
 
+static gint
+_factory_cmp_func (const gpointer a, const gpointer b, GstCaps * sinkcaps)
+{
+  GstElementFactory *factory;
+  gboolean subset_a, subset_b, intersect_a, intersect_b;
+  guint rank_a, rank_b;
+
+  factory = a;
+  subset_a = FALSE;
+  intersect_a = gst_element_factory_can_src_caps (factory, sinkcaps);
+  if (intersect_a) {
+    const GList *l;
+    GstPadTemplate *template;
+    GstCaps *caps;
+
+    l = gst_element_factory_get_static_pad_templates (factory);
+    for (; l; l = l->next) {
+      template = gst_static_pad_template_get (l->data);
+      if (GST_PAD_TEMPLATE_DIRECTION (template) != GST_PAD_SRC ||
+          GST_PAD_TEMPLATE_PRESENCE (template) == GST_PAD_REQUEST)
+        continue;
+      caps = gst_pad_template_get_caps (template);
+      subset_a |= gst_caps_is_subset (caps, sinkcaps);
+      if (subset_a)
+        break;
+    }
+  }
+  rank_a = gst_plugin_feature_get_rank (GST_PLUGIN_FEATURE (factory));
+
+  factory = b;
+  subset_b = FALSE;
+  intersect_b = gst_element_factory_can_src_caps (factory, sinkcaps);
+  if (intersect_b) {
+    const GList *l;
+    GstPadTemplate *template;
+    GstCaps *caps;
+
+    l = gst_element_factory_get_static_pad_templates (factory);
+    for (; l; l = l->next) {
+      template = gst_static_pad_template_get (l->data);
+      if (GST_PAD_TEMPLATE_DIRECTION (template) != GST_PAD_SRC ||
+          GST_PAD_TEMPLATE_PRESENCE (template) == GST_PAD_REQUEST)
+        continue;
+      caps = gst_pad_template_get_caps (template);
+      subset_b |= gst_caps_is_subset (caps, sinkcaps);
+      if (subset_b)
+        break;
+    }
+  }
+  rank_b = gst_plugin_feature_get_rank (GST_PLUGIN_FEATURE (factory));
+
+  if (intersect_a != intersect_b)
+    return (intersect_a) ? -1 : 1;
+  else if (subset_a != subset_b)
+    return (subset_a) ? -1 : 1;
+  else
+    return (gint) rank_b - (gint) rank_a;
+}
+
+static GstCaps *
+_get_favored_sinkcaps (GstPlayBin * playbin, GstSourceGroup * group)
+{
+  GstCaps *caps;
+
+  GST_SOURCE_GROUP_LOCK (group);
+  g_object_get (group->uridecodebin, "caps", &caps, NULL);
+  GST_SOURCE_GROUP_UNLOCK (group);
+  caps = gst_caps_make_writable (caps);
+
+  if (caps && (playbin->audio_sink || playbin->video_sink)) {
+    GstPad *sinkpad;
+    GstCaps *sinkcaps;
+    GstStructure *st;
+    gint i;
+
+    for (i = gst_caps_get_size (caps); i > 0; i--) {
+      st = gst_caps_get_structure (caps, i - 1);
+      if ((playbin->audio_sink &&
+              g_str_has_prefix (gst_structure_get_name (st), "audio/")) ||
+          (playbin->video_sink &&
+              g_str_has_prefix (gst_structure_get_name (st), "video/")))
+        gst_caps_remove_structure (caps, i - 1);
+
+    }
+
+    if (playbin->audio_sink) {
+      sinkpad = NULL;
+      sinkpad = gst_element_get_static_pad (playbin->audio_sink, "sink");
+      if (sinkpad) {
+        sinkcaps = gst_pad_get_caps (sinkpad);
+        gst_object_unref (sinkpad);
+      } else
+        sinkcaps = gst_caps_new_empty ();
+      gst_caps_merge (caps, sinkcaps);
+    }
+
+    if (playbin->video_sink) {
+      sinkpad = NULL;
+      sinkpad = gst_element_get_static_pad (playbin->video_sink, "sink");
+      if (sinkpad) {
+        sinkcaps = gst_pad_get_caps (sinkpad);
+        gst_object_unref (sinkpad);
+      } else
+        sinkcaps = gst_caps_new_empty ();
+      gst_caps_merge (caps, sinkcaps);
+    }
+  }
+  GST_DEBUG_OBJECT (playbin,
+      "merged caps from the sink caps of all the sinks: %" GST_PTR_FORMAT,
+      caps);
+  return caps;
+}
+
 /* Called when we must provide a list of factories to plug to @pad with @caps.
  * We first check if we have a sink that can handle the format and if we do, we
  * return NULL, to expose the pad. If we have no sink (or the sink does not
@@ -2887,18 +3027,28 @@ autoplug_factories_cb (GstElement * decodebin, GstPad * pad,
   GstPlayBin *playbin;
   GList *mylist, *tmp;
   GValueArray *result;
+  GstCaps *sinkcaps;
 
   playbin = group->playbin;
 
   GST_DEBUG_OBJECT (playbin, "factories group %p for %s:%s, %" GST_PTR_FORMAT,
       group, GST_DEBUG_PAD_NAME (pad), caps);
 
+  GST_PLAY_BIN_LOCK (playbin);
+  sinkcaps = _get_favored_sinkcaps (playbin, group);
+  GST_PLAY_BIN_UNLOCK (playbin);
+
   /* filter out the elements based on the caps. */
   g_mutex_lock (playbin->elements_lock);
   gst_play_bin_update_elements_list (playbin);
   mylist =
       gst_element_factory_list_filter (playbin->elements, caps, GST_PAD_SINK,
       FALSE);
+  if (playbin->autoplug_sinkside)
+    mylist =
+        g_list_sort_with_data (mylist, (GCompareDataFunc) _factory_cmp_func,
+        sinkcaps);
+  gst_caps_unref (sinkcaps);
   g_mutex_unlock (playbin->elements_lock);
 
   GST_DEBUG_OBJECT (playbin, "found factories %p", mylist);
