diff --git a/driver/platform/kalama/src/msm_vidc_kalama.c b/driver/platform/kalama/src/msm_vidc_kalama.c index 3a5d43c55a..aad98b4361 100644 --- a/driver/platform/kalama/src/msm_vidc_kalama.c +++ b/driver/platform/kalama/src/msm_vidc_kalama.c @@ -486,6 +486,9 @@ static struct msm_platform_inst_capability instance_cap_data_kalama[] = { {LOWLATENCY_MAX_BITRATE, ENC, H264|HEVC, 0, 70000000, 1, 70000000}, + {NUM_COMV, DEC, CODECS_ALL, + 0, INT_MAX, 1, 0}, + {LOSSLESS, ENC, HEVC, V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE, 1, V4L2_MPEG_MSM_VIDC_DISABLE, diff --git a/driver/variant/iris3/inc/hfi_buffer_iris3.h b/driver/variant/iris3/inc/hfi_buffer_iris3.h index e81410e829..8064b47833 100644 --- a/driver/variant/iris3/inc/hfi_buffer_iris3.h +++ b/driver/variant/iris3/inc/hfi_buffer_iris3.h @@ -386,7 +386,7 @@ typedef HFI_U32 HFI_BOOL; } while (0) #define HFI_BUFFER_COMV_H264D(coMV_size, frame_width, \ - frame_height, _yuv_bufcount_min) \ + frame_height, _comv_bufcount) \ do \ { \ HFI_U32 frame_width_in_mbs = ((frame_width + 15) >> 4); \ @@ -413,7 +413,7 @@ typedef HFI_U32 HFI_BOOL; size_colloc = HFI_ALIGN(size_colloc, \ BUFFER_ALIGNMENT_512_BYTES); \ size_colloc += (col_zero_size + SIZE_H264D_BUFTAB_T * 2); \ - coMV_size = size_colloc * (_yuv_bufcount_min); \ + coMV_size = size_colloc * (_comv_bufcount); \ coMV_size += BUFFER_ALIGNMENT_512_BYTES; \ } while (0) @@ -597,13 +597,13 @@ typedef HFI_U32 HFI_BOOL; } while (0) #define HFI_BUFFER_COMV_H265D(_size, frame_width, frame_height, \ - _yuv_bufcount_min) \ + _comv_bufcount) \ do \ { \ _size = HFI_ALIGN(((((frame_width + 15) >> 4) * \ ((frame_height + 15) >> 4)) << 8), \ BUFFER_ALIGNMENT_512_BYTES); \ - _size *= _yuv_bufcount_min; \ + _size *= _comv_bufcount; \ _size += BUFFER_ALIGNMENT_512_BYTES; \ } while (0) @@ -893,14 +893,14 @@ _yuv_bufcount_min, is_opb, num_vpp_pipes) \ #define AV1D_MAX_TILE_COLS 64 #define HFI_BUFFER_COMV_AV1D(_size, frame_width, frame_height, \ - _yuv_bufcount_min) \ + _comv_bufcount) \ do { \ _size = 2 * HFI_ALIGN(MAX(((frame_width + 63) / 64) * \ ((frame_height + 63) / 64) * 512, \ ((frame_width + 127) / 128) * \ ((frame_height + 127) / 128) * 2816), \ VENUS_DMA_ALIGNMENT); \ - _size *= _yuv_bufcount_min; \ + _size *= _comv_bufcount; \ } while (0) #define SIZE_AV1D_LB_FE_TOP_DATA(frame_width, frame_height) \ diff --git a/driver/variant/iris3/src/msm_vidc_buffer_iris3.c b/driver/variant/iris3/src/msm_vidc_buffer_iris3.c index 93f062ad22..38ce2a15e9 100644 --- a/driver/variant/iris3/src/msm_vidc_buffer_iris3.c +++ b/driver/variant/iris3/src/msm_vidc_buffer_iris3.c @@ -68,10 +68,10 @@ static u32 msm_vidc_decoder_bin_size_iris3(struct msm_vidc_inst *inst) static u32 msm_vidc_decoder_comv_size_iris3(struct msm_vidc_inst* inst) { u32 size = 0; - u32 width, height, out_min_count, vpp_delay; + u32 width, height, num_comv, vpp_delay; struct v4l2_format *f; - if (!inst || !inst->core) { + if (!inst || !inst->core || !inst->capabilities) { d_vpr_e("%s: invalid params\n", __func__); return size; } @@ -79,17 +79,33 @@ static u32 msm_vidc_decoder_comv_size_iris3(struct msm_vidc_inst* inst) f = &inst->fmts[INPUT_PORT]; width = f->fmt.pix_mp.width; height = f->fmt.pix_mp.height; + + if (inst->codec == MSM_VIDC_AV1) { + /* + * AV1 requires larger COMV buffer size to meet performance + * for certain use cases. Increase the COMV buffer size by + * increasing COMV bufcount. Use lower count for 8k to + * achieve performance but save memory. + */ + if (res_is_greater_than(width, height, 4096, 2176)) + num_comv = inst->buffers.output.min_count + 3; + else + num_comv = inst->buffers.output.min_count + 7; + } else { + num_comv = inst->buffers.output.min_count; + } + msm_vidc_update_cap_value(inst, NUM_COMV, num_comv, __func__); + if (inst->decode_vpp_delay.enable) vpp_delay = inst->decode_vpp_delay.size; else vpp_delay = DEFAULT_BSE_VPP_DELAY; - out_min_count = inst->buffers.output.min_count; - out_min_count = max(vpp_delay + 1, out_min_count); + num_comv = max(vpp_delay + 1, num_comv); if (inst->codec == MSM_VIDC_H264) { - HFI_BUFFER_COMV_H264D(size, width, height, out_min_count); + HFI_BUFFER_COMV_H264D(size, width, height, num_comv); } else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC) { - HFI_BUFFER_COMV_H265D(size, width, height, out_min_count); + HFI_BUFFER_COMV_H265D(size, width, height, num_comv); } else if (inst->codec == MSM_VIDC_AV1) { /* * When DRAP is enabled, COMV buffer is part of PERSIST buffer and @@ -99,7 +115,7 @@ static u32 msm_vidc_decoder_comv_size_iris3(struct msm_vidc_inst* inst) if (inst->capabilities->cap[DRAP].value) size = 0; else - HFI_BUFFER_COMV_AV1D(size, width, height, out_min_count); + HFI_BUFFER_COMV_AV1D(size, width, height, num_comv); } i_vpr_l(inst, "%s: size %d\n", __func__, size); diff --git a/driver/vidc/inc/hfi_property.h b/driver/vidc/inc/hfi_property.h index 2661837ff4..e383cbd0b3 100644 --- a/driver/vidc/inc/hfi_property.h +++ b/driver/vidc/inc/hfi_property.h @@ -565,6 +565,8 @@ enum hfi_saliency_type { #define HFI_PROP_DOLBY_RPU_METADATA 0x03000192 +#define HFI_PROP_COMV_BUFFER_COUNT 0x03000193 + #define HFI_PROP_END 0x03FFFFFF #define HFI_SESSION_ERROR_BEGIN 0x04000000 diff --git a/driver/vidc/inc/msm_vdec.h b/driver/vidc/inc/msm_vdec.h index 409f8b7300..b9f721e567 100644 --- a/driver/vidc/inc/msm_vdec.h +++ b/driver/vidc/inc/msm_vdec.h @@ -30,6 +30,7 @@ int msm_vdec_output_port_settings_change(struct msm_vidc_inst *inst); int msm_vdec_process_cmd(struct msm_vidc_inst *inst, u32 cmd); int msm_vdec_handle_release_buffer(struct msm_vidc_inst *inst, struct msm_vidc_buffer *buf); +int msm_vdec_set_num_comv(struct msm_vidc_inst *inst); int msm_vdec_get_input_internal_buffers(struct msm_vidc_inst *inst); int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst); int msm_vdec_queue_input_internal_buffers(struct msm_vidc_inst *inst); diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index 54843ba6f0..2ea18427ed 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -501,6 +501,7 @@ enum msm_vidc_inst_capability_type { ALLINTRA_MAX_BITRATE, LOWLATENCY_MAX_BITRATE, LAST_FLAG_EVENT_ENABLE, + NUM_COMV, /* place all root(no parent) enums before this line */ PROFILE, diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index daf9bf3abc..1b7c2b4395 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -1224,6 +1224,33 @@ int msm_vdec_init_input_subcr_params(struct msm_vidc_inst *inst) return 0; } +int msm_vdec_set_num_comv(struct msm_vidc_inst *inst) +{ + int rc = 0; + u32 num_comv = 0; + + if (!inst || !inst->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + num_comv = inst->capabilities->cap[NUM_COMV].value; + i_vpr_h(inst, "%s: num COMV: %d", __func__, num_comv); + rc = venus_hfi_session_property(inst, + HFI_PROP_COMV_BUFFER_COUNT, + HFI_HOST_FLAGS_NONE, + get_hfi_port(inst, INPUT_PORT), + HFI_PAYLOAD_U32, + &num_comv, + sizeof(u32)); + if (rc) { + i_vpr_e(inst, "%s: set property failed\n", __func__); + return rc; + } + + return rc; +} + static int msm_vdec_read_input_subcr_params(struct msm_vidc_inst *inst) { struct msm_vidc_subscription_params subsc_params; diff --git a/driver/vidc/src/msm_vidc_buffer.c b/driver/vidc/src/msm_vidc_buffer.c index a8fc74f886..0aac6a755e 100644 --- a/driver/vidc/src/msm_vidc_buffer.c +++ b/driver/vidc/src/msm_vidc_buffer.c @@ -70,11 +70,8 @@ u32 msm_vidc_output_min_count(struct msm_vidc_inst *inst) output_min_count = 4; break; case MSM_VIDC_VP9: - output_min_count = 9; - break; case MSM_VIDC_AV1: - // TODO: needs review - output_min_count = 11; + output_min_count = 9; break; case MSM_VIDC_HEIC: output_min_count = 3; diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 8687ccd08c..260a8c0888 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -195,6 +195,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = { {ALLINTRA_MAX_BITRATE, "ALLINTRA_MAX_BITRATE" }, {LOWLATENCY_MAX_BITRATE, "LOWLATENCY_MAX_BITRATE" }, {LAST_FLAG_EVENT_ENABLE, "LAST_FLAG_EVENT_ENABLE" }, + {NUM_COMV, "NUM_COMV" }, {PROFILE, "PROFILE" }, {ENH_LAYER_COUNT, "ENH_LAYER_COUNT" }, {BIT_RATE, "BIT_RATE" }, @@ -3946,6 +3947,12 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst, return 0; } + if (is_decode_session(inst) && buffer_type == MSM_VIDC_BUF_COMV) { + rc = msm_vdec_set_num_comv(inst); + if (rc) + return rc; + } + list_for_each_entry_safe(buffer, dummy, &buffers->list, list) { /* do not queue pending release buffers */ if (buffer->flags & MSM_VIDC_ATTR_PENDING_RELEASE)