v4l2object: Add function to get crop regions from device

Get the current crop bounding region from the V4L2 device so
that it can be provided to applications and used to validate
crop settings. Also make the default crop region available so
that it can be used to reset the crop when appropriate.

Uses the selection API when available with fallback to the crop
API for older kernels.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1089>
This commit is contained in:
Damian Hobson-Garcia 2021-10-13 17:33:12 +09:00 committed by GStreamer Marge Bot
parent 25f240993c
commit ceff3e8ff7
2 changed files with 56 additions and 0 deletions

View file

@ -4415,6 +4415,60 @@ gst_v4l2_object_setup_padding (GstV4l2Object * obj)
return gst_v4l2_object_set_crop (obj, &crop);
}
static gboolean
gst_v4l2_object_get_crop_rect (GstV4l2Object * obj, guint target,
struct v4l2_rect *result)
{
struct v4l2_rect *res_rect;
struct v4l2_selection sel = { 0 };
struct v4l2_cropcap cropcap = { 0 };
GST_V4L2_CHECK_OPEN (obj);
if (target != V4L2_SEL_TGT_CROP_BOUNDS && target != V4L2_SEL_TGT_CROP_DEFAULT)
return FALSE;
sel.type = obj->type;
sel.target = target;
res_rect = &sel.r;
if (obj->ioctl (obj->video_fd, VIDIOC_G_SELECTION, &sel) < 0) {
if (errno != ENOTTY) {
GST_WARNING_OBJECT (obj->dbg_obj,
"Failed to get default crop rectangle with VIDIOC_G_SELECTION: %s",
g_strerror (errno));
return FALSE;
} else {
if (obj->ioctl (obj->video_fd, VIDIOC_CROPCAP, &cropcap) < 0) {
GST_WARNING_OBJECT (obj->dbg_obj, "VIDIOC_CROPCAP failed");
return FALSE;
}
if (target == V4L2_SEL_TGT_CROP_BOUNDS)
res_rect = &cropcap.bounds;
else if (target == V4L2_SEL_TGT_CROP_DEFAULT)
res_rect = &cropcap.defrect;
}
}
*result = *res_rect;
return TRUE;
}
gboolean
gst_v4l2_object_get_crop_bounds (GstV4l2Object * obj, struct v4l2_rect * result)
{
return gst_v4l2_object_get_crop_rect (obj, V4L2_SEL_TGT_CROP_BOUNDS, result);
}
gboolean
gst_v4l2_object_get_crop_default (GstV4l2Object * obj,
struct v4l2_rect * result)
{
return gst_v4l2_object_get_crop_rect (obj, V4L2_SEL_TGT_CROP_DEFAULT, result);
}
gboolean
gst_v4l2_object_caps_equal (GstV4l2Object * v4l2object, GstCaps * caps)
{

View file

@ -315,6 +315,8 @@ GstStructure * gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc);
/* crop / compose */
gboolean gst_v4l2_object_set_crop (GstV4l2Object * obj, struct v4l2_rect *result);
gboolean gst_v4l2_object_get_crop_bounds (GstV4l2Object * obj, struct v4l2_rect *bounds);
gboolean gst_v4l2_object_get_crop_default (GstV4l2Object * obj, struct v4l2_rect *bounds);
/* TODO Move to proper namespace */
/* open/close the device */