From patchwork Thu Aug 18 14:33:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda Delgado X-Patchwork-Id: 9288293 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9D331607FF for ; Thu, 18 Aug 2016 14:36:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8EB85292A4 for ; Thu, 18 Aug 2016 14:36:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 834C8292A7; Thu, 18 Aug 2016 14:36:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B59172922D for ; Thu, 18 Aug 2016 14:36:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1768372AbcHROf5 (ORCPT ); Thu, 18 Aug 2016 10:35:57 -0400 Received: from mail-lf0-f68.google.com ([209.85.215.68]:36617 "EHLO mail-lf0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1768359AbcHROfq (ORCPT ); Thu, 18 Aug 2016 10:35:46 -0400 Received: by mail-lf0-f68.google.com with SMTP id 33so1866085lfw.3; Thu, 18 Aug 2016 07:34:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pQ/K4bOexiJ4oEdkbXX/NpFm4VRYMKB9hs2W+kRRihk=; b=r+MFzLLB9hxOolTSXkWls2A4KHteRnS63NDNqOjxVVbSKR9n7TUB3XSSNsUeS0sgHW 5Im9J+FSYramNNc0c3ByuPNzRS/8OysTiWAk5xJ81u9gGuNEbIMi8V4puxX3HLa2FPCu 45M65ziiiZPvbjs28n8KGnIiTKbp45cbRVXaf/mJBpHDgWhtkPT7bXrpNVz5oQ69kGty LsPFc4ovFuBqbKjkl4Qbdg73VUVWj4QjsplLX25c1HPCaIor8mAqlk0Nv3+pWKqfdbuT 5awV4BZk9xGxMRdKQPYzyuoxJ8ZOZrtQhNyXRHvxcW+AuyvuMZcAGkpdIyOStIAIjUln SgEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pQ/K4bOexiJ4oEdkbXX/NpFm4VRYMKB9hs2W+kRRihk=; b=Vde6DNeWSmSSfipfLpL3v6ATKwSVD/CRdbCtsGefvK3/FtT8s+qxpdNTXumk0z6QmO IgMiycR7elS5m0LSL+x5Jf/6yGZVpU0YLPcMv/x5Hoix1Q+aMpIQi/ig2a9eINHm0toi dyqxUZakOktsLLjwNDVh1bgqJa0c/1SgGQHGYXZxxWyqsMkWPwkguSrLrjkLetMamgS/ 7ArUS77S2oAMuCZUIrd70X9nDzykm+Y45cqe8JqzCu4jv8i/TzRgqjA+9E4g2bLYBzui Z7TnZyaVWW/mug70O66PPA7+RHE4tbA2B8YRtXQ5kmX6RfWMzr/c+LFvatklTgdS+aNo K6VQ== X-Gm-Message-State: AEkoouvnYI+zNt/SnhP6D7diGboaqsHCs3I+N2ARuOpCIZR0pH5cDLA4yTUpU91uz68FQA== X-Received: by 10.25.19.170 with SMTP id 42mr673723lft.147.1471530838335; Thu, 18 Aug 2016 07:33:58 -0700 (PDT) Received: from neopili.qtec.com (cpe.xe-3-0-1-778.vbrnqe10.dk.customer.tdc.net. [80.197.57.18]) by smtp.gmail.com with ESMTPSA id p21sm389218lfp.4.2016.08.18.07.33.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Aug 2016 07:33:57 -0700 (PDT) From: Ricardo Ribalda Delgado To: Mauro Carvalho Chehab , Hans Verkuil , Markus Heiser , Laurent Pinchart , Helen Mae Koike Fornazier , Antti Palosaari , Philipp Zabel , Shuah Khan , linux-kernel@vger.kernel.org, linux-media@vger.kernel.org Cc: Ricardo Ribalda Delgado Subject: [PATCH v5 12/12] [media] vivid: Add support for HSV encoding Date: Thu, 18 Aug 2016 16:33:38 +0200 Message-Id: <1471530818-7928-13-git-send-email-ricardo.ribalda@gmail.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1471530818-7928-1-git-send-email-ricardo.ribalda@gmail.com> References: <1471530818-7928-1-git-send-email-ricardo.ribalda@gmail.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Support HSV encoding. Most of the logic is replicated from ycbcr_enc. Signed-off-by: Ricardo Ribalda Delgado --- drivers/media/common/v4l2-tpg/v4l2-tpg-core.c | 25 +++++++++++++++++-------- drivers/media/platform/vivid/vivid-core.h | 1 + drivers/media/platform/vivid/vivid-ctrls.c | 25 +++++++++++++++++++++++++ drivers/media/platform/vivid/vivid-vid-cap.c | 17 +++++++++++++++-- drivers/media/platform/vivid/vivid-vid-common.c | 2 ++ drivers/media/platform/vivid/vivid-vid-out.c | 1 + include/media/v4l2-tpg.h | 15 +++++++++++++++ 7 files changed, 76 insertions(+), 10 deletions(-) diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index ed37ae307cac..28d7b072d867 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -504,6 +504,7 @@ static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b, int max_rgb, min_rgb, diff_rgb; int aux; int third; + int third_size; r >>= 4; g >>= 4; @@ -530,30 +531,36 @@ static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b, return; } + third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85; + /* Hue */ if (max_rgb == r) { aux = g - b; third = 0; } else if (max_rgb == g) { aux = b - r; - third = 60; + third = third_size; } else { aux = r - g; - third = 120; + third = third_size * 2; } - aux *= 30; + aux *= third_size / 2; aux += diff_rgb / 2; aux /= diff_rgb; aux += third; /* Clamp Hue */ - if (aux < 0) - aux += 180; - else if (aux > 180) - aux -= 180; - *h = aux; + if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) { + if (aux < 0) + aux += 180; + else if (aux > 180) + aux -= 180; + } else { + aux = aux & 0xff; + } + *h = aux; } static void rgb2ycbcr(const int m[3][3], int r, int g, int b, @@ -1928,6 +1935,7 @@ static void tpg_recalc(struct tpg_data *tpg) tpg->recalc_lines = true; tpg->real_xfer_func = tpg->xfer_func; tpg->real_ycbcr_enc = tpg->ycbcr_enc; + tpg->real_hsv_enc = tpg->hsv_enc; tpg->real_quantization = tpg->quantization; if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT) @@ -2018,6 +2026,7 @@ void tpg_log_status(struct tpg_data *tpg) pr_info("tpg colorspace: %d\n", tpg->colorspace); pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func); pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc); + pr_info("tpg HSV encoding: %d/%d\n", tpg->hsv_enc, tpg->real_hsv_enc); pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization); pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range); } diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h index b59b49456d45..5cdf95bdc4d1 100644 --- a/drivers/media/platform/vivid/vivid-core.h +++ b/drivers/media/platform/vivid/vivid-core.h @@ -346,6 +346,7 @@ struct vivid_dev { struct v4l2_dv_timings dv_timings_out; u32 colorspace_out; u32 ycbcr_enc_out; + u32 hsv_enc_out; u32 quantization_out; u32 xfer_func_out; u32 service_set_out; diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index aceb38d9f7e7..34731f71cc00 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -79,6 +79,7 @@ #define VIVID_CID_MAX_EDID_BLOCKS (VIVID_CID_VIVID_BASE + 40) #define VIVID_CID_PERCENTAGE_FILL (VIVID_CID_VIVID_BASE + 41) #define VIVID_CID_REDUCED_FPS (VIVID_CID_VIVID_BASE + 42) +#define VIVID_CID_HSV_ENC (VIVID_CID_VIVID_BASE + 43) #define VIVID_CID_STD_SIGNAL_MODE (VIVID_CID_VIVID_BASE + 60) #define VIVID_CID_STANDARD (VIVID_CID_VIVID_BASE + 61) @@ -378,6 +379,14 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) vivid_send_source_change(dev, HDMI); vivid_send_source_change(dev, WEBCAM); break; + case VIVID_CID_HSV_ENC: + tpg_s_hsv_enc(&dev->tpg, ctrl->val ? V4L2_HSV_ENC_256 : + V4L2_HSV_ENC_180); + vivid_send_source_change(dev, TV); + vivid_send_source_change(dev, SVID); + vivid_send_source_change(dev, HDMI); + vivid_send_source_change(dev, WEBCAM); + break; case VIVID_CID_QUANTIZATION: tpg_s_quantization(&dev->tpg, ctrl->val); vivid_send_source_change(dev, TV); @@ -778,6 +787,21 @@ static const struct v4l2_ctrl_config vivid_ctrl_ycbcr_enc = { .qmenu = vivid_ctrl_ycbcr_enc_strings, }; +static const char * const vivid_ctrl_hsv_enc_strings[] = { + "Hue 0-179", + "Hue 0-256", + NULL, +}; + +static const struct v4l2_ctrl_config vivid_ctrl_hsv_enc = { + .ops = &vivid_vid_cap_ctrl_ops, + .id = VIVID_CID_HSV_ENC, + .name = "HSV Encoding", + .type = V4L2_CTRL_TYPE_MENU, + .max = ARRAY_SIZE(vivid_ctrl_hsv_enc_strings) - 2, + .qmenu = vivid_ctrl_hsv_enc_strings, +}; + static const char * const vivid_ctrl_quantization_strings[] = { "Default", "Full Range", @@ -1454,6 +1478,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, &vivid_ctrl_colorspace, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_xfer_func, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_ycbcr_enc, NULL); + v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_hsv_enc, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_quantization, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_alpha_mode, NULL); } diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c index d404a7ce33a4..fbe1cc8b8a95 100644 --- a/drivers/media/platform/vivid/vivid-vid-cap.c +++ b/drivers/media/platform/vivid/vivid-vid-cap.c @@ -510,6 +510,13 @@ static unsigned vivid_ycbcr_enc_cap(struct vivid_dev *dev) return dev->ycbcr_enc_out; } +static unsigned int vivid_hsv_enc_cap(struct vivid_dev *dev) +{ + if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) + return tpg_g_hsv_enc(&dev->tpg); + return dev->hsv_enc_out; +} + static unsigned vivid_quantization_cap(struct vivid_dev *dev) { if (!dev->loop_video || vivid_is_webcam(dev) || vivid_is_tv_cap(dev)) @@ -530,7 +537,10 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv, mp->pixelformat = dev->fmt_cap->fourcc; mp->colorspace = vivid_colorspace_cap(dev); mp->xfer_func = vivid_xfer_func_cap(dev); - mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); + if (dev->fmt_cap->color_enc == TGP_COLOR_ENC_HSV) + mp->hsv_enc = vivid_hsv_enc_cap(dev); + else + mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); mp->quantization = vivid_quantization_cap(dev); mp->num_planes = dev->fmt_cap->buffers; for (p = 0; p < mp->num_planes; p++) { @@ -618,7 +628,10 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv, memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); } mp->colorspace = vivid_colorspace_cap(dev); - mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); + if (fmt->color_enc == TGP_COLOR_ENC_HSV) + mp->hsv_enc = vivid_hsv_enc_cap(dev); + else + mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); mp->xfer_func = vivid_xfer_func_cap(dev); mp->quantization = vivid_quantization_cap(dev); memset(mp->reserved, 0, sizeof(mp->reserved)); diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index e0df44151461..3d003fb913ed 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -630,6 +630,7 @@ void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt) mp->field = pix->field; mp->colorspace = pix->colorspace; mp->xfer_func = pix->xfer_func; + /* Also copies hsv_enc */ mp->ycbcr_enc = pix->ycbcr_enc; mp->quantization = pix->quantization; mp->num_planes = 1; @@ -659,6 +660,7 @@ int fmt_sp2mp_func(struct file *file, void *priv, pix->field = mp->field; pix->colorspace = mp->colorspace; pix->xfer_func = mp->xfer_func; + /* Also copies hsv_enc */ pix->ycbcr_enc = mp->ycbcr_enc; pix->quantization = mp->quantization; pix->sizeimage = ppix->sizeimage; diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c index dd609eea4753..7ba52ee98371 100644 --- a/drivers/media/platform/vivid/vivid-vid-out.c +++ b/drivers/media/platform/vivid/vivid-vid-out.c @@ -256,6 +256,7 @@ void vivid_update_format_out(struct vivid_dev *dev) } dev->xfer_func_out = V4L2_XFER_FUNC_DEFAULT; dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT; + dev->hsv_enc_out = V4L2_HSV_ENC_180; dev->quantization_out = V4L2_QUANTIZATION_DEFAULT; dev->compose_out = dev->sink_rect; dev->compose_bounds_out = dev->sink_rect; diff --git a/include/media/v4l2-tpg.h b/include/media/v4l2-tpg.h index 8abed92317e8..13e49d85cae3 100644 --- a/include/media/v4l2-tpg.h +++ b/include/media/v4l2-tpg.h @@ -130,6 +130,7 @@ struct tpg_data { u32 colorspace; u32 xfer_func; u32 ycbcr_enc; + u32 hsv_enc; /* * Stores the actual transfer function, i.e. will never be * V4L2_XFER_FUNC_DEFAULT. @@ -139,6 +140,7 @@ struct tpg_data { * Stores the actual Y'CbCr encoding, i.e. will never be * V4L2_YCBCR_ENC_DEFAULT. */ + u32 real_hsv_enc; u32 real_ycbcr_enc; u32 quantization; /* @@ -341,6 +343,19 @@ static inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg) return tpg->ycbcr_enc; } +static inline void tpg_s_hsv_enc(struct tpg_data *tpg, u32 hsv_enc) +{ + if (tpg->hsv_enc == hsv_enc) + return; + tpg->hsv_enc = hsv_enc; + tpg->recalc_colors = true; +} + +static inline u32 tpg_g_hsv_enc(const struct tpg_data *tpg) +{ + return tpg->hsv_enc; +} + static inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func) { if (tpg->xfer_func == xfer_func)