[PATCH] saa6752hs: resolutions handling
authorFrederic CAND <frederic.cand@anevia.com>
Thu, 5 May 2005 23:15:52 +0000 (16:15 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 5 May 2005 23:36:42 +0000 (16:36 -0700)
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>
drivers/media/video/saa7134/saa6752hs.c
drivers/media/video/saa7134/saa7134-empress.c

index cee13584c9cfa123612e3dfa6ade71a8fa3d09b3..fe6abe34168c01539160ecae23a1f48d07a77f1a 100644 (file)
@@ -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;
index 2021e099e35ace85f2cda86c97ab02bbb3642271..fa1357336907cd6df71614e39f61d133b8428607 100644 (file)
@@ -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;