linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Steve Longerbeam <slongerbeam@gmail.com>
To: linux-media@vger.kernel.org
Cc: Steve Longerbeam <slongerbeam@gmail.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	dri-devel@lists.freedesktop.org (open list:DRM DRIVERS FOR
	FREESCALE IMX), linux-kernel@vger.kernel.org (open list)
Subject: [PATCH v8 4/5] gpu: ipu-v3: ipu-ic-csc: Add support for Rec.709 encoding
Date: Tue, 21 May 2019 18:03:16 -0700	[thread overview]
Message-ID: <20190522010317.23710-5-slongerbeam@gmail.com> (raw)
In-Reply-To: <20190522010317.23710-1-slongerbeam@gmail.com>

Add support for Rec.709 encoding and inverse encoding.

Reported-by: Tim Harvey <tharvey@gateworks.com>
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
Changes in v7:
- moved CSC tables to new module ipu-ic-csc.c.
- express negative coefficients as true signed int's, for better
  readability.
Changes in v5:
- moved API changes to a previous patch.
- moved CSC coeff calc to new function calc_csc_coeffs().
Changes in v4:
- fix compile error.
Chnges in v3:
- none.
Changes in v2:
- only return "Unsupported YCbCr encoding" error if inf != outf,
  since if inf == outf, the identity matrix can be used. Reported
  by Tim Harvey.
---
 drivers/gpu/ipu-v3/ipu-ic-csc.c | 139 ++++++++++++++++++++++++++++++--
 1 file changed, 134 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-ic-csc.c b/drivers/gpu/ipu-v3/ipu-ic-csc.c
index 8e9150b1d668..09e94aa12c40 100644
--- a/drivers/gpu/ipu-v3/ipu-ic-csc.c
+++ b/drivers/gpu/ipu-v3/ipu-ic-csc.c
@@ -230,14 +230,133 @@ static const struct ipu_ic_csc_params *yuv2rgb_601[] = {
 	&yuvl2rgbl_601,
 };
 
+/*
+ * REC.709 encoding from RGB full range to YUV full range:
+ *
+ * Y =  .2126 * R + .7152 * G + .0722 * B
+ * U = -.1146 * R - .3854 * G + .5000 * B + 128
+ * V =  .5000 * R - .4542 * G - .0458 * B + 128
+ */
+static const struct ipu_ic_csc_params rgbf2yuvf_709 = {
+	.coeff = {
+		{  54,  183,  19 },
+		{ -29,  -99, 128 },
+		{ 128, -116, -12 },
+	},
+	.offset = { 0, 512, 512 },
+	.scale = 1,
+};
+
+/* Rec.709 RGB full-range to YUV limited-range */
+static const struct ipu_ic_csc_params rgbf2yuvl_709 = {
+	.coeff = {
+		{   47,  157,   16, },
+		{  -26,  -87,  112, },
+		{  112, -102,  -10, },
+	},
+	.offset = { 64, 512, 512, },
+	.scale = 1,
+	.sat = true,
+};
+
+/* Rec.709 RGB limited-range to YUV full-range */
+static const struct ipu_ic_csc_params rgbl2yuvf_709 = {
+	.coeff = {
+		{   63,  213,   22, },
+		{  -34, -115,  149, },
+		{  149, -135,  -14, },
+	},
+	.offset = { -75, 512, 512, },
+	.scale = 1,
+};
+
+/* Rec.709 RGB limited-range to YUV limited-range */
+static const struct ipu_ic_csc_params rgbl2yuvl_709 = {
+	.coeff = {
+		{   54,  183,   18, },
+		{  -30, -101,  131, },
+		{  131, -119,  -12, },
+	},
+	.offset = { 0, 512, 512, },
+	.scale = 1,
+	.sat = true,
+};
+
+/*
+ * Inverse REC.709 encoding from YUV full range to RGB full range:
+ *
+ * R = 1. * Y +      0 * (Cb - 128) + 1.5748 * (Cr - 128)
+ * G = 1. * Y -  .1873 * (Cb - 128) -  .4681 * (Cr - 128)
+ * B = 1. * Y + 1.8556 * (Cb - 128) +      0 * (Cr - 128)
+ *
+ * equivalently (factoring out the offsets):
+ *
+ * R = 1. * Y  +      0 * Cb + 1.5748 * Cr - 201.574
+ * G = 1. * Y  -  .1873 * Cb -  .4681 * Cr +  83.891
+ * B = 1. * Y  + 1.8556 * Cb +      0 * Cr - 237.517
+ */
+static const struct ipu_ic_csc_params yuvf2rgbf_709 = {
+	.coeff = {
+		{  128,   0, 202 },
+		{  128, -24, -60 },
+		{  128, 238,   0 },
+	},
+	.offset = { -403, 168, -475 },
+	.scale = 2,
+};
+
+/* Rec.709 YUV full-range to RGB limited-range */
+static const struct ipu_ic_csc_params yuvf2rgbl_709 = {
+	.coeff = {
+		{  110,    0,  173, },
+		{  110,  -21,  -51, },
+		{  110,  204,    0, },
+	},
+	.offset = { -314, 176, -376, },
+	.scale = 2,
+};
+
+/* Rec.709 YUV limited-range to RGB full-range */
+static const struct ipu_ic_csc_params yuvl2rgbf_709 = {
+	.coeff = {
+		{   75,    0,  115, },
+		{   75,  -14,  -34, },
+		{   75,  135,    0, },
+	},
+	.offset = { -248, 77, -289, },
+	.scale = 3,
+};
+
+/* Rec.709 YUV limited-range to RGB limited-range */
+static const struct ipu_ic_csc_params yuvl2rgbl_709 = {
+	.coeff = {
+		{  128,    0,  197, },
+		{  128,  -23,  -59, },
+		{  128,  232,    0, },
+	},
+	.offset = { -394, 164, -464, },
+	.scale = 2,
+};
+
+static const struct ipu_ic_csc_params *rgb2yuv_709[] = {
+	&rgbf2yuvf_709,
+	&rgbf2yuvl_709,
+	&rgbl2yuvf_709,
+	&rgbl2yuvl_709,
+};
+
+static const struct ipu_ic_csc_params *yuv2rgb_709[] = {
+	&yuvf2rgbf_709,
+	&yuvf2rgbl_709,
+	&yuvl2rgbf_709,
+	&yuvl2rgbl_709,
+};
+
 static int calc_csc_coeffs(struct ipu_ic_csc *csc)
 {
 	const struct ipu_ic_csc_params **params_tbl;
 	int tbl_idx;
 
-	if (csc->out_cs.enc != V4L2_YCBCR_ENC_601)
-		return -ENOTSUPP;
-
 	tbl_idx = (QUANT_MAP(csc->in_cs.quant) << 1) |
 		QUANT_MAP(csc->out_cs.quant);
 
@@ -250,8 +369,18 @@ static int calc_csc_coeffs(struct ipu_ic_csc *csc)
 
 	/* YUV <-> RGB encoding is required */
 
-	params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
-		yuv2rgb_601 : rgb2yuv_601;
+	switch (csc->out_cs.enc) {
+	case V4L2_YCBCR_ENC_601:
+		params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
+			yuv2rgb_601 : rgb2yuv_601;
+		break;
+	case V4L2_YCBCR_ENC_709:
+		params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
+			yuv2rgb_709 : rgb2yuv_709;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
 
 	csc->params = *params_tbl[tbl_idx];
 
-- 
2.17.1


  parent reply	other threads:[~2019-05-22  1:03 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20190522010317.23710-1-slongerbeam@gmail.com>
2019-05-22  1:03 ` [PATCH v8 1/5] gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM Steve Longerbeam
2019-05-22  1:03 ` [PATCH v8 2/5] gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Steve Longerbeam
2019-05-22  1:03 ` [PATCH v8 3/5] gpu: ipu-v3: ipu-ic-csc: Add support for limited range encoding Steve Longerbeam
2019-05-22  1:03 ` Steve Longerbeam [this message]
2019-05-22  1:03 ` [PATCH v8 5/5] media: imx: Try colorimetry at both sink and source pads Steve Longerbeam
2019-05-27  9:47   ` Hans Verkuil
2019-06-14 14:10   ` Philipp Zabel
2019-10-22  1:44   ` Laurent Pinchart
2019-10-22  3:26     ` Steve Longerbeam
2019-10-22  3:55       ` Steve Longerbeam
2019-10-22 13:34     ` Rui Miguel Silva
2019-10-22 16:26       ` Steve Longerbeam
2019-10-23  9:07         ` Rui Miguel Silva

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190522010317.23710-5-slongerbeam@gmail.com \
    --to=slongerbeam@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=p.zabel@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).