diff --git a/driver/platform/waipio/src/msm_vidc_waipio.c b/driver/platform/waipio/src/msm_vidc_waipio.c index 1015dd2524..e32e004411 100644 --- a/driver/platform/waipio/src/msm_vidc_waipio.c +++ b/driver/platform/waipio/src/msm_vidc_waipio.c @@ -159,21 +159,15 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { /* ((4096 * 2304) / 256) * 60 fps */ {POWER_SAVE_MBPS, ENC, CODECS_ALL, 0, 2211840, 1, 2211840}, - // TODO: Decide to store q16 or just int - {FRAME_RATE, ENC, CODECS_ALL, + {FRAME_RATE, ENC|DEC, CODECS_ALL, (MINIMUM_FPS << 16), (MAXIMUM_FPS << 16), 1, (DEFAULT_FPS << 16), 0, HFI_PROP_FRAME_RATE, - CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT, - {0}, {0}, - NULL, msm_vidc_set_q16}, + CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT}, - // Implement: Operating rate will accept any int value. {OPERATING_RATE, ENC|DEC, CODECS_ALL, - 1, INT_MAX, 1, (DEFAULT_FPS << 16), - 0, - HFI_PROP_FRAME_RATE}, + 1, INT_MAX, 1, (DEFAULT_FPS << 16)}, {SCALE_X, ENC, CODECS_ALL, 8192, 65536, 1, 8192}, {SCALE_X, DEC, CODECS_ALL, 65536, 65536, 1, 65536}, @@ -922,9 +916,19 @@ static struct msm_platform_inst_capability instance_data_waipio[] = { CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT}, // TODO - {STAGE, DEC|ENC, CODECS_ALL, 1, 2, 1, 2}, - {PIPE, DEC|ENC, CODECS_ALL, 1, 4, 1, 4}, - {POC, DEC, H264, 0, 1, 1, 0}, + {STAGE, DEC|ENC, CODECS_ALL, + MSM_VIDC_STAGE_1, + MSM_VIDC_STAGE_2, 1, + MSM_VIDC_STAGE_2}, + {PIPE, DEC|ENC, CODECS_ALL, + MSM_VIDC_PIPE_1, + MSM_VIDC_PIPE_4, 1, + MSM_VIDC_PIPE_4}, + {POC, DEC, H264, 0, 18, 1, 1}, + {QUALITY_MODE, DEC|ENC, CODECS_ALL, + MSM_VIDC_MAX_QUALITY_MODE, + MSM_VIDC_POWER_SAVE_MODE, 1, + MSM_VIDC_MAX_QUALITY_MODE}, {CODED_FRAMES, DEC, CODECS_ALL, 0, 1, 1, 0, 0, diff --git a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c index 940d94fa55..fea9826954 100644 --- a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c @@ -194,10 +194,10 @@ static u32 msm_vidc_encoder_bin_size_iris2(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; u32 size = 0; - u32 width, height, num_vpp_pipes; + u32 width, height, num_vpp_pipes, stage; struct v4l2_format *f; - if (!inst || !inst->core) { + if (!inst || !inst->core || !inst->capabilities) { d_vpr_e("%s: invalid params\n", __func__); return size; } @@ -207,14 +207,15 @@ static u32 msm_vidc_encoder_bin_size_iris2(struct msm_vidc_inst *inst) return size; } num_vpp_pipes = core->capabilities[NUM_VPP_PIPE].value; + stage = inst->capabilities->cap[STAGE].value; f = &inst->fmts[OUTPUT_PORT]; width = f->fmt.pix_mp.width; height = f->fmt.pix_mp.height; if (inst->codec == MSM_VIDC_H264) - HFI_BUFFER_BIN_H264E(size, width, height, inst->stage, num_vpp_pipes); + HFI_BUFFER_BIN_H264E(size, width, height, stage, num_vpp_pipes); else if (inst->codec == MSM_VIDC_HEVC) - HFI_BUFFER_BIN_H265E(size, width, height, inst->stage, num_vpp_pipes); + HFI_BUFFER_BIN_H265E(size, width, height, stage, num_vpp_pipes); s_vpr_l(inst->sid, "%s: size %d\n", __func__, size); return size; diff --git a/driver/variant/iris2/src/msm_vidc_power_iris2.c b/driver/variant/iris2/src/msm_vidc_power_iris2.c index e47829d733..eb045d4495 100644 --- a/driver/variant/iris2/src/msm_vidc_power_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_power_iris2.c @@ -65,13 +65,14 @@ u64 msm_vidc_calc_freq_iris2(struct msm_vidc_inst *inst, u32 data_size) /* VSP */ /* bitrate is based on fps, scale it using operating rate */ - operating_rate = inst->prop.operating_rate >> 16; - if (operating_rate > (inst->prop.frame_rate >> 16) && - (inst->prop.frame_rate >> 16)) { + operating_rate = inst->capabilities->cap[OPERATING_RATE].value >> 16; + if (operating_rate > + (inst->capabilities->cap[FRAME_RATE].value >> 16) && + (inst->capabilities->cap[FRAME_RATE].value >> 16)) { vsp_factor_num = operating_rate; - vsp_factor_den = inst->prop.frame_rate >> 16; + vsp_factor_den = inst->capabilities->cap[FRAME_RATE].value >> 16; } - vsp_cycles = div_u64(((u64)inst->prop.bitrate * + vsp_cycles = div_u64(((u64)inst->capabilities->cap[BIT_RATE].value * vsp_factor_num), vsp_factor_den); base_cycles = core->capabilities[MB_CYCLES_VSP].value; diff --git a/driver/vidc/inc/msm_vdec.h b/driver/vidc/inc/msm_vdec.h index f4102549da..132cd74700 100644 --- a/driver/vidc/inc/msm_vdec.h +++ b/driver/vidc/inc/msm_vdec.h @@ -18,6 +18,10 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_vdec_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s); int msm_vdec_g_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s); +int msm_vdec_s_param(struct msm_vidc_inst *inst, + struct v4l2_streamparm *s_parm); +int msm_vdec_g_param(struct msm_vidc_inst *inst, + struct v4l2_streamparm *s_parm); int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f); int msm_vdec_inst_init(struct msm_vidc_inst *inst); int msm_vdec_inst_deinit(struct msm_vidc_inst *inst); diff --git a/driver/vidc/inc/msm_venc.h b/driver/vidc/inc/msm_venc.h index 70e1e44a4d..6714b4b87b 100644 --- a/driver/vidc/inc/msm_venc.h +++ b/driver/vidc/inc/msm_venc.h @@ -18,6 +18,10 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f); int msm_venc_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s); int msm_venc_g_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s); +int msm_venc_s_param(struct msm_vidc_inst *inst, + struct v4l2_streamparm *s_parm); +int msm_venc_g_param(struct msm_vidc_inst *inst, + struct v4l2_streamparm *s_parm); int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f); int msm_venc_inst_init(struct msm_vidc_inst *inst); int msm_venc_inst_deinit(struct msm_vidc_inst *inst); diff --git a/driver/vidc/inc/msm_vidc.h b/driver/vidc/inc/msm_vidc.h index ede165d584..0f8966cc7e 100644 --- a/driver/vidc/inc/msm_vidc.h +++ b/driver/vidc/inc/msm_vidc.h @@ -23,6 +23,8 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f); int msm_vidc_g_fmt(void *instance, struct v4l2_format *f); int msm_vidc_s_selection(void* instance, struct v4l2_selection* s); int msm_vidc_g_selection(void* instance, struct v4l2_selection* s); +int msm_vidc_s_param(void *instance, struct v4l2_streamparm *sp); +int msm_vidc_g_param(void *instance, struct v4l2_streamparm *sp); int msm_vidc_s_ctrl(void *instance, struct v4l2_control *a); int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a); int msm_vidc_g_ext_ctrl(void *instance, struct v4l2_ext_controls *a); diff --git a/driver/vidc/inc/msm_vidc_inst.h b/driver/vidc/inc/msm_vidc_inst.h index f92191b9ef..65440d0168 100644 --- a/driver/vidc/inc/msm_vidc_inst.h +++ b/driver/vidc/inc/msm_vidc_inst.h @@ -105,10 +105,6 @@ struct msm_vidc_inst { struct vb2_queue vb2q[MAX_PORT]; struct msm_vidc_rectangle crop; struct msm_vidc_rectangle compose; - struct msm_vidc_properties prop; - enum msm_vidc_stage_type stage; - enum msm_vidc_pipe_type pipe; - enum msm_vidc_quality_mode quality_mode; struct msm_vidc_power power; enum msm_vidc_modes flags; struct vidc_bus_vote_data bus_data; diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index 346ae758d4..e14038e643 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/driver/vidc/inc/msm_vidc_internal.h @@ -336,6 +336,7 @@ enum msm_vidc_inst_capability_type { STAGE, PIPE, POC, + QUALITY_MODE, CODED_FRAMES, BIT_DEPTH, CODEC_CONFIG, diff --git a/driver/vidc/inc/msm_vidc_v4l2.h b/driver/vidc/inc/msm_vidc_v4l2.h index 0cd9ecdefc..4475122032 100644 --- a/driver/vidc/inc/msm_vidc_v4l2.h +++ b/driver/vidc/inc/msm_vidc_v4l2.h @@ -26,6 +26,10 @@ int msm_v4l2_s_selection(struct file* file, void* fh, struct v4l2_selection* s); int msm_v4l2_g_selection(struct file* file, void* fh, struct v4l2_selection* s); +int msm_v4l2_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *a); +int msm_v4l2_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *a); int msm_v4l2_s_ctrl(struct file *file, void *fh, struct v4l2_control *a); int msm_v4l2_g_ctrl(struct file *file, void *fh, diff --git a/driver/vidc/src/hfi_packet.c b/driver/vidc/src/hfi_packet.c index 3b724dc294..d83d54759c 100644 --- a/driver/vidc/src/hfi_packet.c +++ b/driver/vidc/src/hfi_packet.c @@ -213,7 +213,12 @@ u32 get_hfi_quality_mode(struct msm_vidc_inst *inst) { u32 hfi_mode = HFI_MODE_POWER_SAVE; - switch(inst->quality_mode) { + if (!inst || !inst->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + goto exit; + } + + switch(inst->capabilities->cap[QUALITY_MODE].value) { case MSM_VIDC_MAX_QUALITY_MODE: hfi_mode = HFI_MODE_MAX_QUALITY; break; @@ -221,11 +226,12 @@ u32 get_hfi_quality_mode(struct msm_vidc_inst *inst) hfi_mode = HFI_MODE_POWER_SAVE; break; default: - s_vpr_e(inst->sid, "%s: invalid qulity mode %d\n", - __func__, inst->quality_mode); + s_vpr_e(inst->sid, "%s: invalid qulity mode %d\n", __func__, + inst->capabilities->cap[QUALITY_MODE].value); break; } +exit: return hfi_mode; } diff --git a/driver/vidc/src/msm_vdec.c b/driver/vidc/src/msm_vdec.c index 9d03caa797..ac6ca287d6 100644 --- a/driver/vidc/src/msm_vdec.c +++ b/driver/vidc/src/msm_vdec.c @@ -449,6 +449,7 @@ static int msm_vdec_set_stage(struct msm_vidc_inst *inst) int rc = 0; u32 stage = 0; struct msm_vidc_core *core = inst->core; + struct msm_vidc_inst_capability *capability = inst->capabilities; rc = call_session_op(core, decide_work_mode, inst); if (rc) { @@ -457,7 +458,7 @@ static int msm_vdec_set_stage(struct msm_vidc_inst *inst) return -EINVAL; } - stage = inst->stage; + stage = capability->cap[STAGE].value; s_vpr_h(inst->sid, "%s: stage: %d", __func__, stage); rc = venus_hfi_session_property(inst, HFI_PROP_STAGE, @@ -477,6 +478,7 @@ static int msm_vdec_set_pipe(struct msm_vidc_inst *inst) int rc = 0; u32 pipe; struct msm_vidc_core *core = inst->core; + struct msm_vidc_inst_capability *capability = inst->capabilities; rc = call_session_op(core, decide_work_route, inst); if (rc) { @@ -485,14 +487,14 @@ static int msm_vdec_set_pipe(struct msm_vidc_inst *inst) return -EINVAL; } - pipe = inst->pipe; + pipe = capability->cap[PIPE].value; s_vpr_h(inst->sid, "%s: pipe: %d", __func__, pipe); rc = venus_hfi_session_property(inst, HFI_PROP_PIPE, HFI_HOST_FLAGS_NONE, HFI_PORT_NONE, HFI_PAYLOAD_U32, - &inst->pipe, + &pipe, sizeof(u32)); if (rc) s_vpr_e(inst->sid, "%s: set property failed\n", __func__); @@ -1751,6 +1753,108 @@ int msm_vdec_g_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s) return 0; } +int msm_vdec_s_param(struct msm_vidc_inst *inst, + struct v4l2_streamparm *s_parm) +{ + int rc = 0; + struct msm_vidc_inst_capability *capability = NULL; + struct v4l2_fract *timeperframe = NULL; + u32 q16_rate, max_rate, default_rate; + u64 us_per_frame = 0, input_rate = 0; + bool is_frame_rate = false; + + if (!inst || !s_parm) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + capability = inst->capabilities; + + if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + timeperframe = &s_parm->parm.output.timeperframe; + max_rate = capability->cap[FRAME_RATE].max; + default_rate = capability->cap[FRAME_RATE].value; + is_frame_rate = true; + } else { + timeperframe = &s_parm->parm.capture.timeperframe; + max_rate = capability->cap[OPERATING_RATE].value; + default_rate = capability->cap[OPERATING_RATE].value; + } + + if (!timeperframe->denominator || !timeperframe->numerator) { + s_vpr_e(inst->sid, + "%s: invalid rate for type %u\n", + __func__, s_parm->type); + input_rate = default_rate >> 16; + goto set_default; + } + + us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; + do_div(us_per_frame, timeperframe->denominator); + + if (!us_per_frame) { + s_vpr_e(inst->sid, "%s: us_per_frame is zero\n", + __func__); + rc = -EINVAL; + goto exit; + } + + input_rate = (u64)USEC_PER_SEC; + do_div(input_rate, us_per_frame); + + /* Check max allowed rate */ + if (input_rate > max_rate) { + s_vpr_e(inst->sid, + "%s: Unsupported rate %u, max_fps %u, type: %u\n", + __func__, input_rate, max_rate, s_parm->type); + rc = -ENOTSUPP; + goto exit; + } + +set_default: + q16_rate = (u32)input_rate << 16; + s_vpr_h(inst->sid, "%s: type %u value %#x\n", + __func__, s_parm->type, q16_rate); + + if (is_frame_rate) { + capability->cap[FRAME_RATE].value = q16_rate; + } else { + capability->cap[OPERATING_RATE].value = q16_rate; + } + +exit: + return rc; +} + +int msm_vdec_g_param(struct msm_vidc_inst *inst, + struct v4l2_streamparm *s_parm) +{ + struct msm_vidc_inst_capability *capability = NULL; + struct v4l2_fract *timeperframe = NULL; + + if (!inst || !s_parm) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + capability = inst->capabilities; + + if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + timeperframe = &s_parm->parm.output.timeperframe; + timeperframe->numerator = 1; + timeperframe->denominator = + capability->cap[FRAME_RATE].value >> 16; + } else { + timeperframe = &s_parm->parm.capture.timeperframe; + timeperframe->numerator = 1; + timeperframe->denominator = + capability->cap[OPERATING_RATE].value >> 16; + } + + s_vpr_h(inst->sid, "%s: type %u, num %u denom %u\n", + __func__, s_parm->type, timeperframe->numerator, + timeperframe->denominator); + return 0; +} + int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) { int rc = 0; @@ -1894,11 +1998,6 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) inst->buffers.output_meta.actual_count = inst->buffers.output.actual_count; inst->buffers.output_meta.size = f->fmt.meta.buffersize; - inst->prop.frame_rate = DEFAULT_FPS << 16; - inst->prop.operating_rate = DEFAULT_FPS << 16; - inst->stage = MSM_VIDC_STAGE_2; - inst->pipe = MSM_VIDC_PIPE_4; - rc = msm_vdec_codec_change(inst, inst->fmts[INPUT_PORT].fmt.pix_mp.pixelformat); diff --git a/driver/vidc/src/msm_venc.c b/driver/vidc/src/msm_venc.c index 89c31877ed..09ca3ba166 100644 --- a/driver/vidc/src/msm_venc.c +++ b/driver/vidc/src/msm_venc.c @@ -272,6 +272,8 @@ static int msm_venc_set_stage(struct msm_vidc_inst *inst) { int rc = 0; struct msm_vidc_core *core = inst->core; + struct msm_vidc_inst_capability *capability = inst->capabilities; + u32 stage; rc = call_session_op(core, decide_work_mode, inst); if (rc) { @@ -280,13 +282,14 @@ static int msm_venc_set_stage(struct msm_vidc_inst *inst) return -EINVAL; } - s_vpr_h(inst->sid, "%s: stage: %u\n", __func__, inst->stage); + stage = capability->cap[STAGE].value; + s_vpr_h(inst->sid, "%s: stage: %u\n", __func__, stage); rc = venus_hfi_session_property(inst, HFI_PROP_STAGE, HFI_HOST_FLAGS_NONE, HFI_PORT_NONE, HFI_PAYLOAD_U32, - &inst->stage, + &stage, sizeof(u32)); if (rc) return rc; @@ -297,6 +300,8 @@ static int msm_venc_set_pipe(struct msm_vidc_inst *inst) { int rc = 0; struct msm_vidc_core *core = inst->core; + struct msm_vidc_inst_capability *capability = inst->capabilities; + u32 pipe; rc = call_session_op(core, decide_work_route, inst); if (rc) { @@ -305,13 +310,14 @@ static int msm_venc_set_pipe(struct msm_vidc_inst *inst) return -EINVAL; } - s_vpr_h(inst->sid, "%s: pipe: %u\n", __func__, inst->pipe); + pipe = capability->cap[PIPE].value; + s_vpr_h(inst->sid, "%s: pipe: %u\n", __func__, pipe); rc = venus_hfi_session_property(inst, HFI_PROP_PIPE, HFI_HOST_FLAGS_NONE, HFI_PORT_NONE, HFI_PAYLOAD_U32, - &inst->pipe, + &pipe, sizeof(u32)); if (rc) return rc; @@ -321,20 +327,17 @@ static int msm_venc_set_pipe(struct msm_vidc_inst *inst) static int msm_venc_set_quality_mode(struct msm_vidc_inst *inst) { int rc = 0; + struct msm_vidc_inst_capability *capability = inst->capabilities; + u32 mode; - if (!inst->quality_mode) { - s_vpr_e(inst->sid, "%s: invalid mode: %u\n", - __func__, inst->quality_mode); - return -EINVAL; - } - - s_vpr_h(inst->sid, "%s: quality_mode: %u\n", __func__, inst->quality_mode); + mode = capability->cap[QUALITY_MODE].value; + s_vpr_h(inst->sid, "%s: quality_mode: %u\n", __func__, mode); rc = venus_hfi_session_property(inst, HFI_PROP_QUALITY_MODE, HFI_HOST_FLAGS_NONE, HFI_PORT_BITSTREAM, HFI_PAYLOAD_U32_ENUM, - &inst->quality_mode, + &mode, sizeof(u32)); if (rc) return rc; @@ -1267,6 +1270,121 @@ int msm_venc_g_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s) return rc; } +int msm_venc_s_param(struct msm_vidc_inst *inst, + struct v4l2_streamparm *s_parm) +{ + int rc = 0; + struct msm_vidc_inst_capability *capability = NULL; + struct v4l2_fract *timeperframe = NULL; + u32 q16_rate, max_rate, default_rate; + u64 us_per_frame = 0, input_rate = 0; + bool is_frame_rate = false; + + if (!inst || !s_parm) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + capability = inst->capabilities; + + if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + timeperframe = &s_parm->parm.output.timeperframe; + max_rate = capability->cap[OPERATING_RATE].max; + default_rate = capability->cap[OPERATING_RATE].value; + } else { + timeperframe = &s_parm->parm.capture.timeperframe; + is_frame_rate = true; + max_rate = capability->cap[FRAME_RATE].value; + default_rate = capability->cap[FRAME_RATE].value; + } + + if (!timeperframe->denominator || !timeperframe->numerator) { + s_vpr_e(inst->sid, + "%s: invalid rate for type %u\n", + __func__, s_parm->type); + input_rate = default_rate >> 16; + goto set_default; + } + + us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC; + do_div(us_per_frame, timeperframe->denominator); + + if (!us_per_frame) { + s_vpr_e(inst->sid, "%s: us_per_frame is zero\n", + __func__); + rc = -EINVAL; + goto exit; + } + + input_rate = (u64)USEC_PER_SEC; + do_div(input_rate, us_per_frame); + + /* Check max allowed rate */ + if (input_rate > max_rate) { + s_vpr_e(inst->sid, + "%s: Unsupported rate %u, max_fps %u, type: %u\n", + __func__, input_rate, max_rate, s_parm->type); + rc = -ENOTSUPP; + goto exit; + } + +set_default: + q16_rate = (u32)input_rate << 16; + s_vpr_h(inst->sid, "%s: type %u value %#x\n", + __func__, s_parm->type, q16_rate); + + if (is_frame_rate) { + rc = venus_hfi_session_property(inst, + HFI_PROP_FRAME_RATE, + HFI_HOST_FLAGS_NONE, + HFI_PORT_BITSTREAM, + HFI_PAYLOAD_Q16, + &q16_rate, + sizeof(u32)); + if (rc) { + s_vpr_e(inst->sid, + "%s: failed to set frame rate to fw\n", + __func__); + goto exit; + } + capability->cap[FRAME_RATE].value = q16_rate; + } else { + capability->cap[OPERATING_RATE].value = q16_rate; + } + +exit: + return rc; +} + +int msm_venc_g_param(struct msm_vidc_inst *inst, + struct v4l2_streamparm *s_parm) +{ + struct msm_vidc_inst_capability *capability = NULL; + struct v4l2_fract *timeperframe = NULL; + + if (!inst || !s_parm) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + capability = inst->capabilities; + + if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + timeperframe = &s_parm->parm.output.timeperframe; + timeperframe->numerator = 1; + timeperframe->denominator = + capability->cap[OPERATING_RATE].value >> 16; + } else { + timeperframe = &s_parm->parm.capture.timeperframe; + timeperframe->numerator = 1; + timeperframe->denominator = + capability->cap[FRAME_RATE].value >> 16; + } + + s_vpr_h(inst->sid, "%s: type %u, num %u denom %u\n", + __func__, s_parm->type, timeperframe->numerator, + timeperframe->denominator); + return 0; +} + int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) { int rc = 0; @@ -1409,12 +1527,6 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) inst->buffers.input_meta.actual_count = inst->buffers.input.actual_count; inst->buffers.input_meta.size = f->fmt.meta.buffersize; - inst->prop.frame_rate = DEFAULT_FPS << 16; - inst->prop.operating_rate = DEFAULT_FPS << 16; - inst->stage = MSM_VIDC_STAGE_1; - inst->pipe = MSM_VIDC_PIPE_4; - inst->quality_mode = MSM_VIDC_MAX_QUALITY_MODE; - rc = msm_venc_codec_change(inst, inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat); diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index 4b6137748c..d506e1aa38 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -303,6 +303,52 @@ int msm_vidc_g_selection(void* instance, struct v4l2_selection* s) } EXPORT_SYMBOL(msm_vidc_g_selection); +int msm_vidc_s_param(void *instance, struct v4l2_streamparm *param) +{ + int rc = 0; + struct msm_vidc_inst *inst = instance; + + if (!inst || !param) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && + param->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return -EINVAL; + + if (is_decode_session(inst)) + rc = msm_vdec_s_param(instance, param); + else if (is_encode_session(inst)) + rc = msm_venc_s_param(instance, param); + + return rc; +} +EXPORT_SYMBOL(msm_vidc_s_param); + +int msm_vidc_g_param(void *instance, struct v4l2_streamparm *param) +{ + int rc = 0; + struct msm_vidc_inst *inst = instance; + + if (!inst || !param) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + if (param->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && + param->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + return -EINVAL; + + if (is_decode_session(inst)) + rc = msm_vdec_g_param(instance, param); + else if (is_encode_session(inst)) + rc = msm_venc_g_param(instance, param); + + return rc; +} +EXPORT_SYMBOL(msm_vidc_g_param); + int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control) { struct msm_vidc_inst *inst = instance; diff --git a/driver/vidc/src/msm_vidc_control.c b/driver/vidc/src/msm_vidc_control.c index d4720a435b..7f0654ab9c 100644 --- a/driver/vidc/src/msm_vidc_control.c +++ b/driver/vidc/src/msm_vidc_control.c @@ -850,12 +850,12 @@ int msm_vidc_set_bitrate_mode(void *instance, if (lossless) { hfi_value = HFI_RC_LOSSLESS; - return rc; + goto set; } if (!frame_rc) { hfi_value = HFI_RC_OFF; - return rc; + goto set; } if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { @@ -871,6 +871,7 @@ int msm_vidc_set_bitrate_mode(void *instance, } */ +set: rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32_ENUM, &hfi_value, sizeof(u32), __func__); diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 93fae80cd6..bdf21e6198 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -1061,12 +1061,21 @@ int msm_vidc_get_mbs_per_frame(struct msm_vidc_inst *inst) int msm_vidc_get_fps(struct msm_vidc_inst *inst) { int fps; + u32 frame_rate, operating_rate; - if (inst->prop.operating_rate > inst->prop.frame_rate) - fps = (inst->prop.operating_rate >> 16) ? - (inst->prop.operating_rate >> 16) : 1; + if (!inst || !inst->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + + frame_rate = inst->capabilities->cap[FRAME_RATE].value; + operating_rate = inst->capabilities->cap[OPERATING_RATE].value; + + if (operating_rate > frame_rate) + fps = (operating_rate >> 16) ? + (operating_rate >> 16) : 1; else - fps = inst->prop.frame_rate >> 16; + fps = frame_rate >> 16; return fps; } diff --git a/driver/vidc/src/msm_vidc_platform.c b/driver/vidc/src/msm_vidc_platform.c index fcb69eb38b..07f0fb96f0 100644 --- a/driver/vidc/src/msm_vidc_platform.c +++ b/driver/vidc/src/msm_vidc_platform.c @@ -41,6 +41,8 @@ static struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = { .vidioc_g_fmt_meta_cap = msm_v4l2_g_fmt, .vidioc_g_selection = msm_v4l2_g_selection, .vidioc_s_selection = msm_v4l2_s_selection, + .vidioc_s_parm = msm_v4l2_s_parm, + .vidioc_g_parm = msm_v4l2_g_parm, .vidioc_reqbufs = msm_v4l2_reqbufs, .vidioc_qbuf = msm_v4l2_qbuf, .vidioc_dqbuf = msm_v4l2_dqbuf, diff --git a/driver/vidc/src/msm_vidc_power.c b/driver/vidc/src/msm_vidc_power.c index 4cfe5f8a3f..458bafa9fd 100644 --- a/driver/vidc/src/msm_vidc_power.c +++ b/driver/vidc/src/msm_vidc_power.c @@ -45,7 +45,7 @@ static int msm_vidc_get_mbps(struct msm_vidc_inst *inst, enum load_calc_quirks quirks) { int input_port_mbs, output_port_mbs; - int fps; + int fps, operating_rate, frame_rate; struct v4l2_format *f; f = &inst->fmts[INPUT_PORT]; @@ -56,11 +56,14 @@ static int msm_vidc_get_mbps(struct msm_vidc_inst *inst, output_port_mbs = NUM_MBS_PER_FRAME(f->fmt.pix_mp.width, f->fmt.pix_mp.height); - fps = inst->prop.frame_rate; + frame_rate = inst->capabilities->cap[FRAME_RATE].value; + operating_rate = inst->capabilities->cap[OPERATING_RATE].value; + + fps = frame_rate; /* For admission control operating rate is ignored */ if (quirks == LOAD_POWER) - fps = max(inst->prop.operating_rate, inst->prop.frame_rate); + fps = max(operating_rate, frame_rate); /* In case of fps < 1 we assume 1 */ fps = max(fps >> 16, 1); @@ -73,6 +76,11 @@ int msm_vidc_get_inst_load(struct msm_vidc_inst *inst, { int load = 0; + if (!inst || !inst->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + return -EINVAL; + } + if (inst->state == MSM_VIDC_OPEN || inst->state == MSM_VIDC_ERROR) goto exit; @@ -205,7 +213,7 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst) struct v4l2_format *inp_f; struct msm_vidc_buffer *vbuf; u32 data_size = 0; - int codec = 0; + int codec = 0, frame_rate; if (!inst || !inst->core || !inst->capabilities) { d_vpr_e("%s: invalid params: %pK\n", __func__, inst); @@ -247,6 +255,7 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst) break; } + frame_rate = inst->capabilities->cap[FRAME_RATE].value; vote_data->codec = inst->codec; vote_data->input_width = inp_f->fmt.pix_mp.width; vote_data->input_height = inp_f->fmt.pix_mp.height; @@ -262,10 +271,10 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst) vote_data->b_frames_enabled = inst->capabilities->cap[B_FRAME].value > 0; /* scale bitrate if operating rate is larger than fps */ - if (vote_data->fps > (inst->prop.frame_rate >> 16) && - (inst->prop.frame_rate >> 16)) { + if (vote_data->fps > (frame_rate >> 16) && + (frame_rate >> 16)) { vote_data->bitrate = vote_data->bitrate / - (inst->prop.frame_rate >> 16) * vote_data->fps; + (frame_rate >> 16) * vote_data->fps; } vote_data->num_formats = 1; vote_data->color_formats[0] = v4l2_colorformat_to_driver( @@ -293,7 +302,7 @@ int msm_vidc_scale_buses(struct msm_vidc_inst *inst) vote_data->color_formats[0] = color_format; } } - vote_data->work_mode = inst->stage; + vote_data->work_mode = inst->capabilities->cap[STAGE].value; if (core->dt->sys_cache_res_set) vote_data->use_sys_cache = true; vote_data->num_vpp_pipes = core->capabilities[NUM_VPP_PIPE].value; diff --git a/driver/vidc/src/msm_vidc_v4l2.c b/driver/vidc/src/msm_vidc_v4l2.c index d5f15f22da..74fba3ef65 100644 --- a/driver/vidc/src/msm_vidc_v4l2.c +++ b/driver/vidc/src/msm_vidc_v4l2.c @@ -104,6 +104,22 @@ int msm_v4l2_g_selection(struct file* file, void* fh, return msm_vidc_g_selection((void*)vidc_inst, s); } +int msm_v4l2_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_s_param((void *)vidc_inst, a); +} + +int msm_v4l2_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *a) +{ + struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh); + + return msm_vidc_g_param((void *)vidc_inst, a); +} + int msm_v4l2_s_ctrl(struct file *file, void *fh, struct v4l2_control *a) {