mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-13 10:55:34 +00:00
basetextoverlay: rework caps negotiation
Make textoverlay negotiate caps more correctly. 1) Check what caps we received in the video-sink 2) If it already has the overlay meta -> use it directly 3) If it doesn't, textoverlay try adding the overlay meta and using it, if downstream doesn't support it, just use what is received in the video-sink 4) Check if the allocation query also supports the meta to enable really using it Before it wasn't really doing renegotiation of any kind, just re-checking if it should use the overlay meta or not Also had to update the caps in the test as memory:SystemMemory seems to be required when you use a caps feature otherwise intersection/subset checks will fail. https://bugzilla.gnome.org/show_bug.cgi?id=733916
This commit is contained in:
parent
c20e044ef0
commit
a080c0ebbf
2 changed files with 80 additions and 37 deletions
|
@ -708,46 +708,92 @@ gst_base_text_overlay_setcaps_txt (GstBaseTextOverlay * overlay, GstCaps * caps)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: upstream nego (e.g. when the video window is resized) */
|
|
||||||
|
|
||||||
/* only negotiate/query video overlay composition support for now */
|
/* only negotiate/query video overlay composition support for now */
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_base_text_overlay_negotiate (GstBaseTextOverlay * overlay)
|
gst_base_text_overlay_negotiate (GstBaseTextOverlay * overlay, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstCaps *target;
|
|
||||||
GstQuery *query;
|
GstQuery *query;
|
||||||
gboolean attach = FALSE;
|
gboolean attach = FALSE;
|
||||||
|
gboolean caps_has_meta = TRUE;
|
||||||
|
gboolean ret;
|
||||||
|
GstCapsFeatures *f;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (overlay, "performing negotiation");
|
GST_DEBUG_OBJECT (overlay, "performing negotiation");
|
||||||
|
|
||||||
target = gst_pad_get_current_caps (overlay->srcpad);
|
if (!caps)
|
||||||
|
caps = gst_pad_get_current_caps (overlay->video_sinkpad);
|
||||||
|
else
|
||||||
|
gst_caps_ref (caps);
|
||||||
|
|
||||||
if (!target || gst_caps_is_empty (target))
|
if (!caps || gst_caps_is_empty (caps))
|
||||||
goto no_format;
|
goto no_format;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
GST_DEBUG_OBJECT (overlay, "Using caps %" GST_PTR_FORMAT, caps);
|
||||||
|
ret = gst_pad_set_caps (overlay->srcpad, caps);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
/* find supported meta */
|
/* find supported meta */
|
||||||
query = gst_query_new_allocation (target, TRUE);
|
query = gst_query_new_allocation (caps, TRUE);
|
||||||
|
|
||||||
if (!gst_pad_peer_query (overlay->srcpad, query)) {
|
if (!gst_pad_peer_query (overlay->srcpad, query)) {
|
||||||
/* no problem, we use the query defaults */
|
/* no problem, we use the query defaults */
|
||||||
GST_DEBUG_OBJECT (overlay, "ALLOCATION query failed");
|
GST_DEBUG_OBJECT (overlay, "ALLOCATION query failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gst_query_find_allocation_meta (query,
|
if (caps_has_meta && gst_query_find_allocation_meta (query,
|
||||||
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL))
|
GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL))
|
||||||
attach = TRUE;
|
attach = TRUE;
|
||||||
|
|
||||||
overlay->attach_compo_to_buffer = attach;
|
overlay->attach_compo_to_buffer = attach;
|
||||||
|
|
||||||
gst_query_unref (query);
|
gst_query_unref (query);
|
||||||
gst_caps_unref (target);
|
} else {
|
||||||
|
overlay->attach_compo_to_buffer = FALSE;
|
||||||
|
}
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
return TRUE;
|
return ret;
|
||||||
|
|
||||||
no_format:
|
no_format:
|
||||||
{
|
{
|
||||||
if (target)
|
if (caps)
|
||||||
gst_caps_unref (target);
|
gst_caps_unref (caps);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -780,12 +826,9 @@ gst_base_text_overlay_setcaps (GstBaseTextOverlay * overlay, GstCaps * caps)
|
||||||
overlay->width = GST_VIDEO_INFO_WIDTH (&info);
|
overlay->width = GST_VIDEO_INFO_WIDTH (&info);
|
||||||
overlay->height = GST_VIDEO_INFO_HEIGHT (&info);
|
overlay->height = GST_VIDEO_INFO_HEIGHT (&info);
|
||||||
|
|
||||||
ret = gst_pad_set_caps (overlay->srcpad, caps);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
|
GST_BASE_TEXT_OVERLAY_LOCK (overlay);
|
||||||
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
g_mutex_lock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||||
gst_base_text_overlay_negotiate (overlay);
|
ret = gst_base_text_overlay_negotiate (overlay, caps);
|
||||||
|
|
||||||
if (!overlay->attach_compo_to_buffer &&
|
if (!overlay->attach_compo_to_buffer &&
|
||||||
!gst_base_text_overlay_can_handle_caps (caps)) {
|
!gst_base_text_overlay_can_handle_caps (caps)) {
|
||||||
|
@ -796,7 +839,6 @@ gst_base_text_overlay_setcaps (GstBaseTextOverlay * overlay, GstCaps * caps)
|
||||||
gst_base_text_overlay_update_wrap_mode (overlay);
|
gst_base_text_overlay_update_wrap_mode (overlay);
|
||||||
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
g_mutex_unlock (GST_BASE_TEXT_OVERLAY_GET_CLASS (overlay)->pango_lock);
|
||||||
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
|
GST_BASE_TEXT_OVERLAY_UNLOCK (overlay);
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1852,7 +1894,7 @@ gst_base_text_overlay_push_frame (GstBaseTextOverlay * overlay,
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (gst_pad_check_reconfigure (overlay->srcpad))
|
if (gst_pad_check_reconfigure (overlay->srcpad))
|
||||||
gst_base_text_overlay_negotiate (overlay);
|
gst_base_text_overlay_negotiate (overlay, NULL);
|
||||||
|
|
||||||
video_frame = gst_buffer_make_writable (video_frame);
|
video_frame = gst_buffer_make_writable (video_frame);
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,8 @@ static GstPad *myvideosrcpad, *mytextsrcpad, *mysinkpad;
|
||||||
"format = (string) I420"
|
"format = (string) I420"
|
||||||
|
|
||||||
#define VIDEO_CAPS_TEMPLATE_WITH_FEATURE_STRING \
|
#define VIDEO_CAPS_TEMPLATE_WITH_FEATURE_STRING \
|
||||||
"video/x-raw(" GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
|
"video/x-raw(" GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY ", " \
|
||||||
|
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION "), " \
|
||||||
"format = (string) I420;" \
|
"format = (string) I420;" \
|
||||||
"video/x-raw, " \
|
"video/x-raw, " \
|
||||||
"format = (string) I420;"
|
"format = (string) I420;"
|
||||||
|
|
Loading…
Reference in a new issue