aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core/v4l2-ioctl.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2016-04-15 05:27:28 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2016-05-06 14:43:45 -0400
commit95dd7b7e30f385c1c2d5e41457c082c5f6c535b3 (patch)
treeb0839be230e8587729def14fc77e6ef79404089c /drivers/media/v4l2-core/v4l2-ioctl.c
parent92021e074afe25a607e24ec8f28d3daebca5d434 (diff)
[media] v4l2-ioctl.c: improve cropcap compatibility code
- Add a check for the case that both the cropcap and g_selection ops are NULL. This shouldn't happen, but I feel happier if the code guards against this. - If g_selection exists, then ignore ENOTTY and ENOIOCTLCMD error codes from cropcap. Just assume square pixelaspect ratio in that case. This situation can happen if the bridge driver's cropcap op calls the corresponding subdev's op. So the cropcap ioctl is set, but it might return ENOIOCTLCMD anyway. In the past this would just return an error which is wrong. - Call cropcap first and let g_selection overwrite the bounds and defrect. This safeguards against subdev cropcap implementations that set those rectangles as well. What g_selection returns has priority over what such cropcap implementations return. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-ioctl.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c70
1 files changed, 43 insertions, 27 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 6bf5a3ecd126..28e5be2c2eef 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -2160,40 +2160,56 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
2160 struct file *file, void *fh, void *arg) 2160 struct file *file, void *fh, void *arg)
2161{ 2161{
2162 struct v4l2_cropcap *p = arg; 2162 struct v4l2_cropcap *p = arg;
2163 struct v4l2_selection s = { .type = p->type };
2164 int ret = 0;
2163 2165
2164 if (ops->vidioc_g_selection) { 2166 /* setting trivial pixelaspect */
2165 struct v4l2_selection s = { .type = p->type }; 2167 p->pixelaspect.numerator = 1;
2166 int ret; 2168 p->pixelaspect.denominator = 1;
2167 2169
2168 /* obtaining bounds */ 2170 /*
2169 if (V4L2_TYPE_IS_OUTPUT(p->type)) 2171 * The determine_valid_ioctls() call already should ensure
2170 s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; 2172 * that this can never happen, but just in case...
2171 else 2173 */
2172 s.target = V4L2_SEL_TGT_CROP_BOUNDS; 2174 if (WARN_ON(!ops->vidioc_cropcap && !ops->vidioc_cropcap))
2175 return -ENOTTY;
2173 2176
2174 ret = ops->vidioc_g_selection(file, fh, &s); 2177 if (ops->vidioc_cropcap)
2175 if (ret) 2178 ret = ops->vidioc_cropcap(file, fh, p);
2176 return ret;
2177 p->bounds = s.r;
2178 2179
2179 /* obtaining defrect */ 2180 if (!ops->vidioc_g_selection)
2180 if (V4L2_TYPE_IS_OUTPUT(p->type)) 2181 return ret;
2181 s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
2182 else
2183 s.target = V4L2_SEL_TGT_CROP_DEFAULT;
2184 2182
2185 ret = ops->vidioc_g_selection(file, fh, &s); 2183 /*
2186 if (ret) 2184 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
2187 return ret; 2185 * square pixel aspect ratio in that case.
2188 p->defrect = s.r; 2186 */
2189 } 2187 if (ret && ret != -ENOTTY && ret != -ENOIOCTLCMD)
2188 return ret;
2190 2189
2191 /* setting trivial pixelaspect */ 2190 /* Use g_selection() to fill in the bounds and defrect rectangles */
2192 p->pixelaspect.numerator = 1;
2193 p->pixelaspect.denominator = 1;
2194 2191
2195 if (ops->vidioc_cropcap) 2192 /* obtaining bounds */
2196 return ops->vidioc_cropcap(file, fh, p); 2193 if (V4L2_TYPE_IS_OUTPUT(p->type))
2194 s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
2195 else
2196 s.target = V4L2_SEL_TGT_CROP_BOUNDS;
2197
2198 ret = ops->vidioc_g_selection(file, fh, &s);
2199 if (ret)
2200 return ret;
2201 p->bounds = s.r;
2202
2203 /* obtaining defrect */
2204 if (V4L2_TYPE_IS_OUTPUT(p->type))
2205 s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
2206 else
2207 s.target = V4L2_SEL_TGT_CROP_DEFAULT;
2208
2209 ret = ops->vidioc_g_selection(file, fh, &s);
2210 if (ret)
2211 return ret;
2212 p->defrect = s.r;
2197 2213
2198 return 0; 2214 return 0;
2199} 2215}