Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] vivid: Add support for HSV encoding

Support HSV encoding. Most of the logic is replicated from ycbcr_enc.

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Ricardo Ribalda Delgado and committed by
Mauro Carvalho Chehab
429175e4 5f3d32ec

+76 -10
+17 -8
drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
··· 504 504 int max_rgb, min_rgb, diff_rgb; 505 505 int aux; 506 506 int third; 507 + int third_size; 507 508 508 509 r >>= 4; 509 510 g >>= 4; ··· 531 530 return; 532 531 } 533 532 533 + third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85; 534 + 534 535 /* Hue */ 535 536 if (max_rgb == r) { 536 537 aux = g - b; 537 538 third = 0; 538 539 } else if (max_rgb == g) { 539 540 aux = b - r; 540 - third = 60; 541 + third = third_size; 541 542 } else { 542 543 aux = r - g; 543 - third = 120; 544 + third = third_size * 2; 544 545 } 545 546 546 - aux *= 30; 547 + aux *= third_size / 2; 547 548 aux += diff_rgb / 2; 548 549 aux /= diff_rgb; 549 550 aux += third; 550 551 551 552 /* Clamp Hue */ 552 - if (aux < 0) 553 - aux += 180; 554 - else if (aux > 180) 555 - aux -= 180; 556 - *h = aux; 553 + if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) { 554 + if (aux < 0) 555 + aux += 180; 556 + else if (aux > 180) 557 + aux -= 180; 558 + } else { 559 + aux = aux & 0xff; 560 + } 557 561 562 + *h = aux; 558 563 } 559 564 560 565 static void rgb2ycbcr(const int m[3][3], int r, int g, int b, ··· 1935 1928 tpg->recalc_lines = true; 1936 1929 tpg->real_xfer_func = tpg->xfer_func; 1937 1930 tpg->real_ycbcr_enc = tpg->ycbcr_enc; 1931 + tpg->real_hsv_enc = tpg->hsv_enc; 1938 1932 tpg->real_quantization = tpg->quantization; 1939 1933 1940 1934 if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT) ··· 2026 2018 pr_info("tpg colorspace: %d\n", tpg->colorspace); 2027 2019 pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func); 2028 2020 pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc); 2021 + pr_info("tpg HSV encoding: %d/%d\n", tpg->hsv_enc, tpg->real_hsv_enc); 2029 2022 pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization); 2030 2023 pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range); 2031 2024 }
+1
drivers/media/platform/vivid/vivid-core.h
··· 346 346 struct v4l2_dv_timings dv_timings_out; 347 347 u32 colorspace_out; 348 348 u32 ycbcr_enc_out; 349 + u32 hsv_enc_out; 349 350 u32 quantization_out; 350 351 u32 xfer_func_out; 351 352 u32 service_set_out;
+25
drivers/media/platform/vivid/vivid-ctrls.c
··· 79 79 #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40) 80 80 #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41) 81 81 #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42) 82 + #define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43) 82 83 83 84 #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) 84 85 #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) ··· 374 373 break; 375 374 case VIVID_CID_YCBCR_ENC: 376 375 tpg_s_ycbcr_enc(&dev->tpg, ctrl->val); 376 + vivid_send_source_change(dev, TV); 377 + vivid_send_source_change(dev, SVID); 378 + vivid_send_source_change(dev, HDMI); 379 + vivid_send_source_change(dev, WEBCAM); 380 + break; 381 + case VIVID_CID_HSV_ENC: 382 + tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 : 383 + V4L2_HSV_ENC_180); 377 384 vivid_send_source_change(dev, TV); 378 385 vivid_send_source_change(dev, SVID); 379 386 vivid_send_source_change(dev, HDMI); ··· 785 776 .menu_skip_mask = 1 << 5, 786 777 .max = ARRAY_SIZE(vivid_ctrl_ycbcr_enc_strings) - 2, 787 778 .qmenu = vivid_ctrl_ycbcr_enc_strings, 779 + }; 780 + 781 + static const char * const vivid_ctrl_hsv_enc_strings[] = { 782 + "Hue 0-179", 783 + "Hue 0-256", 784 + NULL, 785 + }; 786 + 787 + static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = { 788 + .ops = &vivid_vid_cap_ctrl_ops, 789 + .id = VIVID_CID_HSV_ENC, 790 + .name = "HSV Encoding", 791 + .type = V4L2_CTRL_TYPE_MENU, 792 + .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2, 793 + .qmenu = vivid_ctrl_hsv_enc_strings, 788 794 }; 789 795 790 796 static const char * const vivid_ctrl_quantization_strings[] = { ··· 1478 1454 &vivid_ctrl_colorspace, NULL); 1479 1455 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL); 1480 1456 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL); 1457 + v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL); 1481 1458 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL); 1482 1459 v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL); 1483 1460 }
+15 -2
drivers/media/platform/vivid/vivid-vid-cap.c
··· 510 510 return dev->ycbcr_enc_out; 511 511 } 512 512 513 + static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev) 514 + { 515 + if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) 516 + return tpg_g_hsv_enc(&dev->tpg); 517 + return dev->hsv_enc_out; 518 + } 519 + 513 520 static unsigned vivid_quantization_cap(struct vivid_dev *dev) 514 521 { 515 522 if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) ··· 537 530 mp->pixelformat = dev->fmt_cap->fourcc; 538 531 mp->colorspace = vivid_colorspace_cap(dev); 539 532 mp->xfer_func = vivid_xfer_func_cap(dev); 540 - mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 533 + if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_HSV) 534 + mp->hsv_enc = vivid_hsv_enc_cap(dev); 535 + else 536 + mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 541 537 mp->quantization = vivid_quantization_cap(dev); 542 538 mp->num_planes = dev->fmt_cap->buffers; 543 539 for (p = 0; p < mp->num_planes; p++) { ··· 628 618 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 629 619 } 630 620 mp->colorspace = vivid_colorspace_cap(dev); 631 - mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 621 + if (fmt->color_enc == TGP_COLOR_ENC_HSV) 622 + mp->hsv_enc = vivid_hsv_enc_cap(dev); 623 + else 624 + mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 632 625 mp->xfer_func = vivid_xfer_func_cap(dev); 633 626 mp->quantization = vivid_quantization_cap(dev); 634 627 memset(mp->reserved, 0, sizeof(mp->reserved));
+2
drivers/media/platform/vivid/vivid-vid-common.c
··· 630 630 mp->field = pix->field; 631 631 mp->colorspace = pix->colorspace; 632 632 mp->xfer_func = pix->xfer_func; 633 + /* Also copies hsv_enc */ 633 634 mp->ycbcr_enc = pix->ycbcr_enc; 634 635 mp->quantization = pix->quantization; 635 636 mp->num_planes = 1; ··· 660 659 pix->field = mp->field; 661 660 pix->colorspace = mp->colorspace; 662 661 pix->xfer_func = mp->xfer_func; 662 + /* Also copies hsv_enc */ 663 663 pix->ycbcr_enc = mp->ycbcr_enc; 664 664 pix->quantization = mp->quantization; 665 665 pix->sizeimage = ppix->sizeimage;
+1
drivers/media/platform/vivid/vivid-vid-out.c
··· 256 256 } 257 257 dev->xfer_func_out = V4L2_XFER_FUNC_DEFAULT; 258 258 dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT; 259 + dev->hsv_enc_out = V4L2_HSV_ENC_180; 259 260 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT; 260 261 dev->compose_out = dev->sink_rect; 261 262 dev->compose_bounds_out = dev->sink_rect;
+15
include/media/v4l2-tpg.h
··· 130 130 u32 colorspace; 131 131 u32 xfer_func; 132 132 u32 ycbcr_enc; 133 + u32 hsv_enc; 133 134 /* 134 135 * Stores the actual transfer function, i.e. will never be 135 136 * V4L2_XFER_FUNC_DEFAULT. ··· 140 139 * Stores the actual Y'CbCr encoding, i.e. will never be 141 140 * V4L2_YCBCR_ENC_DEFAULT. 142 141 */ 142 + u32 real_hsv_enc; 143 143 u32 real_ycbcr_enc; 144 144 u32 quantization; 145 145 /* ··· 341 339 static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg) 342 340 { 343 341 return tpg->ycbcr_enc; 342 + } 343 + 344 + static inline void tpg_s_hsv_enc(struct tpg_data *tpg, u32 hsv_enc) 345 + { 346 + if (tpg->hsv_enc == hsv_enc) 347 + return; 348 + tpg->hsv_enc = hsv_enc; 349 + tpg->recalc_colors = true; 350 + } 351 + 352 + static inline u32 tpg_g_hsv_enc(const struct tpg_data *tpg) 353 + { 354 + return tpg->hsv_enc; 344 355 } 345 356 346 357 static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func)