diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-02 02:15:11 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 14:02:46 -0400 |
commit | 3d51dca2a951330ec60fac705316cf3d82988e29 (patch) | |
tree | 75fc73cd1647798fa22ca91cf56ad4f66e2ef16d /drivers/media/video/vivi.c | |
parent | fa0fcf46f3b5353b531994edcd73e6d442bc3211 (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.c | 165 |
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 | ||
119 | static struct vivi_fmt *get_format(struct v4l2_format *f) | 149 | static 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 | ||
320 | static 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. */ |
359 | static 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, |