diff options
author | Dean Anderson <dean@sensoray.com> | 2010-03-08 18:04:48 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-17 23:46:39 -0400 |
commit | e6b44bc521b48048e3089ed773950867e409f886 (patch) | |
tree | 9e2067871e6dd7129cc0a3d196cefbe1c8851bb0 /drivers/media/video/s2255drv.c | |
parent | e7c3ee6302ef0dde86c1918bae3b0783839e6a39 (diff) |
V4L/DVB: s2255drv: support for frame skipping
adds hardware frame skipping using VIDIOC_S_PARM ioctl.
adds support for VIDIOC_ENUM_FRAMEINTERVALS.
Signed-off-by: Dean Anderson <dean@sensoray.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s2255drv.c')
-rw-r--r-- | drivers/media/video/s2255drv.c | 113 |
1 files changed, 105 insertions, 8 deletions
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 745f557200aa..0092ff52bb27 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -1427,11 +1427,19 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) | |||
1427 | } | 1427 | } |
1428 | mode = &fh->mode; | 1428 | mode = &fh->mode; |
1429 | if (*i & V4L2_STD_NTSC) { | 1429 | if (*i & V4L2_STD_NTSC) { |
1430 | dprintk(4, "vidioc_s_std NTSC\n"); | 1430 | dprintk(4, "%s NTSC\n", __func__); |
1431 | mode->format = FORMAT_NTSC; | 1431 | /* if changing format, reset frame decimation/intervals */ |
1432 | if (mode->format != FORMAT_NTSC) { | ||
1433 | mode->format = FORMAT_NTSC; | ||
1434 | mode->fdec = FDEC_1; | ||
1435 | } | ||
1432 | } else if (*i & V4L2_STD_PAL) { | 1436 | } else if (*i & V4L2_STD_PAL) { |
1433 | dprintk(4, "vidioc_s_std PAL\n"); | 1437 | dprintk(4, "%s PAL\n", __func__); |
1434 | mode->format = FORMAT_PAL; | 1438 | mode->format = FORMAT_PAL; |
1439 | if (mode->format != FORMAT_PAL) { | ||
1440 | mode->format = FORMAT_PAL; | ||
1441 | mode->fdec = FDEC_1; | ||
1442 | } | ||
1435 | } else { | 1443 | } else { |
1436 | ret = -EINVAL; | 1444 | ret = -EINVAL; |
1437 | } | 1445 | } |
@@ -1633,10 +1641,34 @@ static int vidioc_g_parm(struct file *file, void *priv, | |||
1633 | { | 1641 | { |
1634 | struct s2255_fh *fh = priv; | 1642 | struct s2255_fh *fh = priv; |
1635 | struct s2255_dev *dev = fh->dev; | 1643 | struct s2255_dev *dev = fh->dev; |
1644 | __u32 def_num, def_dem; | ||
1636 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1645 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1637 | return -EINVAL; | 1646 | return -EINVAL; |
1647 | memset(sp, 0, sizeof(struct v4l2_streamparm)); | ||
1648 | sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; | ||
1638 | sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode; | 1649 | sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode; |
1639 | dprintk(2, "getting parm %d\n", sp->parm.capture.capturemode); | 1650 | def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000; |
1651 | def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000; | ||
1652 | sp->parm.capture.timeperframe.denominator = def_dem; | ||
1653 | switch (fh->mode.fdec) { | ||
1654 | default: | ||
1655 | case FDEC_1: | ||
1656 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1657 | break; | ||
1658 | case FDEC_2: | ||
1659 | sp->parm.capture.timeperframe.numerator = def_num * 2; | ||
1660 | break; | ||
1661 | case FDEC_3: | ||
1662 | sp->parm.capture.timeperframe.numerator = def_num * 3; | ||
1663 | break; | ||
1664 | case FDEC_5: | ||
1665 | sp->parm.capture.timeperframe.numerator = def_num * 5; | ||
1666 | break; | ||
1667 | } | ||
1668 | dprintk(4, "%s capture mode, %d timeperframe %d/%d\n", __func__, | ||
1669 | sp->parm.capture.capturemode, | ||
1670 | sp->parm.capture.timeperframe.numerator, | ||
1671 | sp->parm.capture.timeperframe.denominator); | ||
1640 | return 0; | 1672 | return 0; |
1641 | } | 1673 | } |
1642 | 1674 | ||
@@ -1645,15 +1677,79 @@ static int vidioc_s_parm(struct file *file, void *priv, | |||
1645 | { | 1677 | { |
1646 | struct s2255_fh *fh = priv; | 1678 | struct s2255_fh *fh = priv; |
1647 | struct s2255_dev *dev = fh->dev; | 1679 | struct s2255_dev *dev = fh->dev; |
1648 | 1680 | int fdec = FDEC_1; | |
1681 | __u32 def_num, def_dem; | ||
1649 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1682 | if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1650 | return -EINVAL; | 1683 | return -EINVAL; |
1684 | /* high quality capture mode requires a stream restart */ | ||
1685 | if (dev->cap_parm[fh->channel].capturemode | ||
1686 | != sp->parm.capture.capturemode && res_locked(fh->dev, fh)) | ||
1687 | return -EBUSY; | ||
1688 | def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000; | ||
1689 | def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000; | ||
1690 | if (def_dem != sp->parm.capture.timeperframe.denominator) | ||
1691 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1692 | else if (sp->parm.capture.timeperframe.numerator <= def_num) | ||
1693 | sp->parm.capture.timeperframe.numerator = def_num; | ||
1694 | else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) { | ||
1695 | sp->parm.capture.timeperframe.numerator = def_num * 2; | ||
1696 | fdec = FDEC_2; | ||
1697 | } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) { | ||
1698 | sp->parm.capture.timeperframe.numerator = def_num * 3; | ||
1699 | fdec = FDEC_3; | ||
1700 | } else { | ||
1701 | sp->parm.capture.timeperframe.numerator = def_num * 5; | ||
1702 | fdec = FDEC_5; | ||
1703 | } | ||
1704 | fh->mode.fdec = fdec; | ||
1705 | sp->parm.capture.timeperframe.denominator = def_dem; | ||
1706 | s2255_set_mode(dev, fh->channel, &fh->mode); | ||
1707 | dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n", | ||
1708 | __func__, | ||
1709 | sp->parm.capture.capturemode, | ||
1710 | sp->parm.capture.timeperframe.numerator, | ||
1711 | sp->parm.capture.timeperframe.denominator, fdec); | ||
1712 | return 0; | ||
1713 | } | ||
1651 | 1714 | ||
1652 | dev->cap_parm[fh->channel].capturemode = sp->parm.capture.capturemode; | 1715 | static int vidioc_enum_frameintervals(struct file *file, void *priv, |
1653 | dprintk(2, "setting param capture mode %d\n", | 1716 | struct v4l2_frmivalenum *fe) |
1654 | sp->parm.capture.capturemode); | 1717 | { |
1718 | int is_ntsc = 0; | ||
1719 | #define NUM_FRAME_ENUMS 4 | ||
1720 | int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5}; | ||
1721 | if (fe->index < 0 || fe->index >= NUM_FRAME_ENUMS) | ||
1722 | return -EINVAL; | ||
1723 | switch (fe->width) { | ||
1724 | case 640: | ||
1725 | if (fe->height != 240 && fe->height != 480) | ||
1726 | return -EINVAL; | ||
1727 | is_ntsc = 1; | ||
1728 | break; | ||
1729 | case 320: | ||
1730 | if (fe->height != 240) | ||
1731 | return -EINVAL; | ||
1732 | is_ntsc = 1; | ||
1733 | break; | ||
1734 | case 704: | ||
1735 | if (fe->height != 288 && fe->height != 576) | ||
1736 | return -EINVAL; | ||
1737 | break; | ||
1738 | case 352: | ||
1739 | if (fe->height != 288) | ||
1740 | return -EINVAL; | ||
1741 | break; | ||
1742 | default: | ||
1743 | return -EINVAL; | ||
1744 | } | ||
1745 | fe->type = V4L2_FRMIVAL_TYPE_DISCRETE; | ||
1746 | fe->discrete.denominator = is_ntsc ? 30000 : 25000; | ||
1747 | fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index]; | ||
1748 | dprintk(4, "%s discrete %d/%d\n", __func__, fe->discrete.numerator, | ||
1749 | fe->discrete.denominator); | ||
1655 | return 0; | 1750 | return 0; |
1656 | } | 1751 | } |
1752 | |||
1657 | static int s2255_open(struct file *file) | 1753 | static int s2255_open(struct file *file) |
1658 | { | 1754 | { |
1659 | struct video_device *vdev = video_devdata(file); | 1755 | struct video_device *vdev = video_devdata(file); |
@@ -1932,6 +2028,7 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { | |||
1932 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, | 2028 | .vidioc_g_jpegcomp = vidioc_g_jpegcomp, |
1933 | .vidioc_s_parm = vidioc_s_parm, | 2029 | .vidioc_s_parm = vidioc_s_parm, |
1934 | .vidioc_g_parm = vidioc_g_parm, | 2030 | .vidioc_g_parm = vidioc_g_parm, |
2031 | .vidioc_enum_frameintervals = vidioc_enum_frameintervals, | ||
1935 | }; | 2032 | }; |
1936 | 2033 | ||
1937 | static struct video_device template = { | 2034 | static struct video_device template = { |