From 0e570d90fa28e843d8b375202b054100256b4e71 Mon Sep 17 00:00:00 2001 From: Qiwei Liu Date: Wed, 10 Jun 2020 15:09:10 +0800 Subject: [PATCH] msm: vidc: improve heif decoder performance Add V4L2 interface to indicate heif decoder, and use below configurations to improve performance. 1. Set turbo session 2. Disable DCVS and batch 3. Increase input and output buffer count to 12 4. Modify input buffer size calculation 5. Avoid framerate calc and ts list maintenance 6. Skip setting bse-vpp delay Change-Id: I9a47a88154238db3ac4285462c6030114546d333 Signed-off-by: Qiwei Liu --- include/uapi/vidc/media/msm_vidc_utils.h | 2 ++ msm/vidc/msm_vdec.c | 18 ++++++++++++++++++ msm/vidc/msm_vidc.c | 6 ++++-- msm/vidc/msm_vidc_buffer_calculations.c | 17 ++++++++++++++++- msm/vidc/msm_vidc_clocks.c | 1 + msm/vidc/msm_vidc_common.c | 1 + msm/vidc/msm_vidc_common.h | 11 +++++++++++ 7 files changed, 53 insertions(+), 3 deletions(-) diff --git a/include/uapi/vidc/media/msm_vidc_utils.h b/include/uapi/vidc/media/msm_vidc_utils.h index 2e4f351c4927..a20d4816841a 100644 --- a/include/uapi/vidc/media/msm_vidc_utils.h +++ b/include/uapi/vidc/media/msm_vidc_utils.h @@ -252,6 +252,8 @@ enum v4l2_mpeg_vidc_video_bitrate_savings_type { (V4L2_CID_MPEG_MSM_VIDC_BASE + 132) #define V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 133) +#define V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE \ + (V4L2_CID_MPEG_MSM_VIDC_BASE + 134) #define V4L2_CID_MPEG_VIDC_VIDEO_UNKNOWN \ (V4L2_CID_MPEG_MSM_VIDC_BASE + 0xFFF) diff --git a/msm/vidc/msm_vdec.c b/msm/vidc/msm_vdec.c index 685f56e6c17b..5a2b8a348978 100644 --- a/msm/vidc/msm_vdec.c +++ b/msm/vidc/msm_vdec.c @@ -434,6 +434,15 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = { .default_value = 0, .step = 1, }, + { + .id = V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE, + .name = "HEIF Decoder", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .minimum = V4L2_MPEG_MSM_VIDC_DISABLE, + .maximum = V4L2_MPEG_MSM_VIDC_ENABLE, + .default_value = V4L2_MPEG_MSM_VIDC_DISABLE, + .step = 1, + }, }; #define NUM_CTRLS ARRAY_SIZE(msm_vdec_ctrls) @@ -948,6 +957,15 @@ int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl) break; case V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_HINT: break; + case V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE: + if(get_v4l2_codec(inst) != V4L2_PIX_FMT_HEVC) + break; + inst->flags &= ~VIDC_TURBO; + if (ctrl->val) + inst->flags |= VIDC_TURBO; + if (inst->state < MSM_VIDC_LOAD_RESOURCES) + msm_vidc_calculate_buffer_counts(inst); + break; default: s_vpr_e(inst->sid, "Unknown control %#x\n", ctrl->id); break; diff --git a/msm/vidc/msm_vidc.c b/msm/vidc/msm_vidc.c index 7f78071d585d..499abc4f5ad8 100644 --- a/msm/vidc/msm_vidc.c +++ b/msm/vidc/msm_vidc.c @@ -432,7 +432,8 @@ int msm_vidc_qbuf(void *instance, struct media_device *mdev, timestamp_us = (s64)((b->timestamp.tv_sec * 1000000) + b->timestamp.tv_usec); - if (is_decode_session(inst) && b->type == INPUT_MPLANE) { + if (is_decode_session(inst) && b->type == INPUT_MPLANE && + !is_heif_decoder(inst)) { if (inst->flush_timestamps) msm_comm_release_timestamps(inst); inst->flush_timestamps = false; @@ -513,7 +514,8 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b) } if (is_decode_session(inst) && b->type == OUTPUT_MPLANE && - !(b->flags & V4L2_BUF_FLAG_CODECCONFIG)) + !(b->flags & V4L2_BUF_FLAG_CODECCONFIG) && + !is_heif_decoder(inst)) msm_comm_fetch_ts_framerate(inst, b); return rc; diff --git a/msm/vidc/msm_vidc_buffer_calculations.c b/msm/vidc/msm_vidc_buffer_calculations.c index 03079a37ee35..4b1a2bd287d9 100644 --- a/msm/vidc/msm_vidc_buffer_calculations.c +++ b/msm/vidc/msm_vidc_buffer_calculations.c @@ -27,6 +27,10 @@ /* extra output buffers for encoder HEIF usecase */ #define HEIF_ENC_TOTAL_OUTPUT_BUFFERS 12 +/* extra buffer count for heif decoder */ +#define HEIF_DEC_TOTAL_INPUT_BUFFERS 12 +#define HEIF_DEC_EXTRA_OUTPUT_BUFFERS 8 + #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_WIDTH 32 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_Y_TILE_HEIGHT 8 #define HFI_COLOR_FORMAT_YUV420_NV12_UBWC_UV_TILE_WIDTH 16 @@ -789,6 +793,9 @@ static int msm_vidc_get_extra_input_buff_count(struct msm_vidc_inst *inst) core = inst->core; + if (is_heif_decoder(inst)) + return (HEIF_DEC_TOTAL_INPUT_BUFFERS - MIN_INPUT_BUFFERS); + /* * For thumbnail session, extra buffers are not required as * neither dcvs nor batching will be enabled. @@ -821,6 +828,9 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) core = inst->core; + if (is_heif_decoder(inst)) + return HEIF_DEC_EXTRA_OUTPUT_BUFFERS; + /* * For a non-realtime session, extra buffers are not required. * For thumbnail session, extra buffers are not required as @@ -829,7 +839,7 @@ static int msm_vidc_get_extra_output_buff_count(struct msm_vidc_inst *inst) if (!is_realtime_session(inst) || is_thumbnail_session(inst)) return extra_output_count; - /* For HEIF, we are increasing buffer count */ + /* For HEIF encoder, we are increasing buffer count */ if (is_image_session(inst)) { extra_output_count = (HEIF_ENC_TOTAL_OUTPUT_BUFFERS - MIN_ENC_OUTPUT_BUFFERS); @@ -889,6 +899,11 @@ u32 msm_vidc_calculate_dec_input_frame_size(struct msm_vidc_inst *inst) base_res_mbs = inst->capability.cap[CAP_MBS_PER_FRAME].max; div_factor = 1; } + /* For HEIF image, use the actual resolution to calc buffer size */ + if (is_heif_decoder(inst)) { + base_res_mbs = num_mbs; + div_factor = 1; + } frame_size = base_res_mbs * MB_SIZE_IN_PIXEL * 3 / 2 / div_factor; diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 0af709fe2d36..64b5f95408f9 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -1293,6 +1293,7 @@ int msm_vidc_set_bse_vpp_delay(struct msm_vidc_inst *inst) if (!inst->core->resources.has_vpp_delay || !is_decode_session(inst) || is_thumbnail_session(inst) || + is_heif_decoder(inst) || inst->clk_data.work_mode != HFI_WORKMODE_2) { s_vpr_hp(inst->sid, "%s: Skip bse-vpp\n", __func__); return 0; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 652334c646c4..0cab94351d95 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -2839,6 +2839,7 @@ bool is_batching_allowed(struct msm_vidc_inst *inst) is_decode_session(inst) && !is_thumbnail_session(inst) && is_realtime_session(inst) && + !is_heif_decoder(inst) && !inst->clk_data.low_latency_mode && (op_pixelformat == V4L2_PIX_FMT_NV12_UBWC || op_pixelformat == V4L2_PIX_FMT_NV12_TP10_UBWC) && diff --git a/msm/vidc/msm_vidc_common.h b/msm/vidc/msm_vidc_common.h index e46c5bbd9f62..24a04dd0a257 100644 --- a/msm/vidc/msm_vidc_common.h +++ b/msm/vidc/msm_vidc_common.h @@ -121,6 +121,17 @@ static inline bool is_grid_session(struct msm_vidc_inst *inst) return 0; } +static inline bool is_heif_decoder(struct msm_vidc_inst *inst) +{ + struct v4l2_ctrl *ctrl = NULL; + if (inst->session_type == MSM_VIDC_DECODER && + get_v4l2_codec(inst) == V4L2_PIX_FMT_HEVC) { + ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VDEC_HEIF_MODE); + return (ctrl->val > 0); + } + return 0; +} + static inline bool is_video_session(struct msm_vidc_inst *inst) { return !is_grid_session(inst);