linux/drivers/gpu/ipu-v3/ipu-ic-csc.c

410 lines
8.9 KiB
C
Raw Normal View History

gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Mentor Graphics Inc.
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/sizes.h>
#include "ipu-prv.h"
#define QUANT_MAP(q) \
((q) == V4L2_QUANTIZATION_FULL_RANGE || \
(q) == V4L2_QUANTIZATION_DEFAULT ? 0 : 1)
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
/* identity matrix */
static const struct ipu_ic_csc_params identity = {
.coeff = {
{ 128, 0, 0, },
{ 0, 128, 0, },
{ 0, 0, 128, },
},
.offset = { 0, 0, 0, },
.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,
};
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
static const struct ipu_ic_csc_params *rgb2rgb[] = {
&identity,
&rgbf2rgbl,
&rgbl2rgbf,
&identity,
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
};
static const struct ipu_ic_csc_params *yuv2yuv[] = {
&identity,
&yuvf2yuvl,
&yuvl2yuvf,
&identity,
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
};
/*
* BT.601 RGB full-range to YUV full-range
*
* Y = .2990 * R + .5870 * G + .1140 * B
* U = -.1687 * R - .3313 * G + .5000 * B + 128
* V = .5000 * R - .4187 * G - .0813 * B + 128
*/
static const struct ipu_ic_csc_params rgbf2yuvf_601 = {
.coeff = {
{ 77, 150, 29, },
{ -43, -85, 128, },
{ 128, -107, -21, },
},
.offset = { 0, 512, 512, },
.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,
};
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
/*
* BT.601 YUV full-range to RGB full-range
*
* R = 1. * Y + 0 * (Cb - 128) + 1.4020 * (Cr - 128)
* G = 1. * Y - .3441 * (Cb - 128) - .7141 * (Cr - 128)
* B = 1. * Y + 1.7720 * (Cb - 128) + 0 * (Cr - 128)
*
* equivalently (factoring out the offsets):
*
* R = 1. * Y + 0 * Cb + 1.4020 * Cr - 179.456
* G = 1. * Y - .3441 * Cb - .7141 * Cr + 135.450
* B = 1. * Y + 1.7720 * Cb + 0 * Cr - 226.816
*/
static const struct ipu_ic_csc_params yuvf2rgbf_601 = {
.coeff = {
{ 128, 0, 179, },
{ 128, -44, -91, },
{ 128, 227, 0, },
},
.offset = { -359, 271, -454, },
.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,
};
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
static const struct ipu_ic_csc_params *rgb2yuv_601[] = {
&rgbf2yuvf_601,
&rgbf2yuvl_601,
&rgbl2yuvf_601,
&rgbl2yuvl_601,
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
};
static const struct ipu_ic_csc_params *yuv2rgb_601[] = {
&yuvf2rgbf_601,
&yuvf2rgbl_601,
&yuvl2rgbf_601,
&yuvl2rgbl_601,
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
};
/*
* 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,
};
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
static int calc_csc_coeffs(struct ipu_ic_csc *csc)
{
const struct ipu_ic_csc_params **params_tbl;
int tbl_idx;
tbl_idx = (QUANT_MAP(csc->in_cs.quant) << 1) |
QUANT_MAP(csc->out_cs.quant);
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
if (csc->in_cs.cs == csc->out_cs.cs) {
csc->params = (csc->in_cs.cs == IPUV3_COLORSPACE_YUV) ?
*yuv2yuv[tbl_idx] : *rgb2rgb[tbl_idx];
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
return 0;
}
/* YUV <-> RGB encoding is required */
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];
gpu: ipu-v3: ipu-ic: Fully describe colorspace conversions Only providing the input and output RGB/YUV space to the IC task init functions is not sufficient. To fully characterize a colorspace conversion, the Y'CbCr encoding standard, and quantization also need to be specified. Define a 'struct ipu_ic_colorspace' that includes all the above. This allows to actually enforce the fact that the IC: - can only encode to/from YUV and RGB full range. A follow-up patch will remove this restriction. - can only encode using BT.601 standard. A follow-up patch will add Rec.709 encoding support. The determination of the CSC coefficients based on the input/output 'struct ipu_ic_colorspace' are moved to a new exported function ipu_ic_calc_csc(), and 'struct ic_csc_params' is exported as 'struct ipu_ic_csc_params'. ipu_ic_calc_csc() fills a 'struct ipu_ic_csc' with the input/output 'struct ipu_ic_colorspace' and the calculated 'struct ic_csc_params' from those input/output colorspaces. The functions ipu_ic_task_init(_rsc)() now take a filled 'struct ipu_ic_csc'. The existing CSC coefficient tables and ipu_ic_calc_csc() are moved to a new module ipu-ic-csc.c. This is in preparation for adding more coefficient tables for limited range quantization and more encoding standards. The existing ycbcr2rgb and inverse rgb2ycbcr tables defined the BT.601 Y'CbCr encoding coefficients. The rgb2ycbcr table specifically described the BT.601 encoding from full range RGB to full range YUV. Table comments have been added in ipu-ic-csc.c to make this more clear. The ycbcr2rgb inverse table described encoding YUV limited range to RGB full range. To be consistent with the rgb2ycbcr table, this table is converted to YUV full range to RGB full range, and the comments are expanded in ipu-ic-csc.c. The ic_csc_rgb2rgb table was just an identity matrix, so it is renamed 'identity' in ipu-ic-csc.c. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> [p.zabel@pengutronix.de: removed a superfluous blank line] Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
2019-05-22 09:03:14 +08:00
return 0;
}
int __ipu_ic_calc_csc(struct ipu_ic_csc *csc)
{
return calc_csc_coeffs(csc);
}
EXPORT_SYMBOL_GPL(__ipu_ic_calc_csc);
int ipu_ic_calc_csc(struct ipu_ic_csc *csc,
enum v4l2_ycbcr_encoding in_enc,
enum v4l2_quantization in_quant,
enum ipu_color_space in_cs,
enum v4l2_ycbcr_encoding out_enc,
enum v4l2_quantization out_quant,
enum ipu_color_space out_cs)
{
ipu_ic_fill_colorspace(&csc->in_cs, in_enc, in_quant, in_cs);
ipu_ic_fill_colorspace(&csc->out_cs, out_enc, out_quant, out_cs);
return __ipu_ic_calc_csc(csc);
}
EXPORT_SYMBOL_GPL(ipu_ic_calc_csc);