Commit 5c7b051b authored by Thiago Santos's avatar Thiago Santos

deinterleave: implement accept-caps

Avoid using default accept-caps handler that will query downstream
and is more expensive. Just check if the caps is compatible with
the template and check if the channels are the same.
parent c0c8d503
...@@ -361,41 +361,24 @@ gst_deinterleave_set_process_function (GstDeinterleave * self) ...@@ -361,41 +361,24 @@ gst_deinterleave_set_process_function (GstDeinterleave * self)
} }
static gboolean static gboolean
gst_deinterleave_sink_setcaps (GstDeinterleave * self, GstCaps * caps) gst_deinterleave_check_caps_change (GstDeinterleave * self,
GstAudioInfo * old_info, GstAudioInfo * new_info)
{ {
GstCaps *srccaps;
GstStructure *s;
GST_DEBUG_OBJECT (self, "got caps: %" GST_PTR_FORMAT, caps);
if (!gst_audio_info_from_caps (&self->audio_info, caps))
goto invalid_caps;
if (!gst_deinterleave_set_process_function (self))
goto unsupported_caps;
if (self->sinkcaps && !gst_caps_is_equal (caps, self->sinkcaps)) {
gint i; gint i;
gboolean same_layout = TRUE; gboolean same_layout = TRUE;
gboolean was_unpositioned; gboolean was_unpositioned;
gboolean is_unpositioned = gboolean is_unpositioned = GST_AUDIO_INFO_IS_UNPOSITIONED (new_info);
GST_AUDIO_INFO_IS_UNPOSITIONED (&self->audio_info); gint new_channels = GST_AUDIO_INFO_CHANNELS (new_info);
gint new_channels = GST_AUDIO_INFO_CHANNELS (&self->audio_info);
gint old_channels; gint old_channels;
GstAudioInfo old_info;
gst_audio_info_init (&old_info); was_unpositioned = GST_AUDIO_INFO_IS_UNPOSITIONED (old_info);
if (!gst_audio_info_from_caps (&old_info, self->sinkcaps)) old_channels = GST_AUDIO_INFO_CHANNELS (old_info);
goto info_from_caps_failed;
was_unpositioned = GST_AUDIO_INFO_IS_UNPOSITIONED (&old_info);
old_channels = GST_AUDIO_INFO_CHANNELS (&old_info);
/* We allow caps changes as long as the number of channels doesn't change /* We allow caps changes as long as the number of channels doesn't change
* and the channel positions stay the same. _getcaps() should've cared * and the channel positions stay the same. _getcaps() should've cared
* for this already but better be safe. * for this already but better be safe.
*/ */
if (new_channels != old_channels || if (new_channels != old_channels)
!gst_deinterleave_set_process_function (self))
goto cannot_change_caps; goto cannot_change_caps;
/* Now check the channel positions. If we had no channel positions /* Now check the channel positions. If we had no channel positions
...@@ -408,11 +391,11 @@ gst_deinterleave_sink_setcaps (GstDeinterleave * self, GstCaps * caps) ...@@ -408,11 +391,11 @@ gst_deinterleave_sink_setcaps (GstDeinterleave * self, GstCaps * caps)
goto cannot_change_caps; goto cannot_change_caps;
if (!is_unpositioned) { if (!is_unpositioned) {
if (GST_AUDIO_INFO_CHANNELS (&old_info) != if (GST_AUDIO_INFO_CHANNELS (old_info) !=
GST_AUDIO_INFO_CHANNELS (&self->audio_info)) GST_AUDIO_INFO_CHANNELS (new_info))
goto cannot_change_caps; goto cannot_change_caps;
for (i = 0; i < GST_AUDIO_INFO_CHANNELS (&old_info); i++) { for (i = 0; i < GST_AUDIO_INFO_CHANNELS (old_info); i++) {
if (self->audio_info.position[i] != old_info.position[i]) { if (new_info->position[i] != old_info->position[i]) {
same_layout = FALSE; same_layout = FALSE;
break; break;
} }
...@@ -421,6 +404,39 @@ gst_deinterleave_sink_setcaps (GstDeinterleave * self, GstCaps * caps) ...@@ -421,6 +404,39 @@ gst_deinterleave_sink_setcaps (GstDeinterleave * self, GstCaps * caps)
goto cannot_change_caps; goto cannot_change_caps;
} }
return TRUE;
cannot_change_caps:
return FALSE;
}
static gboolean
gst_deinterleave_sink_setcaps (GstDeinterleave * self, GstCaps * caps)
{
GstCaps *srccaps;
GstStructure *s;
GST_DEBUG_OBJECT (self, "got caps: %" GST_PTR_FORMAT, caps);
if (!gst_audio_info_from_caps (&self->audio_info, caps))
goto invalid_caps;
if (!gst_deinterleave_set_process_function (self))
goto unsupported_caps;
if (self->sinkcaps && !gst_caps_is_equal (caps, self->sinkcaps)) {
GstAudioInfo old_info;
gst_audio_info_init (&old_info);
if (!gst_audio_info_from_caps (&old_info, self->sinkcaps))
goto info_from_caps_failed;
if (gst_deinterleave_check_caps_change (self, &old_info, &self->audio_info)) {
if (!gst_deinterleave_set_process_function (self))
goto cannot_change_caps;
} else
goto cannot_change_caps;
} }
gst_caps_replace (&self->sinkcaps, caps); gst_caps_replace (&self->sinkcaps, caps);
...@@ -504,6 +520,35 @@ __set_channels (GstCaps * caps, gint channels) ...@@ -504,6 +520,35 @@ __set_channels (GstCaps * caps, gint channels)
} }
} }
static gboolean
gst_deinterleave_sink_acceptcaps (GstPad * pad, GstObject * parent,
GstCaps * caps)
{
GstDeinterleave *self = GST_DEINTERLEAVE (parent);
GstCaps *templ_caps = gst_pad_get_pad_template_caps (pad);
gboolean ret;
ret = gst_caps_can_intersect (templ_caps, caps);
gst_caps_unref (templ_caps);
if (ret && self->sinkcaps) {
GstAudioInfo new_info;
gst_audio_info_init (&new_info);
if (!gst_audio_info_from_caps (&new_info, caps))
goto info_from_caps_failed;
ret =
gst_deinterleave_check_caps_change (self, &self->audio_info, &new_info);
}
return ret;
info_from_caps_failed:
{
GST_ERROR_OBJECT (self, "coud not get info from caps");
return FALSE;
}
}
static GstCaps * static GstCaps *
gst_deinterleave_getcaps (GstPad * pad, GstObject * parent, GstCaps * filter) gst_deinterleave_getcaps (GstPad * pad, GstObject * parent, GstCaps * filter)
{ {
...@@ -642,6 +687,16 @@ gst_deinterleave_sink_query (GstPad * pad, GstObject * parent, GstQuery * query) ...@@ -642,6 +687,16 @@ gst_deinterleave_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
res = TRUE; res = TRUE;
break; break;
} }
case GST_QUERY_ACCEPT_CAPS:{
GstCaps *caps;
gboolean ret;
gst_query_parse_accept_caps (query, &caps);
ret = gst_deinterleave_sink_acceptcaps (pad, parent, caps);
gst_query_set_accept_caps_result (query, ret);
res = TRUE;
break;
}
default: default:
res = gst_pad_query_default (pad, parent, query); res = gst_pad_query_default (pad, parent, query);
break; break;
......
...@@ -306,6 +306,7 @@ GST_START_TEST (test_2_channels_caps_change) ...@@ -306,6 +306,7 @@ GST_START_TEST (test_2_channels_caps_change)
ret_caps = gst_pad_peer_query_caps (mysrcpad, caps); ret_caps = gst_pad_peer_query_caps (mysrcpad, caps);
fail_if (gst_caps_is_empty (ret_caps)); fail_if (gst_caps_is_empty (ret_caps));
fail_unless (gst_pad_peer_query_accept_caps (mysrcpad, caps));
gst_caps_unref (ret_caps); gst_caps_unref (ret_caps);
gst_check_setup_events (mysrcpad, deinterleave, caps, GST_FORMAT_TIME); gst_check_setup_events (mysrcpad, deinterleave, caps, GST_FORMAT_TIME);
...@@ -340,6 +341,7 @@ GST_START_TEST (test_2_channels_caps_change) ...@@ -340,6 +341,7 @@ GST_START_TEST (test_2_channels_caps_change)
NULL); NULL);
ret_caps = gst_pad_peer_query_caps (mysrcpad, caps2); ret_caps = gst_pad_peer_query_caps (mysrcpad, caps2);
fail_if (gst_caps_is_empty (ret_caps)); fail_if (gst_caps_is_empty (ret_caps));
fail_unless (gst_pad_peer_query_accept_caps (mysrcpad, caps2));
gst_caps_unref (ret_caps); gst_caps_unref (ret_caps);
gst_pad_set_caps (mysrcpad, caps2); gst_pad_set_caps (mysrcpad, caps2);
...@@ -371,6 +373,7 @@ GST_START_TEST (test_2_channels_caps_change) ...@@ -371,6 +373,7 @@ GST_START_TEST (test_2_channels_caps_change)
ret_caps = gst_pad_peer_query_caps (mysrcpad, caps2); ret_caps = gst_pad_peer_query_caps (mysrcpad, caps2);
fail_unless (gst_caps_is_empty (ret_caps)); fail_unless (gst_caps_is_empty (ret_caps));
gst_caps_unref (ret_caps); gst_caps_unref (ret_caps);
fail_if (gst_pad_peer_query_accept_caps (mysrcpad, caps2));
gst_pad_set_caps (mysrcpad, caps2); gst_pad_set_caps (mysrcpad, caps2);
inbuf = gst_buffer_new_and_alloc (3 * 48000 * sizeof (gfloat)); inbuf = gst_buffer_new_and_alloc (3 * 48000 * sizeof (gfloat));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment