From e5ef2db489799d4bbf2da3ccbdf72d2ef73bf4ed Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Sat, 29 Mar 2014 19:13:06 -0400 Subject: [PATCH] v4l2: Fix support for caps without width, height, framerate or format For format like mpegts, width and height is rarely in the negotiated caps. This patch fixes failure when setting format, and prevent introducing width, height, framerate and format to the caps when fixating. https://bugzilla.gnome.org/show_bug.cgi?id=725860 --- sys/v4l2/gstv4l2object.c | 23 ++++++++++++----------- sys/v4l2/gstv4l2src.c | 19 +++++++++++++------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index c7f21386b4..b8f66c04ee 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -2334,17 +2334,6 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps) "%" GST_FOURCC_FORMAT " stride: %d", width, height, GST_FOURCC_ARGS (pixelformat), v4l2object->bytesperline[0]); - /* MPEG-TS source cameras don't get their format set for some reason. - * It looks wrong and we weren't able to track down the reason for that code - * so it is disabled until someone who has an mpeg-ts camera complains... - */ -#if 0 - /* Only unconditionally accept mpegts for sources */ - if ((v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G'))) - goto done; -#endif - memset (&format, 0x00, sizeof (struct v4l2_format)); format.type = v4l2object->type; @@ -2360,6 +2349,12 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps) GST_FOURCC_ARGS (format.fmt.pix.pixelformat), format.fmt.pix_mp.colorspace, format.fmt.pix_mp.num_planes); + /* If no size in caps, use configured size */ + if (width == 0 && height == 0) { + width = format.fmt.pix_mp.width; + height = format.fmt.pix_mp.height; + } + if (format.type != v4l2object->type || format.fmt.pix_mp.width != width || format.fmt.pix_mp.height != height || @@ -2439,6 +2434,12 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps) GST_FOURCC_ARGS (format.fmt.pix.pixelformat), format.fmt.pix.bytesperline, format.fmt.pix.colorspace); + /* If no size in caps, use configured size */ + if (width == 0 && height == 0) { + width = format.fmt.pix_mp.width; + height = format.fmt.pix_mp.height; + } + if (format.type != v4l2object->type || format.fmt.pix.width != width || format.fmt.pix.height != height || diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index 2543b4e1cd..e388a3f3c3 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -260,13 +260,20 @@ gst_v4l2src_fixate (GstBaseSrc * basesrc, GstCaps * caps) for (i = 0; i < gst_caps_get_size (caps); ++i) { structure = gst_caps_get_structure (caps, i); - /* We are fixating to a resonable 320x200 resolution + /* We are fixating to a reasonable 320x200 resolution and the maximum framerate resolution for that size */ - gst_structure_fixate_field_nearest_int (structure, "width", 320); - gst_structure_fixate_field_nearest_int (structure, "height", 200); - gst_structure_fixate_field_nearest_fraction (structure, "framerate", - G_MAXINT, 1); - gst_structure_fixate_field (structure, "format"); + if (gst_structure_has_field (structure, "width")) + gst_structure_fixate_field_nearest_int (structure, "width", 320); + + if (gst_structure_has_field (structure, "height")) + gst_structure_fixate_field_nearest_int (structure, "height", 200); + + if (gst_structure_has_field (structure, "framerate")) + gst_structure_fixate_field_nearest_fraction (structure, "framerate", + G_MAXINT, 1); + + if (gst_structure_has_field (structure, "format")) + gst_structure_fixate_field (structure, "format"); } GST_DEBUG_OBJECT (basesrc, "fixated caps %" GST_PTR_FORMAT, caps);