|
@@ -1104,6 +1104,20 @@ bool res_is_greater_than(u32 width, u32 height,
|
|
return false;
|
|
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,
|
|
bool res_is_less_than(u32 width, u32 height,
|
|
u32 ref_width, u32 ref_height)
|
|
u32 ref_width, u32 ref_height)
|
|
{
|
|
{
|
|
@@ -5334,13 +5348,12 @@ exit:
|
|
return allow;
|
|
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;
|
|
struct msm_vidc_inst_capability *capability;
|
|
u32 width = 0, height = 0, min_width, min_height,
|
|
u32 width = 0, height = 0, min_width, min_height,
|
|
max_width, max_height;
|
|
max_width, max_height;
|
|
- bool allow = false, is_interlaced = false;
|
|
|
|
- int rc = 0;
|
|
|
|
|
|
+ bool is_interlaced = false;
|
|
|
|
|
|
if (!inst || !inst->capabilities) {
|
|
if (!inst || !inst->capabilities) {
|
|
d_vpr_e("%s: invalid params\n", __func__);
|
|
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;
|
|
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)) {
|
|
if (is_decode_session(inst)) {
|
|
width = inst->fmts[INPUT_PORT].fmt.pix_mp.width;
|
|
width = inst->fmts[INPUT_PORT].fmt.pix_mp.width;
|
|
height = inst->fmts[INPUT_PORT].fmt.pix_mp.height;
|
|
height = inst->fmts[INPUT_PORT].fmt.pix_mp.height;
|
|
@@ -5399,36 +5394,158 @@ 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",
|
|
i_vpr_e(inst, "%s: resolution is not even. wxh [%u x %u], compose [%u x %u]\n",
|
|
__func__, width, height, inst->compose.width,
|
|
__func__, width, height, inst->compose.width,
|
|
inst->compose.height);
|
|
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) ||
|
|
if (!in_range(width, min_width, max_width) ||
|
|
!in_range(height, min_height, max_height)) {
|
|
!in_range(height, min_height, max_height)) {
|
|
i_vpr_e(inst,
|
|
i_vpr_e(inst,
|
|
"%s: unsupported input wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n",
|
|
"%s: unsupported input wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n",
|
|
__func__, width, height, min_width,
|
|
__func__, width, height, min_width,
|
|
min_height, max_width, max_height);
|
|
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 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 */
|
|
/* check image capabilities */
|
|
if (is_image_encode_session(inst)) {
|
|
if (is_image_encode_session(inst)) {
|
|
allow = msm_vidc_allow_image_encode_session(inst);
|
|
allow = msm_vidc_allow_image_encode_session(inst);
|
|
@@ -5436,18 +5553,11 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
|
|
rc = -EINVAL;
|
|
rc = -EINVAL;
|
|
goto exit;
|
|
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);
|
|
|
|
- rc = -EINVAL;
|
|
|
|
|
|
+ rc = msm_vidc_check_max_sessions(inst);
|
|
|
|
+ if (rc)
|
|
goto exit;
|
|
goto exit;
|
|
- }
|
|
|
|
|
|
|
|
exit:
|
|
exit:
|
|
if (rc) {
|
|
if (rc) {
|