aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-04-20 04:47:49 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-08 13:16:23 -0400
commit433f75ab3d09a666c745d4163e21e811582d8eda (patch)
tree77ed1d115dbc078c716c49daed4b81fa1722d917 /drivers
parent684c8e26e755c0af49c1de554f863602c1803141 (diff)
[media] omap3isp: resizer: Replace the crop API by the selection API
Support for the legacy crop API is emulated in the subdev core. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c138
1 files changed, 88 insertions, 50 deletions
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
index 6958a9e3dc22..d7341ab15ffe 100644
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -1188,32 +1188,6 @@ static int resizer_set_stream(struct v4l2_subdev *sd, int enable)
1188} 1188}
1189 1189
1190/* 1190/*
1191 * resizer_g_crop - handle get crop subdev operation
1192 * @sd : pointer to v4l2 subdev structure
1193 * @pad : subdev pad
1194 * @crop : pointer to crop structure
1195 * @which : active or try format
1196 * return zero
1197 */
1198static int resizer_g_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1199 struct v4l2_subdev_crop *crop)
1200{
1201 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1202 struct v4l2_mbus_framefmt *format;
1203 struct resizer_ratio ratio;
1204
1205 /* Only sink pad has crop capability */
1206 if (crop->pad != RESZ_PAD_SINK)
1207 return -EINVAL;
1208
1209 format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, crop->which);
1210 crop->rect = *__resizer_get_crop(res, fh, crop->which);
1211 resizer_calc_ratios(res, &crop->rect, format, &ratio);
1212
1213 return 0;
1214}
1215
1216/*
1217 * resizer_try_crop - mangles crop parameters. 1191 * resizer_try_crop - mangles crop parameters.
1218 */ 1192 */
1219static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink, 1193static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
@@ -1223,7 +1197,7 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1223 const unsigned int spv = DEFAULT_PHASE; 1197 const unsigned int spv = DEFAULT_PHASE;
1224 const unsigned int sph = DEFAULT_PHASE; 1198 const unsigned int sph = DEFAULT_PHASE;
1225 1199
1226 /* Crop rectangle is constrained to the output size so that zoom ratio 1200 /* Crop rectangle is constrained by the output size so that zoom ratio
1227 * cannot exceed +/-4.0. 1201 * cannot exceed +/-4.0.
1228 */ 1202 */
1229 unsigned int min_width = 1203 unsigned int min_width =
@@ -1248,51 +1222,115 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1248} 1222}
1249 1223
1250/* 1224/*
1251 * resizer_s_crop - handle set crop subdev operation 1225 * resizer_get_selection - Retrieve a selection rectangle on a pad
1252 * @sd : pointer to v4l2 subdev structure 1226 * @sd: ISP resizer V4L2 subdevice
1253 * @pad : subdev pad 1227 * @fh: V4L2 subdev file handle
1254 * @crop : pointer to crop structure 1228 * @sel: Selection rectangle
1255 * @which : active or try format 1229 *
1256 * return -EINVAL or zero when succeed 1230 * The only supported rectangles are the crop rectangles on the sink pad.
1231 *
1232 * Return 0 on success or a negative error code otherwise.
1257 */ 1233 */
1258static int resizer_s_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 1234static int resizer_get_selection(struct v4l2_subdev *sd,
1259 struct v4l2_subdev_crop *crop) 1235 struct v4l2_subdev_fh *fh,
1236 struct v4l2_subdev_selection *sel)
1237{
1238 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1239 struct v4l2_mbus_framefmt *format_source;
1240 struct v4l2_mbus_framefmt *format_sink;
1241 struct resizer_ratio ratio;
1242
1243 if (sel->pad != RESZ_PAD_SINK)
1244 return -EINVAL;
1245
1246 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1247 sel->which);
1248 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1249 sel->which);
1250
1251 switch (sel->target) {
1252 case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
1253 sel->r.left = 0;
1254 sel->r.top = 0;
1255 sel->r.width = INT_MAX;
1256 sel->r.height = INT_MAX;
1257
1258 resizer_try_crop(format_sink, format_source, &sel->r);
1259 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1260 break;
1261
1262 case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
1263 sel->r = *__resizer_get_crop(res, fh, sel->which);
1264 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1265 break;
1266
1267 default:
1268 return -EINVAL;
1269 }
1270
1271 return 0;
1272}
1273
1274/*
1275 * resizer_set_selection - Set a selection rectangle on a pad
1276 * @sd: ISP resizer V4L2 subdevice
1277 * @fh: V4L2 subdev file handle
1278 * @sel: Selection rectangle
1279 *
1280 * The only supported rectangle is the actual crop rectangle on the sink pad.
1281 *
1282 * FIXME: This function currently behaves as if the KEEP_CONFIG selection flag
1283 * was always set.
1284 *
1285 * Return 0 on success or a negative error code otherwise.
1286 */
1287static int resizer_set_selection(struct v4l2_subdev *sd,
1288 struct v4l2_subdev_fh *fh,
1289 struct v4l2_subdev_selection *sel)
1260{ 1290{
1261 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1291 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1262 struct isp_device *isp = to_isp_device(res); 1292 struct isp_device *isp = to_isp_device(res);
1263 struct v4l2_mbus_framefmt *format_sink, *format_source; 1293 struct v4l2_mbus_framefmt *format_sink, *format_source;
1264 struct resizer_ratio ratio; 1294 struct resizer_ratio ratio;
1265 1295
1266 /* Only sink pad has crop capability */ 1296 if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
1267 if (crop->pad != RESZ_PAD_SINK) 1297 sel->pad != RESZ_PAD_SINK)
1268 return -EINVAL; 1298 return -EINVAL;
1269 1299
1270 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK, 1300 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1271 crop->which); 1301 sel->which);
1272 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, 1302 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1273 crop->which); 1303 sel->which);
1274 1304
1275 dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__, 1305 dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__,
1276 crop->rect.left, crop->rect.top, crop->rect.width, 1306 sel->r.left, sel->r.top, sel->r.width, sel->r.height,
1277 crop->rect.height, crop->which); 1307 sel->which);
1278 1308
1279 dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__, 1309 dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__,
1280 format_sink->width, format_sink->height, 1310 format_sink->width, format_sink->height,
1281 format_source->width, format_source->height); 1311 format_source->width, format_source->height);
1282 1312
1283 resizer_try_crop(format_sink, format_source, &crop->rect); 1313 /* Clamp the crop rectangle to the bounds, and then mangle it further to
1284 *__resizer_get_crop(res, fh, crop->which) = crop->rect; 1314 * fulfill the TRM equations. Store the clamped but otherwise unmangled
1285 resizer_calc_ratios(res, &crop->rect, format_source, &ratio); 1315 * rectangle to avoid cropping the input multiple times: when an
1316 * application sets the output format, the current crop rectangle is
1317 * mangled during crop rectangle computation, which would lead to a new,
1318 * smaller input crop rectangle every time the output size is set if we
1319 * stored the mangled rectangle.
1320 */
1321 resizer_try_crop(format_sink, format_source, &sel->r);
1322 *__resizer_get_crop(res, fh, sel->which) = sel->r;
1323 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1286 1324
1287 if (crop->which == V4L2_SUBDEV_FORMAT_TRY) 1325 if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
1288 return 0; 1326 return 0;
1289 1327
1290 res->ratio = ratio; 1328 res->ratio = ratio;
1291 res->crop.active = crop->rect; 1329 res->crop.active = sel->r;
1292 1330
1293 /* 1331 /*
1294 * s_crop can be called while streaming is on. In this case 1332 * set_selection can be called while streaming is on. In this case the
1295 * the crop values will be set in the next IRQ. 1333 * crop values will be set in the next IRQ.
1296 */ 1334 */
1297 if (res->state != ISP_PIPELINE_STREAM_STOPPED) 1335 if (res->state != ISP_PIPELINE_STREAM_STOPPED)
1298 res->applycrop = 1; 1336 res->applycrop = 1;
@@ -1530,8 +1568,8 @@ static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
1530 .enum_frame_size = resizer_enum_frame_size, 1568 .enum_frame_size = resizer_enum_frame_size,
1531 .get_fmt = resizer_get_format, 1569 .get_fmt = resizer_get_format,
1532 .set_fmt = resizer_set_format, 1570 .set_fmt = resizer_set_format,
1533 .get_crop = resizer_g_crop, 1571 .get_selection = resizer_get_selection,
1534 .set_crop = resizer_s_crop, 1572 .set_selection = resizer_set_selection,
1535}; 1573};
1536 1574
1537/* subdev operations */ 1575/* subdev operations */