aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2014-03-13 07:44:09 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-23 13:32:58 -0400
commit2ef114f6821b013c42d2ef1e31600d957a47542b (patch)
treedac425e318755a4a0b3fef7359062dbfe31bebea
parent928bf2ba2f0e65a971a60e940c69af0b02ae4a57 (diff)
[media] v4l: ti-vpe: Add selection API in VPE driver
Add selection ioctl ops. For VPE, cropping makes sense only for the input to VPE(or V4L2_BUF_TYPE_VIDEO_OUTPUT/MPLANE buffers) and composing makes sense only for the output of VPE(or V4L2_BUF_TYPE_VIDEO_CAPTURE/MPLANE buffers). For the CAPTURE type, V4L2_SEL_TGT_COMPOSE results in VPE writing the output in a rectangle within the capture buffer. For the OUTPUT type, V4L2_SEL_TGT_CROP results in selecting a rectangle region within the source buffer. Setting the crop/compose rectangles should successfully result in re-configuration of registers which are affected when either source or destination dimensions change, set_srcdst_params() is called for this purpose. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Kamil Debski <k.debski@samsung.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/platform/ti-vpe/vpe.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c
index 1c9e57c278e9..972f43f69206 100644
--- a/drivers/media/platform/ti-vpe/vpe.c
+++ b/drivers/media/platform/ti-vpe/vpe.c
@@ -410,8 +410,10 @@ static struct vpe_q_data *get_q_data(struct vpe_ctx *ctx,
410{ 410{
411 switch (type) { 411 switch (type) {
412 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 412 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
413 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
413 return &ctx->q_data[Q_DATA_SRC]; 414 return &ctx->q_data[Q_DATA_SRC];
414 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 415 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
416 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
415 return &ctx->q_data[Q_DATA_DST]; 417 return &ctx->q_data[Q_DATA_DST];
416 default: 418 default:
417 BUG(); 419 BUG();
@@ -1591,6 +1593,151 @@ static int vpe_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
1591 return set_srcdst_params(ctx); 1593 return set_srcdst_params(ctx);
1592} 1594}
1593 1595
1596static int __vpe_try_selection(struct vpe_ctx *ctx, struct v4l2_selection *s)
1597{
1598 struct vpe_q_data *q_data;
1599
1600 if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
1601 (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
1602 return -EINVAL;
1603
1604 q_data = get_q_data(ctx, s->type);
1605 if (!q_data)
1606 return -EINVAL;
1607
1608 switch (s->target) {
1609 case V4L2_SEL_TGT_COMPOSE:
1610 /*
1611 * COMPOSE target is only valid for capture buffer type, return
1612 * error for output buffer type
1613 */
1614 if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1615 return -EINVAL;
1616 break;
1617 case V4L2_SEL_TGT_CROP:
1618 /*
1619 * CROP target is only valid for output buffer type, return
1620 * error for capture buffer type
1621 */
1622 if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1623 return -EINVAL;
1624 break;
1625 /*
1626 * bound and default crop/compose targets are invalid targets to
1627 * try/set
1628 */
1629 default:
1630 return -EINVAL;
1631 }
1632
1633 if (s->r.top < 0 || s->r.left < 0) {
1634 vpe_err(ctx->dev, "negative values for top and left\n");
1635 s->r.top = s->r.left = 0;
1636 }
1637
1638 v4l_bound_align_image(&s->r.width, MIN_W, q_data->width, 1,
1639 &s->r.height, MIN_H, q_data->height, H_ALIGN, S_ALIGN);
1640
1641 /* adjust left/top if cropping rectangle is out of bounds */
1642 if (s->r.left + s->r.width > q_data->width)
1643 s->r.left = q_data->width - s->r.width;
1644 if (s->r.top + s->r.height > q_data->height)
1645 s->r.top = q_data->height - s->r.height;
1646
1647 return 0;
1648}
1649
1650static int vpe_g_selection(struct file *file, void *fh,
1651 struct v4l2_selection *s)
1652{
1653 struct vpe_ctx *ctx = file2ctx(file);
1654 struct vpe_q_data *q_data;
1655 bool use_c_rect = false;
1656
1657 if ((s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
1658 (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT))
1659 return -EINVAL;
1660
1661 q_data = get_q_data(ctx, s->type);
1662 if (!q_data)
1663 return -EINVAL;
1664
1665 switch (s->target) {
1666 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1667 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1668 if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1669 return -EINVAL;
1670 break;
1671 case V4L2_SEL_TGT_CROP_BOUNDS:
1672 case V4L2_SEL_TGT_CROP_DEFAULT:
1673 if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1674 return -EINVAL;
1675 break;
1676 case V4L2_SEL_TGT_COMPOSE:
1677 if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1678 return -EINVAL;
1679 use_c_rect = true;
1680 break;
1681 case V4L2_SEL_TGT_CROP:
1682 if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1683 return -EINVAL;
1684 use_c_rect = true;
1685 break;
1686 default:
1687 return -EINVAL;
1688 }
1689
1690 if (use_c_rect) {
1691 /*
1692 * for CROP/COMPOSE target type, return c_rect params from the
1693 * respective buffer type
1694 */
1695 s->r = q_data->c_rect;
1696 } else {
1697 /*
1698 * for DEFAULT/BOUNDS target type, return width and height from
1699 * S_FMT of the respective buffer type
1700 */
1701 s->r.left = 0;
1702 s->r.top = 0;
1703 s->r.width = q_data->width;
1704 s->r.height = q_data->height;
1705 }
1706
1707 return 0;
1708}
1709
1710
1711static int vpe_s_selection(struct file *file, void *fh,
1712 struct v4l2_selection *s)
1713{
1714 struct vpe_ctx *ctx = file2ctx(file);
1715 struct vpe_q_data *q_data;
1716 struct v4l2_selection sel = *s;
1717 int ret;
1718
1719 ret = __vpe_try_selection(ctx, &sel);
1720 if (ret)
1721 return ret;
1722
1723 q_data = get_q_data(ctx, sel.type);
1724 if (!q_data)
1725 return -EINVAL;
1726
1727 if ((q_data->c_rect.left == sel.r.left) &&
1728 (q_data->c_rect.top == sel.r.top) &&
1729 (q_data->c_rect.width == sel.r.width) &&
1730 (q_data->c_rect.height == sel.r.height)) {
1731 vpe_dbg(ctx->dev,
1732 "requested crop/compose values are already set\n");
1733 return 0;
1734 }
1735
1736 q_data->c_rect = sel.r;
1737
1738 return set_srcdst_params(ctx);
1739}
1740
1594static int vpe_reqbufs(struct file *file, void *priv, 1741static int vpe_reqbufs(struct file *file, void *priv,
1595 struct v4l2_requestbuffers *reqbufs) 1742 struct v4l2_requestbuffers *reqbufs)
1596{ 1743{
@@ -1678,6 +1825,9 @@ static const struct v4l2_ioctl_ops vpe_ioctl_ops = {
1678 .vidioc_try_fmt_vid_out_mplane = vpe_try_fmt, 1825 .vidioc_try_fmt_vid_out_mplane = vpe_try_fmt,
1679 .vidioc_s_fmt_vid_out_mplane = vpe_s_fmt, 1826 .vidioc_s_fmt_vid_out_mplane = vpe_s_fmt,
1680 1827
1828 .vidioc_g_selection = vpe_g_selection,
1829 .vidioc_s_selection = vpe_s_selection,
1830
1681 .vidioc_reqbufs = vpe_reqbufs, 1831 .vidioc_reqbufs = vpe_reqbufs,
1682 .vidioc_querybuf = vpe_querybuf, 1832 .vidioc_querybuf = vpe_querybuf,
1683 1833