dvbsuboverlay: improve negotiation
authorThiago Santos <thiagoss@osg.samsung.com>
Mon, 11 Aug 2014 14:35:01 +0000 (11:35 -0300)
committerThiago Santos <thiagoss@osg.samsung.com>
Mon, 11 Aug 2014 14:35:01 +0000 (11:35 -0300)
Check if downstream supports overlay meta, if possible use it and
if not fallback to no-overlay caps

https://bugzilla.gnome.org/show_bug.cgi?id=733916

gst/dvbsuboverlay/gstdvbsuboverlay.c

index 2f36269..3965b65 100644 (file)
@@ -658,42 +658,91 @@ gst_dvbsub_overlay_can_handle_caps (GstCaps * incaps)
 
 /* only negotiate/query video overlay composition support for now */
 static gboolean
-gst_dvbsub_overlay_negotiate (GstDVBSubOverlay * overlay)
+gst_dvbsub_overlay_negotiate (GstDVBSubOverlay * overlay, GstCaps * caps)
 {
-  GstCaps *target;
-  GstQuery *query;
+  gboolean ret;
   gboolean attach = FALSE;
+  gboolean caps_has_meta = TRUE;
+  GstCapsFeatures *f;
 
   GST_DEBUG_OBJECT (overlay, "performing negotiation");
 
-  target = gst_pad_get_current_caps (overlay->srcpad);
+  if (!caps) {
+    caps = gst_pad_get_current_caps (overlay->srcpad);
+  } else {
+    gst_caps_ref (caps);
+  }
 
-  if (!target || gst_caps_is_empty (target))
+  if (!caps || gst_caps_is_empty (caps))
     goto no_format;
 
-  /* find supported meta */
-  query = gst_query_new_allocation (target, TRUE);
+  /* Try to use the overlay meta if possible */
+  f = gst_caps_get_features (caps, 0);
+
+  /* if the caps doesn't have the overlay meta, we query if downstream
+   * accepts it before trying the version without the meta
+   * If upstream already is using the meta then we can only use it */
+  if (!f
+      || !gst_caps_features_contains (f,
+          GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION)) {
+    GstCaps *overlay_caps;
+
+    /* In this case we added the meta, but we can work without it
+     * so preserve the original caps so we can use it as a fallback */
+    overlay_caps = gst_caps_copy (caps);
+
+    f = gst_caps_get_features (overlay_caps, 0);
+    if (f == NULL) {
+      f = gst_caps_features_new
+          (GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL);
+    } else {
+      gst_caps_features_add (f,
+          GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
+    }
+
+    ret = gst_pad_peer_query_accept_caps (overlay->srcpad, overlay_caps);
+    GST_DEBUG_OBJECT (overlay, "Downstream accepts the overlay meta: %d", ret);
+    if (ret) {
+      gst_caps_unref (caps);
+      caps = overlay_caps;
+
+    } else {
+      /* fallback to the original */
+      gst_caps_unref (overlay_caps);
+      caps_has_meta = FALSE;
+    }
 
-  if (!gst_pad_peer_query (overlay->srcpad, query)) {
-    /* no problem, we use the query defaults */
-    GST_DEBUG_OBJECT (overlay, "ALLOCATION query failed");
   }
+  GST_DEBUG_OBJECT (overlay, "Using caps %" GST_PTR_FORMAT, caps);
+  ret = gst_pad_set_caps (overlay->srcpad, caps);
 
-  if (gst_query_find_allocation_meta (query,
-          GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL))
-    attach = TRUE;
+  if (ret) {
+    GstQuery *query;
 
-  overlay->attach_compo_to_buffer = attach;
+    /* find supported meta */
+    query = gst_query_new_allocation (caps, TRUE);
 
-  gst_query_unref (query);
-  gst_caps_unref (target);
+    if (!gst_pad_peer_query (overlay->srcpad, query)) {
+      /* no problem, we use the query defaults */
+      GST_DEBUG_OBJECT (overlay, "ALLOCATION query failed");
+    }
+
+    if (caps_has_meta && gst_query_find_allocation_meta (query,
+            GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL))
+      attach = TRUE;
+
+    overlay->attach_compo_to_buffer = attach;
+
+    gst_query_unref (query);
+  }
+  gst_caps_unref (caps);
 
-  return TRUE;
+  return ret;
 
 no_format:
   {
-    if (target)
-      gst_caps_unref (target);
+    if (caps)
+      gst_caps_unref (caps);
     return FALSE;
   }
 }
@@ -710,11 +759,7 @@ gst_dvbsub_overlay_setcaps_video (GstPad * pad, GstCaps * caps)
 
   render->info = info;
 
-  ret = gst_pad_set_caps (render->srcpad, caps);
-  if (!ret)
-    goto out;
-
-  gst_dvbsub_overlay_negotiate (render);
+  ret = gst_dvbsub_overlay_negotiate (render, caps);
 
   if (!render->attach_compo_to_buffer &&
       !gst_dvbsub_overlay_can_handle_caps (caps))