diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-15 15:49:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-15 15:49:56 -0500 |
commit | 122804ecb59493fbb4d31b3ba9ac59faaf45276f (patch) | |
tree | cff4d8a158c412e4a8d3abc8d91bb0eb52b01c9a /drivers/media/video/v4l2-ioctl.c | |
parent | 16008d641670571ff4cd750b416c7caf2d89f467 (diff) | |
parent | 126400033940afb658123517a2e80eb68259fbd7 (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (655 commits)
[media] revert patch: HDIC HD29L2 DMB-TH USB2.0 reference design driver
mb86a20s: Add a few more register settings at the init seq
mb86a20s: Group registers into the same line
[media] [PATCH] don't reset the delivery system on DTV_CLEAR
[media] [BUG] it913x-fe fix typo error making SNR levels unstable
[media] cx23885: Query the CX25840 during enum_input for status
[media] cx25840: Add support for g_input_status
[media] rc-videomate-m1f.c Rename to match remote controler name
[media] drivers: media: au0828: Fix dependency for VIDEO_AU0828
[media] convert drivers/media/* to use module_platform_driver()
[media] drivers: video: cx231xx: Fix dependency for VIDEO_CX231XX_DVB
[media] Exynos4 JPEG codec v4l2 driver
[media] doc: v4l: selection: choose pixels as units for selection rectangles
[media] v4l: s5p-tv: mixer: fix setup of VP scaling
[media] v4l: s5p-tv: mixer: add support for selection API
[media] v4l: emulate old crop API using extended crop/compose API
[media] doc: v4l: add documentation for selection API
[media] doc: v4l: add binary images for selection API
[media] v4l: add support for selection api
[media] hd29l2: fix review findings
...
Diffstat (limited to 'drivers/media/video/v4l2-ioctl.c')
-rw-r--r-- | drivers/media/video/v4l2-ioctl.c | 120 |
1 files changed, 114 insertions, 6 deletions
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index e1da8fc9dd2f..77feeb67e2db 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -238,6 +238,8 @@ static const char *v4l2_ioctls[] = { | |||
238 | [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", | 238 | [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", |
239 | [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", | 239 | [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", |
240 | [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", | 240 | [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", |
241 | [_IOC_NR(VIDIOC_G_SELECTION)] = "VIDIOC_G_SELECTION", | ||
242 | [_IOC_NR(VIDIOC_S_SELECTION)] = "VIDIOC_S_SELECTION", | ||
241 | [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", | 243 | [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", |
242 | [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", | 244 | [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", |
243 | [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", | 245 | [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", |
@@ -1547,11 +1549,32 @@ static long __video_do_ioctl(struct file *file, | |||
1547 | { | 1549 | { |
1548 | struct v4l2_crop *p = arg; | 1550 | struct v4l2_crop *p = arg; |
1549 | 1551 | ||
1550 | if (!ops->vidioc_g_crop) | 1552 | if (!ops->vidioc_g_crop && !ops->vidioc_g_selection) |
1551 | break; | 1553 | break; |
1552 | 1554 | ||
1553 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | 1555 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
1554 | ret = ops->vidioc_g_crop(file, fh, p); | 1556 | |
1557 | if (ops->vidioc_g_crop) { | ||
1558 | ret = ops->vidioc_g_crop(file, fh, p); | ||
1559 | } else { | ||
1560 | /* simulate capture crop using selection api */ | ||
1561 | struct v4l2_selection s = { | ||
1562 | .type = p->type, | ||
1563 | }; | ||
1564 | |||
1565 | /* crop means compose for output devices */ | ||
1566 | if (V4L2_TYPE_IS_OUTPUT(p->type)) | ||
1567 | s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; | ||
1568 | else | ||
1569 | s.target = V4L2_SEL_TGT_CROP_ACTIVE; | ||
1570 | |||
1571 | ret = ops->vidioc_g_selection(file, fh, &s); | ||
1572 | |||
1573 | /* copying results to old structure on success */ | ||
1574 | if (!ret) | ||
1575 | p->c = s.r; | ||
1576 | } | ||
1577 | |||
1555 | if (!ret) | 1578 | if (!ret) |
1556 | dbgrect(vfd, "", &p->c); | 1579 | dbgrect(vfd, "", &p->c); |
1557 | break; | 1580 | break; |
@@ -1560,15 +1583,65 @@ static long __video_do_ioctl(struct file *file, | |||
1560 | { | 1583 | { |
1561 | struct v4l2_crop *p = arg; | 1584 | struct v4l2_crop *p = arg; |
1562 | 1585 | ||
1563 | if (!ops->vidioc_s_crop) | 1586 | if (!ops->vidioc_s_crop && !ops->vidioc_s_selection) |
1564 | break; | 1587 | break; |
1588 | |||
1565 | if (ret_prio) { | 1589 | if (ret_prio) { |
1566 | ret = ret_prio; | 1590 | ret = ret_prio; |
1567 | break; | 1591 | break; |
1568 | } | 1592 | } |
1569 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | 1593 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
1570 | dbgrect(vfd, "", &p->c); | 1594 | dbgrect(vfd, "", &p->c); |
1571 | ret = ops->vidioc_s_crop(file, fh, p); | 1595 | |
1596 | if (ops->vidioc_s_crop) { | ||
1597 | ret = ops->vidioc_s_crop(file, fh, p); | ||
1598 | } else { | ||
1599 | /* simulate capture crop using selection api */ | ||
1600 | struct v4l2_selection s = { | ||
1601 | .type = p->type, | ||
1602 | .r = p->c, | ||
1603 | }; | ||
1604 | |||
1605 | /* crop means compose for output devices */ | ||
1606 | if (V4L2_TYPE_IS_OUTPUT(p->type)) | ||
1607 | s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; | ||
1608 | else | ||
1609 | s.target = V4L2_SEL_TGT_CROP_ACTIVE; | ||
1610 | |||
1611 | ret = ops->vidioc_s_selection(file, fh, &s); | ||
1612 | } | ||
1613 | break; | ||
1614 | } | ||
1615 | case VIDIOC_G_SELECTION: | ||
1616 | { | ||
1617 | struct v4l2_selection *p = arg; | ||
1618 | |||
1619 | if (!ops->vidioc_g_selection) | ||
1620 | break; | ||
1621 | |||
1622 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | ||
1623 | |||
1624 | ret = ops->vidioc_g_selection(file, fh, p); | ||
1625 | if (!ret) | ||
1626 | dbgrect(vfd, "", &p->r); | ||
1627 | break; | ||
1628 | } | ||
1629 | case VIDIOC_S_SELECTION: | ||
1630 | { | ||
1631 | struct v4l2_selection *p = arg; | ||
1632 | |||
1633 | if (!ops->vidioc_s_selection) | ||
1634 | break; | ||
1635 | |||
1636 | if (ret_prio) { | ||
1637 | ret = ret_prio; | ||
1638 | break; | ||
1639 | } | ||
1640 | |||
1641 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | ||
1642 | dbgrect(vfd, "", &p->r); | ||
1643 | |||
1644 | ret = ops->vidioc_s_selection(file, fh, p); | ||
1572 | break; | 1645 | break; |
1573 | } | 1646 | } |
1574 | case VIDIOC_CROPCAP: | 1647 | case VIDIOC_CROPCAP: |
@@ -1576,11 +1649,42 @@ static long __video_do_ioctl(struct file *file, | |||
1576 | struct v4l2_cropcap *p = arg; | 1649 | struct v4l2_cropcap *p = arg; |
1577 | 1650 | ||
1578 | /*FIXME: Should also show v4l2_fract pixelaspect */ | 1651 | /*FIXME: Should also show v4l2_fract pixelaspect */ |
1579 | if (!ops->vidioc_cropcap) | 1652 | if (!ops->vidioc_cropcap && !ops->vidioc_g_selection) |
1580 | break; | 1653 | break; |
1581 | 1654 | ||
1582 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | 1655 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
1583 | ret = ops->vidioc_cropcap(file, fh, p); | 1656 | if (ops->vidioc_cropcap) { |
1657 | ret = ops->vidioc_cropcap(file, fh, p); | ||
1658 | } else { | ||
1659 | struct v4l2_selection s = { .type = p->type }; | ||
1660 | |||
1661 | /* obtaining bounds */ | ||
1662 | if (V4L2_TYPE_IS_OUTPUT(p->type)) | ||
1663 | s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; | ||
1664 | else | ||
1665 | s.target = V4L2_SEL_TGT_CROP_BOUNDS; | ||
1666 | |||
1667 | ret = ops->vidioc_g_selection(file, fh, &s); | ||
1668 | if (ret) | ||
1669 | break; | ||
1670 | p->bounds = s.r; | ||
1671 | |||
1672 | /* obtaining defrect */ | ||
1673 | if (V4L2_TYPE_IS_OUTPUT(p->type)) | ||
1674 | s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; | ||
1675 | else | ||
1676 | s.target = V4L2_SEL_TGT_CROP_DEFAULT; | ||
1677 | |||
1678 | ret = ops->vidioc_g_selection(file, fh, &s); | ||
1679 | if (ret) | ||
1680 | break; | ||
1681 | p->defrect = s.r; | ||
1682 | |||
1683 | /* setting trivial pixelaspect */ | ||
1684 | p->pixelaspect.numerator = 1; | ||
1685 | p->pixelaspect.denominator = 1; | ||
1686 | } | ||
1687 | |||
1584 | if (!ret) { | 1688 | if (!ret) { |
1585 | dbgrect(vfd, "bounds ", &p->bounds); | 1689 | dbgrect(vfd, "bounds ", &p->bounds); |
1586 | dbgrect(vfd, "defrect ", &p->defrect); | 1690 | dbgrect(vfd, "defrect ", &p->defrect); |
@@ -2226,6 +2330,10 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size, | |||
2226 | struct v4l2_ext_controls *ctrls = parg; | 2330 | struct v4l2_ext_controls *ctrls = parg; |
2227 | 2331 | ||
2228 | if (ctrls->count != 0) { | 2332 | if (ctrls->count != 0) { |
2333 | if (ctrls->count > V4L2_CID_MAX_CTRLS) { | ||
2334 | ret = -EINVAL; | ||
2335 | break; | ||
2336 | } | ||
2229 | *user_ptr = (void __user *)ctrls->controls; | 2337 | *user_ptr = (void __user *)ctrls->controls; |
2230 | *kernel_ptr = (void *)&ctrls->controls; | 2338 | *kernel_ptr = (void *)&ctrls->controls; |
2231 | *array_size = sizeof(struct v4l2_ext_control) | 2339 | *array_size = sizeof(struct v4l2_ext_control) |