aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/vivi.c
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-05-02 02:15:11 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 14:02:46 -0400
commit3d51dca2a951330ec60fac705316cf3d82988e29 (patch)
tree75fc73cd1647798fa22ca91cf56ad4f66e2ef16d /drivers/media/video/vivi.c
parentfa0fcf46f3b5353b531994edcd73e6d442bc3211 (diff)
[media] vivi: add more pixelformats
This is very useful for testing whether userspace can handle the various formats correctly. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r--drivers/media/video/vivi.c165
1 files changed, 135 insertions, 30 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 6f2e354a242d..5e457452a6e1 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -95,6 +95,16 @@ static struct vivi_fmt formats[] = {
95 .depth = 16, 95 .depth = 16,
96 }, 96 },
97 { 97 {
98 .name = "4:2:2, packed, YVYU",
99 .fourcc = V4L2_PIX_FMT_YVYU,
100 .depth = 16,
101 },
102 {
103 .name = "4:2:2, packed, VYUY",
104 .fourcc = V4L2_PIX_FMT_VYUY,
105 .depth = 16,
106 },
107 {
98 .name = "RGB565 (LE)", 108 .name = "RGB565 (LE)",
99 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ 109 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
100 .depth = 16, 110 .depth = 16,
@@ -114,6 +124,26 @@ static struct vivi_fmt formats[] = {
114 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ 124 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
115 .depth = 16, 125 .depth = 16,
116 }, 126 },
127 {
128 .name = "RGB24 (LE)",
129 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
130 .depth = 24,
131 },
132 {
133 .name = "RGB24 (BE)",
134 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
135 .depth = 24,
136 },
137 {
138 .name = "RGB32 (LE)",
139 .fourcc = V4L2_PIX_FMT_RGB32, /* argb */
140 .depth = 32,
141 },
142 {
143 .name = "RGB32 (BE)",
144 .fourcc = V4L2_PIX_FMT_BGR32, /* bgra */
145 .depth = 32,
146 },
117}; 147};
118 148
119static struct vivi_fmt *get_format(struct v4l2_format *f) 149static struct vivi_fmt *get_format(struct v4l2_format *f)
@@ -204,8 +234,9 @@ struct vivi_dev {
204 enum v4l2_field field; 234 enum v4l2_field field;
205 unsigned int field_count; 235 unsigned int field_count;
206 236
207 u8 bars[9][3]; 237 u8 bars[9][3];
208 u8 line[MAX_WIDTH * 4]; 238 u8 line[MAX_WIDTH * 8];
239 unsigned int pixelsize;
209}; 240};
210 241
211/* ------------------------------------------------------------------ 242/* ------------------------------------------------------------------
@@ -284,6 +315,8 @@ static void precalculate_bars(struct vivi_dev *dev)
284 switch (dev->fmt->fourcc) { 315 switch (dev->fmt->fourcc) {
285 case V4L2_PIX_FMT_YUYV: 316 case V4L2_PIX_FMT_YUYV:
286 case V4L2_PIX_FMT_UYVY: 317 case V4L2_PIX_FMT_UYVY:
318 case V4L2_PIX_FMT_YVYU:
319 case V4L2_PIX_FMT_VYUY:
287 is_yuv = 1; 320 is_yuv = 1;
288 break; 321 break;
289 case V4L2_PIX_FMT_RGB565: 322 case V4L2_PIX_FMT_RGB565:
@@ -298,6 +331,11 @@ static void precalculate_bars(struct vivi_dev *dev)
298 g >>= 3; 331 g >>= 3;
299 b >>= 3; 332 b >>= 3;
300 break; 333 break;
334 case V4L2_PIX_FMT_RGB24:
335 case V4L2_PIX_FMT_BGR24:
336 case V4L2_PIX_FMT_RGB32:
337 case V4L2_PIX_FMT_BGR32:
338 break;
301 } 339 }
302 340
303 if (is_yuv) { 341 if (is_yuv) {
@@ -317,7 +355,8 @@ static void precalculate_bars(struct vivi_dev *dev)
317#define TSTAMP_INPUT_X 10 355#define TSTAMP_INPUT_X 10
318#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X) 356#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
319 357
320static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos) 358/* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
359static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd)
321{ 360{
322 u8 r_y, g_u, b_v; 361 u8 r_y, g_u, b_v;
323 int color; 362 int color;
@@ -327,46 +366,56 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
327 g_u = dev->bars[colorpos][1]; /* G or precalculated U */ 366 g_u = dev->bars[colorpos][1]; /* G or precalculated U */
328 b_v = dev->bars[colorpos][2]; /* B or precalculated V */ 367 b_v = dev->bars[colorpos][2]; /* B or precalculated V */
329 368
330 for (color = 0; color < 4; color++) { 369 for (color = 0; color < dev->pixelsize; color++) {
331 p = buf + color; 370 p = buf + color;
332 371
333 switch (dev->fmt->fourcc) { 372 switch (dev->fmt->fourcc) {
334 case V4L2_PIX_FMT_YUYV: 373 case V4L2_PIX_FMT_YUYV:
335 switch (color) { 374 switch (color) {
336 case 0: 375 case 0:
337 case 2:
338 *p = r_y; 376 *p = r_y;
339 break; 377 break;
340 case 1: 378 case 1:
341 *p = g_u; 379 *p = odd ? b_v : g_u;
342 break;
343 case 3:
344 *p = b_v;
345 break; 380 break;
346 } 381 }
347 break; 382 break;
348 case V4L2_PIX_FMT_UYVY: 383 case V4L2_PIX_FMT_UYVY:
349 switch (color) { 384 switch (color) {
385 case 0:
386 *p = odd ? b_v : g_u;
387 break;
350 case 1: 388 case 1:
351 case 3:
352 *p = r_y; 389 *p = r_y;
353 break; 390 break;
391 }
392 break;
393 case V4L2_PIX_FMT_YVYU:
394 switch (color) {
395 case 0:
396 *p = r_y;
397 break;
398 case 1:
399 *p = odd ? g_u : b_v;
400 break;
401 }
402 break;
403 case V4L2_PIX_FMT_VYUY:
404 switch (color) {
354 case 0: 405 case 0:
355 *p = g_u; 406 *p = odd ? g_u : b_v;
356 break; 407 break;
357 case 2: 408 case 1:
358 *p = b_v; 409 *p = r_y;
359 break; 410 break;
360 } 411 }
361 break; 412 break;
362 case V4L2_PIX_FMT_RGB565: 413 case V4L2_PIX_FMT_RGB565:
363 switch (color) { 414 switch (color) {
364 case 0: 415 case 0:
365 case 2:
366 *p = (g_u << 5) | b_v; 416 *p = (g_u << 5) | b_v;
367 break; 417 break;
368 case 1: 418 case 1:
369 case 3:
370 *p = (r_y << 3) | (g_u >> 3); 419 *p = (r_y << 3) | (g_u >> 3);
371 break; 420 break;
372 } 421 }
@@ -374,11 +423,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
374 case V4L2_PIX_FMT_RGB565X: 423 case V4L2_PIX_FMT_RGB565X:
375 switch (color) { 424 switch (color) {
376 case 0: 425 case 0:
377 case 2:
378 *p = (r_y << 3) | (g_u >> 3); 426 *p = (r_y << 3) | (g_u >> 3);
379 break; 427 break;
380 case 1: 428 case 1:
381 case 3:
382 *p = (g_u << 5) | b_v; 429 *p = (g_u << 5) | b_v;
383 break; 430 break;
384 } 431 }
@@ -386,11 +433,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
386 case V4L2_PIX_FMT_RGB555: 433 case V4L2_PIX_FMT_RGB555:
387 switch (color) { 434 switch (color) {
388 case 0: 435 case 0:
389 case 2:
390 *p = (g_u << 5) | b_v; 436 *p = (g_u << 5) | b_v;
391 break; 437 break;
392 case 1: 438 case 1:
393 case 3:
394 *p = (r_y << 2) | (g_u >> 3); 439 *p = (r_y << 2) | (g_u >> 3);
395 break; 440 break;
396 } 441 }
@@ -398,15 +443,71 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
398 case V4L2_PIX_FMT_RGB555X: 443 case V4L2_PIX_FMT_RGB555X:
399 switch (color) { 444 switch (color) {
400 case 0: 445 case 0:
401 case 2:
402 *p = (r_y << 2) | (g_u >> 3); 446 *p = (r_y << 2) | (g_u >> 3);
403 break; 447 break;
404 case 1: 448 case 1:
405 case 3:
406 *p = (g_u << 5) | b_v; 449 *p = (g_u << 5) | b_v;
407 break; 450 break;
408 } 451 }
409 break; 452 break;
453 case V4L2_PIX_FMT_RGB24:
454 switch (color) {
455 case 0:
456 *p = r_y;
457 break;
458 case 1:
459 *p = g_u;
460 break;
461 case 2:
462 *p = b_v;
463 break;
464 }
465 break;
466 case V4L2_PIX_FMT_BGR24:
467 switch (color) {
468 case 0:
469 *p = b_v;
470 break;
471 case 1:
472 *p = g_u;
473 break;
474 case 2:
475 *p = r_y;
476 break;
477 }
478 break;
479 case V4L2_PIX_FMT_RGB32:
480 switch (color) {
481 case 0:
482 *p = 0;
483 break;
484 case 1:
485 *p = r_y;
486 break;
487 case 2:
488 *p = g_u;
489 break;
490 case 3:
491 *p = b_v;
492 break;
493 }
494 break;
495 case V4L2_PIX_FMT_BGR32:
496 switch (color) {
497 case 0:
498 *p = b_v;
499 break;
500 case 1:
501 *p = g_u;
502 break;
503 case 2:
504 *p = r_y;
505 break;
506 case 3:
507 *p = 0;
508 break;
509 }
510 break;
410 } 511 }
411 } 512 }
412} 513}
@@ -415,10 +516,10 @@ static void precalculate_line(struct vivi_dev *dev)
415{ 516{
416 int w; 517 int w;
417 518
418 for (w = 0; w < dev->width * 2; w += 2) { 519 for (w = 0; w < dev->width * 2; w++) {
419 int colorpos = (w / (dev->width / 8) % 8); 520 int colorpos = w / (dev->width / 8) % 8;
420 521
421 gen_twopix(dev, dev->line + w * 2, colorpos); 522 gen_twopix(dev, dev->line + w * dev->pixelsize, colorpos, w & 1);
422 } 523 }
423} 524}
424 525
@@ -434,7 +535,7 @@ static void gen_text(struct vivi_dev *dev, char *basep,
434 /* Print stream time */ 535 /* Print stream time */
435 for (line = y; line < y + 16; line++) { 536 for (line = y; line < y + 16; line++) {
436 int j = 0; 537 int j = 0;
437 char *pos = basep + line * dev->width * 2 + x * 2; 538 char *pos = basep + line * dev->width * dev->pixelsize + x * dev->pixelsize;
438 char *s; 539 char *s;
439 540
440 for (s = text; *s; s++) { 541 for (s = text; *s; s++) {
@@ -444,9 +545,9 @@ static void gen_text(struct vivi_dev *dev, char *basep,
444 for (i = 0; i < 7; i++, j++) { 545 for (i = 0; i < 7; i++, j++) {
445 /* Draw white font on black background */ 546 /* Draw white font on black background */
446 if (chr & (1 << (7 - i))) 547 if (chr & (1 << (7 - i)))
447 gen_twopix(dev, pos + j * 2, WHITE); 548 gen_twopix(dev, pos + j * dev->pixelsize, WHITE, (x+y) & 1);
448 else 549 else
449 gen_twopix(dev, pos + j * 2, TEXT_BLACK); 550 gen_twopix(dev, pos + j * dev->pixelsize, TEXT_BLACK, (x+y) & 1);
450 } 551 }
451 } 552 }
452 } 553 }
@@ -467,7 +568,9 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
467 return; 568 return;
468 569
469 for (h = 0; h < hmax; h++) 570 for (h = 0; h < hmax; h++)
470 memcpy(vbuf + h * wmax * 2, dev->line + (dev->mv_count % wmax) * 2, wmax * 2); 571 memcpy(vbuf + h * wmax * dev->pixelsize,
572 dev->line + (dev->mv_count % wmax) * dev->pixelsize,
573 wmax * dev->pixelsize);
471 574
472 /* Updates stream time */ 575 /* Updates stream time */
473 576
@@ -662,7 +765,7 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
662 struct vivi_dev *dev = vb2_get_drv_priv(vq); 765 struct vivi_dev *dev = vb2_get_drv_priv(vq);
663 unsigned long size; 766 unsigned long size;
664 767
665 size = dev->width * dev->height * 2; 768 size = dev->width * dev->height * dev->pixelsize;
666 769
667 if (0 == *nbuffers) 770 if (0 == *nbuffers)
668 *nbuffers = 32; 771 *nbuffers = 32;
@@ -726,7 +829,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
726 dev->height < 32 || dev->height > MAX_HEIGHT) 829 dev->height < 32 || dev->height > MAX_HEIGHT)
727 return -EINVAL; 830 return -EINVAL;
728 831
729 size = dev->width * dev->height * 2; 832 size = dev->width * dev->height * dev->pixelsize;
730 if (vb2_plane_size(vb, 0) < size) { 833 if (vb2_plane_size(vb, 0) < size) {
731 dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n", 834 dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
732 __func__, vb2_plane_size(vb, 0), size); 835 __func__, vb2_plane_size(vb, 0), size);
@@ -920,6 +1023,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
920 } 1023 }
921 1024
922 dev->fmt = get_format(f); 1025 dev->fmt = get_format(f);
1026 dev->pixelsize = dev->fmt->depth / 8;
923 dev->width = f->fmt.pix.width; 1027 dev->width = f->fmt.pix.width;
924 dev->height = f->fmt.pix.height; 1028 dev->height = f->fmt.pix.height;
925 dev->field = f->fmt.pix.field; 1029 dev->field = f->fmt.pix.field;
@@ -1266,6 +1370,7 @@ static int __init vivi_create_instance(int inst)
1266 dev->fmt = &formats[0]; 1370 dev->fmt = &formats[0];
1267 dev->width = 640; 1371 dev->width = 640;
1268 dev->height = 480; 1372 dev->height = 480;
1373 dev->pixelsize = dev->fmt->depth / 8;
1269 hdl = &dev->ctrl_handler; 1374 hdl = &dev->ctrl_handler;
1270 v4l2_ctrl_handler_init(hdl, 11); 1375 v4l2_ctrl_handler_init(hdl, 11);
1271 dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, 1376 dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,