From 945883602de6892d3423de3123045dfab15a927c Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 17 May 2021 18:38:47 -0700 Subject: [PATCH] video: driver: add support to set csc coefficients Add support to honor client enablement of csc custom matrix and set csc coeff to video firmware. Change-Id: I14d702eb7033541aa439bebe11df7fc4aa49ffdb Signed-off-by: Akshata Sahukar --- driver/platform/waipio/src/msm_vidc_waipio.c | 7 +- driver/vidc/inc/msm_vidc_control.h | 2 + driver/vidc/src/msm_venc.c | 6 +- driver/vidc/src/msm_vidc_control.c | 120 +++++++++++++++++++ 4 files changed, 129 insertions(+), 6 deletions(-) diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index 3ba87d8474..91edd95641 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -456,14 +456,15 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { 0, HFI_PROP_CSC}, - /* Needed for control initialization. TODO */ - /* {CSC_CUSTOM_MATRIX, ENC, CODECS_ALL, + {CSC_CUSTOM_MATRIX, ENC, CODECS_ALL, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE, 1, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_CUSTOM_MATRIX, HFI_PROP_CSC_MATRIX, - CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT}, */ + CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT, + {0}, {0}, + NULL, msm_vidc_set_csc_custom_matrix}, {LOWLATENCY_MODE, ENC, H264 | HEVC, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE, diff --git a/driver/vidc/inc/msm_vidc_control.h b/driver/vidc/inc/msm_vidc_control.h index 50ce7c2cb9..30515f2965 100644 --- a/driver/vidc/inc/msm_vidc_control.h +++ b/driver/vidc/inc/msm_vidc_control.h @@ -90,6 +90,8 @@ int msm_vidc_set_stage(void *instance, enum msm_vidc_inst_capability_type cap_id); int msm_vidc_set_pipe(void *instance, enum msm_vidc_inst_capability_type cap_id); +int msm_vidc_set_csc_custom_matrix(void *instance, + enum msm_vidc_inst_capability_type cap_id); int msm_vidc_set_s32(void *instance, enum msm_vidc_inst_capability_type cap_id); int msm_vidc_set_q16(void *instance, diff --git a/driver/vidc/src/msm_venc.c b/driver/vidc/src/msm_venc.c index 689c60ded6..ce6afaebf3 100644 --- a/driver/vidc/src/msm_venc.c +++ b/driver/vidc/src/msm_venc.c @@ -364,7 +364,7 @@ static bool msm_venc_csc_required(struct msm_vidc_inst* inst) /* video hardware supports conversion to REC709 CSC only */ if (in_fmt->fmt.pix_mp.colorspace != out_fmt->fmt.pix_mp.colorspace && - out_fmt->fmt.pix_mp.colorspace == V4L2_COLORSPACE_REC709) + out_fmt->fmt.pix_mp.colorspace == V4L2_COLORSPACE_REC709) return true; return false; @@ -977,11 +977,11 @@ int msm_venc_streamon_output(struct msm_vidc_inst *inst) if (rc) goto error; - rc = msm_vidc_set_v4l2_properties(inst); + rc = msm_venc_set_output_properties(inst); if (rc) goto error; - rc = msm_venc_set_output_properties(inst); + rc = msm_vidc_set_v4l2_properties(inst); if (rc) goto error; diff --git a/driver/vidc/src/msm_vidc_control.c b/driver/vidc/src/msm_vidc_control.c index eb0bc6b8cf..059c31b72f 100644 --- a/driver/vidc/src/msm_vidc_control.c +++ b/driver/vidc/src/msm_vidc_control.c @@ -11,6 +11,7 @@ #include "msm_vidc_internal.h" #include "msm_vidc_driver.h" #include "msm_venc.h" +#include "msm_vidc_platform.h" #define CAP_TO_8BIT_QP(a) { \ if ((a) < 0) \ @@ -2881,6 +2882,125 @@ int msm_vidc_set_blur_resolution(void *instance, return rc; } +static msm_venc_set_csc_coeff(struct msm_vidc_inst *inst, + const char *prop_name, u32 hfi_id, void *payload, + u32 payload_size, u32 row_count, u32 column_count) +{ + int rc = 0; + + i_vpr_h(inst, + "set cap: name: %24s, hard coded %dx%d matrix array\n", + prop_name, row_count, column_count); + rc = venus_hfi_session_property(inst, + hfi_id, + HFI_HOST_FLAGS_NONE, + HFI_PORT_BITSTREAM, + HFI_PAYLOAD_S32_ARRAY, + payload, + payload_size); + if (rc) { + i_vpr_e(inst, + "%s: failed to set %s to fw\n", + __func__, prop_name); + } + + return rc; +} +int msm_vidc_set_csc_custom_matrix(void *instance, + enum msm_vidc_inst_capability_type cap_id) +{ + int rc = 0; + int i; + struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance; + struct msm_vidc_core *core; + struct msm_vidc_csc_coeff *csc_coeff; + s32 matrix_payload[MAX_MATRIX_COEFFS + 2]; + s32 csc_bias_payload[MAX_BIAS_COEFFS + 2]; + s32 csc_limit_payload[MAX_LIMIT_COEFFS + 2]; + + if (!inst || !inst->capabilities || !inst->core) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + core = inst->core; + if (!core->platform) { + d_vpr_e("%s: invalid core platform\n", __func__); + return -EINVAL; + } + csc_coeff = &core->platform->data.csc_data; + + if (!inst->capabilities->cap[cap_id].value || + !inst->capabilities->cap[CSC].value) { + i_vpr_h(inst, + "%s: ignored as custom martix %u, csc %u\n", + __func__, inst->capabilities->cap[cap_id].value, + inst->capabilities->cap[CSC].value); + return 0; + } + + /* + * first 2 u32's of payload in each case are for + * row and column count, next remaining u32's are + * for the actual payload values. + */ + + /* set custom matrix */ + matrix_payload[0] = 3; + matrix_payload[1] = 3; + + for(i = 0; i < MAX_MATRIX_COEFFS; i++) { + if ((i + 2) >= ARRAY_SIZE(matrix_payload)) + break; + matrix_payload[i + 2] = + csc_coeff->vpe_csc_custom_matrix_coeff[i]; + } + + rc = msm_venc_set_csc_coeff(inst, "CSC_CUSTOM_MATRIX", + HFI_PROP_CSC_MATRIX, &matrix_payload[0], + ARRAY_SIZE(matrix_payload) * sizeof(s32), + matrix_payload[0], matrix_payload[1]); + if (rc) + return rc; + + /* set csc bias */ + csc_bias_payload[0] = 1; + csc_bias_payload[1] = 3; + + for(i = 0; i < MAX_BIAS_COEFFS; i++) { + if ((i + 2) >= ARRAY_SIZE(csc_bias_payload)) + break; + csc_bias_payload[i + 2] = + csc_coeff->vpe_csc_custom_bias_coeff[i]; + } + + rc = msm_venc_set_csc_coeff(inst, "CSC_BIAS", + HFI_PROP_CSC_BIAS, &csc_bias_payload[0], + ARRAY_SIZE(csc_bias_payload) * sizeof(s32), + csc_bias_payload[0], csc_bias_payload[1]); + if (rc) + return rc; + + /* set csc limit */ + csc_limit_payload[0] = 1; + csc_limit_payload[1] = 6; + + for(i = 0; i < MAX_LIMIT_COEFFS; i++) { + if ((i + 2) >= ARRAY_SIZE(csc_limit_payload)) + break; + csc_limit_payload[i + 2] = + csc_coeff->vpe_csc_custom_limit_coeff[i]; + } + + rc = msm_venc_set_csc_coeff(inst, "CSC_LIMIT", + HFI_PROP_CSC_LIMIT, &csc_limit_payload[0], + ARRAY_SIZE(csc_limit_payload) * sizeof(s32), + csc_limit_payload[0], csc_limit_payload[1]); + if (rc) + return rc; + + return rc; +} + int msm_vidc_set_q16(void *instance, enum msm_vidc_inst_capability_type cap_id) {