mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
v4l2src: check field information and set interlaced caps accordingly
Reject the format if the field type is not supported. https://bugzilla.gnome.org/show_bug.cgi?id=634391
This commit is contained in:
parent
b68ae7ac83
commit
351ac54822
1 changed files with 36 additions and 8 deletions
|
@ -1454,6 +1454,10 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
||||||
|
guint32 pixelformat, gint * width, gint * height, gboolean * interlaced);
|
||||||
|
|
||||||
|
|
||||||
/* The frame interval enumeration code first appeared in Linux 2.6.19. */
|
/* The frame interval enumeration code first appeared in Linux 2.6.19. */
|
||||||
#ifdef VIDIOC_ENUM_FRAMEINTERVALS
|
#ifdef VIDIOC_ENUM_FRAMEINTERVALS
|
||||||
|
@ -1467,6 +1471,14 @@ gst_v4l2_object_probe_caps_for_format_and_size (GstV4l2Object * v4l2object,
|
||||||
guint32 num, denom;
|
guint32 num, denom;
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
GValue rates = { 0, };
|
GValue rates = { 0, };
|
||||||
|
gboolean interlaced;
|
||||||
|
gint int_width = width;
|
||||||
|
gint int_height = height;
|
||||||
|
|
||||||
|
/* interlaced detection using VIDIOC_TRY/S_FMT */
|
||||||
|
if (!gst_v4l2_object_get_nearest_size (v4l2object, pixelformat,
|
||||||
|
&int_width, &int_height, &interlaced))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
memset (&ival, 0, sizeof (struct v4l2_frmivalenum));
|
memset (&ival, 0, sizeof (struct v4l2_frmivalenum));
|
||||||
ival.index = 0;
|
ival.index = 0;
|
||||||
|
@ -1624,7 +1636,8 @@ gst_v4l2_object_probe_caps_for_format_and_size (GstV4l2Object * v4l2object,
|
||||||
return_data:
|
return_data:
|
||||||
s = gst_structure_copy (template);
|
s = gst_structure_copy (template);
|
||||||
gst_structure_set (s, "width", G_TYPE_INT, (gint) width,
|
gst_structure_set (s, "width", G_TYPE_INT, (gint) width,
|
||||||
"height", G_TYPE_INT, (gint) height, NULL);
|
"height", G_TYPE_INT, (gint) height,
|
||||||
|
"interlaced", G_TYPE_BOOLEAN, interlaced, NULL);
|
||||||
|
|
||||||
if (G_IS_VALUE (&rates)) {
|
if (G_IS_VALUE (&rates)) {
|
||||||
/* only change the framerate on the template when we have a valid probed new
|
/* only change the framerate on the template when we have a valid probed new
|
||||||
|
@ -1672,10 +1685,6 @@ sort_by_frame_size (GstStructure * s1, GstStructure * s2)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
|
||||||
guint32 pixelformat, gint * width, gint * height);
|
|
||||||
|
|
||||||
GstCaps *
|
GstCaps *
|
||||||
gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
|
gst_v4l2_object_probe_caps_for_format (GstV4l2Object * v4l2object,
|
||||||
guint32 pixelformat, const GstStructure * template)
|
guint32 pixelformat, const GstStructure * template)
|
||||||
|
@ -1831,18 +1840,19 @@ default_frame_sizes:
|
||||||
#endif /* defined VIDIOC_ENUM_FRAMESIZES */
|
#endif /* defined VIDIOC_ENUM_FRAMESIZES */
|
||||||
{
|
{
|
||||||
gint min_w, max_w, min_h, max_h, fix_num = 0, fix_denom = 0;
|
gint min_w, max_w, min_h, max_h, fix_num = 0, fix_denom = 0;
|
||||||
|
gboolean interlaced;
|
||||||
|
|
||||||
/* This code is for Linux < 2.6.19 */
|
/* This code is for Linux < 2.6.19 */
|
||||||
min_w = min_h = 1;
|
min_w = min_h = 1;
|
||||||
max_w = max_h = GST_V4L2_MAX_SIZE;
|
max_w = max_h = GST_V4L2_MAX_SIZE;
|
||||||
if (!gst_v4l2_object_get_nearest_size (v4l2object, pixelformat, &min_w,
|
if (!gst_v4l2_object_get_nearest_size (v4l2object, pixelformat, &min_w,
|
||||||
&min_h)) {
|
&min_h, &interlaced)) {
|
||||||
GST_WARNING_OBJECT (v4l2object->element,
|
GST_WARNING_OBJECT (v4l2object->element,
|
||||||
"Could not probe minimum capture size for pixelformat %"
|
"Could not probe minimum capture size for pixelformat %"
|
||||||
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
|
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
|
||||||
}
|
}
|
||||||
if (!gst_v4l2_object_get_nearest_size (v4l2object, pixelformat, &max_w,
|
if (!gst_v4l2_object_get_nearest_size (v4l2object, pixelformat, &max_w,
|
||||||
&max_h)) {
|
&max_h, &interlaced)) {
|
||||||
GST_WARNING_OBJECT (v4l2object->element,
|
GST_WARNING_OBJECT (v4l2object->element,
|
||||||
"Could not probe maximum capture size for pixelformat %"
|
"Could not probe maximum capture size for pixelformat %"
|
||||||
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
|
GST_FOURCC_FORMAT, GST_FOURCC_ARGS (pixelformat));
|
||||||
|
@ -1885,6 +1895,8 @@ default_frame_sizes:
|
||||||
else
|
else
|
||||||
gst_structure_set (tmp, "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);
|
gst_structure_set (tmp, "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);
|
||||||
|
|
||||||
|
gst_structure_set (tmp, "interlaced", G_TYPE_BOOLEAN, interlaced, NULL);
|
||||||
|
|
||||||
gst_caps_append_structure (ret, tmp);
|
gst_caps_append_structure (ret, tmp);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1893,7 +1905,7 @@ default_frame_sizes:
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
||||||
guint32 pixelformat, gint * width, gint * height)
|
guint32 pixelformat, gint * width, gint * height, gboolean * interlaced)
|
||||||
{
|
{
|
||||||
struct v4l2_format fmt;
|
struct v4l2_format fmt;
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -1963,6 +1975,22 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
|
||||||
*width = fmt.fmt.pix.width;
|
*width = fmt.fmt.pix.width;
|
||||||
*height = fmt.fmt.pix.height;
|
*height = fmt.fmt.pix.height;
|
||||||
|
|
||||||
|
switch (fmt.fmt.pix.field) {
|
||||||
|
case V4L2_FIELD_NONE:
|
||||||
|
*interlaced = FALSE;
|
||||||
|
break;
|
||||||
|
case V4L2_FIELD_INTERLACED:
|
||||||
|
case V4L2_FIELD_INTERLACED_TB:
|
||||||
|
case V4L2_FIELD_INTERLACED_BT:
|
||||||
|
*interlaced = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GST_WARNING_OBJECT (v4l2object->element,
|
||||||
|
"Unsupported field type for %" GST_FOURCC_FORMAT "@%ux%u",
|
||||||
|
GST_FOURCC_ARGS (pixelformat), width, height);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue