video: driver: limit max number of sessions based on resolution
add checks to limit max number of sessions supported based on resolution. max number of 720P sessions: 16 max number of 1080P sessions: 8 max number of 4K sessions: 4 max number of 8K sessions: 2 Change-Id: I2a784a0d28ba050923bdc7f42a21ee9801d01d86 Signed-off-by: Darshana Patil <darshana@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
8e1ba950f0
commit
e17abd45c1
@@ -53,6 +53,10 @@ static struct msm_platform_core_capability core_data_waipio[] = {
|
||||
{ENC_CODECS, H264|HEVC|HEIC},
|
||||
{DEC_CODECS, H264|HEVC|VP9|HEIC},
|
||||
{MAX_SESSION_COUNT, 16},
|
||||
{MAX_NUM_720P_SESSIONS, 16},
|
||||
{MAX_NUM_1080P_SESSIONS, 8},
|
||||
{MAX_NUM_4K_SESSIONS, 4},
|
||||
{MAX_NUM_8K_SESSIONS, 2},
|
||||
{MAX_SECURE_SESSION_COUNT, 3},
|
||||
{MAX_MBPF, 173056}, /* (8192x4320)/256 + (4096x2176)/256*/
|
||||
{MAX_MBPS, 7833600}, /* max_load
|
||||
|
@@ -428,6 +428,8 @@ void msm_vidc_free_capabililty_list(struct msm_vidc_inst *inst,
|
||||
enum msm_vidc_ctrl_list_type list_type);
|
||||
bool res_is_greater_than(u32 width, u32 height,
|
||||
u32 ref_width, u32 ref_height);
|
||||
bool res_is_greater_than_or_equal_to(u32 width, u32 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,
|
||||
|
@@ -304,6 +304,10 @@ enum msm_vidc_core_capability_type {
|
||||
ENC_CODECS,
|
||||
DEC_CODECS,
|
||||
MAX_SESSION_COUNT,
|
||||
MAX_NUM_720P_SESSIONS,
|
||||
MAX_NUM_1080P_SESSIONS,
|
||||
MAX_NUM_4K_SESSIONS,
|
||||
MAX_NUM_8K_SESSIONS,
|
||||
MAX_SECURE_SESSION_COUNT,
|
||||
MAX_LOAD,
|
||||
MAX_MBPF,
|
||||
|
@@ -1104,6 +1104,20 @@ bool res_is_greater_than(u32 width, u32 height,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res_is_greater_than_or_equal_to(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(u32 width, u32 height,
|
||||
u32 ref_width, u32 ref_height)
|
||||
{
|
||||
@@ -5334,13 +5348,12 @@ exit:
|
||||
return allow;
|
||||
}
|
||||
|
||||
int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
|
||||
static int msm_vidc_check_resolution_supported(struct msm_vidc_inst *inst)
|
||||
{
|
||||
struct msm_vidc_inst_capability *capability;
|
||||
u32 width = 0, height = 0, min_width, min_height,
|
||||
max_width, max_height;
|
||||
bool allow = false, is_interlaced = false;
|
||||
int rc = 0;
|
||||
bool is_interlaced = false;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
@@ -5348,24 +5361,6 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
|
||||
}
|
||||
capability = inst->capabilities;
|
||||
|
||||
if (is_image_session(inst) && is_secure_session(inst)) {
|
||||
i_vpr_e(inst, "%s: secure image session not supported\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = msm_vidc_check_core_mbps(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
rc = msm_vidc_check_core_mbpf(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
rc = msm_vidc_check_inst_mbpf(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
if (is_decode_session(inst)) {
|
||||
width = inst->fmts[INPUT_PORT].fmt.pix_mp.width;
|
||||
height = inst->fmts[INPUT_PORT].fmt.pix_mp.height;
|
||||
@@ -5399,56 +5394,171 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
|
||||
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;
|
||||
goto exit;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check decoder input width and height is in supported range */
|
||||
if (is_decode_session(inst)) {
|
||||
/* check if input width and height is in supported range */
|
||||
if (is_decode_session(inst) || is_encode_session(inst)) {
|
||||
if (!in_range(width, min_width, max_width) ||
|
||||
!in_range(height, min_height, max_height)) {
|
||||
i_vpr_e(inst,
|
||||
"%s: unsupported input wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n",
|
||||
__func__, width, height, min_width,
|
||||
min_height, max_width, max_height);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* check encoder crop width and height is in supported range */
|
||||
if (is_encode_session(inst)) {
|
||||
if (!in_range(width, min_width, max_width) ||
|
||||
!in_range(height, min_height, max_height)) {
|
||||
i_vpr_e(inst,
|
||||
"%s: unsupported wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n",
|
||||
__func__, width, height, min_width,
|
||||
min_height, max_width, max_height);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* check image capabilities */
|
||||
if (is_image_encode_session(inst)) {
|
||||
allow = msm_vidc_allow_image_encode_session(inst);
|
||||
if (!allow) {
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check interlace supported resolution */
|
||||
is_interlaced = capability->cap[CODED_FRAMES].value == CODED_FRAMES_INTERLACE;
|
||||
if (is_interlaced && (width > INTERLACE_WIDTH_MAX || height > INTERLACE_HEIGHT_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",
|
||||
__func__, width, height, INTERLACE_WIDTH_MAX, INTERLACE_HEIGHT_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vidc_check_max_sessions(struct msm_vidc_inst *inst)
|
||||
{
|
||||
u32 width = 0, height = 0;
|
||||
u32 num_720p_sessions = 0, num_1080p_sessions = 0;
|
||||
u32 num_4k_sessions = 0, num_8k_sessions = 0;
|
||||
struct msm_vidc_inst *i;
|
||||
struct msm_vidc_core *core;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
core = inst->core;
|
||||
|
||||
if (!core->capabilities) {
|
||||
i_vpr_e(inst, "%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core_lock(core, __func__);
|
||||
list_for_each_entry(i, &core->instances, list) {
|
||||
/* skip image sessions count */
|
||||
if (is_image_session(inst))
|
||||
continue;
|
||||
|
||||
if (is_decode_session(i)) {
|
||||
width = i->fmts[INPUT_PORT].fmt.pix_mp.width;
|
||||
height = i->fmts[INPUT_PORT].fmt.pix_mp.height;
|
||||
} else if (is_encode_session(i)) {
|
||||
width = i->crop.width;
|
||||
height = i->crop.height;
|
||||
}
|
||||
|
||||
/*
|
||||
* one 8k session equals to 64 720p sessions in reality.
|
||||
* So for one 8k session the number of 720p sessions will
|
||||
* exceed max supported session count(16), hence one 8k session
|
||||
* will be rejected as well.
|
||||
* Therefore, treat one 8k session equal to two 4k sessions and
|
||||
* one 4k session equal to two 1080p sessions and
|
||||
* one 1080p session equal to two 720p sessions. This equation
|
||||
* will make one 8k session equal to eight 720p sessions
|
||||
* which looks good.
|
||||
*/
|
||||
if (res_is_greater_than(width, height, 4096, 2176)) {
|
||||
num_8k_sessions += 1;
|
||||
num_4k_sessions += 2;
|
||||
num_1080p_sessions += 4;
|
||||
num_720p_sessions += 8;
|
||||
} else if (res_is_greater_than(width, height, 1920, 1088)) {
|
||||
num_4k_sessions += 1;
|
||||
num_1080p_sessions += 2;
|
||||
num_720p_sessions += 4;
|
||||
} else if (res_is_greater_than(width, height, 1280, 736)) {
|
||||
num_1080p_sessions += 1;
|
||||
num_720p_sessions += 2;
|
||||
} else {
|
||||
num_720p_sessions += 1;
|
||||
}
|
||||
}
|
||||
core_unlock(core, __func__);
|
||||
|
||||
if (num_8k_sessions > core->capabilities[MAX_NUM_8K_SESSIONS].value) {
|
||||
i_vpr_e(inst, "%s: total 8k sessions %d, exceeded max limit %d\n",
|
||||
__func__, num_8k_sessions,
|
||||
core->capabilities[MAX_NUM_8K_SESSIONS].value);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (num_4k_sessions > core->capabilities[MAX_NUM_4K_SESSIONS].value) {
|
||||
i_vpr_e(inst, "%s: total 4K sessions %d, exceeded max limit %d\n",
|
||||
__func__, num_4k_sessions,
|
||||
core->capabilities[MAX_NUM_4K_SESSIONS].value);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (num_1080p_sessions > core->capabilities[MAX_NUM_1080P_SESSIONS].value) {
|
||||
i_vpr_e(inst, "%s: total 1080p sessions %d, exceeded max limit %d\n",
|
||||
__func__, num_1080p_sessions,
|
||||
core->capabilities[MAX_NUM_1080P_SESSIONS].value);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (num_720p_sessions > core->capabilities[MAX_NUM_720P_SESSIONS].value) {
|
||||
i_vpr_e(inst, "%s: total sessions(<=720p) %d, exceeded max limit %d\n",
|
||||
__func__, num_720p_sessions,
|
||||
core->capabilities[MAX_NUM_720P_SESSIONS].value);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
|
||||
{
|
||||
bool allow = false;
|
||||
int rc = 0;
|
||||
|
||||
if (!inst) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_image_session(inst) && is_secure_session(inst)) {
|
||||
i_vpr_e(inst, "%s: secure image session not supported\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = msm_vidc_check_core_mbps(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
rc = msm_vidc_check_core_mbpf(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
rc = msm_vidc_check_inst_mbpf(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
rc = msm_vidc_check_resolution_supported(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
/* check image capabilities */
|
||||
if (is_image_encode_session(inst)) {
|
||||
allow = msm_vidc_allow_image_encode_session(inst);
|
||||
if (!allow) {
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
rc = msm_vidc_check_max_sessions(inst);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
if (rc) {
|
||||
i_vpr_e(inst, "%s: current session not supported\n", __func__);
|
||||
|
Reference in New Issue
Block a user