summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
authorGerd Knorr <devnull@localhost>2004-03-10 11:18:28 +0000
committerGerd Knorr <devnull@localhost>2004-03-10 11:18:28 +0000
commit95ad49d0c99df0841db058fc31fa68a77ff16a51 (patch)
tree12ded39d6b579b90480c8b539cd58b23b79183cb /linux
parent5e75451a9c1886889354226799b25639a19b29ec (diff)
downloadmediapointer-dvb-s2-95ad49d0c99df0841db058fc31fa68a77ff16a51.tar.gz
mediapointer-dvb-s2-95ad49d0c99df0841db058fc31fa68a77ff16a51.tar.bz2
- crop support for saa7134.
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/video/cx88/cx88-cards.c4
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-video.c135
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h9
3 files changed, 116 insertions, 32 deletions
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c
index 9fd1e5b58..1c1b18a6f 100644
--- a/linux/drivers/media/video/cx88/cx88-cards.c
+++ b/linux/drivers/media/video/cx88/cx88-cards.c
@@ -62,6 +62,10 @@ struct cx88_board cx88_boards[] = {
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0xff02,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0xff02,
}},
.radio = {
.type = CX88_RADIO,
diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c
index 170956f92..e281def4f 100644
--- a/linux/drivers/media/video/saa7134/saa7134-video.c
+++ b/linux/drivers/media/video/saa7134/saa7134-video.c
@@ -152,8 +152,6 @@ static struct saa7134_tvnorm tvnorms[] = {
{
.name = "PAL",
.id = V4L2_STD_PAL,
- .width = 720,
- .height = 576,
.sync_control = 0x18,
.luma_control = 0x40,
@@ -172,8 +170,6 @@ static struct saa7134_tvnorm tvnorms[] = {
},{
.name = "NTSC",
.id = V4L2_STD_NTSC,
- .width = 720,
- .height = 480,
.sync_control = 0x59,
.luma_control = 0x40,
@@ -192,8 +188,6 @@ static struct saa7134_tvnorm tvnorms[] = {
},{
.name = "SECAM",
.id = V4L2_STD_SECAM,
- .width = 720,
- .height = 576,
.sync_control = 0x18, /* old: 0x58, */
.luma_control = 0x1b,
@@ -212,8 +206,6 @@ static struct saa7134_tvnorm tvnorms[] = {
},{
.name = "PAL-M",
.id = V4L2_STD_PAL_M,
- .width = 720,
- .height = 480,
.sync_control = 0x59,
.luma_control = 0x40,
@@ -232,8 +224,6 @@ static struct saa7134_tvnorm tvnorms[] = {
},{
.name = "PAL-Nc",
.id = V4L2_STD_PAL_Nc,
- .width = 720,
- .height = 576,
.sync_control = 0x18,
.luma_control = 0x40,
@@ -454,6 +444,20 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
if (noninterlaced)
sync_control |= 0x20;
+ /* setup cropping */
+ dev->crop_bounds.left = norm->h_start;
+ dev->crop_defrect.left = norm->h_start;
+ dev->crop_bounds.width = norm->h_stop - norm->h_start +1;
+ dev->crop_defrect.width = norm->h_stop - norm->h_start +1;
+
+ dev->crop_bounds.top = (norm->vbi_v_stop+1)*2;
+ dev->crop_defrect.top = norm->video_v_start*2;
+ dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
+ - dev->crop_bounds.top;
+ dev->crop_defrect.height = (norm->video_v_stop - norm->video_v_start +1)*2;
+
+ dev->crop_current = dev->crop_defrect;
+
/* setup video decoder */
saa_writeb(SAA7134_INCR_DELAY, 0x08);
saa_writeb(SAA7134_ANALOG_IN_CTRL1, 0xc0 | mux);
@@ -570,25 +574,30 @@ static void set_v_scale(struct saa7134_dev *dev, int task, int yscale)
static void set_size(struct saa7134_dev *dev, int task,
int width, int height, int interlace)
{
- struct saa7134_tvnorm *norm = dev->tvnorm;
int prescale,xscale,yscale,y_even,y_odd;
+ int h_start, h_stop, v_start, v_stop;
int div = interlace ? 2 : 1;
/* setup video scaler */
- saa_writeb(SAA7134_VIDEO_H_START1(task), norm->h_start & 0xff);
- saa_writeb(SAA7134_VIDEO_H_START2(task), norm->h_start >> 8);
- saa_writeb(SAA7134_VIDEO_H_STOP1(task), norm->h_stop & 0xff);
- saa_writeb(SAA7134_VIDEO_H_STOP2(task), norm->h_stop >> 8);
- saa_writeb(SAA7134_VIDEO_V_START1(task), norm->video_v_start & 0xff);
- saa_writeb(SAA7134_VIDEO_V_START2(task), norm->video_v_start >> 8);
- saa_writeb(SAA7134_VIDEO_V_STOP1(task), norm->video_v_stop & 0xff);
- saa_writeb(SAA7134_VIDEO_V_STOP2(task), norm->video_v_stop >> 8);
-
- prescale = norm->width / width;
+ h_start = dev->crop_current.left/2;
+ v_start = dev->crop_current.top/2;
+ h_stop = (dev->crop_current.left + dev->crop_current.width -1)/2;
+ v_stop = (dev->crop_current.top + dev->crop_current.height -1)/2;
+
+ saa_writeb(SAA7134_VIDEO_H_START1(task), h_start & 0xff);
+ saa_writeb(SAA7134_VIDEO_H_START2(task), h_start >> 8);
+ saa_writeb(SAA7134_VIDEO_H_STOP1(task), h_stop & 0xff);
+ saa_writeb(SAA7134_VIDEO_H_STOP2(task), h_stop >> 8);
+ saa_writeb(SAA7134_VIDEO_V_START1(task), v_start & 0xff);
+ saa_writeb(SAA7134_VIDEO_V_START2(task), v_start >> 8);
+ saa_writeb(SAA7134_VIDEO_V_STOP1(task), v_stop & 0xff);
+ saa_writeb(SAA7134_VIDEO_V_STOP2(task), v_stop >> 8);
+
+ prescale = dev->crop_defrect.width / width;
if (0 == prescale)
prescale = 1;
- xscale = 1024 * norm->width / prescale / width;
- yscale = 512 * div * norm->height / height;
+ xscale = 1024 * dev->crop_defrect.width / prescale / width;
+ yscale = 512 * div * dev->crop_defrect.height / height;
dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
set_h_prescale(dev,task,prescale);
saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
@@ -715,8 +724,8 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
return -EINVAL;
field = win->field;
- maxw = dev->tvnorm->width;
- maxh = dev->tvnorm->height;
+ maxw = dev->crop_current.width;
+ maxh = dev->crop_current.height;
if (V4L2_FIELD_ANY == field) {
field = (win->w.height > maxh/2)
@@ -902,8 +911,8 @@ static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,
return -EINVAL;
if (fh->width < 48 ||
fh->height < 32 ||
- fh->width > dev->tvnorm->width ||
- fh->height > dev->tvnorm->height)
+ fh->width > dev->crop_current.width ||
+ fh->height > dev->crop_current.height)
return -EINVAL;
size = (fh->width * fh->height * fh->fmt->depth) >> 3;
if (0 != buf->vb.baddr && buf->vb.bsize < size)
@@ -1400,8 +1409,8 @@ int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
return -EINVAL;
field = f->fmt.pix.field;
- maxw = dev->tvnorm->width;
- maxh = dev->tvnorm->height;
+ maxw = dev->crop_current.width;
+ maxh = dev->crop_current.height;
if (V4L2_FIELD_ANY == field) {
field = (f->fmt.pix.height > maxh/2)
@@ -1680,6 +1689,74 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
return 0;
}
+ case VIDIOC_CROPCAP:
+ {
+ struct v4l2_cropcap *cap = arg;
+
+ if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
+ return -EINVAL;
+ cap->bounds = dev->crop_bounds;
+ cap->defrect = dev->crop_defrect;
+ cap->pixelaspect.numerator = 1;
+ cap->pixelaspect.denominator = 1;
+ if (dev->tvnorm->id & V4L2_STD_525_60) {
+ cap->pixelaspect.numerator = 11;
+ cap->pixelaspect.denominator = 10;
+ }
+ if (dev->tvnorm->id & V4L2_STD_625_50) {
+ cap->pixelaspect.numerator = 54;
+ cap->pixelaspect.denominator = 59;
+ }
+ return 0;
+ }
+
+ case VIDIOC_G_CROP:
+ {
+ struct v4l2_crop * crop = arg;
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
+ return -EINVAL;
+ crop->c = dev->crop_current;
+ return 0;
+ }
+ case VIDIOC_S_CROP:
+ {
+ struct v4l2_crop *crop = arg;
+ struct v4l2_rect *b = &dev->crop_bounds;
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
+ return -EINVAL;
+ if (crop->c.height < 0)
+ return -EINVAL;
+ if (crop->c.width < 0)
+ return -EINVAL;
+
+ if (res_locked(fh->dev,RESOURCE_OVERLAY))
+ return -EBUSY;
+ if (res_locked(fh->dev,RESOURCE_VIDEO))
+ return -EBUSY;
+
+ if (crop->c.top < b->top)
+ crop->c.top = b->top;
+ if (crop->c.top > b->top + b->height)
+ crop->c.top = b->top + b->height;
+ if (crop->c.height > b->top - crop->c.top + b->height)
+ crop->c.height = b->top - crop->c.top + b->height;
+
+ if (crop->c.left < b->left)
+ crop->c.top = b->left;
+ if (crop->c.left > b->left + b->width)
+ crop->c.top = b->left + b->width;
+ if (crop->c.width > b->left - crop->c.left + b->width)
+ crop->c.width = b->left - crop->c.left + b->width;
+
+ dev->crop_current = crop->c;
+ return 0;
+ }
+
/* --- tuner ioctls ------------------------------------------ */
case VIDIOC_G_TUNER:
{
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index a0da01a82..86e69bfec 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -101,8 +101,6 @@ enum saa7134_video_out {
struct saa7134_tvnorm {
char *name;
v4l2_std_id id;
- unsigned int width;
- unsigned int height;
/* video decoder */
unsigned int sync_control;
@@ -423,7 +421,12 @@ struct saa7134_dev {
int ctl_mirror;
int ctl_y_odd;
int ctl_y_even;
-
+
+ /* crop */
+ struct v4l2_rect crop_bounds;
+ struct v4l2_rect crop_defrect;
+ struct v4l2_rect crop_current;
+
/* other global state info */
unsigned int automute;
struct saa7134_thread thread;