static gboolean
gst_base_text_overlay_negotiate (GstBaseTextOverlay * overlay, GstCaps * caps)
{
- GstQuery *query;
+ gboolean upstream_has_meta = FALSE;
+ gboolean caps_has_meta = FALSE;
+ gboolean alloc_has_meta = FALSE;
gboolean attach = FALSE;
- gboolean caps_has_meta = TRUE;
- gboolean ret;
+ gboolean ret = TRUE;
GstCapsFeatures *f;
- GstCaps *original_caps;
- gboolean original_has_meta = FALSE;
- gboolean allocation_ret = TRUE;
+ GstCaps *overlay_caps;
GST_DEBUG_OBJECT (overlay, "performing negotiation");
if (!caps || gst_caps_is_empty (caps))
goto no_format;
- original_caps = caps;
-
- /* 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);
- gst_caps_features_add (f,
+ /* Check if upstream caps have meta */
+ if ((f = gst_caps_get_features (caps, 0))) {
+ caps_has_meta = gst_caps_features_contains (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 (upstream_has_meta) {
+ overlay_caps = gst_caps_ref (caps);
} else {
- original_has_meta = TRUE;
- }
- GST_DEBUG_OBJECT (overlay, "Using caps %" GST_PTR_FORMAT, caps);
- ret = gst_pad_set_caps (overlay->srcpad, caps);
+ GstQuery *query;
- if (ret) {
- /* find supported meta */
+ /* First check if the allocation meta has compositon */
query = gst_query_new_allocation (caps, FALSE);
if (!gst_pad_peer_query (overlay->srcpad, query)) {
/* no problem, we use the query defaults */
GST_DEBUG_OBJECT (overlay, "ALLOCATION query failed");
- allocation_ret = FALSE;
+
+ /* In case we were flushing, mark reconfigure and fail this method,
+ * will make it retry */
+ if (overlay->video_flushing)
+ ret = FALSE;
}
- if (caps_has_meta && gst_query_find_allocation_meta (query,
- GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL))
- attach = TRUE;
+ alloc_has_meta = gst_query_find_allocation_meta (query,
+ GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
gst_query_unref (query);
+
+ /* Then check if downstream accept overlay composition in caps */
+ overlay_caps = gst_caps_copy (caps);
+
+ f = gst_caps_get_features (overlay_caps, 0);
+ gst_caps_features_add (f,
+ GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION);
+
+ caps_has_meta = gst_pad_peer_query_accept_caps (overlay->srcpad,
+ overlay_caps);
}
- overlay->attach_compo_to_buffer = attach;
+ /* For backward compatbility, we will prefer bliting if downstream
+ * allocation does not support the meta. In other case we will prefer
+ * attaching, and will fail the negotiation in the unlikely case we are
+ * force to blit, but format isn't supported. */
- if (!allocation_ret && overlay->video_flushing) {
- ret = FALSE;
- } else if (original_caps && !original_has_meta && !attach) {
- if (caps_has_meta) {
- /* Some elements (fakesink) claim to accept the meta on caps but won't
- put it in the allocation query result, this leads below
- check to fail. Prevent this by removing the meta from caps */
- gst_caps_unref (caps);
- caps = gst_caps_ref (original_caps);
- ret = gst_pad_set_caps (overlay->srcpad, caps);
- if (ret && !gst_base_text_overlay_can_handle_caps (caps))
- ret = FALSE;
+ if (upstream_has_meta) {
+ attach = TRUE;
+ } else if (caps_has_meta) {
+ if (alloc_has_meta) {
+ attach = TRUE;
+ } else {
+ /* Don't attach unless we cannot handle the format */
+ attach = !gst_base_text_overlay_can_handle_caps (caps);
}
+ } else {
+ ret = gst_base_text_overlay_can_handle_caps (caps);
+ }
+
+ /* If we attach, then pick the overlay caps */
+ if (attach) {
+ gst_caps_unref (caps);
+ caps = overlay_caps;
+ } else {
+ gst_caps_unref (overlay_caps);
+ }
+
+ /* If negotiation worked, set the caps and remember to attach */
+ if (ret) {
+ GST_DEBUG_OBJECT (overlay, "Using caps %" GST_PTR_FORMAT, caps);
+ overlay->attach_compo_to_buffer = attach;
+ ret = gst_pad_set_caps (overlay->srcpad, caps);
}
if (!ret) {