diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index 99d178bb87..b1ea1b24a0 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -1331,15 +1331,13 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { /* configure image properties */ {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, DEC, HEIC, 512, 8192, 1, 8192}, {MIN_BUFFERS_INPUT, ENC|DEC, HEIC, 0, 64, 1, 1, V4L2_CID_MIN_BUFFERS_FOR_OUTPUT}, - {MBPF, ENC, HEIC, 64, 262144, 262144}, /* ((8192x8192)/256) */ - {MBPF, DEC, HEIC, 36, 1048576, 1, 1048576}, /* ((16384x16384)/256) */ - {MBPS, ENC, HEIC, 64, 262144, 262144}, /* ((8192x8192)/256)@1fps */ - {MBPS, DEC, HEIC, 36, 1048576, 1, 1048576}, /* ((16384x16384)/256)@1fps */ + {MBPF, DEC, HEIC, 64, 262144, 1, 262144 }, /* ((8192x8192)/256) */ + {MBPF, ENC, HEIC, 36, 1048576, 1, 1048576}, /* ((16384x16384)/256) */ + {MBPS, DEC, HEIC, 64, 262144, 1, 262144 }, /* ((8192x8192)/256)@1fps */ + {MBPS, ENC, HEIC, 36, 1048576, 1, 1048576}, /* ((16384x16384)/256)@1fps */ {BITRATE_MODE, ENC, HEIC, V4L2_MPEG_VIDEO_BITRATE_MODE_CQ, V4L2_MPEG_VIDEO_BITRATE_MODE_CQ, diff --git a/driver/vidc/inc/msm_vidc_power.h b/driver/vidc/inc/msm_vidc_power.h index 322936fa04..4bcabbec49 100644 --- a/driver/vidc/inc/msm_vidc_power.h +++ b/driver/vidc/inc/msm_vidc_power.h @@ -248,6 +248,7 @@ static inline int __bpp(enum msm_vidc_colorformat_type f) 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_mbps(struct msm_vidc_inst *inst); int msm_vidc_scale_power(struct msm_vidc_inst *inst, bool scale_buses); void msm_vidc_power_data_reset(struct msm_vidc_inst *inst); #endif diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index 1ec521e917..88c7570c1b 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -1465,10 +1465,6 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst) if (rc) 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); if (rc) 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.width = f->fmt.pix_mp.width; 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, "%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, @@ -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, inst->buffers.input.min_count, inst->buffers.input.extra_count); - - //msm_vidc_update_dcvs(inst); - //msm_vidc_update_batching(inst); - } else if (f->type == INPUT_META_PLANE) { fmt = &inst->fmts[INPUT_META_PORT]; 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; pix_fmt = v4l2_colorformat_to_driver(f->fmt.pix_mp.pixelformat, __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, "%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, diff --git a/driver/vidc/src/msm_venc.c b/driver/vidc/src/msm_venc.c index 633ae356b6..a632c36714 100644 --- a/driver/vidc/src/msm_venc.c +++ b/driver/vidc/src/msm_venc.c @@ -1151,14 +1151,6 @@ int msm_venc_s_fmt_output(struct msm_vidc_inst *inst, struct v4l2_format *f) } inst->buffers.output.size = 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)); 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.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)); return rc; diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index d5d7d08fd1..e58e9be471 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -13,6 +13,7 @@ #include "msm_vidc_internal.h" #include "msm_vidc_control.h" #include "msm_vidc_memory.h" +#include "msm_vidc_power.h" #include "msm_vidc_debug.h" #include "msm_vidc_power.h" #include "msm_vidc.h" @@ -23,6 +24,8 @@ #include "hfi_packet.h" 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) { \ while ((a) >= 1) { \ (out) += (a) & (1); \ @@ -4665,12 +4668,119 @@ static int msm_vidc_check_mbpf_supported(struct msm_vidc_inst *inst) return 0; } +static bool msm_vidc_allow_image_encode_session(struct msm_vidc_inst *inst) +{ + struct msm_vidc_inst_capability *capability; + struct v4l2_format *fmt; + u32 min_width, min_height, max_width, max_height, pix_fmt, profile; + bool allow = false; + + if (!inst || !inst->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + return false; + } + capability = inst->capabilities; + + if (!is_image_encode_session(inst)) { + i_vpr_e(inst, "%s: not an image encode session\n", __func__); + return false; + } + + pix_fmt = capability->cap[PIX_FMTS].value; + profile = capability->cap[PROFILE].value; + + /* 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 */ + allow = is_linear_colorformat(pix_fmt); + if (!allow) { + i_vpr_e(inst, "%s: compressed fmt: %#x\n", __func__, pix_fmt); + goto exit; + } + + /* is input grid aligned */ + fmt = &inst->fmts[INPUT_PORT]; + allow = IS_ALIGNED(fmt->fmt.pix_mp.width, HEIC_GRID_DIMENSION); + allow &= IS_ALIGNED(fmt->fmt.pix_mp.height, HEIC_GRID_DIMENSION); + if (!allow) { + i_vpr_e(inst, "%s: input is not grid aligned: %u x %u\n", __func__, + fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height); + goto exit; + } + + /* is output grid dimension */ + fmt = &inst->fmts[OUTPUT_PORT]; + allow = fmt->fmt.pix_mp.width == HEIC_GRID_DIMENSION; + allow &= fmt->fmt.pix_mp.height == HEIC_GRID_DIMENSION; + if (!allow) { + i_vpr_e(inst, "%s: output is not a grid dimension: %u x %u\n", __func__, + fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height); + goto exit; + } + + /* is bitrate mode CQ */ + allow = capability->cap[BITRATE_MODE].value == HFI_RC_CQ; + if (!allow) { + i_vpr_e(inst, "%s: bitrate mode is not CQ: %#x\n", __func__, + capability->cap[BITRATE_MODE].value); + goto exit; + } + + /* is all intra */ + allow = !capability->cap[GOP_SIZE].value; + allow &= !capability->cap[B_FRAME].value; + if (!allow) { + i_vpr_e(inst, "%s: not all intra: gop: %u, bframe: %u\n", __func__, + capability->cap[GOP_SIZE].value, capability->cap[B_FRAME].value); + goto exit; + } + + /* is time delta based rc disabled */ + allow = !capability->cap[TIME_DELTA_BASED_RC].value; + if (!allow) { + i_vpr_e(inst, "%s: time delta based rc not disabled: %#x\n", __func__, + capability->cap[TIME_DELTA_BASED_RC].value); + goto exit; + } + + /* is profile type Still Pic */ + if (is_10bit_colorformat(pix_fmt)) + allow = profile == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10; + else + allow = profile == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE; + if (!allow) { + i_vpr_e(inst, "%s: profile not valid: %#x\n", __func__, + capability->cap[PROFILE].value); + 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 pix_fmt, profile; - bool allow = false; + 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) { @@ -4679,78 +4789,6 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) } capability = inst->capabilities; - /* todo: enable checks for all session type */ - if (!is_image_session(inst)) - return 0; - - pix_fmt = capability->cap[PIX_FMTS].value; - profile = capability->cap[PROFILE].value; - - if (is_image_encode_session(inst)) { - /* is linear color fmt */ - allow = is_linear_colorformat(pix_fmt); - if (!allow) { - i_vpr_e(inst, "%s: compressed fmt: %#x\n", __func__, pix_fmt); - goto exit; - } - - /* is input grid aligned */ - fmt = &inst->fmts[INPUT_PORT]; - allow = IS_ALIGNED(fmt->fmt.pix_mp.width, HEIC_GRID_DIMENSION); - allow &= IS_ALIGNED(fmt->fmt.pix_mp.height, HEIC_GRID_DIMENSION); - if (!allow) { - i_vpr_e(inst, "%s: input is not grid aligned: %u x %u\n", __func__, - fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height); - goto exit; - } - - /* is output grid dimension */ - fmt = &inst->fmts[OUTPUT_PORT]; - allow = fmt->fmt.pix_mp.width == HEIC_GRID_DIMENSION; - allow &= fmt->fmt.pix_mp.height == HEIC_GRID_DIMENSION; - if (!allow) { - i_vpr_e(inst, "%s: output is not a grid dimension: %u x %u\n", __func__, - fmt->fmt.pix_mp.width, fmt->fmt.pix_mp.height); - goto exit; - } - - /* is bitrate mode CQ */ - allow = capability->cap[BITRATE_MODE].value == HFI_RC_CQ; - if (!allow) { - i_vpr_e(inst, "%s: bitrate mode is not CQ: %#x\n", __func__, - capability->cap[BITRATE_MODE].value); - goto exit; - } - - /* is all intra */ - allow = !capability->cap[GOP_SIZE].value; - allow &= !capability->cap[B_FRAME].value; - if (!allow) { - i_vpr_e(inst, "%s: not all intra: gop: %u, bframe: %u\n", __func__, - capability->cap[GOP_SIZE].value, capability->cap[B_FRAME].value); - goto exit; - } - - /* is time delta based rc disabled */ - allow = !capability->cap[TIME_DELTA_BASED_RC].value; - if (!allow) { - i_vpr_e(inst, "%s: time delta based rc not disabled: %#x\n", __func__, - capability->cap[TIME_DELTA_BASED_RC].value); - goto exit; - } - - /* is profile type Still Pic */ - if (is_10bit_colorformat(pix_fmt)) - allow = profile == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10; - else - allow = profile == V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE; - if (!allow) { - i_vpr_e(inst, "%s: profile not valid: %#x\n", __func__, - capability->cap[PROFILE].value); - goto exit; - } - } - rc = msm_vidc_check_mbps_supported(inst); if (rc) goto exit; @@ -4759,7 +4797,76 @@ int msm_vidc_check_session_supported(struct msm_vidc_inst *inst) if (rc) 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; diff --git a/driver/vidc/src/msm_vidc_power.c b/driver/vidc/src/msm_vidc_power.c index eb2160601d..879115566f 100644 --- a/driver/vidc/src/msm_vidc_power.c +++ b/driver/vidc/src/msm_vidc_power.c @@ -45,7 +45,7 @@ u64 msm_vidc_max_freq(struct msm_vidc_inst *inst) 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 fps, operating_rate, frame_rate;