mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
[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>
This commit is contained in:
parent
ac5f34c028
commit
0a4c9c93c2
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user