From 620d330953042888aade78f06e240bc45b496cb2 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Mon, 4 Jun 2012 18:44:56 +1000 Subject: [PATCH] [505/906] GstGLColorscale: update for 1.0 --- gst/gl/gstglcolorscale.c | 610 +++++++++++++++++++++++++++++---------- 1 file changed, 456 insertions(+), 154 deletions(-) diff --git a/gst/gl/gstglcolorscale.c b/gst/gl/gstglcolorscale.c index 63b7846109..f67164cfff 100644 --- a/gst/gl/gstglcolorscale.c +++ b/gst/gl/gstglcolorscale.c @@ -55,26 +55,18 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); /* Source pad definition */ static GstStaticPadTemplate gst_gl_colorscale_src_pad_template = - GST_STATIC_PAD_TEMPLATE ("src", +GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx ";" - GST_VIDEO_CAPS_BGRx ";" - GST_VIDEO_CAPS_xRGB ";" - GST_VIDEO_CAPS_xBGR ";" - GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }")) + GST_STATIC_CAPS (GST_GL_VIDEO_CAPS) ); /* Source pad definition */ static GstStaticPadTemplate gst_gl_colorscale_sink_pad_template = - GST_STATIC_PAD_TEMPLATE ("sink", +GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBx ";" - GST_VIDEO_CAPS_BGRx ";" - GST_VIDEO_CAPS_xRGB ";" - GST_VIDEO_CAPS_xBGR ";" - GST_VIDEO_CAPS_YUV ("{ I420, YV12, YUY2, UYVY, AYUV }")) + GST_STATIC_CAPS (GST_GL_VIDEO_CAPS) ); /* Properties */ @@ -98,22 +90,17 @@ static void gst_gl_colorscale_reset (GstGLColorscale * colorscale); static gboolean gst_gl_colorscale_set_caps (GstBaseTransform * bt, GstCaps * incaps, GstCaps * outcaps); static GstCaps *gst_gl_colorscale_transform_caps (GstBaseTransform * bt, - GstPadDirection direction, GstCaps * caps); -static void gst_gl_colorscale_fixate_caps (GstBaseTransform * base, + GstPadDirection direction, GstCaps * caps, GstCaps * filter); +static GstCaps *gst_gl_colorscale_fixate_caps (GstBaseTransform * base, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps); static gboolean gst_gl_colorscale_start (GstBaseTransform * bt); static gboolean gst_gl_colorscale_stop (GstBaseTransform * bt); static GstFlowReturn gst_gl_colorscale_transform (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf); static gboolean gst_gl_colorscale_get_unit_size (GstBaseTransform * trans, - GstCaps * caps, guint * size); + GstCaps * caps, gsize * size); -static void -gst_gl_colorscale_base_init (gpointer klass) -{ -} - static void gst_gl_colorscale_class_init (GstGLColorscaleClass * klass) { @@ -207,23 +194,22 @@ gst_gl_colorscale_stop (GstBaseTransform * bt) static GstCaps * gst_gl_colorscale_transform_caps (GstBaseTransform * bt, - GstPadDirection direction, GstCaps * caps) + GstPadDirection direction, GstCaps * caps, GstCaps * filter) { //GstGLColorscale* colorscale = GST_GL_COLORSCALE (bt); - GstStructure *structure = gst_caps_get_structure (caps, 0); - GstCaps *newcaps = gst_caps_new_simple ("video/x-raw-yuv", NULL); - GstCaps *newothercaps = gst_caps_new_simple ("video/x-raw-rgb", NULL); - const GValue *framerate_value = NULL; - const GValue *par_value = NULL; + GstStructure *structure; + GstCaps *newcaps; + const GValue *framerate_value; + const GValue *par_value; GST_DEBUG ("transform caps %" GST_PTR_FORMAT, caps); + structure = gst_caps_get_structure (caps, 0); + newcaps = gst_caps_new_empty_simple ("video/x-raw"); + framerate_value = gst_structure_get_value (structure, "framerate"); par_value = gst_structure_get_value (structure, "pixel-aspect-ratio"); - gst_caps_append (newcaps, newothercaps); - - structure = gst_structure_copy (gst_caps_get_structure (newcaps, 0)); gst_structure_set (structure, @@ -237,7 +223,7 @@ gst_gl_colorscale_transform_caps (GstBaseTransform * bt, gst_structure_set (structure, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); - gst_caps_merge_structure (newcaps, gst_structure_copy (structure)); + newcaps = gst_caps_merge_structure (newcaps, gst_structure_copy (structure)); GST_DEBUG ("new caps %" GST_PTR_FORMAT, newcaps); @@ -245,15 +231,17 @@ gst_gl_colorscale_transform_caps (GstBaseTransform * bt, } /* from gst-plugins-base "videoscale" code */ -static void +static GstCaps * gst_gl_colorscale_fixate_caps (GstBaseTransform * base, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps) { GstStructure *ins, *outs; - const GValue *from_par, *to_par; + GValue fpar = { 0, }, tpar = { + 0,}; - g_return_if_fail (gst_caps_is_fixed (caps)); + othercaps = gst_caps_truncate (othercaps); + othercaps = gst_caps_make_writable (othercaps); GST_DEBUG_OBJECT (base, "trying to fixate othercaps %" GST_PTR_FORMAT " based on caps %" GST_PTR_FORMAT, othercaps, caps); @@ -264,130 +252,451 @@ gst_gl_colorscale_fixate_caps (GstBaseTransform * base, from_par = gst_structure_get_value (ins, "pixel-aspect-ratio"); to_par = gst_structure_get_value (outs, "pixel-aspect-ratio"); - //we have both PAR but they might not be fixated - if (from_par && to_par) { + /* If we're fixating from the sinkpad we always set the PAR and + * assume that missing PAR on the sinkpad means 1/1 and + * missing PAR on the srcpad means undefined + */ + if (direction == GST_PAD_SINK) { + if (!from_par) { + g_value_init (&fpar, GST_TYPE_FRACTION); + gst_value_set_fraction (&fpar, 1, 1); + from_par = &fpar; + } + if (!to_par) { + g_value_init (&tpar, GST_TYPE_FRACTION_RANGE); + gst_value_set_fraction_range_full (&tpar, 1, G_MAXINT, G_MAXINT, 1); + to_par = &tpar; + } + } else { + if (!to_par) { + g_value_init (&tpar, GST_TYPE_FRACTION); + gst_value_set_fraction (&tpar, 1, 1); + to_par = &tpar; + + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, + NULL); + } + if (!from_par) { + g_value_init (&fpar, GST_TYPE_FRACTION); + gst_value_set_fraction (&fpar, 1, 1); + from_par = &fpar; + } + } + + /* we have both PAR but they might not be fixated */ + { gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d; + gint w = 0, h = 0; + gint from_dar_n, from_dar_d; + gint num, den; - gint count = 0, w = 0, h = 0; - - guint num, den; - - //from_par should be fixed - g_return_if_fail (gst_value_is_fixed (from_par)); + /* from_par should be fixed */ + g_return_val_if_fail (gst_value_is_fixed (from_par), othercaps); from_par_n = gst_value_get_fraction_numerator (from_par); from_par_d = gst_value_get_fraction_denominator (from_par); - //fixate the out PAR - if (!gst_value_is_fixed (to_par)) { - GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", from_par_n, - from_par_d); - gst_structure_fixate_field_nearest_fraction (outs, "pixel-aspect-ratio", - from_par_n, from_par_d); - } - - to_par_n = gst_value_get_fraction_numerator (to_par); - to_par_d = gst_value_get_fraction_denominator (to_par); - - //f both width and height are already fixed, we can't do anything - //about it anymore - if (gst_structure_get_int (outs, "width", &w)) - ++count; - if (gst_structure_get_int (outs, "height", &h)) - ++count; - if (count == 2) { - GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating", - w, h); - return; - } - gst_structure_get_int (ins, "width", &from_w); gst_structure_get_int (ins, "height", &from_h); - if (!gst_video_calculate_display_ratio (&num, &den, from_w, from_h, - from_par_n, from_par_d, to_par_n, to_par_d)) { + gst_structure_get_int (outs, "width", &w); + gst_structure_get_int (outs, "height", &h); + + /* if both width and height are already fixed, we can't do anything + * about it anymore */ + if (w && h) { + guint n, d; + + GST_DEBUG_OBJECT (base, "dimensions already set to %dx%d, not fixating", + w, h); + if (!gst_value_is_fixed (to_par)) { + if (gst_video_calculate_display_ratio (&n, &d, from_w, from_h, + from_par_n, from_par_d, w, h)) { + GST_DEBUG_OBJECT (base, "fixating to_par to %dx%d", n, d); + if (gst_structure_has_field (outs, "pixel-aspect-ratio")) + gst_structure_fixate_field_nearest_fraction (outs, + "pixel-aspect-ratio", n, d); + else if (n != d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + n, d, NULL); + } + } + goto done; + } + + /* Calculate input DAR */ + if (!gst_util_fraction_multiply (from_w, from_h, from_par_n, from_par_d, + &from_dar_n, &from_dar_d)) { GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), ("Error calculating the output scaled size - integer overflow")); - return; + goto done; } - GST_DEBUG_OBJECT (base, - "scaling input with %dx%d and PAR %d/%d to output PAR %d/%d", - from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d); - GST_DEBUG_OBJECT (base, "resulting output should respect ratio of %d/%d", - num, den); + GST_DEBUG_OBJECT (base, "Input DAR is %d/%d", from_dar_n, from_dar_d); - //now find a width x height that respects this display ratio. - //prefer those that have one of w/h the same as the incoming video - //using wd / hd = num / den - - //if one of the output width or height is fixed, we work from there + /* If either width or height are fixed there's not much we + * can do either except choosing a height or width and PAR + * that matches the DAR as good as possible + */ if (h) { - GST_DEBUG_OBJECT (base, "height is fixed,scaling width"); + GstStructure *tmp; + gint set_w, set_par_n, set_par_d; + + GST_DEBUG_OBJECT (base, "height is fixed (%d)", h); + + /* If the PAR is fixed too, there's not much to do + * except choosing the width that is nearest to the + * width with the same DAR */ + if (gst_value_is_fixed (to_par)) { + to_par_n = gst_value_get_fraction_numerator (to_par); + to_par_d = gst_value_get_fraction_denominator (to_par); + + GST_DEBUG_OBJECT (base, "PAR is fixed %d/%d", to_par_n, to_par_d); + + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d, + to_par_n, &num, &den)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + goto done; + } + + w = (guint) gst_util_uint64_scale_int (h, num, den); + gst_structure_fixate_field_nearest_int (outs, "width", w); + + goto done; + } + + /* The PAR is not fixed and it's quite likely that we can set + * an arbitrary PAR. */ + + /* Check if we can keep the input width */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "width", from_w); + gst_structure_get_int (tmp, "width", &set_w); + + /* Might have failed but try to keep the DAR nonetheless by + * adjusting the PAR */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, h, set_w, + &to_par_n, &to_par_d)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + gst_structure_free (tmp); + goto done; + } + + if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) + gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); + gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", + to_par_n, to_par_d); + gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, + &set_par_d); + gst_structure_free (tmp); + + /* Check if the adjusted PAR is accepted */ + if (set_par_n == to_par_n && set_par_d == to_par_d) { + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "width", G_TYPE_INT, set_w, + "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d, + NULL); + goto done; + } + + /* Otherwise scale the width to the new PAR and check if the + * adjusted with is accepted. If all that fails we can't keep + * the DAR */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, + set_par_n, &num, &den)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + goto done; + } + w = (guint) gst_util_uint64_scale_int (h, num, den); + gst_structure_fixate_field_nearest_int (outs, "width", w); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + + goto done; } else if (w) { - GST_DEBUG_OBJECT (base, "width is fixed, scaling height"); - h = (guint) gst_util_uint64_scale_int (w, den, num); - } else { - //none of width or height is fixed, figure out both of them based only on - //the input width and height - //check hd / den is an integer scale factor, and scale wd with the PAR - if (from_h % den == 0) { - GST_DEBUG_OBJECT (base, "keeping video height"); - h = from_h; - w = (guint) gst_util_uint64_scale_int (h, num, den); - } else if (from_w % num == 0) { - GST_DEBUG_OBJECT (base, "keeping video width"); - w = from_w; + GstStructure *tmp; + gint set_h, set_par_n, set_par_d; + + GST_DEBUG_OBJECT (base, "width is fixed (%d)", w); + + /* If the PAR is fixed too, there's not much to do + * except choosing the height that is nearest to the + * height with the same DAR */ + if (gst_value_is_fixed (to_par)) { + to_par_n = gst_value_get_fraction_numerator (to_par); + to_par_d = gst_value_get_fraction_denominator (to_par); + + GST_DEBUG_OBJECT (base, "PAR is fixed %d/%d", to_par_n, to_par_d); + + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_d, + to_par_n, &num, &den)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + goto done; + } + h = (guint) gst_util_uint64_scale_int (w, den, num); - } else { - GST_DEBUG_OBJECT (base, "approximating but keeping video height"); - h = from_h; - w = (guint) gst_util_uint64_scale_int (h, num, den); - } - } - GST_DEBUG_OBJECT (base, "scaling to %dx%d", w, h); + gst_structure_fixate_field_nearest_int (outs, "height", h); - //now fixate - gst_structure_fixate_field_nearest_int (outs, "width", w); - gst_structure_fixate_field_nearest_int (outs, "height", h); - } else { - gint width, height; - - if (gst_structure_get_int (ins, "width", &width)) { - if (gst_structure_has_field (outs, "width")) - gst_structure_fixate_field_nearest_int (outs, "width", width); - } - if (gst_structure_get_int (ins, "height", &height)) { - if (gst_structure_has_field (outs, "height")) { - gst_structure_fixate_field_nearest_int (outs, "height", height); + goto done; } + + /* The PAR is not fixed and it's quite likely that we can set + * an arbitrary PAR. */ + + /* Check if we can keep the input height */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "height", from_h); + gst_structure_get_int (tmp, "height", &set_h); + + /* Might have failed but try to keep the DAR nonetheless by + * adjusting the PAR */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, w, + &to_par_n, &to_par_d)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + gst_structure_free (tmp); + goto done; + } + if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) + gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); + gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", + to_par_n, to_par_d); + gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, + &set_par_d); + gst_structure_free (tmp); + + /* Check if the adjusted PAR is accepted */ + if (set_par_n == to_par_n && set_par_d == to_par_d) { + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "height", G_TYPE_INT, set_h, + "pixel-aspect-ratio", GST_TYPE_FRACTION, set_par_n, set_par_d, + NULL); + goto done; + } + + /* Otherwise scale the height to the new PAR and check if the + * adjusted with is accepted. If all that fails we can't keep + * the DAR */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, + set_par_n, &num, &den)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + goto done; + } + + h = (guint) gst_util_uint64_scale_int (w, den, num); + gst_structure_fixate_field_nearest_int (outs, "height", h); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + + goto done; + } else if (gst_value_is_fixed (to_par)) { + GstStructure *tmp; + gint set_h, set_w, f_h, f_w; + + to_par_n = gst_value_get_fraction_numerator (to_par); + to_par_d = gst_value_get_fraction_denominator (to_par); + + /* Calculate scale factor for the PAR change */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, to_par_n, + to_par_d, &num, &den)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + goto done; + } + + /* Try to keep the input height (because of interlacing) */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "height", from_h); + gst_structure_get_int (tmp, "height", &set_h); + + /* This might have failed but try to scale the width + * to keep the DAR nonetheless */ + w = (guint) gst_util_uint64_scale_int (set_h, num, den); + gst_structure_fixate_field_nearest_int (tmp, "width", w); + gst_structure_get_int (tmp, "width", &set_w); + gst_structure_free (tmp); + + /* We kept the DAR and the height is nearest to the original height */ + if (set_w == w) { + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, set_h, NULL); + goto done; + } + + f_h = set_h; + f_w = set_w; + + /* If the former failed, try to keep the input width at least */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "width", from_w); + gst_structure_get_int (tmp, "width", &set_w); + + /* This might have failed but try to scale the width + * to keep the DAR nonetheless */ + h = (guint) gst_util_uint64_scale_int (set_w, den, num); + gst_structure_fixate_field_nearest_int (tmp, "height", h); + gst_structure_get_int (tmp, "height", &set_h); + gst_structure_free (tmp); + + /* We kept the DAR and the width is nearest to the original width */ + if (set_h == h) { + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, set_h, NULL); + goto done; + } + + /* If all this failed, keep the height that was nearest to the orignal + * height and the nearest possible width. This changes the DAR but + * there's not much else to do here. + */ + gst_structure_set (outs, "width", G_TYPE_INT, f_w, "height", G_TYPE_INT, + f_h, NULL); + goto done; + } else { + GstStructure *tmp; + gint set_h, set_w, set_par_n, set_par_d, tmp2; + + /* width, height and PAR are not fixed but passthrough is not possible */ + + /* First try to keep the height and width as good as possible + * and scale PAR */ + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "height", from_h); + gst_structure_get_int (tmp, "height", &set_h); + gst_structure_fixate_field_nearest_int (tmp, "width", from_w); + gst_structure_get_int (tmp, "width", &set_w); + + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_h, set_w, + &to_par_n, &to_par_d)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + goto done; + } + + if (!gst_structure_has_field (tmp, "pixel-aspect-ratio")) + gst_structure_set_value (tmp, "pixel-aspect-ratio", to_par); + gst_structure_fixate_field_nearest_fraction (tmp, "pixel-aspect-ratio", + to_par_n, to_par_d); + gst_structure_get_fraction (tmp, "pixel-aspect-ratio", &set_par_n, + &set_par_d); + gst_structure_free (tmp); + + if (set_par_n == to_par_n && set_par_d == to_par_d) { + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, set_h, NULL); + + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + goto done; + } + + /* Otherwise try to scale width to keep the DAR with the set + * PAR and height */ + if (!gst_util_fraction_multiply (from_dar_n, from_dar_d, set_par_d, + set_par_n, &num, &den)) { + GST_ELEMENT_ERROR (base, CORE, NEGOTIATION, (NULL), + ("Error calculating the output scaled size - integer overflow")); + goto done; + } + + w = (guint) gst_util_uint64_scale_int (set_h, num, den); + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "width", w); + gst_structure_get_int (tmp, "width", &tmp2); + gst_structure_free (tmp); + + if (tmp2 == w) { + gst_structure_set (outs, "width", G_TYPE_INT, tmp2, "height", + G_TYPE_INT, set_h, NULL); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + goto done; + } + + /* ... or try the same with the height */ + h = (guint) gst_util_uint64_scale_int (set_w, den, num); + tmp = gst_structure_copy (outs); + gst_structure_fixate_field_nearest_int (tmp, "height", h); + gst_structure_get_int (tmp, "height", &tmp2); + gst_structure_free (tmp); + + if (tmp2 == h) { + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, tmp2, NULL); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); + goto done; + } + + /* If all fails we can't keep the DAR and take the nearest values + * for everything from the first try */ + gst_structure_set (outs, "width", G_TYPE_INT, set_w, "height", + G_TYPE_INT, set_h, NULL); + if (gst_structure_has_field (outs, "pixel-aspect-ratio") || + set_par_n != set_par_d) + gst_structure_set (outs, "pixel-aspect-ratio", GST_TYPE_FRACTION, + set_par_n, set_par_d, NULL); } } +done: GST_DEBUG_OBJECT (base, "fixated othercaps to %" GST_PTR_FORMAT, othercaps); + + if (from_par == &fpar) + g_value_unset (&fpar); + if (to_par == &tpar) + g_value_unset (&tpar); + + return othercaps; } static gboolean gst_gl_colorscale_set_caps (GstBaseTransform * bt, GstCaps * incaps, GstCaps * outcaps) { - GstGLColorscale *colorscale = GST_GL_COLORSCALE (bt); - gboolean ret = FALSE; + GstGLColorscale *colorscale; + GstVideoInfo in_vinfo, out_vinfo; + gboolean ret; GST_DEBUG ("called with %" GST_PTR_FORMAT, incaps); - ret = gst_video_format_parse_caps (outcaps, &colorscale->output_video_format, - &colorscale->output_video_width, &colorscale->output_video_height); + ret = FALSE; + colorscale = GST_GL_COLORSCALE (bt); - ret |= gst_video_format_parse_caps (incaps, &colorscale->input_video_format, - &colorscale->input_video_width, &colorscale->input_video_height); + ret = gst_video_info_from_caps (&out_vinfo, outcaps); + ret |= gst_video_info_from_caps (&in_vinfo, incaps); if (!ret) { GST_DEBUG ("bad caps"); return FALSE; } + colorscale->output_video_format = GST_VIDEO_INFO_FORMAT (&out_vinfo); + colorscale->output_video_width = GST_VIDEO_INFO_WIDTH (&out_vinfo); + colorscale->output_video_height = GST_VIDEO_INFO_HEIGHT (&out_vinfo); + + colorscale->input_video_format = GST_VIDEO_INFO_FORMAT (&in_vinfo); + colorscale->input_video_width = GST_VIDEO_INFO_WIDTH (&in_vinfo); + colorscale->input_video_height = GST_VIDEO_INFO_HEIGHT (&in_vinfo); + colorscale->display = gst_gl_display_new (); //init unvisible opengl context @@ -423,24 +732,12 @@ gst_gl_colorscale_set_caps (GstBaseTransform * bt, GstCaps * incaps, static gboolean gst_gl_colorscale_get_unit_size (GstBaseTransform * trans, GstCaps * caps, - guint * size) + gsize * size) { - gboolean ret; - GstStructure *structure; - gint width; - gint height; + GstVideoInfo vinfo; - structure = gst_caps_get_structure (caps, 0); - if (gst_structure_has_name (structure, "video/x-raw-gl")) { - ret = gst_gl_buffer_parse_caps (caps, &width, &height); - if (ret) - *size = gst_gl_buffer_get_size (width, height); - } else { - GstVideoFormat video_format; - - ret = gst_video_format_parse_caps (caps, &video_format, &width, &height); - if (ret) - *size = gst_video_format_get_size (video_format, width, height); + if (gst_video_info_from_caps (&vinfo, caps)) { + *size = GST_VIDEO_INFO_SIZE (&vinfo); } return TRUE; @@ -450,34 +747,39 @@ static GstFlowReturn gst_gl_colorscale_transform (GstBaseTransform * trans, GstBuffer * inbuf, GstBuffer * outbuf) { - GstGLColorscale *colorscale = GST_GL_COLORSCALE (trans); - gboolean isAlive = TRUE; + /*GstGLColorscale *colorscale; */ + gboolean ok; - //blocking call - GstGLBuffer *gl_temp_buffer = gst_gl_buffer_new (colorscale->display, - colorscale->output_video_width, colorscale->output_video_height); + /*colorscale = GST_GL_COLORSCALE (trans); */ + ok = TRUE; - GST_DEBUG ("input size %p size %d", - GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf)); + /* FIXME: implement using GstGLMeta */ + /*//blocking call + GstGLBuffer *gl_temp_buffer = gst_gl_buffer_new (colorscale->display, + colorscale->output_video_width, colorscale->output_video_height); - //blocking call - isAlive = - gst_gl_display_do_upload (colorscale->display, gl_temp_buffer->texture, - colorscale->input_video_width, colorscale->input_video_height, - GST_BUFFER_DATA (inbuf)); + GST_DEBUG ("input size %p size %d", + GST_BUFFER_DATA (inbuf), GST_BUFFER_SIZE (inbuf)); - GST_DEBUG ("output size %p size %d", - GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf)); + //blocking call + ok = + gst_gl_display_do_upload (colorscale->display, gl_temp_buffer->texture, + colorscale->input_video_width, colorscale->input_video_height, + GST_BUFFER_DATA (inbuf)); - //blocking call - isAlive &= - gst_gl_display_do_download (colorscale->display, gl_temp_buffer->texture, - gl_temp_buffer->width, gl_temp_buffer->height, GST_BUFFER_DATA (outbuf)); + GST_DEBUG ("output size %p size %d", + GST_BUFFER_DATA (outbuf), GST_BUFFER_SIZE (outbuf)); - gst_buffer_unref (GST_BUFFER_CAST (gl_temp_buffer)); + //blocking call + ok &= + gst_gl_display_do_download (colorscale->display, gl_temp_buffer->texture, + gl_temp_buffer->width, gl_temp_buffer->height, GST_BUFFER_DATA (outbuf)); - if (isAlive) + gst_buffer_unref (GST_BUFFER_CAST (gl_temp_buffer)); + */ + + if (ok) return GST_FLOW_OK; else - return GST_FLOW_UNEXPECTED; + return GST_FLOW_EOS; }