videomixer: Don't mix input with different pixel aspect ratios

Fixes bug #618530.
This commit is contained in:
Sebastian Dröge 2010-05-14 17:57:59 +02:00
parent dc6dd62824
commit f5bca501e5
3 changed files with 33 additions and 21 deletions

View file

@ -280,7 +280,7 @@ static void
gst_videomixer_set_master_geometry (GstVideoMixer * mix) gst_videomixer_set_master_geometry (GstVideoMixer * mix)
{ {
GSList *walk; GSList *walk;
gint width = 0, height = 0, fps_n = 0, fps_d = 0; gint width = 0, height = 0, fps_n = 0, fps_d = 0, par_n = 0, par_d = 0;
GstVideoMixerPad *master = NULL; GstVideoMixerPad *master = NULL;
walk = mix->sinkpads; walk = mix->sinkpads;
@ -300,6 +300,8 @@ gst_videomixer_set_master_geometry (GstVideoMixer * mix)
((gint64) fps_n * mixpad->fps_d < (gint64) mixpad->fps_n * fps_d)) { ((gint64) fps_n * mixpad->fps_d < (gint64) mixpad->fps_n * fps_d)) {
fps_n = mixpad->fps_n; fps_n = mixpad->fps_n;
fps_d = mixpad->fps_d; fps_d = mixpad->fps_d;
par_n = mixpad->par_n;
par_d = mixpad->par_d;
GST_DEBUG_OBJECT (mixpad, "becomes the master pad"); GST_DEBUG_OBJECT (mixpad, "becomes the master pad");
master = mixpad; master = mixpad;
} }
@ -308,7 +310,7 @@ gst_videomixer_set_master_geometry (GstVideoMixer * mix)
/* set results */ /* set results */
if (mix->master != master || mix->in_width != width if (mix->master != master || mix->in_width != width
|| mix->in_height != height || mix->fps_n != fps_n || mix->in_height != height || mix->fps_n != fps_n
|| mix->fps_d != fps_d) { || mix->fps_d != fps_d || mix->par_n != par_n || mix->par_d != par_d) {
mix->setcaps = TRUE; mix->setcaps = TRUE;
mix->sendseg = TRUE; mix->sendseg = TRUE;
gst_videomixer_reset_qos (mix); gst_videomixer_reset_qos (mix);
@ -317,6 +319,8 @@ gst_videomixer_set_master_geometry (GstVideoMixer * mix)
mix->in_height = height; mix->in_height = height;
mix->fps_n = fps_n; mix->fps_n = fps_n;
mix->fps_d = fps_d; mix->fps_d = fps_d;
mix->par_n = par_n;
mix->par_d = par_d;
} }
} }
@ -328,7 +332,7 @@ gst_videomixer_pad_sink_setcaps (GstPad * pad, GstCaps * vscaps)
GstStructure *structure; GstStructure *structure;
gint in_width, in_height; gint in_width, in_height;
gboolean ret = FALSE; gboolean ret = FALSE;
const GValue *framerate; const GValue *framerate, *par;
GST_INFO_OBJECT (pad, "Setting caps %" GST_PTR_FORMAT, vscaps); GST_INFO_OBJECT (pad, "Setting caps %" GST_PTR_FORMAT, vscaps);
@ -344,10 +348,17 @@ gst_videomixer_pad_sink_setcaps (GstPad * pad, GstCaps * vscaps)
|| !gst_structure_get_int (structure, "height", &in_height) || !gst_structure_get_int (structure, "height", &in_height)
|| (framerate = gst_structure_get_value (structure, "framerate")) == NULL) || (framerate = gst_structure_get_value (structure, "framerate")) == NULL)
goto beach; goto beach;
par = gst_structure_get_value (structure, "pixel-aspect-ratio");
GST_VIDEO_MIXER_STATE_LOCK (mix); GST_VIDEO_MIXER_STATE_LOCK (mix);
mixpad->fps_n = gst_value_get_fraction_numerator (framerate); mixpad->fps_n = gst_value_get_fraction_numerator (framerate);
mixpad->fps_d = gst_value_get_fraction_denominator (framerate); mixpad->fps_d = gst_value_get_fraction_denominator (framerate);
if (par) {
mixpad->par_n = gst_value_get_fraction_numerator (par);
mixpad->par_d = gst_value_get_fraction_denominator (par);
} else {
mixpad->par_n = mixpad->par_d = 1;
}
mixpad->in_width = in_width; mixpad->in_width = in_width;
mixpad->in_height = in_height; mixpad->in_height = in_height;
@ -383,22 +394,14 @@ gst_videomixer_pad_sink_acceptcaps (GstPad * pad, GstCaps * vscaps)
acceptedCaps = gst_caps_make_writable (acceptedCaps); acceptedCaps = gst_caps_make_writable (acceptedCaps);
GST_LOG_OBJECT (pad, "master's caps %" GST_PTR_FORMAT, acceptedCaps); GST_LOG_OBJECT (pad, "master's caps %" GST_PTR_FORMAT, acceptedCaps);
if (GST_CAPS_IS_SIMPLE (acceptedCaps)) { if (GST_CAPS_IS_SIMPLE (acceptedCaps)) {
int templCapsSize = GstStructure *s;
gst_caps_get_size (gst_pad_get_pad_template_caps (pad)); s = gst_caps_get_structure (acceptedCaps, 0);
guint i; gst_structure_set (s, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
for (i = 0; i < templCapsSize; i++) { "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
GstCaps *caps1 = gst_caps_copy (acceptedCaps); "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
GstCaps *caps2 = if (!gst_structure_has_field (s, "pixel-aspect-ratio"))
gst_caps_copy_nth (gst_pad_get_pad_template_caps (pad), i); gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
gst_caps_merge (caps1, caps2); NULL);
gst_caps_do_simplify (caps1);
if (GST_CAPS_IS_SIMPLE (caps1)) {
gst_caps_replace (&acceptedCaps, caps1);
gst_caps_unref (caps1);
break;
}
gst_caps_unref (caps1);
}
} }
} else { } else {
acceptedCaps = gst_pad_get_fixed_caps_func (pad); acceptedCaps = gst_pad_get_fixed_caps_func (pad);
@ -407,7 +410,9 @@ gst_videomixer_pad_sink_acceptcaps (GstPad * pad, GstCaps * vscaps)
GST_INFO_OBJECT (pad, "vscaps: %" GST_PTR_FORMAT, vscaps); GST_INFO_OBJECT (pad, "vscaps: %" GST_PTR_FORMAT, vscaps);
GST_INFO_OBJECT (pad, "acceptedCaps: %" GST_PTR_FORMAT, acceptedCaps); GST_INFO_OBJECT (pad, "acceptedCaps: %" GST_PTR_FORMAT, acceptedCaps);
ret = gst_caps_is_always_compatible (vscaps, acceptedCaps); ret = gst_caps_can_intersect (vscaps, acceptedCaps);
GST_INFO_OBJECT (pad, "%saccepted caps %" GST_PTR_FORMAT, (ret ? "" : "not "),
vscaps);
gst_caps_unref (acceptedCaps); gst_caps_unref (acceptedCaps);
GST_VIDEO_MIXER_STATE_UNLOCK (mix); GST_VIDEO_MIXER_STATE_UNLOCK (mix);
gst_object_unref (mix); gst_object_unref (mix);
@ -636,6 +641,7 @@ gst_videomixer_reset (GstVideoMixer * mix)
mix->out_width = 0; mix->out_width = 0;
mix->out_height = 0; mix->out_height = 0;
mix->fps_n = mix->fps_d = 0; mix->fps_n = mix->fps_d = 0;
mix->par_n = mix->par_d = 1;
mix->setcaps = FALSE; mix->setcaps = FALSE;
mix->sendseg = FALSE; mix->sendseg = FALSE;
@ -1430,7 +1436,8 @@ gst_videomixer_collected (GstCollectPads * pads, GstVideoMixer * mix)
(gst_pad_get_negotiated_caps (GST_PAD (mix->master))); (gst_pad_get_negotiated_caps (GST_PAD (mix->master)));
gst_caps_set_simple (newcaps, gst_caps_set_simple (newcaps,
"width", G_TYPE_INT, mix->in_width, "width", G_TYPE_INT, mix->in_width,
"height", G_TYPE_INT, mix->in_height, NULL); "height", G_TYPE_INT, mix->in_height,
"pixel-aspect-ratio", GST_TYPE_FRACTION, mix->par_n, mix->par_d, NULL);
mix->out_width = mix->in_width; mix->out_width = mix->in_width;
mix->out_height = mix->in_height; mix->out_height = mix->in_height;

View file

@ -99,6 +99,9 @@ struct _GstVideoMixer
gint fps_n; gint fps_n;
gint fps_d; gint fps_d;
gint par_n;
gint par_d;
/* Next available sinkpad index */ /* Next available sinkpad index */
gint next_sinkpad; gint next_sinkpad;

View file

@ -58,6 +58,8 @@ struct _GstVideoMixerPad
guint in_width, in_height; guint in_width, in_height;
gint fps_n; gint fps_n;
gint fps_d; gint fps_d;
gint par_n;
gint par_d;
gint xpos, ypos; gint xpos, ypos;
guint zorder; guint zorder;