mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 13:58:04 +02:00
amd/vpelib: Luma AND Color Keyer Full Support
[New] - Added new vpe_stream params for color keying - Added new struct in dpp to capture keying params - Added new capability for color keying - Added keying support in vpe1.0 [Updated] - Updated capability check - Updated Luma and Color Keying functions to better implement the entire feature - Updated resource to map stream params -> dpp keyer param Reviewed-by: Roy Chan <Roy.Chan@amd.com> Acked-by: Chih-Wei Chien <Chih-Wei.Chien@amd.com> Signed-off-by: Evan <evan.damphousse@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31605>
This commit is contained in:
parent
338760d9b5
commit
3ef8e6a6ae
7 changed files with 174 additions and 36 deletions
|
|
@ -69,6 +69,8 @@ enum vpe_status {
|
|||
VPE_STATUS_ALPHA_BLENDING_NOT_SUPPORTED, /**< Alpha blending is not supported. */
|
||||
VPE_STATUS_VIEWPORT_SIZE_NOT_SUPPORTED, /**< Given viewport size is not supported. */
|
||||
VPE_STATUS_LUMA_KEYING_NOT_SUPPORTED, /**< Luma keying is not supported. */
|
||||
VPE_STATUS_COLOR_KEYING_NOT_SUPPORTED, /**< Color keying is not supported. */
|
||||
VPE_STATUS_INVALID_KEYER_CONFIG, /**< Keying config is invalid. */
|
||||
VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED, /**< Given plane address is not supported. */
|
||||
VPE_STATUS_ADJUSTMENT_NOT_SUPPORTED, /**< Color adjustment is not supported. */
|
||||
VPE_STATUS_CMD_OVERFLOW_ERROR, /**< More than 256 commands/jobs. */
|
||||
|
|
@ -161,6 +163,7 @@ struct vpe_rom_curve_caps {
|
|||
struct dpp_color_caps {
|
||||
uint32_t pre_csc : 1;
|
||||
uint32_t luma_key : 1;
|
||||
uint32_t color_key : 1;
|
||||
uint32_t dgam_ram : 1;
|
||||
uint32_t post_csc : 1; /**< before gamut remap */
|
||||
uint32_t gamma_corr : 1;
|
||||
|
|
@ -727,6 +730,33 @@ struct vpe_tonemap_params {
|
|||
bool enable_3dlut; /**< Enable/Disable 3D-LUT */
|
||||
};
|
||||
|
||||
/** @enum vpe_keyer_mode
|
||||
* @brief Dictates the behavior of keyer's generated alpha
|
||||
*/
|
||||
enum vpe_keyer_mode {
|
||||
VPE_KEYER_MODE_RANGE_00 = 0, /**< (Default) if in range -> generated alpha = 00 */
|
||||
VPE_KEYER_MODE_RANGE_FF, /**< if in_range -> generated alpha = FF */
|
||||
VPE_KEYER_MODE_FORCE_00, /**< ignore range setting, force generating alpha = 00 */
|
||||
VPE_KEYER_MODE_FORCE_FF, /**< ignore range setting, force generating alpha = FF */
|
||||
};
|
||||
|
||||
/** @enum vpe_color_keyer
|
||||
* @brief Input Parameters for Color keyer.
|
||||
* bounds should be programmed to 0.0 <= 1.0, with lower < upper
|
||||
* if format does not have alpha (RGBx) when using the color keyer, alpha should be programmed to
|
||||
* lower=0.0, upper=1.0
|
||||
*/
|
||||
struct vpe_color_keyer {
|
||||
bool enable_color_key; /**< Enable Color Key. Mutually Exclusive with Luma Key */
|
||||
float lower_g_bound; /**< Green Low Bound. */
|
||||
float upper_g_bound; /**< Green High Bound. */
|
||||
float lower_b_bound; /**< Blue Low Bound. */
|
||||
float upper_b_bound; /**< Blue High Bound. */
|
||||
float lower_r_bound; /**< Red Low Bound. */
|
||||
float upper_r_bound; /**< Red High Bound. */
|
||||
float lower_a_bound; /**< Alpha Low Bound. Program 0.0f if no alpha channel in input format.*/
|
||||
float upper_a_bound; /**< Alpha High Bound. Program 1.0f if no alpha channel in input format.*/
|
||||
};
|
||||
/** @struct vpe_stream
|
||||
* @brief Input stream/frame properties to be passed to vpelib
|
||||
*/
|
||||
|
|
@ -756,6 +786,10 @@ struct vpe_stream {
|
|||
*/
|
||||
float lower_luma_bound; /**< Lowest range of the luma */
|
||||
float upper_luma_bound; /**< Highest range of the luma */
|
||||
struct vpe_color_keyer color_keyer; /**< Enable Luma Keying & Set Parameters. */
|
||||
enum vpe_keyer_mode keyer_mode; /**< Set Keyer Behavior.
|
||||
* Used for both Luma & Color Keying.
|
||||
*/
|
||||
struct vpe_reserved_param reserved_param;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -870,7 +870,11 @@ void vpe10_dpp_cnv_program_pre_dgam(struct dpp *dpp, enum color_transfer_func tr
|
|||
|
||||
void vpe10_dpp_program_cnv_bias_scale(struct dpp *dpp, struct bias_and_scale *bias_and_scale);
|
||||
|
||||
void vpe10_dpp_cnv_program_alpha_keyer(struct dpp *dpp, enum vpe_surface_pixel_format format, bool enable_luma_key, float lower_luma_bound, float upper_luma_bound);
|
||||
void vpe10_dpp_build_keyer_params(
|
||||
struct dpp *dpp, const struct stream_ctx *stream_ctx, struct cnv_keyer_params *keyer_params);
|
||||
|
||||
void vpe10_dpp_cnv_program_alpha_keyer(
|
||||
struct dpp *dpp, const struct cnv_keyer_params *keyer_params);
|
||||
|
||||
void vpe10_dpp_program_input_transfer_func(struct dpp *dpp, struct transfer_func *input_tf);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ static struct dpp_funcs vpe10_dpp_funcs = {
|
|||
.program_cnv = vpe10_dpp_program_cnv,
|
||||
.program_pre_dgam = vpe10_dpp_cnv_program_pre_dgam,
|
||||
.program_cnv_bias_scale = vpe10_dpp_program_cnv_bias_scale,
|
||||
.build_keyer_params = vpe10_dpp_build_keyer_params,
|
||||
.program_alpha_keyer = vpe10_dpp_cnv_program_alpha_keyer,
|
||||
.program_crc = vpe10_dpp_program_crc,
|
||||
|
||||
|
|
@ -346,37 +347,88 @@ void vpe10_dpp_cnv_program_pre_dgam(struct dpp *dpp, enum color_transfer_func tr
|
|||
VPCNVC_PRE_DEGAM, 0, PRE_DEGAM_MODE, pre_degam_en, PRE_DEGAM_SELECT, degamma_lut_selection);
|
||||
}
|
||||
|
||||
void vpe10_dpp_cnv_program_alpha_keyer(
|
||||
struct dpp *dpp,
|
||||
enum vpe_surface_pixel_format format,
|
||||
bool enable_luma_key,
|
||||
float lower_luma_bound,
|
||||
float upper_luma_bound)
|
||||
/** @brief Build the color Keyer Structure */
|
||||
void vpe10_dpp_build_keyer_params(
|
||||
struct dpp *dpp, const struct stream_ctx *stream_ctx, struct cnv_keyer_params *keyer_params)
|
||||
{
|
||||
uint32_t lower_luma_bound_int = (uint32_t)lower_luma_bound * 65535;
|
||||
uint32_t upper_luma_bound_int = (uint32_t)upper_luma_bound * 65535;
|
||||
if (stream_ctx->stream.enable_luma_key) {
|
||||
keyer_params->keyer_en = 1;
|
||||
keyer_params->is_color_key = 0;
|
||||
keyer_params->keyer_mode = stream_ctx->stream.keyer_mode;
|
||||
|
||||
keyer_params->luma_keyer.lower_luma_bound =
|
||||
(uint16_t)(stream_ctx->stream.lower_luma_bound * 65535);
|
||||
keyer_params->luma_keyer.upper_luma_bound =
|
||||
(uint16_t)(stream_ctx->stream.upper_luma_bound * 65535);
|
||||
} else if (stream_ctx->stream.color_keyer.enable_color_key) {
|
||||
keyer_params->keyer_en = 1;
|
||||
keyer_params->is_color_key = 1;
|
||||
keyer_params->keyer_mode = stream_ctx->stream.keyer_mode;
|
||||
|
||||
keyer_params->color_keyer.color_keyer_green_low =
|
||||
(uint16_t)(stream_ctx->stream.color_keyer.lower_g_bound * 65535);
|
||||
keyer_params->color_keyer.color_keyer_green_high =
|
||||
(uint16_t)(stream_ctx->stream.color_keyer.upper_g_bound * 65535);
|
||||
keyer_params->color_keyer.color_keyer_alpha_low =
|
||||
(uint16_t)(stream_ctx->stream.color_keyer.lower_a_bound * 65535);
|
||||
keyer_params->color_keyer.color_keyer_alpha_high =
|
||||
(uint16_t)(stream_ctx->stream.color_keyer.upper_a_bound * 65535);
|
||||
keyer_params->color_keyer.color_keyer_red_low =
|
||||
(uint16_t)(stream_ctx->stream.color_keyer.lower_r_bound * 65535);
|
||||
keyer_params->color_keyer.color_keyer_red_high =
|
||||
(uint16_t)(stream_ctx->stream.color_keyer.upper_r_bound * 65535);
|
||||
keyer_params->color_keyer.color_keyer_blue_low =
|
||||
(uint16_t)(stream_ctx->stream.color_keyer.lower_b_bound * 65535);
|
||||
keyer_params->color_keyer.color_keyer_blue_high =
|
||||
(uint16_t)(stream_ctx->stream.color_keyer.upper_b_bound * 65535);
|
||||
} else {
|
||||
keyer_params->keyer_en = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Program DPP FCNV Keyer
|
||||
* if keyer_params.keyer_en -> Program keyer
|
||||
* else program reset default
|
||||
*/
|
||||
void vpe10_dpp_cnv_program_alpha_keyer(struct dpp *dpp, const struct cnv_keyer_params *keyer_params)
|
||||
{
|
||||
PROGRAM_ENTRY();
|
||||
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_CONTROL, 0,
|
||||
COLOR_KEYER_EN, enable_luma_key,
|
||||
COLOR_KEYER_MODE, CNV_COLOR_KEYER_MODE_RANGE_00);
|
||||
if (keyer_params->keyer_en && keyer_params->is_color_key) {
|
||||
uint8_t keyer_mode = 0;
|
||||
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_ALPHA, 0,
|
||||
COLOR_KEYER_ALPHA_LOW, lower_luma_bound_int,
|
||||
COLOR_KEYER_ALPHA_HIGH, upper_luma_bound_int);
|
||||
switch (keyer_params->keyer_mode) {
|
||||
case VPE_KEYER_MODE_FORCE_00:
|
||||
keyer_mode = 0;
|
||||
break;
|
||||
case VPE_KEYER_MODE_FORCE_FF:
|
||||
keyer_mode = 1;
|
||||
break;
|
||||
case VPE_KEYER_MODE_RANGE_FF:
|
||||
keyer_mode = 2;
|
||||
break;
|
||||
case VPE_KEYER_MODE_RANGE_00:
|
||||
default:
|
||||
keyer_mode = 3; // Default Mode VPE_KEYER_MODE_RANGE_00
|
||||
break;
|
||||
}
|
||||
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_RED, 0,
|
||||
COLOR_KEYER_RED_LOW, lower_luma_bound_int,
|
||||
COLOR_KEYER_RED_HIGH, upper_luma_bound_int);
|
||||
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_GREEN, 0,
|
||||
COLOR_KEYER_GREEN_LOW, lower_luma_bound_int,
|
||||
COLOR_KEYER_GREEN_HIGH, upper_luma_bound_int);
|
||||
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_BLUE, 0,
|
||||
COLOR_KEYER_BLUE_LOW, lower_luma_bound_int,
|
||||
COLOR_KEYER_BLUE_HIGH, upper_luma_bound_int);
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_CONTROL, 0, COLOR_KEYER_EN, 1, COLOR_KEYER_MODE, keyer_mode);
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_GREEN, 0, COLOR_KEYER_GREEN_LOW,
|
||||
keyer_params->color_keyer.color_keyer_green_low, COLOR_KEYER_GREEN_HIGH,
|
||||
keyer_params->color_keyer.color_keyer_green_high);
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_BLUE, 0, COLOR_KEYER_BLUE_LOW,
|
||||
keyer_params->color_keyer.color_keyer_blue_low, COLOR_KEYER_BLUE_HIGH,
|
||||
keyer_params->color_keyer.color_keyer_blue_high);
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_RED, 0, COLOR_KEYER_RED_LOW,
|
||||
keyer_params->color_keyer.color_keyer_red_low, COLOR_KEYER_RED_HIGH,
|
||||
keyer_params->color_keyer.color_keyer_red_high);
|
||||
REG_SET_2(VPCNVC_COLOR_KEYER_ALPHA, 0, COLOR_KEYER_ALPHA_LOW,
|
||||
keyer_params->color_keyer.color_keyer_alpha_low, COLOR_KEYER_ALPHA_HIGH,
|
||||
keyer_params->color_keyer.color_keyer_alpha_high);
|
||||
} else {
|
||||
REG_SET_DEFAULT(VPCNVC_COLOR_KEYER_CONTROL);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t vpe10_get_line_buffer_size()
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ static struct vpe_caps caps = {
|
|||
{
|
||||
.pre_csc = 1,
|
||||
.luma_key = 0,
|
||||
.color_key = 1,
|
||||
.dgam_ram = 0,
|
||||
.post_csc = 1,
|
||||
.gamma_corr = 1,
|
||||
|
|
@ -718,6 +719,7 @@ int32_t vpe10_program_frontend(struct vpe_priv *vpe_priv, uint32_t pipe_idx, uin
|
|||
struct mpc *mpc = vpe_priv->resource.mpc[pipe_idx];
|
||||
enum input_csc_select select = INPUT_CSC_SELECT_BYPASS;
|
||||
uint32_t hw_mult = 0;
|
||||
struct cnv_keyer_params keyer_params;
|
||||
struct custom_float_format fmt;
|
||||
|
||||
vpe_priv->fe_cb_ctx.stream_idx = cmd_input->stream_idx;
|
||||
|
|
@ -741,6 +743,9 @@ int32_t vpe10_program_frontend(struct vpe_priv *vpe_priv, uint32_t pipe_idx, uin
|
|||
if (stream_ctx->bias_scale)
|
||||
dpp->funcs->program_cnv_bias_scale(dpp, stream_ctx->bias_scale);
|
||||
|
||||
dpp->funcs->build_keyer_params(dpp, stream_ctx, &keyer_params);
|
||||
dpp->funcs->program_alpha_keyer(dpp, &keyer_params);
|
||||
|
||||
/* If input adjustment exists, program the ICSC with those values. */
|
||||
if (stream_ctx->input_cs) {
|
||||
select = INPUT_CSC_SELECT_ICSC;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ static struct vpe_caps caps = {
|
|||
{
|
||||
.pre_csc = 1,
|
||||
.luma_key = 0,
|
||||
.color_key = 1,
|
||||
.dgam_ram = 0,
|
||||
.post_csc = 1,
|
||||
.gamma_corr = 1,
|
||||
|
|
|
|||
|
|
@ -184,6 +184,12 @@ bool vpe_is_yuv444(enum vpe_surface_pixel_format format)
|
|||
return (vpe_is_yuv444_8(format) || vpe_is_yuv444_10(format));
|
||||
}
|
||||
|
||||
bool vpe_is_yuv(enum vpe_surface_pixel_format format)
|
||||
{
|
||||
return (vpe_is_yuv420(format) ||
|
||||
vpe_is_yuv444(format));
|
||||
}
|
||||
|
||||
static uint8_t vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format, int plane_idx)
|
||||
{
|
||||
switch (format) {
|
||||
|
|
@ -539,12 +545,29 @@ enum vpe_status vpe_check_input_support(struct vpe *vpe, const struct vpe_stream
|
|||
return VPE_STATUS_ROTATION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// luma keying
|
||||
if (stream->enable_luma_key && !vpe->caps->color_caps.dpp.luma_key) {
|
||||
vpe_log("luma keying not supported\n");
|
||||
return VPE_STATUS_LUMA_KEYING_NOT_SUPPORTED;
|
||||
// keying
|
||||
if (stream->enable_luma_key && stream->color_keyer.enable_color_key) {
|
||||
vpe_log("Invalid Keying configuration. Both Luma and Color Keying Enabled\n");
|
||||
return VPE_STATUS_INVALID_KEYER_CONFIG;
|
||||
} else if (stream->enable_luma_key) {
|
||||
if (!vpe->caps->color_caps.dpp.luma_key) {
|
||||
vpe_log("Luma keying not supported\n");
|
||||
return VPE_STATUS_LUMA_KEYING_NOT_SUPPORTED;
|
||||
} else if (!vpe_is_yuv(surface_info->format)) {
|
||||
vpe_log("Invalid Keying configuration. Luma Key Enabled with RGB Input\n");
|
||||
return VPE_STATUS_INVALID_KEYER_CONFIG;
|
||||
}
|
||||
} else if (stream->color_keyer.enable_color_key) {
|
||||
if (!vpe->caps->color_caps.dpp.color_key) {
|
||||
vpe_log("color keying not supported\n");
|
||||
return VPE_STATUS_COLOR_KEYING_NOT_SUPPORTED;
|
||||
} else if (vpe_is_yuv(surface_info->format)) {
|
||||
vpe_log("Invalid Keying configuration. Color Keying Enabled with YUV Input\n");
|
||||
return VPE_STATUS_INVALID_KEYER_CONFIG;
|
||||
}
|
||||
}
|
||||
|
||||
// mirroring
|
||||
if (stream->horizontal_mirror && !vpe->caps->h_mirror_support) {
|
||||
vpe_log("output horizontal mirroring not supported h:%d\n", (int)stream->horizontal_mirror);
|
||||
return VPE_STATUS_MIRROR_NOT_SUPPORTED;
|
||||
|
|
|
|||
|
|
@ -44,11 +44,27 @@ struct cnv_alpha_2bit_lut {
|
|||
int lut3;
|
||||
};
|
||||
|
||||
enum CNV_COLOR_KEYER_MODE {
|
||||
CNV_COLOR_KEYER_MODE_FORCE_00 = 0,
|
||||
CNV_COLOR_KEYER_MODE_FORCE_FF = 1,
|
||||
CNV_COLOR_KEYER_MODE_RANGE_FF = 2,
|
||||
CNV_COLOR_KEYER_MODE_RANGE_00 = 3
|
||||
struct cnv_keyer_params {
|
||||
uint8_t keyer_en;
|
||||
uint8_t is_color_key;
|
||||
enum vpe_keyer_mode keyer_mode;
|
||||
union {
|
||||
struct {
|
||||
uint16_t color_keyer_green_low;
|
||||
uint16_t color_keyer_green_high;
|
||||
uint16_t color_keyer_alpha_low;
|
||||
uint16_t color_keyer_alpha_high;
|
||||
uint16_t color_keyer_red_low;
|
||||
uint16_t color_keyer_red_high;
|
||||
uint16_t color_keyer_blue_low;
|
||||
uint16_t color_keyer_blue_high;
|
||||
} color_keyer;
|
||||
|
||||
struct {
|
||||
uint16_t lower_luma_bound;
|
||||
uint16_t upper_luma_bound;
|
||||
} luma_keyer;
|
||||
};
|
||||
};
|
||||
|
||||
enum input_csc_select {
|
||||
|
|
@ -72,7 +88,10 @@ struct dpp_funcs {
|
|||
|
||||
void (*program_cnv_bias_scale)(struct dpp *dpp, struct bias_and_scale *bias_and_scale);
|
||||
|
||||
void (*program_alpha_keyer)(struct dpp *dpp, enum vpe_surface_pixel_format format, bool enable_luma_key, float lower_luma_bound, float upper_luma_bound);
|
||||
void (*build_keyer_params)(struct dpp *dpp, const struct stream_ctx *stream_ctx,
|
||||
struct cnv_keyer_params *keyer_params);
|
||||
|
||||
void (*program_alpha_keyer)(struct dpp *dpp, const struct cnv_keyer_params *keyer_params);
|
||||
|
||||
void (*program_input_transfer_func)(struct dpp *dpp, struct transfer_func *input_tf);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue