mirror of
https://github.com/torvalds/linux.git
synced 2024-12-05 10:32:35 +00:00
V4L/DVB (9236): Teach vivi about multiple pixel formats
This patch contains the ground work to add support for multiple pixel formats to vivi.c Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
74d7c5af78
commit
d891f47581
@ -128,12 +128,31 @@ struct vivi_fmt {
|
||||
int depth;
|
||||
};
|
||||
|
||||
static struct vivi_fmt format = {
|
||||
.name = "4:2:2, packed, YUYV",
|
||||
.fourcc = V4L2_PIX_FMT_YUYV,
|
||||
.depth = 16,
|
||||
static struct vivi_fmt formats[] = {
|
||||
{
|
||||
.name = "4:2:2, packed, YUYV",
|
||||
.fourcc = V4L2_PIX_FMT_YUYV,
|
||||
.depth = 16,
|
||||
},
|
||||
};
|
||||
|
||||
static struct vivi_fmt *get_format(struct v4l2_format *f)
|
||||
{
|
||||
struct vivi_fmt *fmt;
|
||||
unsigned int k;
|
||||
|
||||
for (k = 0; k < ARRAY_SIZE(formats); k++) {
|
||||
fmt = &formats[k];
|
||||
if (fmt->fourcc == f->fmt.pix.pixelformat)
|
||||
break;
|
||||
}
|
||||
|
||||
if (k == ARRAY_SIZE(formats))
|
||||
return NULL;
|
||||
|
||||
return &formats[k];
|
||||
}
|
||||
|
||||
struct sg_to_addr {
|
||||
int pos;
|
||||
struct scatterlist *sg;
|
||||
@ -248,16 +267,20 @@ static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
|
||||
for (color = 0; color < 4; color++) {
|
||||
p = buf + color;
|
||||
|
||||
switch (color) {
|
||||
case 0:
|
||||
case 2:
|
||||
*p = r_y;
|
||||
break;
|
||||
case 1:
|
||||
*p = g_u;
|
||||
break;
|
||||
case 3:
|
||||
*p = b_v;
|
||||
switch (fh->fmt->fourcc) {
|
||||
case V4L2_PIX_FMT_YUYV:
|
||||
switch (color) {
|
||||
case 0:
|
||||
case 2:
|
||||
*p = r_y;
|
||||
break;
|
||||
case 1:
|
||||
*p = g_u;
|
||||
break;
|
||||
case 3:
|
||||
*p = b_v;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -622,11 +645,15 @@ static int vidioc_querycap(struct file *file, void *priv,
|
||||
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct v4l2_fmtdesc *f)
|
||||
{
|
||||
if (f->index > 0)
|
||||
struct vivi_fmt *fmt;
|
||||
|
||||
if (f->index >= ARRAY_SIZE(formats))
|
||||
return -EINVAL;
|
||||
|
||||
strlcpy(f->description, format.name, sizeof(f->description));
|
||||
f->pixelformat = format.fourcc;
|
||||
fmt = &formats[f->index];
|
||||
|
||||
strlcpy(f->description, fmt->name, sizeof(f->description));
|
||||
f->pixelformat = fmt->fourcc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -656,13 +683,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
enum v4l2_field field;
|
||||
unsigned int maxw, maxh;
|
||||
|
||||
if (format.fourcc != f->fmt.pix.pixelformat) {
|
||||
dprintk(dev, 1, "Fourcc format (0x%08x) invalid. "
|
||||
"Driver accepts only 0x%08x\n",
|
||||
f->fmt.pix.pixelformat, format.fourcc);
|
||||
fmt = get_format(f);
|
||||
if (!fmt) {
|
||||
dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n",
|
||||
f->fmt.pix.pixelformat);
|
||||
return -EINVAL;
|
||||
}
|
||||
fmt = &format;
|
||||
|
||||
field = f->fmt.pix.field;
|
||||
|
||||
@ -701,7 +727,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct vivi_fh *fh = priv;
|
||||
struct videobuf_queue *q = &fh->vb_vidq;
|
||||
unsigned char r, g, b;
|
||||
int k;
|
||||
int k, is_yuv;
|
||||
|
||||
int ret = vidioc_try_fmt_vid_cap(file, fh, f);
|
||||
if (ret < 0)
|
||||
@ -715,7 +741,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
||||
goto out;
|
||||
}
|
||||
|
||||
fh->fmt = &format;
|
||||
fh->fmt = get_format(f);
|
||||
fh->width = f->fmt.pix.width;
|
||||
fh->height = f->fmt.pix.height;
|
||||
fh->vb_vidq.field = f->fmt.pix.field;
|
||||
@ -726,10 +752,23 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
||||
r = bars[k][0];
|
||||
g = bars[k][1];
|
||||
b = bars[k][2];
|
||||
is_yuv = 0;
|
||||
|
||||
fh->bars[k][0] = TO_Y(r, g, b); /* Luma */
|
||||
fh->bars[k][1] = TO_U(r, g, b); /* Cb */
|
||||
fh->bars[k][2] = TO_V(r, g, b); /* Cr */
|
||||
switch (fh->fmt->fourcc) {
|
||||
case V4L2_PIX_FMT_YUYV:
|
||||
is_yuv = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_yuv) {
|
||||
fh->bars[k][0] = TO_Y(r, g, b); /* Luma */
|
||||
fh->bars[k][1] = TO_U(r, g, b); /* Cb */
|
||||
fh->bars[k][2] = TO_V(r, g, b); /* Cr */
|
||||
} else {
|
||||
fh->bars[k][0] = r;
|
||||
fh->bars[k][1] = g;
|
||||
fh->bars[k][2] = b;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
@ -885,8 +924,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
||||
File operations for the device
|
||||
------------------------------------------------------------------*/
|
||||
|
||||
#define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8)
|
||||
|
||||
static int vivi_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int minor = iminor(inode);
|
||||
@ -935,7 +972,7 @@ unlock:
|
||||
fh->dev = dev;
|
||||
|
||||
fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
fh->fmt = &format;
|
||||
fh->fmt = &formats[0];
|
||||
fh->width = 640;
|
||||
fh->height = 480;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user