aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s2255drv.c
diff options
context:
space:
mode:
authorDean Anderson <dean@sensoray.com>2010-03-08 18:04:48 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:46:39 -0400
commite6b44bc521b48048e3089ed773950867e409f886 (patch)
tree9e2067871e6dd7129cc0a3d196cefbe1c8851bb0 /drivers/media/video/s2255drv.c
parente7c3ee6302ef0dde86c1918bae3b0783839e6a39 (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.c113
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; 1715static 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
1657static int s2255_open(struct file *file) 1753static 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
1937static struct video_device template = { 2034static struct video_device template = {