Commit bd27a1f3 authored by Vivia Nikolaidou's avatar Vivia Nikolaidou Committed by Sebastian Dröge
Browse files

deinterlace: Do passthrough in auto mode if downstream only supports interlaced

If the following conditions are met:
1) upstream and downstream caps are compatible
2) upstream is interlaced
3) downstream doesn't support progressive mode
then deinterlace will just do passthrough instead of failing to link.

This is done with the following scenario in mind:

videotestsrc ! "video/x-raw,interlace-mode=interleaved" ! deinterlace
name=dein_src ! tee name=t ! queue ! deinterlace name=dein_file ! filesink t. !
queue ! deinterlace name=dein_desktop ! autovideosink
In this case, dein_src will do the deinterlacing. However,

videotestsrc ! "video/x-raw,interlace-mode=interleaved" ! deinterlace
name=dein_src ! tee name=t ! queue ! deinterlace name=dein_file ! filesink t. !
queue ! deinterlace name=dein_desktop ! autovideosink t. ! queue !
"video/x-raw,interlace-mode=interleaved" ! fakesink

In this case, caps auto-negotiation will make dein_file and dein_desktop do
the deinterlacing, while dein_src will be passthrough.

https://bugzilla.gnome.org/show_bug.cgi?id=760995
parent 46735f8d
......@@ -2504,7 +2504,7 @@ gst_deinterlace_do_bufferpool (GstDeinterlace * self, GstCaps * outcaps)
static gboolean
gst_deinterlace_setcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps)
{
GstCaps *srccaps;
GstCaps *srccaps = NULL;
GstVideoInterlaceMode interlacing_mode;
gint fps_n, fps_d;
......@@ -2555,9 +2555,52 @@ gst_deinterlace_setcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps)
"Passthrough because mode=auto and progressive caps");
self->passthrough = TRUE;
} else if (gst_caps_can_intersect (caps, tmp)) {
GstCaps *peercaps;
peercaps = gst_pad_peer_query_caps (self->srcpad, NULL);
if (peercaps) {
GstCaps *templcaps = gst_pad_get_pad_template_caps (self->srcpad);
GstCaps *allowed_caps;
GstCaps *tmp2;
GstStructure *s;
allowed_caps = gst_caps_intersect (templcaps, peercaps);
gst_caps_unref (templcaps);
gst_caps_unref (peercaps);
peercaps = allowed_caps;
allowed_caps = gst_caps_intersect (peercaps, tmp);
gst_caps_unref (peercaps);
tmp2 = gst_caps_copy (caps);
s = gst_caps_get_structure (tmp2, 0);
gst_structure_set (s, "interlace-mode", G_TYPE_STRING, "progressive",
NULL);
gst_structure_remove_field (s, "framerate");
/* Downstream does not support progressive caps but supports
* the upstream caps, go passthrough.
* TODO: We might want to check the framerate compatibility
* of the caps too here
*/
if (gst_caps_can_intersect (allowed_caps, caps)
&& !gst_caps_can_intersect (allowed_caps, tmp2)) {
GST_DEBUG_OBJECT (self,
"Passthrough because mode=auto, "
"downstream does not support progressive caps and interlaced caps");
self->passthrough = TRUE;
} else {
GST_DEBUG_OBJECT (self, "Not passthrough because mode=auto, "
"downstream supports progressive caps and interlaced caps");
self->passthrough = FALSE;
}
gst_caps_unref (allowed_caps);
gst_caps_unref (tmp2);
} else {
GST_DEBUG_OBJECT (self,
"Not passthrough because mode=auto and interlaced caps");
self->passthrough = FALSE;
}
} else {
if (self->mode == GST_DEINTERLACE_MODE_AUTO) {
GST_WARNING_OBJECT (self,
......@@ -2647,17 +2690,21 @@ gst_deinterlace_setcaps (GstDeinterlace * self, GstPad * pad, GstCaps * caps)
invalid_caps:
{
GST_ERROR_OBJECT (pad, "Invalid caps: %" GST_PTR_FORMAT, caps);
if (srccaps)
gst_caps_unref (srccaps);
return FALSE;
}
set_caps_failed:
{
GST_ERROR_OBJECT (pad, "Failed to set caps: %" GST_PTR_FORMAT, srccaps);
if (srccaps)
gst_caps_unref (srccaps);
return FALSE;
}
no_bufferpool:
{
GST_ERROR_OBJECT (pad, "could not negotiate bufferpool");
if (srccaps)
gst_caps_unref (srccaps);
return FALSE;
}
......
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