diff options
author | Michael Olbrich <m.olbrich@pengutronix.de> | 2013-06-04 08:26:33 +0200 |
---|---|---|
committer | Michael Olbrich <m.olbrich@pengutronix.de> | 2013-09-13 16:29:48 +0200 |
commit | 5290e247a8bdabc6de075fd5fe0c2007ff04f25f (patch) | |
tree | 7699e9864f03c927da3e9638163ee669cfbb4ff0 | |
parent | c85dae5eec58ba83292188abed8e1fccc062c85b (diff) | |
download | gst-plugins-good-5290e247a8bdabc6de075fd5fe0c2007ff04f25f.tar.gz gst-plugins-good-5290e247a8bdabc6de075fd5fe0c2007ff04f25f.tar.xz |
v4l2: improve pixel aspect ratio handling
Instead of just assuming a aspect ratio of 1/1 use VIDIOC_CROPCAP to ask
the device.
This also add a pixel-aspect-ratio property to overwrite the value from the
driver and a force-aspect-ratio property to ignore it.
https://bugzilla.gnome.org/show_bug.cgi?id=700285
-rw-r--r-- | sys/v4l2/gstv4l2object.c | 95 | ||||
-rw-r--r-- | sys/v4l2/gstv4l2object.h | 6 |
2 files changed, 96 insertions, 5 deletions
diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index 50c88d76b..49654de59 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -504,6 +504,33 @@ gst_v4l2_object_install_properties_helper (GObjectClass * gobject_class, g_param_spec_boxed ("extra-controls", "Extra Controls", "Extra v4l2 controls (CIDs) for the device", GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstV4l2Src:pixel-aspect-ratio + * + * The pixel aspect ratio of the device. This overwrites the pixel aspect + * ratio queried from the device. + * + * Since: 1.2 + */ + g_object_class_install_property (gobject_class, PROP_PIXEL_ASPECT_RATIO, + g_param_spec_string ("pixel-aspect-ratio", "Pixel Aspect Ratio", + "Overwrite the pixel aspect ratio of the device", "1/1", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GstV4l2Src:force-aspect-ratio + * + * When enabled, the pixel aspect ratio queried from the device or set + * with the pixel-aspect-ratio property will be enforced. + * + * Since: 1.2 + */ + g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO, + g_param_spec_boolean ("force-aspect-ratio", "Force aspect ratio", + "When enabled, the pixel aspect ratio will be enforced", TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + } GstV4l2Object * @@ -540,6 +567,8 @@ gst_v4l2_object_new (GstElement * element, v4l2object->xwindow_id = 0; + v4l2object->keep_aspect = TRUE; + return v4l2object; } @@ -679,6 +708,21 @@ gst_v4l2_object_set_property_helper (GstV4l2Object * v4l2object, gst_v4l2_set_controls (v4l2object, v4l2object->extra_controls); break; } + case PROP_PIXEL_ASPECT_RATIO: + g_free (v4l2object->par); + v4l2object->par = g_new0 (GValue, 1); + g_value_init (v4l2object->par, GST_TYPE_FRACTION); + if (!g_value_transform (value, v4l2object->par)) { + g_warning ("Could not transform string to aspect ratio"); + gst_value_set_fraction (v4l2object->par, 1, 1); + } + GST_DEBUG_OBJECT (v4l2object->element, "set PAR to %d/%d", + gst_value_get_fraction_numerator (v4l2object->par), + gst_value_get_fraction_denominator (v4l2object->par)); + break; + case PROP_FORCE_ASPECT_RATIO: + v4l2object->keep_aspect = g_value_get_boolean (value); + break; default: return FALSE; break; @@ -758,6 +802,13 @@ gst_v4l2_object_get_property_helper (GstV4l2Object * v4l2object, case PROP_EXTRA_CONTROLS: gst_value_set_structure (value, v4l2object->extra_controls); break; + case PROP_PIXEL_ASPECT_RATIO: + if (v4l2object->par) + g_value_transform (v4l2object->par, value); + break; + case PROP_FORCE_ASPECT_RATIO: + g_value_set_boolean (value, v4l2object->keep_aspect); + break; default: return FALSE; break; @@ -1625,6 +1676,43 @@ static gboolean gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object, guint32 pixelformat, gint * width, gint * height, gboolean * interlaced); +static void +gst_v4l2_object_add_aspect_ratio (GstV4l2Object * v4l2object, GstStructure * s) +{ + struct v4l2_cropcap cropcap; + int num = 1, den = 1; + + if (!v4l2object->keep_aspect) + return; + + if (v4l2object->par) { + num = gst_value_get_fraction_numerator (v4l2object->par); + den = gst_value_get_fraction_denominator (v4l2object->par); + goto done; + } + + memset (&cropcap, 0, sizeof (cropcap)); + + cropcap.type = v4l2object->type; + if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_CROPCAP, &cropcap) < 0) + goto cropcap_failed; + + num = cropcap.pixelaspect.numerator; + den = cropcap.pixelaspect.denominator; + +done: + gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, num, den, + NULL); + return; + +cropcap_failed: + if (errno != ENOTTY) + GST_WARNING_OBJECT (v4l2object->element, + "Failed to probe pixel aspect ratio with VIDIOC_CROPCAP: %s", + g_strerror (errno)); + goto done; +} + /* The frame interval enumeration code first appeared in Linux 2.6.19. */ #ifdef VIDIOC_ENUM_FRAMEINTERVALS @@ -1811,8 +1899,8 @@ gst_v4l2_object_probe_caps_for_format_and_size (GstV4l2Object * v4l2object, return_data: s = gst_structure_copy (template); gst_structure_set (s, "width", G_TYPE_INT, (gint) width, - "height", G_TYPE_INT, (gint) height, - "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); + "height", G_TYPE_INT, (gint) height, NULL); + gst_v4l2_object_add_aspect_ratio (v4l2object, s); if (g_str_equal (gst_structure_get_name (s), "video/x-raw")) gst_structure_set (s, "interlace-mode", G_TYPE_STRING, (interlaced ? "mixed" : "progressive"), NULL); @@ -2078,8 +2166,7 @@ default_frame_sizes: if (g_str_equal (gst_structure_get_name (tmp), "video/x-raw")) gst_structure_set (tmp, "interlace-mode", G_TYPE_STRING, (interlaced ? "mixed" : "progressive"), NULL); - gst_structure_set (tmp, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, - NULL); + gst_v4l2_object_add_aspect_ratio (v4l2object, tmp); gst_caps_append_structure (ret, tmp); diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index e177937d8..2505f4796 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -150,6 +150,8 @@ struct _GstV4l2Object { gchar *channel; gulong frequency; GstStructure *extra_controls; + gboolean keep_aspect; + GValue *par; /* X-overlay */ GstV4l2Xv *xv; @@ -179,7 +181,9 @@ GType gst_v4l2_object_get_type (void); PROP_HUE, \ PROP_TV_NORM, \ PROP_IO_MODE, \ - PROP_EXTRA_CONTROLS + PROP_EXTRA_CONTROLS, \ + PROP_PIXEL_ASPECT_RATIO, \ + PROP_FORCE_ASPECT_RATIO /* create/destroy */ GstV4l2Object * gst_v4l2_object_new (GstElement * element, |