From 6f422178aa2c69466e27e475c02d245673d78187 Mon Sep 17 00:00:00 2001 From: Akshata Sahukar Date: Mon, 12 Aug 2019 16:54:01 -0700 Subject: [PATCH] msm: vidc: Add support to CVP skip ratio Introduced CVP skip ratio property to indicate the number of buffers skipped for CVP processing. This serves as a hint to Video firmware to know the number of frames for which CVP metadata has to be reused from earlier frame to which CVP metadata was sent Change-Id: I58ad5daf9a9c6ae7a0aa48e3bd1d60e7dc9229e6 Signed-off-by: Akshata Sahukar --- msm/vidc/msm_cvp_external.c | 17 ++++++++++-- msm/vidc/msm_venc.c | 54 +++++++++++++++++++++++++++++++++++++ msm/vidc/msm_venc.h | 1 + msm/vidc/msm_vidc.c | 29 ++++++++++++++++++++ msm/vidc/msm_vidc_common.c | 29 ++++++++++++++++++++ msm/vidc/msm_vidc_common.h | 2 ++ msm/vidc/vidc_hfi_helper.h | 6 +++++ 7 files changed, 136 insertions(+), 2 deletions(-) diff --git a/msm/vidc/msm_cvp_external.c b/msm/vidc/msm_cvp_external.c index 5fb23bbe1c5a..fe64b227d812 100644 --- a/msm/vidc/msm_cvp_external.c +++ b/msm/vidc/msm_cvp_external.c @@ -869,9 +869,10 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, struct cvp_kmd_arg *arg; struct msm_cvp_dme_frame_packet *frame; const u32 fps_max = CVP_FRAME_RATE_MAX; - u32 fps, operating_rate, skip_framecount; + u32 fps, operating_rate, skip_framecount, capture_rate, cvp_rate; bool skipframe = false; bool first_frame = false; + bool fps_data_changed = false; if (!inst || !inst->cvp || !inst->cvp->arg || !mbuf) { d_vpr_e("%s: invalid params %pK %pK\n", @@ -896,6 +897,7 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, cvp->operating_rate != inst->clk_data.operating_rate) { /* update cvp parameters */ cvp->framecount = 0; + fps_data_changed = true; cvp->frame_rate = inst->clk_data.frame_rate; cvp->operating_rate = inst->clk_data.operating_rate; rc = msm_cvp_set_clocks_and_bus(inst); @@ -929,9 +931,12 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, * fps <= 960: 0, 16, 32, 48 .. are not skipped */ fps = roundup(fps, fps_max); + cvp_rate = fps_max << 16; skip_framecount = fps / fps_max; skipframe = cvp->framecount % skip_framecount; - } + } else + cvp_rate = fps << 16; + if (skipframe) { print_cvp_buffer(VIDC_LOW, "input frame with skipflag", inst, &cvp->fullres_buffer); @@ -940,6 +945,14 @@ static int msm_cvp_frame_process(struct msm_vidc_inst *inst, mbuf->vvb.flags |= V4L2_BUF_FLAG_CVPMETADATA_SKIP; return 0; } + capture_rate = fps << 16; + if (fps_data_changed) { + rc = msm_comm_set_cvp_skip_ratio(inst, capture_rate, cvp_rate); + if (rc) { + s_vpr_e(inst->sid,"Setting CVP skip ratio failed"); + goto error; + } + } memset(arg, 0, sizeof(struct cvp_kmd_arg)); arg->type = CVP_KMD_SEND_CMD_PKT; diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 488778080468..26452da8c3e8 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -956,6 +956,24 @@ static struct msm_vidc_ctrl msm_venc_ctrls[] = { .default_value = 0, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE, + .name = "Capture Frame Rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = (MAXIMUM_FPS << 16), + .default_value = (DEFAULT_FPS << 16), + .step = 1, + }, + { + .id = V4L2_CID_MPEG_VIDC_CVP_FRAME_RATE, + .name = "CVP Frame Rate", + .type = V4L2_CTRL_TYPE_INTEGER, + .minimum = (MINIMUM_FPS << 16), + .maximum = (MAXIMUM_FPS << 16), + .default_value = (DEFAULT_FPS << 16), + .step = 1, + }, }; #define NUM_CTRLS ARRAY_SIZE(msm_venc_ctrls) @@ -1810,6 +1828,16 @@ int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) s_vpr_e(sid, "%s: set flip failed\n", __func__); } break; + case V4L2_CID_MPEG_VIDC_CVP_FRAME_RATE: + if (inst->state == MSM_VIDC_START_DONE) { + rc = msm_venc_set_cvp_skipratio(inst); + if (rc) + s_vpr_e(sid, + "%s: set cvp skip ratio failed\n", + __func__); + } + break; + case V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE: case V4L2_CID_MPEG_VIDC_COMPRESSION_QUALITY: case V4L2_CID_MPEG_VIDC_IMG_GRID_SIZE: case V4L2_CID_MPEG_VIDC_VIDEO_HEVC_MAX_HIER_CODING_LAYER: @@ -2087,6 +2115,9 @@ int msm_venc_set_operating_rate(struct msm_vidc_inst *inst) d_vpr_e("%s: invalid params %pK\n", __func__, inst); return -EINVAL; } + if (!inst->core->resources.cvp_internal) + return 0; + hdev = inst->core->device; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE); @@ -4212,6 +4243,29 @@ int msm_venc_set_lossless(struct msm_vidc_inst *inst) return rc; } +int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst) +{ + int rc = 0; + struct v4l2_ctrl *capture_rate_ctrl; + struct v4l2_ctrl *cvp_rate_ctrl; + + if (!inst || !inst->core) { + d_vpr_e("%s: invalid params %pK\n", __func__, inst); + return -EINVAL; + } + if (!msm_vidc_cvp_usage || !inst->core->resources.cvp_external) + return 0; + + capture_rate_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_CAPTURE_FRAME_RATE); + cvp_rate_ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_CVP_FRAME_RATE); + + rc = msm_comm_set_cvp_skip_ratio(inst, + capture_rate_ctrl->val, cvp_rate_ctrl->val); + if (rc) + s_vpr_e(inst->sid, "Failed to set cvp skip ratio\n"); + + return rc; +} int handle_all_intra_restrictions(struct msm_vidc_inst *inst) { diff --git a/msm/vidc/msm_venc.h b/msm/vidc/msm_venc.h index f9e8d227b37a..e13b2cc3536e 100644 --- a/msm/vidc/msm_venc.h +++ b/msm/vidc/msm_venc.h @@ -41,6 +41,7 @@ int msm_venc_check_dynamic_flip_constraints(struct msm_vidc_inst *inst); int msm_venc_set_dynamic_flip(struct msm_vidc_inst *inst); int msm_venc_set_lossless(struct msm_vidc_inst *inst); int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst); +int msm_venc_set_cvp_skipratio(struct msm_vidc_inst *inst); int handle_all_intra_restrictions(struct msm_vidc_inst *inst); int check_blur_restrictions(struct msm_vidc_inst *inst); #endif diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index f72719a38d88..a4e35c7f7977 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -837,6 +837,35 @@ static bool msm_vidc_set_cvp_metadata(struct msm_vidc_inst *inst) { s_vpr_e(inst->sid, "%s: set CVP extradata failed\n", __func__); return false; } + + if (inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_KK_CVP) { + u32 cap_rate = 0; + u32 cvp_rate = 0; + u32 oprate = 0; + u32 fps_max = CVP_FRAME_RATE_MAX << 16; + + if (inst->clk_data.operating_rate == INT_MAX) + oprate = fps_max; + else + oprate = inst->clk_data.operating_rate; + + cap_rate = max(inst->clk_data.frame_rate, oprate); + if (cap_rate > fps_max) { + cap_rate = roundup(cap_rate, fps_max); + cvp_rate = fps_max; + } + else + cvp_rate = cap_rate; + rc = msm_comm_set_cvp_skip_ratio(inst, cap_rate, cvp_rate); + } + else if(inst->prop.extradata_ctrls & EXTRADATA_ENC_INPUT_CVP) + rc = msm_venc_set_cvp_skipratio(inst); + + if (rc) { + s_vpr_e(inst->sid, + "%s: set CVP skip ratio controls failed\n", __func__); + return false; + } return true; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index d1f57b0e8700..973b9fdf7dbb 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -7176,6 +7176,35 @@ int msm_comm_set_extradata(struct msm_vidc_inst *inst, return rc; } +int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, + uint32_t capture_rate, uint32_t cvp_rate) +{ + int rc = 0; + struct hfi_cvp_skip_ratio cvp_data; + struct hfi_device *hdev; + u32 integral_part, fractional_part, skip_ratio; + + hdev = inst->core->device; + + skip_ratio = 0; + integral_part = ((capture_rate / cvp_rate) << 16); + fractional_part = capture_rate % cvp_rate; + if (fractional_part) { + fractional_part = (fractional_part * 100) / cvp_rate; + skip_ratio = integral_part | ((fractional_part << 16)/100) ; + } + else + skip_ratio = integral_part; + + cvp_data.cvp_skip_ratio = skip_ratio; + rc = call_hfi_op(hdev, session_set_property, (void *) + inst->session, HFI_PROPERTY_CONFIG_CVP_SKIP_RATIO, &cvp_data, + sizeof(cvp_data)); + + return rc; +} + + bool msm_comm_check_for_inst_overload(struct msm_vidc_core *core) { u32 instance_count = 0; diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index 882b97a93eb3..db1fc943c9e4 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -327,4 +327,6 @@ int msm_comm_check_window_bitrate(struct msm_vidc_inst *inst, struct vidc_frame_data *frame_data); void msm_comm_clear_window_data(struct msm_vidc_inst *inst); void msm_comm_release_window_data(struct msm_vidc_inst *inst); +int msm_comm_set_cvp_skip_ratio(struct msm_vidc_inst *inst, + uint32_t capture_rate, uint32_t cvp_rate); #endif diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index f345fdf475f6..3dfc8c1ddb68 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -387,6 +387,8 @@ struct hfi_buffer_info { (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x014) #define HFI_PROPERTY_CONFIG_HEIC_GRID_ENABLE \ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x015) +#define HFI_PROPERTY_CONFIG_CVP_SKIP_RATIO \ + (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x016) #define HFI_PROPERTY_PARAM_VPE_COMMON_START \ (HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x7000) @@ -401,6 +403,10 @@ struct hfi_buffer_info { #define HFI_PROPERTY_CONFIG_VPE_FLIP \ (HFI_PROPERTY_CONFIG_VPE_COMMON_START + 0x001) +struct hfi_cvp_skip_ratio { + u32 cvp_skip_ratio; +}; + struct hfi_pic_struct { u32 progressive_only; };