diff options
author | Frederic CAND <frederic.cand@anevia.com> | 2005-05-05 19:15:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-05 19:36:42 -0400 |
commit | 0a4c9c93c2fb5d09259136531d3e8e70fdcd6027 (patch) | |
tree | 07f8f2723b9339a2246d32c1bcff4a96df5eec00 /drivers/media/video/saa7134/saa6752hs.c | |
parent | ac5f34c028a043405de087e43699195ab3974dbf (diff) |
[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>
Diffstat (limited to 'drivers/media/video/saa7134/saa6752hs.c')
-rw-r--r-- | drivers/media/video/saa7134/saa6752hs.c | 89 |
1 files changed, 88 insertions, 1 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"); | |||
32 | static struct i2c_driver driver; | 32 | static struct i2c_driver driver; |
33 | static struct i2c_client client_template; | 33 | static struct i2c_client client_template; |
34 | 34 | ||
35 | enum saa6752hs_videoformat { | ||
36 | SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */ | ||
37 | SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */ | ||
38 | SAA6752HS_VF_1_2_D1 = 2,/* 1/2D1 video format: 352x576 */ | ||
39 | SAA6752HS_VF_SIF = 3, /* SIF video format: 352x288 */ | ||
40 | SAA6752HS_VF_UNKNOWN, | ||
41 | }; | ||
42 | |||
43 | static const struct v4l2_format v4l2_format_table[] = | ||
44 | { | ||
45 | [SAA6752HS_VF_D1] = { | ||
46 | .fmt.pix.width = 720, .fmt.pix.height = 576 }, | ||
47 | [SAA6752HS_VF_2_3_D1] = { | ||
48 | .fmt.pix.width = 480, .fmt.pix.height = 576 }, | ||
49 | [SAA6752HS_VF_1_2_D1] = { | ||
50 | .fmt.pix.width = 352, .fmt.pix.height = 576 }, | ||
51 | [SAA6752HS_VF_SIF] = { | ||
52 | .fmt.pix.width = 352, .fmt.pix.height = 288 }, | ||
53 | [SAA6752HS_VF_UNKNOWN] = { | ||
54 | .fmt.pix.width = 0, .fmt.pix.height = 0}, | ||
55 | }; | ||
56 | |||
35 | struct saa6752hs_state { | 57 | struct saa6752hs_state { |
36 | struct i2c_client client; | 58 | struct i2c_client client; |
37 | struct v4l2_mpeg_compression params; | 59 | struct v4l2_mpeg_compression params; |
60 | enum saa6752hs_videoformat video_format; | ||
38 | }; | 61 | }; |
39 | 62 | ||
40 | enum saa6752hs_command { | 63 | enum saa6752hs_command { |
@@ -256,6 +279,51 @@ static int saa6752hs_set_bitrate(struct i2c_client* client, | |||
256 | return 0; | 279 | return 0; |
257 | } | 280 | } |
258 | 281 | ||
282 | static void saa6752hs_set_subsampling(struct i2c_client* client, | ||
283 | struct v4l2_format* f) | ||
284 | { | ||
285 | struct saa6752hs_state *h = i2c_get_clientdata(client); | ||
286 | int dist_352, dist_480, dist_720; | ||
287 | |||
288 | /* | ||
289 | FIXME: translate and round width/height into EMPRESS | ||
290 | subsample type: | ||
291 | |||
292 | type | PAL | NTSC | ||
293 | --------------------------- | ||
294 | SIF | 352x288 | 352x240 | ||
295 | 1/2 D1 | 352x576 | 352x480 | ||
296 | 2/3 D1 | 480x576 | 480x480 | ||
297 | D1 | 720x576 | 720x480 | ||
298 | */ | ||
299 | |||
300 | dist_352 = abs(f->fmt.pix.width - 352); | ||
301 | dist_480 = abs(f->fmt.pix.width - 480); | ||
302 | dist_720 = abs(f->fmt.pix.width - 720); | ||
303 | if (dist_720 < dist_480) { | ||
304 | f->fmt.pix.width = 720; | ||
305 | f->fmt.pix.height = 576; | ||
306 | h->video_format = SAA6752HS_VF_D1; | ||
307 | } | ||
308 | else if (dist_480 < dist_352) { | ||
309 | f->fmt.pix.width = 480; | ||
310 | f->fmt.pix.height = 576; | ||
311 | h->video_format = SAA6752HS_VF_2_3_D1; | ||
312 | } | ||
313 | else { | ||
314 | f->fmt.pix.width = 352; | ||
315 | if (abs(f->fmt.pix.height - 576) < | ||
316 | abs(f->fmt.pix.height - 288)) { | ||
317 | f->fmt.pix.height = 576; | ||
318 | h->video_format = SAA6752HS_VF_1_2_D1; | ||
319 | } | ||
320 | else { | ||
321 | f->fmt.pix.height = 288; | ||
322 | h->video_format = SAA6752HS_VF_SIF; | ||
323 | } | ||
324 | } | ||
325 | } | ||
326 | |||
259 | 327 | ||
260 | static void saa6752hs_set_params(struct i2c_client* client, | 328 | static void saa6752hs_set_params(struct i2c_client* client, |
261 | struct v4l2_mpeg_compression* params) | 329 | struct v4l2_mpeg_compression* params) |
@@ -315,7 +383,7 @@ static int saa6752hs_init(struct i2c_client* client) | |||
315 | 383 | ||
316 | // Set video format - must be done first as it resets other settings | 384 | // Set video format - must be done first as it resets other settings |
317 | buf[0] = 0x41; | 385 | buf[0] = 0x41; |
318 | buf[1] = 0 /* MPEG_VIDEO_FORMAT_D1 */; | 386 | buf[1] = h->video_format; |
319 | i2c_master_send(client, buf, 2); | 387 | i2c_master_send(client, buf, 2); |
320 | 388 | ||
321 | // set bitrate | 389 | // set bitrate |
@@ -494,6 +562,25 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
494 | case VIDIOC_G_MPEGCOMP: | 562 | case VIDIOC_G_MPEGCOMP: |
495 | *params = h->params; | 563 | *params = h->params; |
496 | break; | 564 | break; |
565 | case VIDIOC_G_FMT: | ||
566 | { | ||
567 | struct v4l2_format *f = arg; | ||
568 | |||
569 | if (h->video_format == SAA6752HS_VF_UNKNOWN) | ||
570 | h->video_format = SAA6752HS_VF_D1; | ||
571 | f->fmt.pix.width = | ||
572 | v4l2_format_table[h->video_format].fmt.pix.width; | ||
573 | f->fmt.pix.height = | ||
574 | v4l2_format_table[h->video_format].fmt.pix.height; | ||
575 | break ; | ||
576 | } | ||
577 | case VIDIOC_S_FMT: | ||
578 | { | ||
579 | struct v4l2_format *f = arg; | ||
580 | |||
581 | saa6752hs_set_subsampling(client, f); | ||
582 | break; | ||
583 | } | ||
497 | default: | 584 | default: |
498 | /* nothing */ | 585 | /* nothing */ |
499 | break; | 586 | break; |