Merge "video: driver: Update session admission and work modes"

This commit is contained in:
qctecmdr
2021-06-05 11:13:10 -07:00
committed by Gerrit - the friendly Code Review server
4 changed files with 79 additions and 51 deletions

View File

@@ -1430,8 +1430,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
HFI_PROP_DEC_QP_METADATA}, HFI_PROP_DEC_QP_METADATA},
/* configure image properties */ /* configure image properties */
{FRAME_WIDTH, ENC, HEIC, 512, 16384, 1, 16384}, {FRAME_WIDTH, ENC, HEIC, 128, 16384, 1, 16384},
{FRAME_HEIGHT, ENC, HEIC, 512, 16384, 1, 16384}, {FRAME_HEIGHT, ENC, HEIC, 128, 16384, 1, 16384},
{MIN_BUFFERS_INPUT, ENC|DEC, HEIC, 0, 64, 1, 1, {MIN_BUFFERS_INPUT, ENC|DEC, HEIC, 0, 64, 1, 1,
V4L2_CID_MIN_BUFFERS_FOR_OUTPUT}, V4L2_CID_MIN_BUFFERS_FOR_OUTPUT},
{MBPF, DEC, HEIC, 64, 262144, 1, 262144 }, /* ((8192x8192)/256) */ {MBPF, DEC, HEIC, 64, 262144, 1, 262144 }, /* ((8192x8192)/256) */

View File

@@ -536,7 +536,7 @@ static int __boot_firmware_iris2(struct msm_vidc_core *vidc_core)
int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst) int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst)
{ {
u32 work_mode; u32 work_mode;
struct v4l2_format* out_f; struct v4l2_format *inp_f;
u32 width, height; u32 width, height;
bool res_ok = false; bool res_ok = false;
@@ -546,7 +546,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst)
} }
work_mode = MSM_VIDC_STAGE_2; work_mode = MSM_VIDC_STAGE_2;
out_f = &inst->fmts[OUTPUT_PORT]; inp_f = &inst->fmts[INPUT_PORT];
if (is_image_decode_session(inst)) if (is_image_decode_session(inst))
work_mode = MSM_VIDC_STAGE_1; work_mode = MSM_VIDC_STAGE_1;
@@ -555,9 +555,9 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst)
goto exit; goto exit;
if (is_decode_session(inst)) { if (is_decode_session(inst)) {
height = out_f->fmt.pix_mp.height; height = inp_f->fmt.pix_mp.height;
width = out_f->fmt.pix_mp.width; width = inp_f->fmt.pix_mp.width;
res_ok = res_is_less_than_or_equal_to(width, height, 1280, 720); res_ok = res_is_less_than(width, height, 1280, 720);
if (inst->capabilities->cap[CODED_FRAMES].value == if (inst->capabilities->cap[CODED_FRAMES].value ==
CODED_FRAMES_INTERLACE || CODED_FRAMES_INTERLACE ||
inst->capabilities->cap[LOWLATENCY_MODE].value || inst->capabilities->cap[LOWLATENCY_MODE].value ||
@@ -572,19 +572,20 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst* inst)
(inst->capabilities->cap[LOWLATENCY_MODE].value)) { (inst->capabilities->cap[LOWLATENCY_MODE].value)) {
work_mode = MSM_VIDC_STAGE_1; work_mode = MSM_VIDC_STAGE_1;
} }
if (inst->capabilities->cap[LOSSLESS].value) { if (inst->capabilities->cap[LOSSLESS].value)
/*TODO Set 2 stage in case of ALL INTRA */
work_mode = MSM_VIDC_STAGE_2; work_mode = MSM_VIDC_STAGE_2;
}
} if (!inst->capabilities->cap[GOP_SIZE].value)
else { work_mode = MSM_VIDC_STAGE_2;
} else {
i_vpr_e(inst, "%s: invalid session type\n", __func__); i_vpr_e(inst, "%s: invalid session type\n", __func__);
return -EINVAL; return -EINVAL;
} }
exit: exit:
i_vpr_h(inst, "Configuring work mode = %u low latency = %u", i_vpr_h(inst, "Configuring work mode = %u low latency = %u, gop size = %u\n",
work_mode, inst->capabilities->cap[LOWLATENCY_MODE].value); work_mode, inst->capabilities->cap[LOWLATENCY_MODE].value,
inst->capabilities->cap[GOP_SIZE].value);
msm_vidc_update_cap_value(inst, STAGE, work_mode, __func__); msm_vidc_update_cap_value(inst, STAGE, work_mode, __func__);
return 0; return 0;

View File

@@ -429,6 +429,8 @@ void msm_vidc_free_capabililty_list(struct msm_vidc_inst *inst,
enum msm_vidc_ctrl_list_type list_type); enum msm_vidc_ctrl_list_type list_type);
bool res_is_greater_than(u32 width, u32 height, bool res_is_greater_than(u32 width, u32 height,
u32 ref_width, u32 ref_height); u32 ref_width, u32 ref_height);
bool res_is_less_than(u32 width, u32 height,
u32 ref_width, u32 ref_height);
bool res_is_less_than_or_equal_to(u32 width, u32 height, bool res_is_less_than_or_equal_to(u32 width, u32 height,
u32 ref_width, u32 ref_height); u32 ref_width, u32 ref_height);
#endif // _MSM_VIDC_DRIVER_H_ #endif // _MSM_VIDC_DRIVER_H_

View File

@@ -1075,6 +1075,20 @@ bool res_is_greater_than(u32 width, u32 height,
return false; return false;
} }
bool res_is_less_than(u32 width, u32 height,
u32 ref_width, u32 ref_height)
{
u32 num_mbs = NUM_MBS_PER_FRAME(height, width);
u32 max_side = max(ref_width, ref_height);
if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) &&
width < max_side &&
height < max_side)
return true;
else
return false;
}
bool res_is_less_than_or_equal_to(u32 width, u32 height, bool res_is_less_than_or_equal_to(u32 width, u32 height,
u32 ref_width, u32 ref_height) u32 ref_width, u32 ref_height)
{ {
@@ -1844,16 +1858,17 @@ int msm_vidc_get_control(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst) int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst)
{ {
int height, width; int height = 0, width = 0;
struct v4l2_format *out_f;
struct v4l2_format *inp_f; struct v4l2_format *inp_f;
out_f = &inst->fmts[OUTPUT_PORT]; if (is_decode_session(inst)) {
inp_f = &inst->fmts[INPUT_PORT]; inp_f = &inst->fmts[INPUT_PORT];
height = max(out_f->fmt.pix_mp.height, width = inp_f->fmt.pix_mp.width;
inp_f->fmt.pix_mp.height); height = inp_f->fmt.pix_mp.height;
width = max(out_f->fmt.pix_mp.width, } else if (is_encode_session(inst)) {
inp_f->fmt.pix_mp.width); width = inst->crop.width;
height = inst->crop.height;
}
return NUM_MBS_PER_FRAME(height, width); return NUM_MBS_PER_FRAME(height, width);
} }
@@ -5307,8 +5322,7 @@ exit:
int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
{ {
struct msm_vidc_inst_capability *capability; struct msm_vidc_inst_capability *capability;
struct v4l2_format *fmt; u32 width = 0, height = 0, min_width, min_height,
u32 iwidth, owidth, iheight, oheight, min_width, min_height,
max_width, max_height; max_width, max_height;
bool allow = false, is_interlaced = false; bool allow = false, is_interlaced = false;
int rc = 0; int rc = 0;
@@ -5337,13 +5351,13 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
if (rc) if (rc)
goto exit; goto exit;
fmt = &inst->fmts[INPUT_PORT]; if (is_decode_session(inst)) {
iwidth = fmt->fmt.pix_mp.width; width = inst->fmts[INPUT_PORT].fmt.pix_mp.width;
iheight = fmt->fmt.pix_mp.height; height = inst->fmts[INPUT_PORT].fmt.pix_mp.height;
} else if (is_encode_session(inst)) {
fmt = &inst->fmts[OUTPUT_PORT]; width = inst->crop.width;
owidth = fmt->fmt.pix_mp.width; height = inst->crop.height;
oheight = fmt->fmt.pix_mp.height; }
if (is_secure_session(inst)) { if (is_secure_session(inst)) {
min_width = capability->cap[SECURE_FRAME_WIDTH].min; min_width = capability->cap[SECURE_FRAME_WIDTH].min;
@@ -5364,29 +5378,40 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
/* reject odd resolution session */ /* reject odd resolution session */
if (is_encode_session(inst) && if (is_encode_session(inst) &&
(is_odd(iwidth) || is_odd(iheight) || is_odd(owidth) || is_odd(oheight))) { (is_odd(width) || is_odd(height) ||
i_vpr_e(inst, "%s: resolution is not even. input [%u x %u], output [%u x %u]\n", is_odd(inst->compose.width) ||
__func__, iwidth, iheight, owidth, oheight); is_odd(inst->compose.height))) {
i_vpr_e(inst, "%s: resolution is not even. wxh [%u x %u], compose [%u x %u]\n",
__func__, width, height, inst->compose.width,
inst->compose.height);
rc = -EINVAL; rc = -EINVAL;
goto exit; goto exit;
} }
/* check input width and height is in supported range */ /* check decoder input width and height is in supported range */
if (!in_range(iwidth, min_width, max_width) || !in_range(iheight, min_height, max_height)) { if (is_decode_session(inst)) {
i_vpr_e(inst, if (!in_range(width, min_width, max_width) ||
"%s: unsupported input wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n", !in_range(height, min_height, max_height)) {
__func__, iwidth, iheight, min_width, min_height, max_width, max_height); i_vpr_e(inst,
rc = -EINVAL; "%s: unsupported input wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n",
goto exit; __func__, width, height, min_width,
min_height, max_width, max_height);
rc = -EINVAL;
goto exit;
}
} }
/* check output width and height is in supported range */ /* check encoder crop width and height is in supported range */
if (!in_range(owidth, min_width, max_width) || !in_range(oheight, min_height, max_height)) { if (is_encode_session(inst)) {
i_vpr_e(inst, if (!in_range(width, min_width, max_width) ||
"%s: unsupported output wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n", !in_range(height, min_height, max_height)) {
__func__, owidth, oheight, min_width, min_height, max_width, max_height); i_vpr_e(inst,
rc = -EINVAL; "%s: unsupported wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n",
goto exit; __func__, width, height, min_width,
min_height, max_width, max_height);
rc = -EINVAL;
goto exit;
}
} }
/* check image capabilities */ /* check image capabilities */
@@ -5401,10 +5426,10 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
/* check interlace supported resolution */ /* check interlace supported resolution */
is_interlaced = capability->cap[CODED_FRAMES].value == CODED_FRAMES_INTERLACE; is_interlaced = capability->cap[CODED_FRAMES].value == CODED_FRAMES_INTERLACE;
if (is_interlaced && (owidth > INTERLACE_WIDTH_MAX || oheight > INTERLACE_HEIGHT_MAX || if (is_interlaced && (width > INTERLACE_WIDTH_MAX || height > INTERLACE_HEIGHT_MAX ||
NUM_MBS_PER_FRAME(owidth, oheight) > INTERLACE_MB_PER_FRAME_MAX)) { NUM_MBS_PER_FRAME(width, height) > INTERLACE_MB_PER_FRAME_MAX)) {
i_vpr_e(inst, "%s: unsupported interlace wxh [%u x %u], max [%u x %u]\n", i_vpr_e(inst, "%s: unsupported interlace wxh [%u x %u], max [%u x %u]\n",
__func__, owidth, oheight, INTERLACE_WIDTH_MAX, INTERLACE_HEIGHT_MAX); __func__, width, height, INTERLACE_WIDTH_MAX, INTERLACE_HEIGHT_MAX);
rc = -EINVAL; rc = -EINVAL;
goto exit; goto exit;
} }