Commit 3d51dca2 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] vivi: add more pixelformats

This is very useful for testing whether userspace can handle the various formats
correctly.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent fa0fcf46
...@@ -94,6 +94,16 @@ static struct vivi_fmt formats[] = { ...@@ -94,6 +94,16 @@ static struct vivi_fmt formats[] = {
.fourcc = V4L2_PIX_FMT_UYVY, .fourcc = V4L2_PIX_FMT_UYVY,
.depth = 16, .depth = 16,
}, },
{
.name = "4:2:2, packed, YVYU",
.fourcc = V4L2_PIX_FMT_YVYU,
.depth = 16,
},
{
.name = "4:2:2, packed, VYUY",
.fourcc = V4L2_PIX_FMT_VYUY,
.depth = 16,
},
{ {
.name = "RGB565 (LE)", .name = "RGB565 (LE)",
.fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
...@@ -114,6 +124,26 @@ static struct vivi_fmt formats[] = { ...@@ -114,6 +124,26 @@ static struct vivi_fmt formats[] = {
.fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
.depth = 16, .depth = 16,
}, },
{
.name = "RGB24 (LE)",
.fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
.depth = 24,
},
{
.name = "RGB24 (BE)",
.fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
.depth = 24,
},
{
.name = "RGB32 (LE)",
.fourcc = V4L2_PIX_FMT_RGB32, /* argb */
.depth = 32,
},
{
.name = "RGB32 (BE)",
.fourcc = V4L2_PIX_FMT_BGR32, /* bgra */
.depth = 32,
},
}; };
static struct vivi_fmt *get_format(struct v4l2_format *f) static struct vivi_fmt *get_format(struct v4l2_format *f)
...@@ -205,7 +235,8 @@ struct vivi_dev { ...@@ -205,7 +235,8 @@ struct vivi_dev {
unsigned int field_count; unsigned int field_count;
u8 bars[9][3]; u8 bars[9][3];
u8 line[MAX_WIDTH * 4]; u8 line[MAX_WIDTH * 8];
unsigned int pixelsize;
}; };
/* ------------------------------------------------------------------ /* ------------------------------------------------------------------
...@@ -284,6 +315,8 @@ static void precalculate_bars(struct vivi_dev *dev) ...@@ -284,6 +315,8 @@ static void precalculate_bars(struct vivi_dev *dev)
switch (dev->fmt->fourcc) { switch (dev->fmt->fourcc) {
case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_UYVY:
case V4L2_PIX_FMT_YVYU:
case V4L2_PIX_FMT_VYUY:
is_yuv = 1; is_yuv = 1;
break; break;
case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_RGB565:
...@@ -298,6 +331,11 @@ static void precalculate_bars(struct vivi_dev *dev) ...@@ -298,6 +331,11 @@ static void precalculate_bars(struct vivi_dev *dev)
g >>= 3; g >>= 3;
b >>= 3; b >>= 3;
break; break;
case V4L2_PIX_FMT_RGB24:
case V4L2_PIX_FMT_BGR24:
case V4L2_PIX_FMT_RGB32:
case V4L2_PIX_FMT_BGR32:
break;
} }
if (is_yuv) { if (is_yuv) {
...@@ -317,7 +355,8 @@ static void precalculate_bars(struct vivi_dev *dev) ...@@ -317,7 +355,8 @@ static void precalculate_bars(struct vivi_dev *dev)
#define TSTAMP_INPUT_X 10 #define TSTAMP_INPUT_X 10
#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) #define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd)
{ {
u8 r_y, g_u, b_v; u8 r_y, g_u, b_v;
int color; int color;
...@@ -327,46 +366,56 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) ...@@ -327,46 +366,56 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
g_u = dev->bars[colorpos][1]; /* G or precalculated U */ g_u = dev->bars[colorpos][1]; /* G or precalculated U */
b_v = dev->bars[colorpos][2]; /* B or precalculated V */ b_v = dev->bars[colorpos][2]; /* B or precalculated V */
for (color = 0; color < 4; color++) { for (color = 0; color < dev->pixelsize; color++) {
p = buf + color; p = buf + color;
switch (dev->fmt->fourcc) { switch (dev->fmt->fourcc) {
case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YUYV:
switch (color) { switch (color) {
case 0: case 0:
case 2:
*p = r_y; *p = r_y;
break; break;
case 1: case 1:
*p = g_u; *p = odd ? b_v : g_u;
break;
case 3:
*p = b_v;
break; break;
} }
break; break;
case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_UYVY:
switch (color) { switch (color) {
case 0:
*p = odd ? b_v : g_u;
break;
case 1: case 1:
case 3:
*p = r_y; *p = r_y;
break; break;
}
break;
case V4L2_PIX_FMT_YVYU:
switch (color) {
case 0:
*p = r_y;
break;
case 1:
*p = odd ? g_u : b_v;
break;
}
break;
case V4L2_PIX_FMT_VYUY:
switch (color) {
case 0: case 0:
*p = g_u; *p = odd ? g_u : b_v;
break; break;
case 2: case 1:
*p = b_v; *p = r_y;
break; break;
} }
break; break;
case V4L2_PIX_FMT_RGB565: case V4L2_PIX_FMT_RGB565:
switch (color) { switch (color) {
case 0: case 0:
case 2:
*p = (g_u << 5) | b_v; *p = (g_u << 5) | b_v;
break; break;
case 1: case 1:
case 3:
*p = (r_y << 3) | (g_u >> 3); *p = (r_y << 3) | (g_u >> 3);
break; break;
} }
...@@ -374,11 +423,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) ...@@ -374,11 +423,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
case V4L2_PIX_FMT_RGB565X: case V4L2_PIX_FMT_RGB565X:
switch (color) { switch (color) {
case 0: case 0:
case 2:
*p = (r_y << 3) | (g_u >> 3); *p = (r_y << 3) | (g_u >> 3);
break; break;
case 1: case 1:
case 3:
*p = (g_u << 5) | b_v; *p = (g_u << 5) | b_v;
break; break;
} }
...@@ -386,11 +433,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) ...@@ -386,11 +433,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
case V4L2_PIX_FMT_RGB555: case V4L2_PIX_FMT_RGB555:
switch (color) { switch (color) {
case 0: case 0:
case 2:
*p = (g_u << 5) | b_v; *p = (g_u << 5) | b_v;
break; break;
case 1: case 1:
case 3:
*p = (r_y << 2) | (g_u >> 3); *p = (r_y << 2) | (g_u >> 3);
break; break;
} }
...@@ -398,15 +443,71 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) ...@@ -398,15 +443,71 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
case V4L2_PIX_FMT_RGB555X: case V4L2_PIX_FMT_RGB555X:
switch (color) { switch (color) {
case 0: case 0:
case 2:
*p = (r_y << 2) | (g_u >> 3); *p = (r_y << 2) | (g_u >> 3);
break; break;
case 1: case 1:
case 3:
*p = (g_u << 5) | b_v; *p = (g_u << 5) | b_v;
break; break;
} }
break; break;
case V4L2_PIX_FMT_RGB24:
switch (color) {
case 0:
*p = r_y;
break;
case 1:
*p = g_u;
break;
case 2:
*p = b_v;
break;
}
break;
case V4L2_PIX_FMT_BGR24:
switch (color) {
case 0:
*p = b_v;
break;
case 1:
*p = g_u;
break;
case 2:
*p = r_y;
break;
}
break;
case V4L2_PIX_FMT_RGB32:
switch (color) {
case 0:
*p = 0;
break;
case 1:
*p = r_y;
break;
case 2:
*p = g_u;
break;
case 3:
*p = b_v;
break;
}
break;
case V4L2_PIX_FMT_BGR32:
switch (color) {
case 0:
*p = b_v;
break;
case 1:
*p = g_u;
break;
case 2:
*p = r_y;
break;
case 3:
*p = 0;
break;
}
break;
} }
} }
} }
...@@ -415,10 +516,10 @@ static void precalculate_line(struct vivi_dev *dev) ...@@ -415,10 +516,10 @@ static void precalculate_line(struct vivi_dev *dev)
{ {
int w; int w;
for (w = 0; w < dev->width * 2; w += 2) { for (w = 0; w < dev->width * 2; w++) {
int colorpos = (w / (dev->width / 8) % 8); int colorpos = w / (dev->width / 8) % 8;
gen_twopix(dev, dev->line + w * 2, colorpos); gen_twopix(dev, dev->line + w * dev->pixelsize, colorpos, w & 1);
} }
} }
...@@ -434,7 +535,7 @@ static void gen_text(struct vivi_dev *dev, char *basep, ...@@ -434,7 +535,7 @@ static void gen_text(struct vivi_dev *dev, char *basep,
/* Print stream time */ /* Print stream time */
for (line = y; line < y + 16; line++) { for (line = y; line < y + 16; line++) {
int j = 0; int j = 0;
char *pos = basep + line * dev->width * 2 + x * 2; char *pos = basep + line * dev->width * dev->pixelsize + x * dev->pixelsize;
char *s; char *s;
for (s = text; *s; s++) { for (s = text; *s; s++) {
...@@ -444,9 +545,9 @@ static void gen_text(struct vivi_dev *dev, char *basep, ...@@ -444,9 +545,9 @@ static void gen_text(struct vivi_dev *dev, char *basep,
for (i = 0; i < 7; i++, j++) { for (i = 0; i < 7; i++, j++) {
/* Draw white font on black background */ /* Draw white font on black background */
if (chr & (1 << (7 - i))) if (chr & (1 << (7 - i)))
gen_twopix(dev, pos + j * 2, WHITE); gen_twopix(dev, pos + j * dev->pixelsize, WHITE, (x+y) & 1);
else else
gen_twopix(dev, pos + j * 2, TEXT_BLACK); gen_twopix(dev, pos + j * dev->pixelsize, TEXT_BLACK, (x+y) & 1);
} }
} }
} }
...@@ -467,7 +568,9 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) ...@@ -467,7 +568,9 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
return; return;
for (h = 0; h < hmax; h++) for (h = 0; h < hmax; h++)
memcpy(vbuf + h * wmax * 2, dev->line + (dev->mv_count % wmax) * 2, wmax * 2); memcpy(vbuf + h * wmax * dev->pixelsize,
dev->line + (dev->mv_count % wmax) * dev->pixelsize,
wmax * dev->pixelsize);
/* Updates stream time */ /* Updates stream time */
...@@ -662,7 +765,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, ...@@ -662,7 +765,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
struct vivi_dev *dev = vb2_get_drv_priv(vq); struct vivi_dev *dev = vb2_get_drv_priv(vq);
unsigned long size; unsigned long size;
size = dev->width * dev->height * 2; size = dev->width * dev->height * dev->pixelsize;
if (0 == *nbuffers) if (0 == *nbuffers)
*nbuffers = 32; *nbuffers = 32;
...@@ -726,7 +829,7 @@ static int buffer_prepare(struct vb2_buffer *vb) ...@@ -726,7 +829,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
dev->height < 32 || dev->height > MAX_HEIGHT) dev->height < 32 || dev->height > MAX_HEIGHT)
return -EINVAL; return -EINVAL;
size = dev->width * dev->height * 2; size = dev->width * dev->height * dev->pixelsize;
if (vb2_plane_size(vb, 0) < size) { if (vb2_plane_size(vb, 0) < size) {
dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n", dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
__func__, vb2_plane_size(vb, 0), size); __func__, vb2_plane_size(vb, 0), size);
...@@ -920,6 +1023,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, ...@@ -920,6 +1023,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
} }
dev->fmt = get_format(f); dev->fmt = get_format(f);
dev->pixelsize = dev->fmt->depth / 8;
dev->width = f->fmt.pix.width; dev->width = f->fmt.pix.width;
dev->height = f->fmt.pix.height; dev->height = f->fmt.pix.height;
dev->field = f->fmt.pix.field; dev->field = f->fmt.pix.field;
...@@ -1266,6 +1370,7 @@ static int __init vivi_create_instance(int inst) ...@@ -1266,6 +1370,7 @@ static int __init vivi_create_instance(int inst)
dev->fmt = &formats[0]; dev->fmt = &formats[0];
dev->width = 640; dev->width = 640;
dev->height = 480; dev->height = 480;
dev->pixelsize = dev->fmt->depth / 8;
hdl = &dev->ctrl_handler; hdl = &dev->ctrl_handler;
v4l2_ctrl_handler_init(hdl, 11); v4l2_ctrl_handler_init(hdl, 11);
dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment