video: driver: add check_session_supported for session admission

- check total mbps is within range(including current session)
- check total mbpf is within range(including current session)
- image session:
    - decode: Only non-secure allowed
    - encode: check basic image_encode requirements
        - wxh should be within allowed cap range
        - only linear fmt
        - input & output is 512 aligned
        - only CQ bitrate mode
        - GOP size should be zero
        - b-frame count is zero
        - timedelta based RC disabled
        - still-pic profile for 8bit and main10 for 10bit
- interlace resolution should be less than (1920*1088)/256.
- reject odd input or output resolution
- output resolution is with in inst->cap [min, max] range.
- current session mbpf is less than inst->cap[MBPF].max

Change-Id: I81c46950a8ef5b64bf5ac94564613998b1079b52
Signed-off-by: Govindaraj Rajagopal <grajagop@codeaurora.org>
Signed-off-by: Mihir Ganu <mganu@codeaurora.org>
This commit is contained in:
Govindaraj Rajagopal
2021-05-03 16:54:43 +05:30
committed by Mihir Ganu
parent 1ecbcd6110
commit 03db3bfd7f
6 changed files with 188 additions and 117 deletions

View File

@@ -1331,15 +1331,13 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
/* configure image properties */ /* configure image properties */
{FRAME_WIDTH, ENC, HEIC, 512, 16384, 1, 16384}, {FRAME_WIDTH, ENC, HEIC, 512, 16384, 1, 16384},
{FRAME_WIDTH, DEC, HEIC, 512, 8192, 1, 8192},
{FRAME_HEIGHT, ENC, HEIC, 512, 16384, 1, 16384}, {FRAME_HEIGHT, ENC, HEIC, 512, 16384, 1, 16384},
{FRAME_HEIGHT, DEC, HEIC, 512, 8192, 1, 8192},
{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, ENC, HEIC, 64, 262144, 262144}, /* ((8192x8192)/256) */ {MBPF, DEC, HEIC, 64, 262144, 1, 262144 }, /* ((8192x8192)/256) */
{MBPF, DEC, HEIC, 36, 1048576, 1, 1048576}, /* ((16384x16384)/256) */ {MBPF, ENC, HEIC, 36, 1048576, 1, 1048576}, /* ((16384x16384)/256) */
{MBPS, ENC, HEIC, 64, 262144, 262144}, /* ((8192x8192)/256)@1fps */ {MBPS, DEC, HEIC, 64, 262144, 1, 262144 }, /* ((8192x8192)/256)@1fps */
{MBPS, DEC, HEIC, 36, 1048576, 1, 1048576}, /* ((16384x16384)/256)@1fps */ {MBPS, ENC, HEIC, 36, 1048576, 1, 1048576}, /* ((16384x16384)/256)@1fps */
{BITRATE_MODE, ENC, HEIC, {BITRATE_MODE, ENC, HEIC,
V4L2_MPEG_VIDEO_BITRATE_MODE_CQ, V4L2_MPEG_VIDEO_BITRATE_MODE_CQ,
V4L2_MPEG_VIDEO_BITRATE_MODE_CQ, V4L2_MPEG_VIDEO_BITRATE_MODE_CQ,

View File

@@ -248,6 +248,7 @@ static inline int __bpp(enum msm_vidc_colorformat_type f)
u64 msm_vidc_max_freq(struct msm_vidc_inst* inst); u64 msm_vidc_max_freq(struct msm_vidc_inst* inst);
int msm_vidc_get_inst_load(struct msm_vidc_inst *inst); int msm_vidc_get_inst_load(struct msm_vidc_inst *inst);
int msm_vidc_get_mbps(struct msm_vidc_inst *inst);
int msm_vidc_scale_power(struct msm_vidc_inst *inst, bool scale_buses); int msm_vidc_scale_power(struct msm_vidc_inst *inst, bool scale_buses);
void msm_vidc_power_data_reset(struct msm_vidc_inst *inst); void msm_vidc_power_data_reset(struct msm_vidc_inst *inst);
#endif #endif

View File

@@ -1465,10 +1465,6 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
if (rc) if (rc)
goto error; goto error;
//msm_vidc_update_dcvs(inst);
//msm_vidc_update_batching(inst);
//msm_vidc_scale_power(inst);
rc = msm_vdec_create_input_internal_buffers(inst); rc = msm_vdec_create_input_internal_buffers(inst);
if (rc) if (rc)
goto error; goto error;
@@ -2094,12 +2090,6 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->crop.left = inst->crop.top = 0; inst->crop.left = inst->crop.top = 0;
inst->crop.width = f->fmt.pix_mp.width; inst->crop.width = f->fmt.pix_mp.width;
inst->crop.height = f->fmt.pix_mp.height; inst->crop.height = f->fmt.pix_mp.height;
//rc = msm_vidc_check_session_supported(inst);
if (rc)
goto err_invalid_fmt;
//update_log_ctxt(inst->sid, inst->session_type,
// mplane->pixelformat);
i_vpr_h(inst, i_vpr_h(inst,
"%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n", "%s: input: codec %#x width %d height %d size %d min_count %d extra_count %d\n",
__func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width, __func__, f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
@@ -2107,10 +2097,6 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
fmt->fmt.pix_mp.plane_fmt[0].sizeimage, fmt->fmt.pix_mp.plane_fmt[0].sizeimage,
inst->buffers.input.min_count, inst->buffers.input.min_count,
inst->buffers.input.extra_count); inst->buffers.input.extra_count);
//msm_vidc_update_dcvs(inst);
//msm_vidc_update_batching(inst);
} else if (f->type == INPUT_META_PLANE) { } else if (f->type == INPUT_META_PLANE) {
fmt = &inst->fmts[INPUT_META_PORT]; fmt = &inst->fmts[INPUT_META_PORT];
fmt->type = INPUT_META_PLANE; fmt->type = INPUT_META_PLANE;
@@ -2174,9 +2160,6 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
fmt->fmt.pix_mp.plane_fmt[0].sizeimage; fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
pix_fmt = v4l2_colorformat_to_driver(f->fmt.pix_mp.pixelformat, __func__); pix_fmt = v4l2_colorformat_to_driver(f->fmt.pix_mp.pixelformat, __func__);
msm_vidc_update_cap_value(inst, PIX_FMTS, pix_fmt, __func__); msm_vidc_update_cap_value(inst, PIX_FMTS, pix_fmt, __func__);
//rc = msm_vidc_check_session_supported(inst);
if (rc)
goto err_invalid_fmt;
i_vpr_h(inst, i_vpr_h(inst,
"%s: output: format %#x width %d height %d size %d min_count %d extra_count %d\n", "%s: output: format %#x width %d height %d size %d min_count %d extra_count %d\n",
__func__, fmt->fmt.pix_mp.pixelformat, fmt->fmt.pix_mp.width, __func__, fmt->fmt.pix_mp.pixelformat, fmt->fmt.pix_mp.width,

View File

@@ -1151,14 +1151,6 @@ int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format *f)
} }
inst->buffers.output.size = inst->buffers.output.size =
fmt->fmt.pix_mp.plane_fmt[0].sizeimage; fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
//rc = msm_vidc_check_session_supported(inst);
if (rc)
return rc;
//update_log_ctxt(inst->sid, inst->session_type,
// mplane->pixelformat);
memcpy(f, fmt, sizeof(struct v4l2_format)); memcpy(f, fmt, sizeof(struct v4l2_format));
return rc; return rc;
@@ -1293,16 +1285,6 @@ static int msm_venc_s_fmt_input(struct msm_vidc_inst *inst, struct v4l2_format *
output_fmt->fmt.pix_mp.height, output_fmt->fmt.pix_mp.height,
output_fmt->fmt.pix_mp.plane_fmt[0].sizeimage); output_fmt->fmt.pix_mp.plane_fmt[0].sizeimage);
} }
//rc = msm_vidc_check_session_supported(inst);
if (rc)
return rc;
//update_log_ctxt(inst->sid, inst->session_type,
// mplane->pixelformat);
//msm_vidc_update_dcvs(inst);
//msm_vidc_update_batching(inst);
memcpy(f, fmt, sizeof(struct v4l2_format)); memcpy(f, fmt, sizeof(struct v4l2_format));
return rc; return rc;

View File

@@ -13,6 +13,7 @@
#include "msm_vidc_internal.h" #include "msm_vidc_internal.h"
#include "msm_vidc_control.h" #include "msm_vidc_control.h"
#include "msm_vidc_memory.h" #include "msm_vidc_memory.h"
#include "msm_vidc_power.h"
#include "msm_vidc_debug.h" #include "msm_vidc_debug.h"
#include "msm_vidc_power.h" #include "msm_vidc_power.h"
#include "msm_vidc.h" #include "msm_vidc.h"
@@ -23,6 +24,8 @@
#include "hfi_packet.h" #include "hfi_packet.h"
extern struct msm_vidc_core *g_core; extern struct msm_vidc_core *g_core;
#define is_odd(val) ((val) % 2 == 1)
#define in_range(val, min, max) (((min) <= (val)) && ((val) <= (max)))
#define COUNT_BITS(a, out) { \ #define COUNT_BITS(a, out) { \
while ((a) >= 1) { \ while ((a) >= 1) { \
(out) += (a) & (1); \ (out) += (a) & (1); \
@@ -4665,28 +4668,42 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst)
return 0; return 0;
} }
int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) static bool msm_vidc_allow_image_encode_session(struct msm_vidc_inst *inst)
{ {
struct msm_vidc_inst_capability *capability; struct msm_vidc_inst_capability *capability;
struct v4l2_format *fmt; struct v4l2_format *fmt;
u32 pix_fmt, profile; u32 min_width, min_height, max_width, max_height, pix_fmt, profile;
bool allow = false; bool allow = false;
int rc = 0;
if (!inst || !inst->capabilities) { if (!inst || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__); d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL; return false;
} }
capability = inst->capabilities; capability = inst->capabilities;
/* todo: enable checks for all session type */ if (!is_image_encode_session(inst)) {
if (!is_image_session(inst)) i_vpr_e(inst, "%s: not an image encode session\n", __func__);
return 0; return false;
}
pix_fmt = capability->cap[PIX_FMTS].value; pix_fmt = capability->cap[PIX_FMTS].value;
profile = capability->cap[PROFILE].value; profile = capability->cap[PROFILE].value;
if (is_image_encode_session(inst)) { /* is input with & height is in allowed range */
min_width = capability->cap[FRAME_WIDTH].min;
max_width = capability->cap[FRAME_WIDTH].max;
min_height = capability->cap[FRAME_HEIGHT].min;
max_height = capability->cap[FRAME_HEIGHT].max;
fmt = &inst->fmts[INPUT_PORT];
if (!in_range(fmt->fmt.pix_mp.width, min_width, max_width) ||
!in_range(fmt->fmt.pix_mp.height, min_height, max_height)) {
i_vpr_e(inst, "unsupported wxh [%u x %u], allowed [%u x %u] to [%u x %u]\n",
fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height,
min_width, min_height, max_width, max_height);
allow = false;
goto exit;
}
/* is linear color fmt */ /* is linear color fmt */
allow = is_linear_colorformat(pix_fmt); allow = is_linear_colorformat(pix_fmt);
if (!allow) { if (!allow) {
@@ -4749,8 +4766,29 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
capability->cap[PROFILE].value); capability->cap[PROFILE].value);
goto exit; goto exit;
} }
return true;
exit:
i_vpr_e(inst, "%s: current session not allowed\n", __func__);
return allow;
} }
int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
{
struct msm_vidc_inst_capability *capability;
struct v4l2_format *fmt;
u32 iwidth, owidth, iheight, oheight, min_width, min_height,
max_width, max_height, mbpf, max_mbpf;
bool allow = false, is_interlaced = false;
int rc = 0;
if (!inst || !inst->capabilities) {
d_vpr_e("%s: invalid params\n", __func__);
return -EINVAL;
}
capability = inst->capabilities;
rc = msm_vidc_check_mbps_supported(inst); rc = msm_vidc_check_mbps_supported(inst);
if (rc) if (rc)
goto exit; goto exit;
@@ -4759,7 +4797,76 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst)
if (rc) if (rc)
goto exit; goto exit;
/* todo: add additional checks related to capabilities */ if (is_image_session(inst) && is_secure_session(inst)) {
i_vpr_e(inst, "%s: secure image session not supported\n", __func__);
goto exit;
}
/* check image capabilities */
if (is_image_encode_session(inst)) {
allow = msm_vidc_allow_image_encode_session(inst);
if (!allow)
goto exit;
return 0;
}
fmt = &inst->fmts[INPUT_PORT];
iwidth = fmt->fmt.pix_mp.width;
iheight = fmt->fmt.pix_mp.height;
fmt = &inst->fmts[OUTPUT_PORT];
owidth = fmt->fmt.pix_mp.width;
oheight = fmt->fmt.pix_mp.height;
if (is_secure_session(inst)) {
min_width = capability->cap[SECURE_FRAME_WIDTH].min;
max_width = capability->cap[SECURE_FRAME_WIDTH].max;
min_height = capability->cap[SECURE_FRAME_HEIGHT].min;
max_height = capability->cap[SECURE_FRAME_HEIGHT].max;
max_mbpf = capability->cap[SECURE_MBPF].max;
} else if (is_encode_session(inst) && capability->cap[LOSSLESS].value) {
min_width = capability->cap[LOSSLESS_FRAME_WIDTH].min;
max_width = capability->cap[LOSSLESS_FRAME_WIDTH].max;
min_height = capability->cap[LOSSLESS_FRAME_HEIGHT].min;
max_height = capability->cap[LOSSLESS_FRAME_HEIGHT].max;
max_mbpf = capability->cap[LOSSLESS_MBPF].max;
} else {
min_width = capability->cap[FRAME_WIDTH].min;
max_width = capability->cap[FRAME_WIDTH].max;
min_height = capability->cap[FRAME_HEIGHT].min;
max_height = capability->cap[FRAME_HEIGHT].max;
max_mbpf = capability->cap[MBPF].max;
}
/* check interlace supported resolution */
is_interlaced = capability->cap[CODED_FRAMES].value == CODED_FRAMES_INTERLACE;
if (is_interlaced && (owidth > INTERLACE_WIDTH_MAX || oheight > INTERLACE_HEIGHT_MAX ||
NUM_MBS_PER_FRAME(owidth, oheight) > INTERLACE_MB_PER_FRAME_MAX)) {
i_vpr_e(inst, "unsupported interlace wxh [%u x %u], max [%u x %u]\n",
owidth, oheight, INTERLACE_WIDTH_MAX, INTERLACE_HEIGHT_MAX);
goto exit;
}
/* reject odd resolution session */
if (is_odd(iwidth) || is_odd(iheight) || is_odd(owidth) || is_odd(oheight)) {
i_vpr_e(inst, "resolution is not even. input [%u x %u], output [%u x %u]\n",
iwidth, iheight, owidth, oheight);
goto exit;
}
/* check width and height is in supported range */
if (!in_range(owidth, min_width, max_width) || !in_range(oheight, min_height, max_height)) {
i_vpr_e(inst, "unsupported wxh [%u x %u], allowed range: [%u x %u] to [%u x %u]\n",
owidth, oheight, min_width, min_height, max_width, max_height);
goto exit;
}
/* check current session mbpf */
mbpf = msm_vidc_get_mbs_per_frame(inst);
if (mbpf > max_mbpf) {
i_vpr_e(inst, "unsupported mbpf %u, max %u\n", mbpf, max_mbpf);
goto exit;
}
return 0; return 0;

View File

@@ -45,7 +45,7 @@ u64 msm_vidc_max_freq(struct msm_vidc_inst *inst)
return freq; return freq;
} }
static int msm_vidc_get_mbps(struct msm_vidc_inst *inst) int msm_vidc_get_mbps(struct msm_vidc_inst *inst)
{ {
int input_port_mbs, output_port_mbs; int input_port_mbs, output_port_mbs;
int fps, operating_rate, frame_rate; int fps, operating_rate, frame_rate;