video: driver: Introduce a property to set COMV bufcount

Certain codecs/use cases require larger COMV buffer sizes to achieve
performance. Introduce a property to set COMV bufcount and calculate
COMV buffer size based on the bufcount.

Change-Id: Ib0ed8afe77708dc453cbcc121bcd8606db637152
Signed-off-by: Mihir Ganu <quic_mganu@quicinc.com>
This commit is contained in:
Mihir Ganu
2022-07-06 09:08:00 -07:00
committed by Darshana Patil
parent b79ec844f2
commit 1e87ceec2b
9 changed files with 71 additions and 17 deletions

View File

@@ -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,

View File

@@ -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) \

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)