mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 20:42:30 +00:00
v4l2object: add gst_v4l2_object_try_format
Similar to set_format but it uses TRY_FMT instead of S_FMT https://bugzilla.gnome.org/show_bug.cgi?id=682770
This commit is contained in:
parent
3c595f308a
commit
6cfa6c0da8
2 changed files with 63 additions and 24 deletions
|
@ -2647,8 +2647,9 @@ gst_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * finfo,
|
||||||
return estride;
|
return estride;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
static gboolean
|
||||||
gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
|
||||||
|
gboolean try_only)
|
||||||
{
|
{
|
||||||
gint fd = v4l2object->video_fd;
|
gint fd = v4l2object->video_fd;
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
|
@ -2665,7 +2666,8 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
enum v4l2_colorspace colorspace = 0;
|
enum v4l2_colorspace colorspace = 0;
|
||||||
|
|
||||||
GST_V4L2_CHECK_OPEN (v4l2object);
|
GST_V4L2_CHECK_OPEN (v4l2object);
|
||||||
GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
|
if (!try_only)
|
||||||
|
GST_V4L2_CHECK_NOT_ACTIVE (v4l2object);
|
||||||
|
|
||||||
is_mplane = V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type);
|
is_mplane = V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type);
|
||||||
|
|
||||||
|
@ -2796,8 +2798,13 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
colorspace);
|
colorspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
|
if (try_only) {
|
||||||
goto set_fmt_failed;
|
if (v4l2_ioctl (fd, VIDIOC_TRY_FMT, &format) < 0)
|
||||||
|
goto try_fmt_failed;
|
||||||
|
} else {
|
||||||
|
if (v4l2_ioctl (fd, VIDIOC_S_FMT, &format) < 0)
|
||||||
|
goto set_fmt_failed;
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (v4l2object->element, "Got format of %dx%d, format "
|
GST_DEBUG_OBJECT (v4l2object->element, "Got format of %dx%d, format "
|
||||||
"%" GST_FOURCC_FORMAT ", nb planes %d, colorspace %d",
|
"%" GST_FOURCC_FORMAT ", nb planes %d, colorspace %d",
|
||||||
|
@ -2840,6 +2847,9 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
if (is_mplane && format.fmt.pix_mp.num_planes != n_v4l_planes)
|
if (is_mplane && format.fmt.pix_mp.num_planes != n_v4l_planes)
|
||||||
goto invalid_planes;
|
goto invalid_planes;
|
||||||
|
|
||||||
|
if (try_only) /* good enough for trying only */
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (GST_VIDEO_INFO_HAS_ALPHA (&info)) {
|
if (GST_VIDEO_INFO_HAS_ALPHA (&info)) {
|
||||||
struct v4l2_control ctl = { 0, };
|
struct v4l2_control ctl = { 0, };
|
||||||
ctl.id = V4L2_CID_ALPHA_COMPONENT;
|
ctl.id = V4L2_CID_ALPHA_COMPONENT;
|
||||||
|
@ -2894,7 +2904,7 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
goto set_parm_failed;
|
goto set_parm_failed;
|
||||||
|
|
||||||
if (streamparm.parm.capture.timeperframe.numerator > 0 &&
|
if (streamparm.parm.capture.timeperframe.numerator > 0 &&
|
||||||
streamparm.parm.capture.timeperframe.denominator > 0) {
|
streamparm.parm.capture.timeperframe.denominator > 0) {
|
||||||
/* get new values */
|
/* get new values */
|
||||||
fps_d = streamparm.parm.capture.timeperframe.numerator;
|
fps_d = streamparm.parm.capture.timeperframe.numerator;
|
||||||
fps_n = streamparm.parm.capture.timeperframe.denominator;
|
fps_n = streamparm.parm.capture.timeperframe.denominator;
|
||||||
|
@ -2904,8 +2914,7 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
} else {
|
} else {
|
||||||
/* fix v4l2 capture driver to provide framerate values */
|
/* fix v4l2 capture driver to provide framerate values */
|
||||||
GST_WARNING_OBJECT (v4l2object->element,
|
GST_WARNING_OBJECT (v4l2object->element,
|
||||||
"Reuse caps framerate %u/%u - fix v4l2 capture driver",
|
"Reuse caps framerate %u/%u - fix v4l2 capture driver", fps_n, fps_d);
|
||||||
fps_n, fps_d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_VIDEO_INFO_FPS_N (&info) = fps_n;
|
GST_VIDEO_INFO_FPS_N (&info) = fps_n;
|
||||||
|
@ -2929,6 +2938,17 @@ invalid_caps:
|
||||||
caps);
|
caps);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
try_fmt_failed:
|
||||||
|
{
|
||||||
|
if (errno == EBUSY) {
|
||||||
|
GST_ELEMENT_WARNING (v4l2object->element, RESOURCE, BUSY,
|
||||||
|
(_("Device '%s' is busy"), v4l2object->videodev),
|
||||||
|
("Call to TRY_FMT failed for %" GST_FOURCC_FORMAT " @ %dx%d: %s",
|
||||||
|
GST_FOURCC_ARGS (pixelformat), width, height,
|
||||||
|
g_strerror (errno)));
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
set_fmt_failed:
|
set_fmt_failed:
|
||||||
{
|
{
|
||||||
if (errno == EBUSY) {
|
if (errno == EBUSY) {
|
||||||
|
@ -2949,30 +2969,36 @@ set_fmt_failed:
|
||||||
}
|
}
|
||||||
invalid_dimensions:
|
invalid_dimensions:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
if (!try_only) {
|
||||||
(_("Device '%s' cannot capture at %dx%d"),
|
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
||||||
v4l2object->videodev, width, height),
|
(_("Device '%s' cannot capture at %dx%d"),
|
||||||
("Tried to capture at %dx%d, but device returned size %dx%d",
|
v4l2object->videodev, width, height),
|
||||||
width, height, format.fmt.pix.width, format.fmt.pix.height));
|
("Tried to capture at %dx%d, but device returned size %dx%d",
|
||||||
|
width, height, format.fmt.pix.width, format.fmt.pix.height));
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
invalid_pixelformat:
|
invalid_pixelformat:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
if (!try_only) {
|
||||||
(_("Device '%s' cannot capture in the specified format"),
|
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
||||||
v4l2object->videodev),
|
(_("Device '%s' cannot capture in the specified format"),
|
||||||
("Tried to capture in %" GST_FOURCC_FORMAT
|
v4l2object->videodev),
|
||||||
", but device returned format" " %" GST_FOURCC_FORMAT,
|
("Tried to capture in %" GST_FOURCC_FORMAT
|
||||||
GST_FOURCC_ARGS (pixelformat),
|
", but device returned format" " %" GST_FOURCC_FORMAT,
|
||||||
GST_FOURCC_ARGS (format.fmt.pix.pixelformat)));
|
GST_FOURCC_ARGS (pixelformat),
|
||||||
|
GST_FOURCC_ARGS (format.fmt.pix.pixelformat)));
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
invalid_planes:
|
invalid_planes:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
if (!try_only) {
|
||||||
(_("Device '%s' does support non-contiguous planes"),
|
GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
|
||||||
v4l2object->videodev),
|
(_("Device '%s' does support non-contiguous planes"),
|
||||||
("Device wants %d planes", format.fmt.pix_mp.num_planes));
|
v4l2object->videodev),
|
||||||
|
("Device wants %d planes", format.fmt.pix_mp.num_planes));
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
get_parm_failed:
|
get_parm_failed:
|
||||||
|
@ -2999,6 +3025,18 @@ pool_failed:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
|
{
|
||||||
|
return gst_v4l2_object_set_format_full (v4l2object, caps, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_v4l2_object_try_format (GstV4l2Object * v4l2object, GstCaps * caps)
|
||||||
|
{
|
||||||
|
return gst_v4l2_object_set_format_full (v4l2object, caps, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_v4l2_object_acquire_format:
|
* gst_v4l2_object_acquire_format:
|
||||||
* @v4l2object the object
|
* @v4l2object the object
|
||||||
|
|
|
@ -251,6 +251,7 @@ gint gst_v4l2_object_extrapolate_stride (const GstVideoFormatInfo * fin
|
||||||
gint plane, gint stride);
|
gint plane, gint stride);
|
||||||
|
|
||||||
gboolean gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps);
|
gboolean gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps);
|
||||||
|
gboolean gst_v4l2_object_try_format (GstV4l2Object * v4l2object, GstCaps * caps);
|
||||||
|
|
||||||
gboolean gst_v4l2_object_caps_equal (GstV4l2Object * v4l2object, GstCaps * caps);
|
gboolean gst_v4l2_object_caps_equal (GstV4l2Object * v4l2object, GstCaps * caps);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue