From: Steve Longerbeam <slongerbeam@gmail.com>
To: linux-media@vger.kernel.org
Cc: open list <linux-kernel@vger.kernel.org>,
"open list:DRM DRIVERS FOR FREESCALE IMX"
<dri-devel@lists.freedesktop.org>,
Steve Longerbeam <slongerbeam@gmail.com>
Subject: [PATCH v8 3/5] gpu: ipu-v3: ipu-ic-csc: Add support for limited range encoding
Date: Tue, 21 May 2019 18:03:15 -0700 [thread overview]
Message-ID: <20190522010317.23710-4-slongerbeam@gmail.com> (raw)
In-Reply-To: <20190522010317.23710-1-slongerbeam@gmail.com>
Add support for encodings to or from limited range quantization.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
Changes in v7:
- hard-code the coefficients instead of deriving the limited range
coefficients from the full2full coefficients on the fly with
fixed-point math.
- add support for RGB limited-range.
---
drivers/gpu/ipu-v3/ipu-ic-csc.c | 180 +++++++++++++++++++++++++++++---
1 file changed, 166 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/ipu-v3/ipu-ic-csc.c b/drivers/gpu/ipu-v3/ipu-ic-csc.c
index 5fb469cd64fe..8e9150b1d668 100644
--- a/drivers/gpu/ipu-v3/ipu-ic-csc.c
+++ b/drivers/gpu/ipu-v3/ipu-ic-csc.c
@@ -10,6 +10,10 @@
#include <linux/sizes.h>
#include "ipu-prv.h"
+#define QUANT_MAP(q) \
+ ((q) == V4L2_QUANTIZATION_FULL_RANGE || \
+ (q) == V4L2_QUANTIZATION_DEFAULT ? 0 : 1)
+
/* identity matrix */
static const struct ipu_ic_csc_params identity = {
.coeff = {
@@ -21,12 +25,87 @@ static const struct ipu_ic_csc_params identity = {
.scale = 2,
};
+/*
+ * RGB full-range to RGB limited-range
+ *
+ * R_lim = 0.8588 * R_full + 16
+ * G_lim = 0.8588 * G_full + 16
+ * B_lim = 0.8588 * B_full + 16
+ */
+static const struct ipu_ic_csc_params rgbf2rgbl = {
+ .coeff = {
+ { 220, 0, 0, },
+ { 0, 220, 0, },
+ { 0, 0, 220, },
+ },
+ .offset = { 64, 64, 64, },
+ .scale = 1,
+};
+
+/*
+ * RGB limited-range to RGB full-range
+ *
+ * R_full = 1.1644 * (R_lim - 16)
+ * G_full = 1.1644 * (G_lim - 16)
+ * B_full = 1.1644 * (B_lim - 16)
+ */
+static const struct ipu_ic_csc_params rgbl2rgbf = {
+ .coeff = {
+ { 149, 0, 0, },
+ { 0, 149, 0, },
+ { 0, 0, 149, },
+ },
+ .offset = { -37, -37, -37, },
+ .scale = 2,
+};
+
+/*
+ * YUV full-range to YUV limited-range
+ *
+ * Y_lim = 0.8588 * Y_full + 16
+ * Cb_lim = 0.8784 * (Cb_full - 128) + 128
+ * Cr_lim = 0.8784 * (Cr_full - 128) + 128
+ */
+static const struct ipu_ic_csc_params yuvf2yuvl = {
+ .coeff = {
+ { 220, 0, 0, },
+ { 0, 225, 0, },
+ { 0, 0, 225, },
+ },
+ .offset = { 64, 62, 62, },
+ .scale = 1,
+ .sat = true,
+};
+
+/*
+ * YUV limited-range to YUV full-range
+ *
+ * Y_full = 1.1644 * (Y_lim - 16)
+ * Cb_full = 1.1384 * (Cb_lim - 128) + 128
+ * Cr_full = 1.1384 * (Cr_lim - 128) + 128
+ */
+static const struct ipu_ic_csc_params yuvl2yuvf = {
+ .coeff = {
+ { 149, 0, 0, },
+ { 0, 146, 0, },
+ { 0, 0, 146, },
+ },
+ .offset = { -37, -35, -35, },
+ .scale = 2,
+};
+
static const struct ipu_ic_csc_params *rgb2rgb[] = {
&identity,
+ &rgbf2rgbl,
+ &rgbl2rgbf,
+ &identity,
};
static const struct ipu_ic_csc_params *yuv2yuv[] = {
&identity,
+ &yuvf2yuvl,
+ &yuvl2yuvf,
+ &identity,
};
/*
@@ -46,6 +125,41 @@ static const struct ipu_ic_csc_params rgbf2yuvf_601 = {
.scale = 1,
};
+/* BT.601 RGB full-range to YUV limited-range */
+static const struct ipu_ic_csc_params rgbf2yuvl_601 = {
+ .coeff = {
+ { 66, 129, 25, },
+ { -38, -74, 112, },
+ { 112, -94, -18, },
+ },
+ .offset = { 64, 512, 512, },
+ .scale = 1,
+ .sat = true,
+};
+
+/* BT.601 RGB limited-range to YUV full-range */
+static const struct ipu_ic_csc_params rgbl2yuvf_601 = {
+ .coeff = {
+ { 89, 175, 34, },
+ { -50, -99, 149, },
+ { 149, -125, -24, },
+ },
+ .offset = { -75, 512, 512, },
+ .scale = 1,
+};
+
+/* BT.601 RGB limited-range to YUV limited-range */
+static const struct ipu_ic_csc_params rgbl2yuvl_601 = {
+ .coeff = {
+ { 77, 150, 29, },
+ { -44, -87, 131, },
+ { 131, -110, -21, },
+ },
+ .offset = { 0, 512, 512, },
+ .scale = 1,
+ .sat = true,
+};
+
/*
* BT.601 YUV full-range to RGB full-range
*
@@ -69,39 +183,77 @@ static const struct ipu_ic_csc_params yuvf2rgbf_601 = {
.scale = 2,
};
+/* BT.601 YUV full-range to RGB limited-range */
+static const struct ipu_ic_csc_params yuvf2rgbl_601 = {
+ .coeff = {
+ { 110, 0, 154, },
+ { 110, -38, -78, },
+ { 110, 195, 0, },
+ },
+ .offset = { -276, 265, -358, },
+ .scale = 2,
+};
+
+/* BT.601 YUV limited-range to RGB full-range */
+static const struct ipu_ic_csc_params yuvl2rgbf_601 = {
+ .coeff = {
+ { 75, 0, 102, },
+ { 75, -25, -52, },
+ { 75, 129, 0, },
+ },
+ .offset = { -223, 136, -277, },
+ .scale = 3,
+};
+
+/* BT.601 YUV limited-range to RGB limited-range */
+static const struct ipu_ic_csc_params yuvl2rgbl_601 = {
+ .coeff = {
+ { 128, 0, 175, },
+ { 128, -43, -89, },
+ { 128, 222, 0, },
+ },
+ .offset = { -351, 265, -443, },
+ .scale = 2,
+};
+
static const struct ipu_ic_csc_params *rgb2yuv_601[] = {
&rgbf2yuvf_601,
+ &rgbf2yuvl_601,
+ &rgbl2yuvf_601,
+ &rgbl2yuvl_601,
};
static const struct ipu_ic_csc_params *yuv2rgb_601[] = {
&yuvf2rgbf_601,
+ &yuvf2rgbl_601,
+ &yuvl2rgbf_601,
+ &yuvl2rgbl_601,
};
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;
- if ((csc->in_cs.cs == IPUV3_COLORSPACE_YUV &&
- csc->in_cs.quant != V4L2_QUANTIZATION_FULL_RANGE) ||
- (csc->out_cs.cs == IPUV3_COLORSPACE_YUV &&
- csc->out_cs.quant != V4L2_QUANTIZATION_FULL_RANGE))
- return -ENOTSUPP;
-
- if ((csc->in_cs.cs == IPUV3_COLORSPACE_RGB &&
- csc->in_cs.quant != V4L2_QUANTIZATION_FULL_RANGE) ||
- (csc->out_cs.cs == IPUV3_COLORSPACE_RGB &&
- csc->out_cs.quant != V4L2_QUANTIZATION_FULL_RANGE))
- return -ENOTSUPP;
+ tbl_idx = (QUANT_MAP(csc->in_cs.quant) << 1) |
+ QUANT_MAP(csc->out_cs.quant);
if (csc->in_cs.cs == csc->out_cs.cs) {
csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
- *yuv2yuv[0] : *rgb2rgb[0];
+ *yuv2yuv[tbl_idx] : *rgb2rgb[tbl_idx];
+
return 0;
}
- csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
- *yuv2rgb_601[0] : *rgb2yuv_601[0];
+ /* YUV <-> RGB encoding is required */
+
+ params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
+ yuv2rgb_601 : rgb2yuv_601;
+
+ csc->params = *params_tbl[tbl_idx];
return 0;
}
--
2.17.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
WARNING: multiple messages have this Message-ID (diff)
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 3/5] gpu: ipu-v3: ipu-ic-csc: Add support for limited range encoding
Date: Tue, 21 May 2019 18:03:15 -0700 [thread overview]
Message-ID: <20190522010317.23710-4-slongerbeam@gmail.com> (raw)
In-Reply-To: <20190522010317.23710-1-slongerbeam@gmail.com>
Add support for encodings to or from limited range quantization.
Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com>
---
Changes in v7:
- hard-code the coefficients instead of deriving the limited range
coefficients from the full2full coefficients on the fly with
fixed-point math.
- add support for RGB limited-range.
---
drivers/gpu/ipu-v3/ipu-ic-csc.c | 180 +++++++++++++++++++++++++++++---
1 file changed, 166 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/ipu-v3/ipu-ic-csc.c b/drivers/gpu/ipu-v3/ipu-ic-csc.c
index 5fb469cd64fe..8e9150b1d668 100644
--- a/drivers/gpu/ipu-v3/ipu-ic-csc.c
+++ b/drivers/gpu/ipu-v3/ipu-ic-csc.c
@@ -10,6 +10,10 @@
#include <linux/sizes.h>
#include "ipu-prv.h"
+#define QUANT_MAP(q) \
+ ((q) == V4L2_QUANTIZATION_FULL_RANGE || \
+ (q) == V4L2_QUANTIZATION_DEFAULT ? 0 : 1)
+
/* identity matrix */
static const struct ipu_ic_csc_params identity = {
.coeff = {
@@ -21,12 +25,87 @@ static const struct ipu_ic_csc_params identity = {
.scale = 2,
};
+/*
+ * RGB full-range to RGB limited-range
+ *
+ * R_lim = 0.8588 * R_full + 16
+ * G_lim = 0.8588 * G_full + 16
+ * B_lim = 0.8588 * B_full + 16
+ */
+static const struct ipu_ic_csc_params rgbf2rgbl = {
+ .coeff = {
+ { 220, 0, 0, },
+ { 0, 220, 0, },
+ { 0, 0, 220, },
+ },
+ .offset = { 64, 64, 64, },
+ .scale = 1,
+};
+
+/*
+ * RGB limited-range to RGB full-range
+ *
+ * R_full = 1.1644 * (R_lim - 16)
+ * G_full = 1.1644 * (G_lim - 16)
+ * B_full = 1.1644 * (B_lim - 16)
+ */
+static const struct ipu_ic_csc_params rgbl2rgbf = {
+ .coeff = {
+ { 149, 0, 0, },
+ { 0, 149, 0, },
+ { 0, 0, 149, },
+ },
+ .offset = { -37, -37, -37, },
+ .scale = 2,
+};
+
+/*
+ * YUV full-range to YUV limited-range
+ *
+ * Y_lim = 0.8588 * Y_full + 16
+ * Cb_lim = 0.8784 * (Cb_full - 128) + 128
+ * Cr_lim = 0.8784 * (Cr_full - 128) + 128
+ */
+static const struct ipu_ic_csc_params yuvf2yuvl = {
+ .coeff = {
+ { 220, 0, 0, },
+ { 0, 225, 0, },
+ { 0, 0, 225, },
+ },
+ .offset = { 64, 62, 62, },
+ .scale = 1,
+ .sat = true,
+};
+
+/*
+ * YUV limited-range to YUV full-range
+ *
+ * Y_full = 1.1644 * (Y_lim - 16)
+ * Cb_full = 1.1384 * (Cb_lim - 128) + 128
+ * Cr_full = 1.1384 * (Cr_lim - 128) + 128
+ */
+static const struct ipu_ic_csc_params yuvl2yuvf = {
+ .coeff = {
+ { 149, 0, 0, },
+ { 0, 146, 0, },
+ { 0, 0, 146, },
+ },
+ .offset = { -37, -35, -35, },
+ .scale = 2,
+};
+
static const struct ipu_ic_csc_params *rgb2rgb[] = {
&identity,
+ &rgbf2rgbl,
+ &rgbl2rgbf,
+ &identity,
};
static const struct ipu_ic_csc_params *yuv2yuv[] = {
&identity,
+ &yuvf2yuvl,
+ &yuvl2yuvf,
+ &identity,
};
/*
@@ -46,6 +125,41 @@ static const struct ipu_ic_csc_params rgbf2yuvf_601 = {
.scale = 1,
};
+/* BT.601 RGB full-range to YUV limited-range */
+static const struct ipu_ic_csc_params rgbf2yuvl_601 = {
+ .coeff = {
+ { 66, 129, 25, },
+ { -38, -74, 112, },
+ { 112, -94, -18, },
+ },
+ .offset = { 64, 512, 512, },
+ .scale = 1,
+ .sat = true,
+};
+
+/* BT.601 RGB limited-range to YUV full-range */
+static const struct ipu_ic_csc_params rgbl2yuvf_601 = {
+ .coeff = {
+ { 89, 175, 34, },
+ { -50, -99, 149, },
+ { 149, -125, -24, },
+ },
+ .offset = { -75, 512, 512, },
+ .scale = 1,
+};
+
+/* BT.601 RGB limited-range to YUV limited-range */
+static const struct ipu_ic_csc_params rgbl2yuvl_601 = {
+ .coeff = {
+ { 77, 150, 29, },
+ { -44, -87, 131, },
+ { 131, -110, -21, },
+ },
+ .offset = { 0, 512, 512, },
+ .scale = 1,
+ .sat = true,
+};
+
/*
* BT.601 YUV full-range to RGB full-range
*
@@ -69,39 +183,77 @@ static const struct ipu_ic_csc_params yuvf2rgbf_601 = {
.scale = 2,
};
+/* BT.601 YUV full-range to RGB limited-range */
+static const struct ipu_ic_csc_params yuvf2rgbl_601 = {
+ .coeff = {
+ { 110, 0, 154, },
+ { 110, -38, -78, },
+ { 110, 195, 0, },
+ },
+ .offset = { -276, 265, -358, },
+ .scale = 2,
+};
+
+/* BT.601 YUV limited-range to RGB full-range */
+static const struct ipu_ic_csc_params yuvl2rgbf_601 = {
+ .coeff = {
+ { 75, 0, 102, },
+ { 75, -25, -52, },
+ { 75, 129, 0, },
+ },
+ .offset = { -223, 136, -277, },
+ .scale = 3,
+};
+
+/* BT.601 YUV limited-range to RGB limited-range */
+static const struct ipu_ic_csc_params yuvl2rgbl_601 = {
+ .coeff = {
+ { 128, 0, 175, },
+ { 128, -43, -89, },
+ { 128, 222, 0, },
+ },
+ .offset = { -351, 265, -443, },
+ .scale = 2,
+};
+
static const struct ipu_ic_csc_params *rgb2yuv_601[] = {
&rgbf2yuvf_601,
+ &rgbf2yuvl_601,
+ &rgbl2yuvf_601,
+ &rgbl2yuvl_601,
};
static const struct ipu_ic_csc_params *yuv2rgb_601[] = {
&yuvf2rgbf_601,
+ &yuvf2rgbl_601,
+ &yuvl2rgbf_601,
+ &yuvl2rgbl_601,
};
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;
- if ((csc->in_cs.cs == IPUV3_COLORSPACE_YUV &&
- csc->in_cs.quant != V4L2_QUANTIZATION_FULL_RANGE) ||
- (csc->out_cs.cs == IPUV3_COLORSPACE_YUV &&
- csc->out_cs.quant != V4L2_QUANTIZATION_FULL_RANGE))
- return -ENOTSUPP;
-
- if ((csc->in_cs.cs == IPUV3_COLORSPACE_RGB &&
- csc->in_cs.quant != V4L2_QUANTIZATION_FULL_RANGE) ||
- (csc->out_cs.cs == IPUV3_COLORSPACE_RGB &&
- csc->out_cs.quant != V4L2_QUANTIZATION_FULL_RANGE))
- return -ENOTSUPP;
+ tbl_idx = (QUANT_MAP(csc->in_cs.quant) << 1) |
+ QUANT_MAP(csc->out_cs.quant);
if (csc->in_cs.cs == csc->out_cs.cs) {
csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
- *yuv2yuv[0] : *rgb2rgb[0];
+ *yuv2yuv[tbl_idx] : *rgb2rgb[tbl_idx];
+
return 0;
}
- csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
- *yuv2rgb_601[0] : *rgb2yuv_601[0];
+ /* YUV <-> RGB encoding is required */
+
+ params_tbl = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
+ yuv2rgb_601 : rgb2yuv_601;
+
+ csc->params = *params_tbl[tbl_idx];
return 0;
}
--
2.17.1
next prev parent reply other threads:[~2019-05-22 1:03 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-22 1:03 [PATCH v8 0/5] media: imx: Add Rec.709 and limited range encoding support Steve Longerbeam
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 ` 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 ` Steve Longerbeam
2019-05-22 1:03 ` Steve Longerbeam
2019-05-22 1:03 ` Steve Longerbeam
2019-05-22 1:03 ` Steve Longerbeam [this message]
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 ` [PATCH v8 4/5] gpu: ipu-v3: ipu-ic-csc: Add support for Rec.709 encoding Steve Longerbeam
2019-05-22 1:03 ` Steve Longerbeam
2019-05-22 1:03 ` [PATCH v8 5/5] media: imx: Try colorimetry at both sink and source pads Steve Longerbeam
2019-05-22 1:03 ` Steve Longerbeam
2019-05-27 9:47 ` Hans Verkuil
2019-05-27 9:47 ` Hans Verkuil
2019-06-14 14:10 ` Philipp Zabel
2019-06-14 14:10 ` Philipp Zabel
2019-10-22 1:44 ` Laurent Pinchart
2019-10-22 1:44 ` Laurent Pinchart
2019-10-22 3:26 ` Steve Longerbeam
2019-10-22 3:26 ` Steve Longerbeam
2019-10-22 3:55 ` Steve Longerbeam
2019-10-22 3:55 ` Steve Longerbeam
2019-10-22 13:34 ` Rui Miguel Silva
2019-10-22 13:34 ` Rui Miguel Silva
2019-10-22 16:26 ` Steve Longerbeam
2019-10-22 16:26 ` Steve Longerbeam
2019-10-23 9:07 ` Rui Miguel Silva
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-4-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 \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.