media: v4l2-ioctl: add QUIRK_INVERTED_CROP
Some old Samsung drivers use the legacy crop API incorrectly: the crop and compose targets are swapped. Normally VIDIOC_G_CROP will return the CROP rectangle of a CAPTURE stream and the COMPOSE rectangle of an OUTPUT stream. The Samsung drivers do the opposite. Note that these drivers predate the selection API. If this 'QUIRK' flag is set, then the v4l2-ioctl core will swap the CROP and COMPOSE targets as well. That way backwards compatibility is ensured and we can convert the Samsung drivers to the selection API. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
此提交包含在:
@@ -2202,6 +2202,7 @@ static int v4l_s_selection(const struct v4l2_ioctl_ops *ops,
|
||||
static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
|
||||
struct file *file, void *fh, void *arg)
|
||||
{
|
||||
struct video_device *vfd = video_devdata(file);
|
||||
struct v4l2_crop *p = arg;
|
||||
struct v4l2_selection s = {
|
||||
.type = p->type,
|
||||
@@ -2218,6 +2219,10 @@ static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
|
||||
else
|
||||
s.target = V4L2_SEL_TGT_CROP;
|
||||
|
||||
if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
|
||||
s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
|
||||
V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
|
||||
|
||||
ret = v4l_g_selection(ops, file, fh, &s);
|
||||
|
||||
/* copying results to old structure on success */
|
||||
@@ -2229,6 +2234,7 @@ static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
|
||||
static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
|
||||
struct file *file, void *fh, void *arg)
|
||||
{
|
||||
struct video_device *vfd = video_devdata(file);
|
||||
struct v4l2_crop *p = arg;
|
||||
struct v4l2_selection s = {
|
||||
.type = p->type,
|
||||
@@ -2245,12 +2251,17 @@ static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
|
||||
else
|
||||
s.target = V4L2_SEL_TGT_CROP;
|
||||
|
||||
if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
|
||||
s.target = s.target == V4L2_SEL_TGT_COMPOSE ?
|
||||
V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE;
|
||||
|
||||
return v4l_s_selection(ops, file, fh, &s);
|
||||
}
|
||||
|
||||
static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
|
||||
struct file *file, void *fh, void *arg)
|
||||
{
|
||||
struct video_device *vfd = video_devdata(file);
|
||||
struct v4l2_cropcap *p = arg;
|
||||
struct v4l2_selection s = { .type = p->type };
|
||||
int ret = 0;
|
||||
@@ -2287,13 +2298,17 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
|
||||
else
|
||||
s.target = V4L2_SEL_TGT_CROP_BOUNDS;
|
||||
|
||||
if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags))
|
||||
s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ?
|
||||
V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS;
|
||||
|
||||
ret = v4l_g_selection(ops, file, fh, &s);
|
||||
if (ret)
|
||||
return ret;
|
||||
p->bounds = s.r;
|
||||
|
||||
/* obtaining defrect */
|
||||
if (V4L2_TYPE_IS_OUTPUT(p->type))
|
||||
if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
|
||||
s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
|
||||
else
|
||||
s.target = V4L2_SEL_TGT_CROP_DEFAULT;
|
||||
|
新增問題並參考
封鎖使用者