Index: gstvideoscale.c =================================================================== RCS file: /cvs/gstreamer/gst-plugins-base/gst/videoscale/gstvideoscale.c,v retrieving revision 1.75 diff -u -u -r1.75 gstvideoscale.c --- gstvideoscale.c 14 Mar 2006 11:11:59 -0000 1.75 +++ gstvideoscale.c 23 Apr 2006 23:16:48 -0000 @@ -315,19 +315,38 @@ { GstVideoScale *videoscale; GstCaps *ret; - int i; + GstStructure *structure; + const GValue *par; videoscale = GST_VIDEO_SCALE (trans); ret = gst_caps_copy (caps); - for (i = 0; i < gst_caps_get_size (ret); i++) { - GstStructure *structure = gst_caps_get_structure (ret, i); + /* this function is always called with a simple caps */ + g_return_val_if_fail (GST_CAPS_IS_SIMPLE (ret), NULL); + + structure = gst_caps_get_structure (ret, 0); gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 16, 4096, "height", GST_TYPE_INT_RANGE, 16, 4096, NULL); - gst_structure_remove_field (structure, "pixel-aspect-ratio"); + + /* if pixel aspect ratio, make a range of it */ + if ((par = gst_structure_get_value (structure, "pixel-aspect-ratio"))) { + GstCaps *copy; + GstStructure *cstruct; + + /* copy input PAR first, this is the prefered PAR */ + gst_structure_set_value (structure, "pixel-aspect-ratio", par); + + /* then make a copy with a fraction range as a second choice */ + copy = gst_caps_copy (ret); + cstruct = gst_caps_get_structure (copy, 0); + gst_structure_set (cstruct, + "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); + + /* and append */ + gst_caps_append (ret, copy); } GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret); @@ -520,11 +539,28 @@ 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) { GValue to_ratio = { 0, }; /* w/h of output video */ gint from_w, from_h, from_par_n, from_par_d, to_par_n, to_par_d; gint count = 0, w = 0, h = 0, num, den; + /* from_par should be fixed */ + g_return_if_fail (gst_value_is_fixed (from_par)); + + 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); + /* if both width and height are already fixed, we can't do anything * about it anymore */ if (gst_structure_get_int (outs, "width", &w)) @@ -539,10 +575,6 @@ gst_structure_get_int (ins, "width", &from_w); gst_structure_get_int (ins, "height", &from_h); - from_par_n = gst_value_get_fraction_numerator (from_par); - from_par_d = gst_value_get_fraction_denominator (from_par); - to_par_n = gst_value_get_fraction_numerator (to_par); - to_par_d = gst_value_get_fraction_denominator (to_par); g_value_init (&to_ratio, GST_TYPE_FRACTION); gst_value_set_fraction (&to_ratio, from_w * from_par_n * to_par_d, @@ -560,15 +592,14 @@ * using wd / hd = num / den */ /* start with same height, because of interlaced video */ - /* check hd / den is an integer scale factor, and scale wd with the PAR */ - if (from_h % den == 0) { + if (h) { GST_DEBUG_OBJECT (base, "keeping video height"); - h = from_h; w = h * num / den; - } else if (from_w % num == 0) { + w -= w % 16; + } else if (w) { GST_DEBUG_OBJECT (base, "keeping video width"); - w = from_w; h = w * den / num; + h -= h % 16; } else { GST_DEBUG_OBJECT (base, "approximating but keeping video height"); h = from_h; @@ -761,8 +792,7 @@ videoscale = GST_VIDEO_SCALE (trans); - GST_DEBUG_OBJECT (videoscale, "handling %s event", - GST_EVENT_TYPE_NAME (event)); + GST_DEBUG_OBJECT (videoscale, "handling %s event", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_NAVIGATION: