summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic CAND <frederic.cand@anevia.com>2005-05-06 03:15:52 +0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-06 03:36:42 +0400
commit0a4c9c93c2fb5d09259136531d3e8e70fdcd6027 (patch)
tree07f8f2723b9339a2246d32c1bcff4a96df5eec00
parentac5f34c028a043405de087e43699195ab3974dbf (diff)
downloadlinux-0a4c9c93c2fb5d09259136531d3e8e70fdcd6027.tar.xz
[PATCH] saa6752hs: resolutions handling
This patch handles the VIDIOC_S_FMT and VIDIOC_G_FMT ioctls for the saa6752hs. As only 4 preset video formats are supported (SIF, 1/2D1, 2/3D1, D1), we compute to which the asked resolution is the nearest and apply it. Signed-off-by: Frederic Cand <frederic.cand@anevia.com> Acked-by: Gerd Knorr <kraxel@bytesex.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c89
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c20
2 files changed, 90 insertions, 19 deletions
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index cee13584c9cf..fe6abe34168c 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -32,9 +32,32 @@ MODULE_LICENSE("GPL");
static struct i2c_driver driver;
static struct i2c_client client_template;
+enum saa6752hs_videoformat {
+ SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */
+ SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */
+ SAA6752HS_VF_1_2_D1 = 2,/* 1/2D1 video format: 352x576 */
+ SAA6752HS_VF_SIF = 3, /* SIF video format: 352x288 */
+ SAA6752HS_VF_UNKNOWN,
+};
+
+static const struct v4l2_format v4l2_format_table[] =
+{
+ [SAA6752HS_VF_D1] = {
+ .fmt.pix.width = 720, .fmt.pix.height = 576 },
+ [SAA6752HS_VF_2_3_D1] = {
+ .fmt.pix.width = 480, .fmt.pix.height = 576 },
+ [SAA6752HS_VF_1_2_D1] = {
+ .fmt.pix.width = 352, .fmt.pix.height = 576 },
+ [SAA6752HS_VF_SIF] = {
+ .fmt.pix.width = 352, .fmt.pix.height = 288 },
+ [SAA6752HS_VF_UNKNOWN] = {
+ .fmt.pix.width = 0, .fmt.pix.height = 0},
+};
+
struct saa6752hs_state {
struct i2c_client client;
struct v4l2_mpeg_compression params;
+ enum saa6752hs_videoformat video_format;
};
enum saa6752hs_command {
@@ -256,6 +279,51 @@ static int saa6752hs_set_bitrate(struct i2c_client* client,
return 0;
}
+static void saa6752hs_set_subsampling(struct i2c_client* client,
+ struct v4l2_format* f)
+{
+ struct saa6752hs_state *h = i2c_get_clientdata(client);
+ int dist_352, dist_480, dist_720;
+
+ /*
+ FIXME: translate and round width/height into EMPRESS
+ subsample type:
+
+ type | PAL | NTSC
+ ---------------------------
+ SIF | 352x288 | 352x240
+ 1/2 D1 | 352x576 | 352x480
+ 2/3 D1 | 480x576 | 480x480
+ D1 | 720x576 | 720x480
+ */
+
+ dist_352 = abs(f->fmt.pix.width - 352);
+ dist_480 = abs(f->fmt.pix.width - 480);
+ dist_720 = abs(f->fmt.pix.width - 720);
+ if (dist_720 < dist_480) {
+ f->fmt.pix.width = 720;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_D1;
+ }
+ else if (dist_480 < dist_352) {
+ f->fmt.pix.width = 480;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_2_3_D1;
+ }
+ else {
+ f->fmt.pix.width = 352;
+ if (abs(f->fmt.pix.height - 576) <
+ abs(f->fmt.pix.height - 288)) {
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_1_2_D1;
+ }
+ else {
+ f->fmt.pix.height = 288;
+ h->video_format = SAA6752HS_VF_SIF;
+ }
+ }
+}
+
static void saa6752hs_set_params(struct i2c_client* client,
struct v4l2_mpeg_compression* params)
@@ -315,7 +383,7 @@ static int saa6752hs_init(struct i2c_client* client)
// Set video format - must be done first as it resets other settings
buf[0] = 0x41;
- buf[1] = 0 /* MPEG_VIDEO_FORMAT_D1 */;
+ buf[1] = h->video_format;
i2c_master_send(client, buf, 2);
// set bitrate
@@ -494,6 +562,25 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
case VIDIOC_G_MPEGCOMP:
*params = h->params;
break;
+ case VIDIOC_G_FMT:
+ {
+ struct v4l2_format *f = arg;
+
+ if (h->video_format == SAA6752HS_VF_UNKNOWN)
+ h->video_format = SAA6752HS_VF_D1;
+ f->fmt.pix.width =
+ v4l2_format_table[h->video_format].fmt.pix.width;
+ f->fmt.pix.height =
+ v4l2_format_table[h->video_format].fmt.pix.height;
+ break ;
+ }
+ case VIDIOC_S_FMT:
+ {
+ struct v4l2_format *f = arg;
+
+ saa6752hs_set_subsampling(client, f);
+ break;
+ }
default:
/* nothing */
break;
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 2021e099e35a..fa1357336907 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -233,10 +233,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
memset(f,0,sizeof(*f));
f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- /* FIXME: translate subsampling type EMPRESS into
- * width/height: */
- f->fmt.pix.width = 720; /* D1 */
- f->fmt.pix.height = 576;
+ saa7134_i2c_call_clients(dev, cmd, arg);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
return 0;
@@ -249,20 +246,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- /*
- FIXME: translate and round width/height into EMPRESS
- subsample type:
-
- type | PAL | NTSC
- ---------------------------
- SIF | 352x288 | 352x240
- 1/2 D1 | 352x576 | 352x480
- 2/3 D1 | 480x576 | 480x480
- D1 | 720x576 | 720x480
- */
-
- f->fmt.pix.width = 720; /* D1 */
- f->fmt.pix.height = 576;
+ saa7134_i2c_call_clients(dev, cmd, arg);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE* dev->ts.nr_packets;
return 0;