diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2012-04-29 16:46:03 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-20 08:29:12 -0400 |
commit | fed07f848888267d5991b9446e103f35aaeb58d8 (patch) | |
tree | 22ce87821891d519873b59deca91bd846f6a215c | |
parent | 9448ab7dec30489d5318f786d0faee08354ef3d5 (diff) |
[media] s5p-fimc: Use selection API in place of crop operations
Replace deprecated crop operations with the selection API.
Original crop ioctls are supported through a compatibility
layer at the v4l2 core.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kuyngmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 176 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.h | 2 |
2 files changed, 109 insertions, 69 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 12415e7383d4..354574591908 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -611,8 +611,13 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, | |||
611 | } | 611 | } |
612 | /* Apply the scaler and the output DMA constraints */ | 612 | /* Apply the scaler and the output DMA constraints */ |
613 | max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w; | 613 | max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w; |
614 | min_w = ctx->state & FIMC_DST_CROP ? dst->width : var->min_out_pixsize; | 614 | if (ctx->state & FIMC_COMPOSE) { |
615 | min_h = ctx->state & FIMC_DST_CROP ? dst->height : var->min_out_pixsize; | 615 | min_w = dst->offs_h + dst->width; |
616 | min_h = dst->offs_v + dst->height; | ||
617 | } else { | ||
618 | min_w = var->min_out_pixsize; | ||
619 | min_h = var->min_out_pixsize; | ||
620 | } | ||
616 | if (var->min_vsize_align == 1 && !rotation) | 621 | if (var->min_vsize_align == 1 && !rotation) |
617 | align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1; | 622 | align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1; |
618 | 623 | ||
@@ -630,8 +635,9 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, | |||
630 | return ffmt; | 635 | return ffmt; |
631 | } | 636 | } |
632 | 637 | ||
633 | static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r, | 638 | static void fimc_capture_try_selection(struct fimc_ctx *ctx, |
634 | int pad) | 639 | struct v4l2_rect *r, |
640 | int target) | ||
635 | { | 641 | { |
636 | bool rotate = ctx->rotation == 90 || ctx->rotation == 270; | 642 | bool rotate = ctx->rotation == 90 || ctx->rotation == 270; |
637 | struct fimc_dev *fimc = ctx->fimc_dev; | 643 | struct fimc_dev *fimc = ctx->fimc_dev; |
@@ -649,7 +655,7 @@ static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r, | |||
649 | r->left = r->top = 0; | 655 | r->left = r->top = 0; |
650 | return; | 656 | return; |
651 | } | 657 | } |
652 | if (pad == FIMC_SD_PAD_SOURCE) { | 658 | if (target == V4L2_SEL_TGT_COMPOSE_ACTIVE) { |
653 | if (ctx->rotation != 90 && ctx->rotation != 270) | 659 | if (ctx->rotation != 90 && ctx->rotation != 270) |
654 | align_h = 1; | 660 | align_h = 1; |
655 | max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3)); | 661 | max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3)); |
@@ -663,8 +669,7 @@ static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r, | |||
663 | max_sc_h = max_sc_v = 1; | 669 | max_sc_h = max_sc_v = 1; |
664 | } | 670 | } |
665 | /* | 671 | /* |
666 | * For the crop rectangle at source pad the following constraints | 672 | * For the compose rectangle the following constraints must be met: |
667 | * must be met: | ||
668 | * - it must fit in the sink pad format rectangle (f_width/f_height); | 673 | * - it must fit in the sink pad format rectangle (f_width/f_height); |
669 | * - maximum downscaling ratio is 64; | 674 | * - maximum downscaling ratio is 64; |
670 | * - maximum crop size depends if the rotator is used or not; | 675 | * - maximum crop size depends if the rotator is used or not; |
@@ -676,7 +681,8 @@ static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r, | |||
676 | rotate ? pl->out_rot_en_w : pl->out_rot_dis_w, | 681 | rotate ? pl->out_rot_en_w : pl->out_rot_dis_w, |
677 | rotate ? sink->f_height : sink->f_width); | 682 | rotate ? sink->f_height : sink->f_width); |
678 | max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height); | 683 | max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height); |
679 | if (pad == FIMC_SD_PAD_SOURCE) { | 684 | |
685 | if (target == V4L2_SEL_TGT_COMPOSE_ACTIVE) { | ||
680 | min_w = min_t(u32, max_w, sink->f_width / max_sc_h); | 686 | min_w = min_t(u32, max_w, sink->f_width / max_sc_h); |
681 | min_h = min_t(u32, max_h, sink->f_height / max_sc_v); | 687 | min_h = min_t(u32, max_h, sink->f_height / max_sc_v); |
682 | if (rotate) { | 688 | if (rotate) { |
@@ -687,13 +693,13 @@ static void fimc_capture_try_crop(struct fimc_ctx *ctx, struct v4l2_rect *r, | |||
687 | v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1, | 693 | v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1, |
688 | &r->height, min_h, max_h, align_h, | 694 | &r->height, min_h, max_h, align_h, |
689 | align_sz); | 695 | align_sz); |
690 | /* Adjust left/top if cropping rectangle is out of bounds */ | 696 | /* Adjust left/top if crop/compose rectangle is out of bounds */ |
691 | r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width); | 697 | r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width); |
692 | r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height); | 698 | r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height); |
693 | r->left = round_down(r->left, var->hor_offs_align); | 699 | r->left = round_down(r->left, var->hor_offs_align); |
694 | 700 | ||
695 | dbg("pad%d: (%d,%d)/%dx%d, sink fmt: %dx%d", | 701 | dbg("target %#x: (%d,%d)/%dx%d, sink fmt: %dx%d", |
696 | pad, r->left, r->top, r->width, r->height, | 702 | target, r->left, r->top, r->width, r->height, |
697 | sink->f_width, sink->f_height); | 703 | sink->f_width, sink->f_height); |
698 | } | 704 | } |
699 | 705 | ||
@@ -925,7 +931,7 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) | |||
925 | 931 | ||
926 | set_frame_bounds(ff, pix->width, pix->height); | 932 | set_frame_bounds(ff, pix->width, pix->height); |
927 | /* Reset the composition rectangle if not yet configured */ | 933 | /* Reset the composition rectangle if not yet configured */ |
928 | if (!(ctx->state & FIMC_DST_CROP)) | 934 | if (!(ctx->state & FIMC_COMPOSE)) |
929 | set_frame_crop(ff, 0, 0, pix->width, pix->height); | 935 | set_frame_crop(ff, 0, 0, pix->width, pix->height); |
930 | 936 | ||
931 | fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color)); | 937 | fimc_capture_mark_jpeg_xfer(ctx, fimc_fmt_is_jpeg(ff->fmt->color)); |
@@ -1175,29 +1181,18 @@ static int fimc_cap_s_selection(struct file *file, void *fh, | |||
1175 | struct v4l2_rect rect = s->r; | 1181 | struct v4l2_rect rect = s->r; |
1176 | struct fimc_frame *f; | 1182 | struct fimc_frame *f; |
1177 | unsigned long flags; | 1183 | unsigned long flags; |
1178 | unsigned int pad; | ||
1179 | 1184 | ||
1180 | if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | 1185 | if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) |
1181 | return -EINVAL; | 1186 | return -EINVAL; |
1182 | 1187 | ||
1183 | switch (s->target) { | 1188 | if (s->target == V4L2_SEL_TGT_COMPOSE_ACTIVE) |
1184 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: | ||
1185 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | ||
1186 | case V4L2_SEL_TGT_COMPOSE_ACTIVE: | ||
1187 | f = &ctx->d_frame; | 1189 | f = &ctx->d_frame; |
1188 | pad = FIMC_SD_PAD_SOURCE; | 1190 | else if (s->target == V4L2_SEL_TGT_CROP_ACTIVE) |
1189 | break; | ||
1190 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
1191 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
1192 | case V4L2_SEL_TGT_CROP_ACTIVE: | ||
1193 | f = &ctx->s_frame; | 1191 | f = &ctx->s_frame; |
1194 | pad = FIMC_SD_PAD_SINK; | 1192 | else |
1195 | break; | ||
1196 | default: | ||
1197 | return -EINVAL; | 1193 | return -EINVAL; |
1198 | } | ||
1199 | 1194 | ||
1200 | fimc_capture_try_crop(ctx, &rect, pad); | 1195 | fimc_capture_try_selection(ctx, &rect, s->target); |
1201 | 1196 | ||
1202 | if (s->flags & V4L2_SEL_FLAG_LE && | 1197 | if (s->flags & V4L2_SEL_FLAG_LE && |
1203 | !enclosed_rectangle(&rect, &s->r)) | 1198 | !enclosed_rectangle(&rect, &s->r)) |
@@ -1409,77 +1404,122 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, | |||
1409 | ff->fmt = ffmt; | 1404 | ff->fmt = ffmt; |
1410 | 1405 | ||
1411 | /* Reset the crop rectangle if required. */ | 1406 | /* Reset the crop rectangle if required. */ |
1412 | if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_DST_CROP))) | 1407 | if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_COMPOSE))) |
1413 | set_frame_crop(ff, 0, 0, mf->width, mf->height); | 1408 | set_frame_crop(ff, 0, 0, mf->width, mf->height); |
1414 | 1409 | ||
1415 | if (fmt->pad == FIMC_SD_PAD_SINK) | 1410 | if (fmt->pad == FIMC_SD_PAD_SINK) |
1416 | ctx->state &= ~FIMC_DST_CROP; | 1411 | ctx->state &= ~FIMC_COMPOSE; |
1417 | mutex_unlock(&fimc->lock); | 1412 | mutex_unlock(&fimc->lock); |
1418 | return 0; | 1413 | return 0; |
1419 | } | 1414 | } |
1420 | 1415 | ||
1421 | static int fimc_subdev_get_crop(struct v4l2_subdev *sd, | 1416 | static int fimc_subdev_get_selection(struct v4l2_subdev *sd, |
1422 | struct v4l2_subdev_fh *fh, | 1417 | struct v4l2_subdev_fh *fh, |
1423 | struct v4l2_subdev_crop *crop) | 1418 | struct v4l2_subdev_selection *sel) |
1424 | { | 1419 | { |
1425 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); | 1420 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); |
1426 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; | 1421 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; |
1427 | struct v4l2_rect *r = &crop->rect; | 1422 | struct fimc_frame *f = &ctx->s_frame; |
1428 | struct fimc_frame *ff; | 1423 | struct v4l2_rect *r = &sel->r; |
1424 | struct v4l2_rect *try_sel; | ||
1425 | |||
1426 | if (sel->pad != FIMC_SD_PAD_SINK) | ||
1427 | return -EINVAL; | ||
1428 | |||
1429 | mutex_lock(&fimc->lock); | ||
1429 | 1430 | ||
1430 | if (crop->which == V4L2_SUBDEV_FORMAT_TRY) { | 1431 | switch (sel->target) { |
1431 | crop->rect = *v4l2_subdev_get_try_crop(fh, crop->pad); | 1432 | case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS: |
1433 | f = &ctx->d_frame; | ||
1434 | case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: | ||
1435 | r->width = f->o_width; | ||
1436 | r->height = f->o_height; | ||
1437 | r->left = 0; | ||
1438 | r->top = 0; | ||
1439 | mutex_unlock(&fimc->lock); | ||
1432 | return 0; | 1440 | return 0; |
1441 | |||
1442 | case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: | ||
1443 | try_sel = v4l2_subdev_get_try_crop(fh, sel->pad); | ||
1444 | break; | ||
1445 | case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL: | ||
1446 | try_sel = v4l2_subdev_get_try_compose(fh, sel->pad); | ||
1447 | f = &ctx->d_frame; | ||
1448 | break; | ||
1449 | default: | ||
1450 | mutex_unlock(&fimc->lock); | ||
1451 | return -EINVAL; | ||
1433 | } | 1452 | } |
1434 | ff = crop->pad == FIMC_SD_PAD_SINK ? | ||
1435 | &ctx->s_frame : &ctx->d_frame; | ||
1436 | 1453 | ||
1437 | mutex_lock(&fimc->lock); | 1454 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1438 | r->left = ff->offs_h; | 1455 | sel->r = *try_sel; |
1439 | r->top = ff->offs_v; | 1456 | } else { |
1440 | r->width = ff->width; | 1457 | r->left = f->offs_h; |
1441 | r->height = ff->height; | 1458 | r->top = f->offs_v; |
1442 | mutex_unlock(&fimc->lock); | 1459 | r->width = f->width; |
1460 | r->height = f->height; | ||
1461 | } | ||
1443 | 1462 | ||
1444 | dbg("ff:%p, pad%d: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d", | 1463 | dbg("target %#x: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d", |
1445 | ff, crop->pad, r->left, r->top, r->width, r->height, | 1464 | sel->pad, r->left, r->top, r->width, r->height, |
1446 | ff->f_width, ff->f_height); | 1465 | f->f_width, f->f_height); |
1447 | 1466 | ||
1467 | mutex_unlock(&fimc->lock); | ||
1448 | return 0; | 1468 | return 0; |
1449 | } | 1469 | } |
1450 | 1470 | ||
1451 | static int fimc_subdev_set_crop(struct v4l2_subdev *sd, | 1471 | static int fimc_subdev_set_selection(struct v4l2_subdev *sd, |
1452 | struct v4l2_subdev_fh *fh, | 1472 | struct v4l2_subdev_fh *fh, |
1453 | struct v4l2_subdev_crop *crop) | 1473 | struct v4l2_subdev_selection *sel) |
1454 | { | 1474 | { |
1455 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); | 1475 | struct fimc_dev *fimc = v4l2_get_subdevdata(sd); |
1456 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; | 1476 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; |
1457 | struct v4l2_rect *r = &crop->rect; | 1477 | struct fimc_frame *f = &ctx->s_frame; |
1458 | struct fimc_frame *ff; | 1478 | struct v4l2_rect *r = &sel->r; |
1479 | struct v4l2_rect *try_sel; | ||
1459 | unsigned long flags; | 1480 | unsigned long flags; |
1460 | 1481 | ||
1461 | dbg("(%d,%d)/%dx%d", r->left, r->top, r->width, r->height); | 1482 | if (sel->pad != FIMC_SD_PAD_SINK) |
1462 | 1483 | return -EINVAL; | |
1463 | ff = crop->pad == FIMC_SD_PAD_SOURCE ? | ||
1464 | &ctx->d_frame : &ctx->s_frame; | ||
1465 | 1484 | ||
1466 | mutex_lock(&fimc->lock); | 1485 | mutex_lock(&fimc->lock); |
1467 | fimc_capture_try_crop(ctx, r, crop->pad); | 1486 | fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP_ACTIVE); |
1468 | 1487 | ||
1469 | if (crop->which == V4L2_SUBDEV_FORMAT_TRY) { | 1488 | switch (sel->target) { |
1489 | case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS: | ||
1490 | f = &ctx->d_frame; | ||
1491 | case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS: | ||
1492 | r->width = f->o_width; | ||
1493 | r->height = f->o_height; | ||
1494 | r->left = 0; | ||
1495 | r->top = 0; | ||
1470 | mutex_unlock(&fimc->lock); | 1496 | mutex_unlock(&fimc->lock); |
1471 | *v4l2_subdev_get_try_crop(fh, crop->pad) = *r; | ||
1472 | return 0; | 1497 | return 0; |
1498 | |||
1499 | case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL: | ||
1500 | try_sel = v4l2_subdev_get_try_crop(fh, sel->pad); | ||
1501 | break; | ||
1502 | case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL: | ||
1503 | try_sel = v4l2_subdev_get_try_compose(fh, sel->pad); | ||
1504 | f = &ctx->d_frame; | ||
1505 | break; | ||
1506 | default: | ||
1507 | mutex_unlock(&fimc->lock); | ||
1508 | return -EINVAL; | ||
1473 | } | 1509 | } |
1474 | spin_lock_irqsave(&fimc->slock, flags); | ||
1475 | set_frame_crop(ff, r->left, r->top, r->width, r->height); | ||
1476 | if (crop->pad == FIMC_SD_PAD_SOURCE) | ||
1477 | ctx->state |= FIMC_DST_CROP; | ||
1478 | 1510 | ||
1479 | set_bit(ST_CAPT_APPLY_CFG, &fimc->state); | 1511 | if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { |
1480 | spin_unlock_irqrestore(&fimc->slock, flags); | 1512 | *try_sel = sel->r; |
1513 | } else { | ||
1514 | spin_lock_irqsave(&fimc->slock, flags); | ||
1515 | set_frame_crop(f, r->left, r->top, r->width, r->height); | ||
1516 | set_bit(ST_CAPT_APPLY_CFG, &fimc->state); | ||
1517 | spin_unlock_irqrestore(&fimc->slock, flags); | ||
1518 | if (sel->target == V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL) | ||
1519 | ctx->state |= FIMC_COMPOSE; | ||
1520 | } | ||
1481 | 1521 | ||
1482 | dbg("pad%d: (%d,%d)/%dx%d", crop->pad, r->left, r->top, | 1522 | dbg("target %#x: (%d,%d)/%dx%d", sel->target, r->left, r->top, |
1483 | r->width, r->height); | 1523 | r->width, r->height); |
1484 | 1524 | ||
1485 | mutex_unlock(&fimc->lock); | 1525 | mutex_unlock(&fimc->lock); |
@@ -1488,10 +1528,10 @@ static int fimc_subdev_set_crop(struct v4l2_subdev *sd, | |||
1488 | 1528 | ||
1489 | static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = { | 1529 | static struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = { |
1490 | .enum_mbus_code = fimc_subdev_enum_mbus_code, | 1530 | .enum_mbus_code = fimc_subdev_enum_mbus_code, |
1531 | .get_selection = fimc_subdev_get_selection, | ||
1532 | .set_selection = fimc_subdev_set_selection, | ||
1491 | .get_fmt = fimc_subdev_get_fmt, | 1533 | .get_fmt = fimc_subdev_get_fmt, |
1492 | .set_fmt = fimc_subdev_set_fmt, | 1534 | .set_fmt = fimc_subdev_set_fmt, |
1493 | .get_crop = fimc_subdev_get_crop, | ||
1494 | .set_crop = fimc_subdev_set_crop, | ||
1495 | }; | 1535 | }; |
1496 | 1536 | ||
1497 | static struct v4l2_subdev_ops fimc_subdev_ops = { | 1537 | static struct v4l2_subdev_ops fimc_subdev_ops = { |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 794c496d6811..95b27ae5cf27 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -114,7 +114,7 @@ enum fimc_color_fmt { | |||
114 | #define FIMC_PARAMS (1 << 0) | 114 | #define FIMC_PARAMS (1 << 0) |
115 | #define FIMC_SRC_FMT (1 << 3) | 115 | #define FIMC_SRC_FMT (1 << 3) |
116 | #define FIMC_DST_FMT (1 << 4) | 116 | #define FIMC_DST_FMT (1 << 4) |
117 | #define FIMC_DST_CROP (1 << 5) | 117 | #define FIMC_COMPOSE (1 << 5) |
118 | #define FIMC_CTX_M2M (1 << 16) | 118 | #define FIMC_CTX_M2M (1 << 16) |
119 | #define FIMC_CTX_CAP (1 << 17) | 119 | #define FIMC_CTX_CAP (1 << 17) |
120 | #define FIMC_CTX_SHUT (1 << 18) | 120 | #define FIMC_CTX_SHUT (1 << 18) |