capsfilter: optimisation: avoid unnecessary gst_pad_has_current_caps() checks

No need to do this for every input buffer, since it involves
locking and iterating of the sticky events array and such.

https://bugzilla.gnome.org/show_bug.cgi?id=763337
This commit is contained in:
Tim-Philipp Müller 2016-03-08 19:08:16 +00:00 committed by Sebastian Dröge
parent 8cc3e908c3
commit bc78548cfe
2 changed files with 30 additions and 23 deletions

View file

@ -167,6 +167,7 @@ gst_capsfilter_init (GstCapsFilter * filter)
gst_base_transform_set_prefer_passthrough (trans, FALSE); gst_base_transform_set_prefer_passthrough (trans, FALSE);
filter->filter_caps = gst_caps_new_any (); filter->filter_caps = gst_caps_new_any ();
filter->filter_caps_used = FALSE; filter->filter_caps_used = FALSE;
filter->got_sink_caps = FALSE;
filter->caps_change_mode = DEFAULT_CAPS_CHANGE_MODE; filter->caps_change_mode = DEFAULT_CAPS_CHANGE_MODE;
} }
@ -404,7 +405,7 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
*buf = input; *buf = input;
if (GST_PAD_MODE (trans->srcpad) == GST_PAD_MODE_PUSH if (GST_PAD_MODE (trans->srcpad) == GST_PAD_MODE_PUSH
&& !gst_pad_has_current_caps (trans->sinkpad)) { && !filter->got_sink_caps) {
/* No caps. See if the output pad only supports fixed caps */ /* No caps. See if the output pad only supports fixed caps */
GstCaps *out_caps; GstCaps *out_caps;
@ -505,7 +506,7 @@ gst_capsfilter_sink_event (GstBaseTransform * trans, GstEvent * event)
} }
g_list_free (filter->pending_events); g_list_free (filter->pending_events);
filter->pending_events = NULL; filter->pending_events = NULL;
} else if (!gst_pad_has_current_caps (trans->sinkpad)) { } else if (!filter->got_sink_caps) {
GST_LOG_OBJECT (trans, "Got %s event before caps, queueing", GST_LOG_OBJECT (trans, "Got %s event before caps, queueing",
GST_EVENT_TYPE_NAME (event)); GST_EVENT_TYPE_NAME (event));
@ -521,32 +522,35 @@ done:
GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans,
gst_event_ref (event)); gst_event_ref (event));
if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS) {
&& filter->caps_change_mode == GST_CAPS_FILTER_CAPS_CHANGE_MODE_DELAYED) { filter->got_sink_caps = TRUE;
GList *l; if (filter->caps_change_mode == GST_CAPS_FILTER_CAPS_CHANGE_MODE_DELAYED) {
GstCaps *caps; GList *l;
GstCaps *caps;
gst_event_parse_caps (event, &caps); gst_event_parse_caps (event, &caps);
/* Remove all previous caps up to one that works. /* Remove all previous caps up to one that works.
* Note that this might keep some leftover caps if there * Note that this might keep some leftover caps if there
* are multiple compatible caps */ * are multiple compatible caps */
GST_OBJECT_LOCK (filter); GST_OBJECT_LOCK (filter);
for (l = g_list_last (filter->previous_caps); l; l = l->prev) { for (l = g_list_last (filter->previous_caps); l; l = l->prev) {
if (gst_caps_can_intersect (caps, l->data)) { if (gst_caps_can_intersect (caps, l->data)) {
while (l->next) { while (l->next) {
gst_caps_unref (l->next->data); gst_caps_unref (l->next->data);
l = g_list_delete_link (l, l->next); l = g_list_delete_link (l, l->next);
}
break;
} }
break;
} }
if (!l && gst_caps_can_intersect (caps, filter->filter_caps)) {
g_list_free_full (filter->previous_caps,
(GDestroyNotify) gst_caps_unref);
filter->previous_caps = NULL;
filter->filter_caps_used = TRUE;
}
GST_OBJECT_UNLOCK (filter);
} }
if (!l && gst_caps_can_intersect (caps, filter->filter_caps)) {
g_list_free_full (filter->previous_caps, (GDestroyNotify) gst_caps_unref);
filter->previous_caps = NULL;
filter->filter_caps_used = TRUE;
}
GST_OBJECT_UNLOCK (filter);
} }
gst_event_unref (event); gst_event_unref (event);
@ -566,5 +570,7 @@ gst_capsfilter_stop (GstBaseTransform * trans)
filter->previous_caps = NULL; filter->previous_caps = NULL;
GST_OBJECT_UNLOCK (filter); GST_OBJECT_UNLOCK (filter);
filter->got_sink_caps = FALSE;
return TRUE; return TRUE;
} }

View file

@ -67,6 +67,7 @@ struct _GstCapsFilter {
GstCaps *filter_caps; GstCaps *filter_caps;
gboolean filter_caps_used; gboolean filter_caps_used;
GstCapsFilterCapsChangeMode caps_change_mode; GstCapsFilterCapsChangeMode caps_change_mode;
gboolean got_sink_caps;
GList *pending_events; GList *pending_events;
GList *previous_caps; GList *previous_caps;