mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
v4l2object: probe all colorspace supported by device
A device can support more than one colorspace for a given image dimension and pixel format. So we have to probe all the supported colorspace and not only rely on the default one. Otherwise we could end up with negotiation failure if the caps colorimetry field don't match the v4l2 device default one even if the v4l2 could support such colorimetry. This patch enable probing if colorspace for both capture and output device. It really makes sense for output device since the colorspace shall be set by the application and a little less for capture device which, at the moment, shall provide the colorspace; ie: the v4l2 specification seems to not take into account the fact that a capture device could do colorspace conversion. As a side effet, probing takes some times and so sligthly delay v4l2 initialization. Note that this patch only probe colorspace and not all colorspace, matrix, transfer and range combination to avoid taking too much time, especially with low-speed devices as full probing do 1782 ioctl. https://bugzilla.gnome.org/show_bug.cgi?id=755937
This commit is contained in:
parent
c4f06420b3
commit
c163250f0d
1 changed files with 89 additions and 6 deletions
|
@ -2137,13 +2137,43 @@ gst_v4l2_object_add_interlace_mode (GstV4l2Object * v4l2object,
|
|||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_object_fill_colorimetry_list (GValue * list,
|
||||
GstVideoColorimetry * cinfo)
|
||||
{
|
||||
GValue colorimetry = G_VALUE_INIT;
|
||||
guint size;
|
||||
guint i;
|
||||
gboolean found = FALSE;
|
||||
|
||||
g_value_init (&colorimetry, G_TYPE_STRING);
|
||||
g_value_take_string (&colorimetry, gst_video_colorimetry_to_string (cinfo));
|
||||
|
||||
/* only insert if no duplicate */
|
||||
size = gst_value_list_get_size (list);
|
||||
for (i = 0; i < size; i++) {
|
||||
const GValue *tmp;
|
||||
|
||||
tmp = gst_value_list_get_value (list, i);
|
||||
if (gst_value_compare (&colorimetry, tmp) == GST_VALUE_EQUAL) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
gst_value_list_append_and_take_value (list, &colorimetry);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_v4l2_object_add_colorspace (GstV4l2Object * v4l2object, GstStructure * s,
|
||||
guint32 width, guint32 height, guint32 pixelformat)
|
||||
{
|
||||
struct v4l2_format fmt;
|
||||
GValue colorimetry = G_VALUE_INIT;
|
||||
GValue list = G_VALUE_INIT;
|
||||
GstVideoColorimetry cinfo;
|
||||
enum v4l2_colorspace req_cspace;
|
||||
gboolean is_rgb = gst_v4l2_object_v4l2fourcc_is_rgb (pixelformat);
|
||||
|
||||
memset (&fmt, 0, sizeof (fmt));
|
||||
fmt.type = v4l2object->type;
|
||||
|
@ -2151,12 +2181,15 @@ gst_v4l2_object_add_colorspace (GstV4l2Object * v4l2object, GstStructure * s,
|
|||
fmt.fmt.pix.height = height;
|
||||
fmt.fmt.pix.pixelformat = pixelformat;
|
||||
|
||||
g_value_init (&list, GST_TYPE_LIST);
|
||||
|
||||
/* step 1: get device default colorspace and insert it first as
|
||||
* it should be the preferred one */
|
||||
if (gst_v4l2_object_try_fmt (v4l2object, &fmt) == 0) {
|
||||
enum v4l2_colorspace colorspace;
|
||||
enum v4l2_quantization range;
|
||||
enum v4l2_ycbcr_encoding matrix;
|
||||
enum v4l2_xfer_func transfer;
|
||||
gboolean is_rgb = gst_v4l2_object_v4l2fourcc_is_rgb (pixelformat);
|
||||
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type)) {
|
||||
colorspace = fmt.fmt.pix_mp.colorspace;
|
||||
|
@ -2178,12 +2211,62 @@ gst_v4l2_object_add_colorspace (GstV4l2Object * v4l2object, GstStructure * s,
|
|||
if (is_rgb)
|
||||
cinfo.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
|
||||
|
||||
g_value_init (&colorimetry, G_TYPE_STRING);
|
||||
g_value_take_string (&colorimetry,
|
||||
gst_video_colorimetry_to_string (&cinfo));
|
||||
gst_structure_take_value (s, "colorimetry", &colorimetry);
|
||||
gst_v4l2_object_fill_colorimetry_list (&list, &cinfo);
|
||||
}
|
||||
}
|
||||
|
||||
/* step 2: probe all colorspace other than default
|
||||
* We don't probe all colorspace, range, matrix and transfer combination to
|
||||
* avoid ioctl flooding which could greatly increase initialization time
|
||||
* with low-speed devices (UVC...) */
|
||||
for (req_cspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
req_cspace <= V4L2_COLORSPACE_RAW; req_cspace++) {
|
||||
/* V4L2_COLORSPACE_BT878 is deprecated and shall not be used, so skip */
|
||||
if (req_cspace == V4L2_COLORSPACE_BT878)
|
||||
continue;
|
||||
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type))
|
||||
fmt.fmt.pix_mp.colorspace = req_cspace;
|
||||
else
|
||||
fmt.fmt.pix.colorspace = req_cspace;
|
||||
|
||||
if (gst_v4l2_object_try_fmt (v4l2object, &fmt) == 0) {
|
||||
enum v4l2_colorspace colorspace;
|
||||
enum v4l2_quantization range;
|
||||
enum v4l2_ycbcr_encoding matrix;
|
||||
enum v4l2_xfer_func transfer;
|
||||
|
||||
if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type)) {
|
||||
colorspace = fmt.fmt.pix_mp.colorspace;
|
||||
range = fmt.fmt.pix_mp.quantization;
|
||||
matrix = fmt.fmt.pix_mp.ycbcr_enc;
|
||||
transfer = fmt.fmt.pix_mp.xfer_func;
|
||||
} else {
|
||||
colorspace = fmt.fmt.pix.colorspace;
|
||||
range = fmt.fmt.pix.quantization;
|
||||
matrix = fmt.fmt.pix.ycbcr_enc;
|
||||
transfer = fmt.fmt.pix.xfer_func;
|
||||
}
|
||||
|
||||
if (colorspace == req_cspace) {
|
||||
if (gst_v4l2_object_get_colorspace (colorspace, range, matrix, transfer,
|
||||
is_rgb, &cinfo)) {
|
||||
/* Set identity matrix for R'G'B' formats to avoid creating
|
||||
* confusion. This though is cosmetic as it's now properly ignored by
|
||||
* the video info API and videoconvert. */
|
||||
if (is_rgb)
|
||||
cinfo.matrix = GST_VIDEO_COLOR_MATRIX_RGB;
|
||||
|
||||
gst_v4l2_object_fill_colorimetry_list (&list, &cinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gst_value_list_get_size (&list) > 0)
|
||||
gst_structure_take_value (s, "colorimetry", &list);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* The frame interval enumeration code first appeared in Linux 2.6.19. */
|
||||
|
|
Loading…
Reference in a new issue