video: driver: Add support to adjust slice mode

Add support to adjust slice mode.

Change-Id: Id09e951b3085c55cc5bc6b15a2ce002645923435
Signed-off-by: Akshata Sahukar <asahukar@codeaurora.org>
This commit is contained in:
Akshata Sahukar
2021-04-12 13:09:40 -07:00
parent 140af50ab5
commit 5a2b2ee399
5 changed files with 152 additions and 10 deletions

View File

@@ -1072,6 +1072,112 @@ int msm_vidc_adjust_transform_8x8(void *instance, struct v4l2_ctrl *ctrl)
return 0;
}
int msm_vidc_adjust_slice_count(void *instance, struct v4l2_ctrl *ctrl)
{
struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
struct msm_vidc_inst_capability *capability;
struct v4l2_format *output_fmt;
s32 adjusted_value, rc_type = -1, slice_mode;
u32 slice_val, mbpf = 0, mbps = 0, max_mbpf = 0, max_mbps = 0;
u32 update_cap, max_avg_slicesize, output_width, output_height;
u32 min_width, min_height, max_width, max_height, fps;
if (!inst || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
capability = inst->capabilities;
slice_mode = ctrl ? ctrl->val :
capability->cap[SLICE_MODE].value;
if (msm_vidc_get_parent_value(inst, SLICE_MODE,
BITRATE_MODE, &rc_type, __func__))
return -EINVAL;
if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE)
return 0;
fps = capability->cap[FRAME_RATE].value >> 16;
if (fps > MAX_SLICES_FRAME_RATE ||
(rc_type != HFI_RC_OFF &&
rc_type != HFI_RC_CBR_CFR &&
rc_type != HFI_RC_CBR_VFR)) {
adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
update_cap = SLICE_MODE;
i_vpr_h(inst,
"%s: slice unsupported, fps: %u, rc_type: %#x\n",
__func__, fps, rc_type);
goto exit;
}
output_fmt = &inst->fmts[OUTPUT_PORT];
output_width = output_fmt->fmt.pix_mp.width;
output_height = output_fmt->fmt.pix_mp.height;
max_width = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
MAX_MB_SLICE_WIDTH : MAX_BYTES_SLICE_WIDTH;
max_height = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
MAX_MB_SLICE_HEIGHT : MAX_BYTES_SLICE_HEIGHT;
min_width = (inst->codec == MSM_VIDC_HEVC) ?
MIN_HEVC_SLICE_WIDTH : MIN_AVC_SLICE_WIDTH;
min_height = MIN_SLICE_HEIGHT;
/*
* For V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB:
* - width >= 384 and height >= 128
* - width and height <= 4096
* For V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES:
* - width >= 192 and height >= 128
* - width and height <= 1920
*/
if (output_width < min_width || output_height < min_height ||
output_width > max_width || output_height > max_width) {
adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
update_cap = SLICE_MODE;
i_vpr_h(inst,
"%s: slice unsupported, codec: %#x wxh: [%dx%d]\n",
__func__, inst->codec, output_width, output_height);
goto exit;
}
mbpf = NUM_MBS_PER_FRAME(output_height, output_width);
mbps = NUM_MBS_PER_SEC(output_height, output_width, fps);
max_mbpf = NUM_MBS_PER_FRAME(max_height, max_width);
max_mbps = NUM_MBS_PER_SEC(max_height, max_width, fps);
if (mbpf > max_mbpf || mbps > max_mbps) {
adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
update_cap = SLICE_MODE;
i_vpr_h(inst,
"%s: Unsupported, mbpf[%u] > max[%u], mbps[%u] > max[%u]\n",
__func__, mbpf, max_mbpf, mbps, max_mbps);
goto exit;
}
if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
update_cap = SLICE_MAX_MB;
slice_val = capability->cap[SLICE_MAX_MB].value;
slice_val = max(slice_val, mbpf / MAX_SLICES_PER_FRAME);
} else {
slice_val = capability->cap[SLICE_MAX_BYTES].value;
update_cap = SLICE_MAX_BYTES;
if (rc_type != HFI_RC_OFF) {
max_avg_slicesize = ((capability->cap[BIT_RATE].value /
fps) / 8) /
MAX_SLICES_PER_FRAME;
slice_val = max(slice_val, max_avg_slicesize);
}
}
adjusted_value = slice_val;
exit:
msm_vidc_update_cap_value(inst, update_cap,
adjusted_value, __func__);
return 0;
}
static int msm_vidc_adjust_static_layer_count_and_type(struct msm_vidc_inst *inst,
s32 layer_count)
{
@@ -2033,7 +2139,9 @@ int msm_vidc_set_slice_count(void* instance,
return 0;
}
if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
hfi_value = inst->capabilities->cap[SLICE_MAX_MB].value;
hfi_value = (inst->codec == MSM_VIDC_HEVC) ?
((inst->capabilities->cap[SLICE_MAX_MB].value + 3) / 4) :
inst->capabilities->cap[SLICE_MAX_MB].value;
set_cap_id = SLICE_MAX_MB;
} else if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
hfi_value = inst->capabilities->cap[SLICE_MAX_BYTES].value;