Commit 357a856a authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: v4l2-dv-timings: add v4l2_hdmi_colorimetry()

Add the v4l2_hdmi_colorimetry() function so we have a single function
that determines the colorspace, YCbCr encoding, quantization range and
transfer function from the InfoFrame data.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent bd2a0f08
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/v4l2-dv-timings.h> #include <linux/v4l2-dv-timings.h>
#include <media/v4l2-dv-timings.h> #include <media/v4l2-dv-timings.h>
#include <linux/math64.h> #include <linux/math64.h>
#include <linux/hdmi.h>
MODULE_AUTHOR("Hans Verkuil"); MODULE_AUTHOR("Hans Verkuil");
MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions"); MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions");
...@@ -801,3 +802,143 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait) ...@@ -801,3 +802,143 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait)
return aspect; return aspect;
} }
EXPORT_SYMBOL_GPL(v4l2_calc_aspect_ratio); EXPORT_SYMBOL_GPL(v4l2_calc_aspect_ratio);
/** v4l2_hdmi_rx_colorimetry - determine HDMI colorimetry information
* based on various InfoFrames.
* @avi: the AVI InfoFrame
* @hdmi: the HDMI Vendor InfoFrame, may be NULL
* @height: the frame height
*
* Determines the HDMI colorimetry information, i.e. how the HDMI
* pixel color data should be interpreted.
*
* Note that some of the newer features (DCI-P3, HDR) are not yet
* implemented: the hdmi.h header needs to be updated to the HDMI 2.0
* and CTA-861-G standards.
*/
struct v4l2_hdmi_colorimetry
v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
const struct hdmi_vendor_infoframe *hdmi,
unsigned int height)
{
struct v4l2_hdmi_colorimetry c = {
V4L2_COLORSPACE_SRGB,
V4L2_YCBCR_ENC_DEFAULT,
V4L2_QUANTIZATION_FULL_RANGE,
V4L2_XFER_FUNC_SRGB
};
bool is_ce = avi->video_code || (hdmi && hdmi->vic);
bool is_sdtv = height <= 576;
bool default_is_lim_range_rgb = avi->video_code > 1;
switch (avi->colorspace) {
case HDMI_COLORSPACE_RGB:
/* RGB pixel encoding */
switch (avi->colorimetry) {
case HDMI_COLORIMETRY_EXTENDED:
switch (avi->extended_colorimetry) {
case HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB:
c.colorspace = V4L2_COLORSPACE_ADOBERGB;
c.xfer_func = V4L2_XFER_FUNC_ADOBERGB;
break;
case HDMI_EXTENDED_COLORIMETRY_BT2020:
c.colorspace = V4L2_COLORSPACE_BT2020;
c.xfer_func = V4L2_XFER_FUNC_709;
break;
default:
break;
}
break;
default:
break;
}
switch (avi->quantization_range) {
case HDMI_QUANTIZATION_RANGE_LIMITED:
c.quantization = V4L2_QUANTIZATION_LIM_RANGE;
break;
case HDMI_QUANTIZATION_RANGE_FULL:
break;
default:
if (default_is_lim_range_rgb)
c.quantization = V4L2_QUANTIZATION_LIM_RANGE;
break;
}
break;
default:
/* YCbCr pixel encoding */
c.quantization = V4L2_QUANTIZATION_LIM_RANGE;
switch (avi->colorimetry) {
case HDMI_COLORIMETRY_NONE:
if (!is_ce)
break;
if (is_sdtv) {
c.colorspace = V4L2_COLORSPACE_SMPTE170M;
c.ycbcr_enc = V4L2_YCBCR_ENC_601;
} else {
c.colorspace = V4L2_COLORSPACE_REC709;
c.ycbcr_enc = V4L2_YCBCR_ENC_709;
}
c.xfer_func = V4L2_XFER_FUNC_709;
break;
case HDMI_COLORIMETRY_ITU_601:
c.colorspace = V4L2_COLORSPACE_SMPTE170M;
c.ycbcr_enc = V4L2_YCBCR_ENC_601;
c.xfer_func = V4L2_XFER_FUNC_709;
break;
case HDMI_COLORIMETRY_ITU_709:
c.colorspace = V4L2_COLORSPACE_REC709;
c.ycbcr_enc = V4L2_YCBCR_ENC_709;
c.xfer_func = V4L2_XFER_FUNC_709;
break;
case HDMI_COLORIMETRY_EXTENDED:
switch (avi->extended_colorimetry) {
case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601:
c.colorspace = V4L2_COLORSPACE_REC709;
c.ycbcr_enc = V4L2_YCBCR_ENC_XV709;
c.xfer_func = V4L2_XFER_FUNC_709;
break;
case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709:
c.colorspace = V4L2_COLORSPACE_REC709;
c.ycbcr_enc = V4L2_YCBCR_ENC_XV601;
c.xfer_func = V4L2_XFER_FUNC_709;
break;
case HDMI_EXTENDED_COLORIMETRY_S_YCC_601:
c.colorspace = V4L2_COLORSPACE_SRGB;
c.ycbcr_enc = V4L2_YCBCR_ENC_601;
c.xfer_func = V4L2_XFER_FUNC_SRGB;
break;
case HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601:
c.colorspace = V4L2_COLORSPACE_ADOBERGB;
c.ycbcr_enc = V4L2_YCBCR_ENC_601;
c.xfer_func = V4L2_XFER_FUNC_ADOBERGB;
break;
case HDMI_EXTENDED_COLORIMETRY_BT2020:
c.colorspace = V4L2_COLORSPACE_BT2020;
c.ycbcr_enc = V4L2_YCBCR_ENC_BT2020;
c.xfer_func = V4L2_XFER_FUNC_709;
break;
case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM:
c.colorspace = V4L2_COLORSPACE_BT2020;
c.ycbcr_enc = V4L2_YCBCR_ENC_BT2020_CONST_LUM;
c.xfer_func = V4L2_XFER_FUNC_709;
break;
default: /* fall back to ITU_709 */
c.colorspace = V4L2_COLORSPACE_REC709;
c.ycbcr_enc = V4L2_YCBCR_ENC_709;
c.xfer_func = V4L2_XFER_FUNC_709;
break;
}
break;
default:
break;
}
/*
* YCC Quantization Range signaling is more-or-less broken,
* let's just ignore this.
*/
break;
}
return c;
}
EXPORT_SYMBOL_GPL(v4l2_hdmi_rx_colorimetry);
...@@ -212,5 +212,26 @@ static inline bool can_reduce_fps(struct v4l2_bt_timings *bt) ...@@ -212,5 +212,26 @@ static inline bool can_reduce_fps(struct v4l2_bt_timings *bt)
return false; return false;
} }
/**
* struct v4l2_hdmi_rx_colorimetry - describes the HDMI colorimetry information
* @colorspace: enum v4l2_colorspace, the colorspace
* @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
* @quantization: enum v4l2_quantization, colorspace quantization
* @xfer_func: enum v4l2_xfer_func, colorspace transfer function
*/
struct v4l2_hdmi_colorimetry {
enum v4l2_colorspace colorspace;
enum v4l2_ycbcr_encoding ycbcr_enc;
enum v4l2_quantization quantization;
enum v4l2_xfer_func xfer_func;
};
struct hdmi_avi_infoframe;
struct hdmi_vendor_infoframe;
struct v4l2_hdmi_colorimetry
v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
const struct hdmi_vendor_infoframe *hdmi,
unsigned int height);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment