Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e167911f authored by Praneeth Paladugu's avatar Praneeth Paladugu Committed by Gerrit - the friendly Code Review server
Browse files

msm: vidc: Add support for querying controls



Add support in driver to query for control information.
This helps clients to findout limits for various controls
and sets the values accordingly.

Also update the control limits based on Venus HW capabilities.
This helps to prevent rogue clients not to set invalid values
to HW.

CRs-Fixed: 2006193
Change-Id: I0e6271c31fad83ee1d48ffd6a5fe0f23a5599c7a
Signed-off-by: default avatarPraneeth Paladugu <ppaladug@codeaurora.org>
Signed-off-by: default avatarVaibhav Deshu Venkatesh <vdeshuve@codeaurora.org>
parent b7d205ea
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -230,6 +230,14 @@ static int msm_v4l2_enum_framesizes(struct file *file, void *fh,
	return msm_vidc_enum_framesizes((void *)vidc_inst, fsize);
}

static int msm_v4l2_queryctrl(struct file *file, void *fh,
	struct v4l2_queryctrl *ctrl)
{
	struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);

	return msm_vidc_query_ctrl((void *)vidc_inst, ctrl);
}

static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
	.vidioc_querycap = msm_v4l2_querycap,
	.vidioc_enum_fmt_vid_cap_mplane = msm_v4l2_enum_fmt,
@@ -245,6 +253,7 @@ static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
	.vidioc_streamoff = msm_v4l2_streamoff,
	.vidioc_s_ctrl = msm_v4l2_s_ctrl,
	.vidioc_g_ctrl = msm_v4l2_g_ctrl,
	.vidioc_queryctrl = msm_v4l2_queryctrl,
	.vidioc_s_ext_ctrls = msm_v4l2_s_ext_ctrl,
	.vidioc_subscribe_event = msm_v4l2_subscribe_event,
	.vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event,
+46 −0
Original line number Diff line number Diff line
@@ -123,6 +123,52 @@ int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
}
EXPORT_SYMBOL(msm_vidc_enum_fmt);

static void msm_vidc_ctrl_get_range(struct v4l2_queryctrl *ctrl,
	struct hal_capability_supported *capability)

{
	ctrl->maximum = capability->max;
	ctrl->minimum = capability->min;
}

int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl)
{
	struct msm_vidc_inst *inst = instance;
	int rc = 0;

	if (!inst || !ctrl)
		return -EINVAL;

	switch (ctrl->id) {
	case V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE:
		msm_vidc_ctrl_get_range(ctrl,
			&inst->capability.hier_p_hybrid);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS:
		msm_vidc_ctrl_get_range(ctrl, &inst->capability.hier_b);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS:
		msm_vidc_ctrl_get_range(ctrl, &inst->capability.hier_p);
		break;
	case  V4L2_CID_MPEG_VIDEO_BITRATE:
		msm_vidc_ctrl_get_range(ctrl, &inst->capability.bitrate);
		break;
	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
		msm_vidc_ctrl_get_range(ctrl, &inst->capability.peakbitrate);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH:
		msm_vidc_ctrl_get_range(ctrl, &inst->capability.blur_width);
		break;
	case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT:
		msm_vidc_ctrl_get_range(ctrl, &inst->capability.blur_height);
		break;
	default:
		rc = -EINVAL;
	}
	return rc;
}
EXPORT_SYMBOL(msm_vidc_query_ctrl);

int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
{
	struct msm_vidc_inst *inst = instance;
+71 −0
Original line number Diff line number Diff line
@@ -952,6 +952,60 @@ static void print_cap(const char *type,
		type, cap->min, cap->max, cap->step_size);
}

static int msm_vidc_comm_update_ctrl(struct msm_vidc_inst *inst,
	u32 id, struct hal_capability_supported *capability)
{
	struct v4l2_ctrl *ctrl = NULL;
	int rc = 0;

	ctrl = v4l2_ctrl_find(&inst->ctrl_handler, id);
	if (ctrl) {
		v4l2_ctrl_modify_range(ctrl, capability->min,
				capability->max, ctrl->step,
				capability->min);
		dprintk(VIDC_DBG,
			"%s: Updated Range = %lld --> %lld Def value = %lld\n",
			ctrl->name, ctrl->minimum, ctrl->maximum,
			ctrl->default_value);
	} else {
		dprintk(VIDC_ERR,
			"Failed to find Conrol %d\n", id);
		rc = -EINVAL;
	}

	return rc;
	}

static void msm_vidc_comm_update_ctrl_limits(struct msm_vidc_inst *inst)
{
	msm_vidc_comm_update_ctrl(inst,
			V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE,
			&inst->capability.hier_p_hybrid);
	msm_vidc_comm_update_ctrl(inst,
			V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS,
			&inst->capability.hier_b);
	msm_vidc_comm_update_ctrl(inst,
			V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS,
			&inst->capability.hier_p);
	msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE,
			&inst->capability.bitrate);
	msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
			&inst->capability.peakbitrate);
	msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH,
			&inst->capability.blur_width);
	msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT,
			&inst->capability.blur_height);
	msm_vidc_comm_update_ctrl(inst,
			V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
			&inst->capability.slice_bytes);
	msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
			&inst->capability.slice_mbs);
	msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT,
			&inst->capability.ltr_count);
	msm_vidc_comm_update_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES,
			&inst->capability.bframe);
}

static void handle_session_init_done(enum hal_command_response cmd, void *data)
{
	struct msm_vidc_cb_cmd_done *response = data;
@@ -1062,6 +1116,13 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data)
	print_cap("ubwc_cr_stats", &inst->capability.ubwc_cr_stats);

	signal_session_msg_receipt(cmd, inst);

	/*
	 * Update controls after informing session_init_done to avoid
	 * timeouts.
	 */

	msm_vidc_comm_update_ctrl_limits(inst);
	put_inst(inst);
}

@@ -5227,6 +5288,16 @@ int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a)
	else if ((fps > 1) && (fps % 24 == 1 || fps % 15 == 1))
		fps = fps - 1;

	if (fps < inst->capability.frame_rate.min ||
			fps > inst->capability.frame_rate.max) {
		dprintk(VIDC_ERR,
			"FPS is out of limits : fps = %d Min = %d, Max = %d\n",
			fps, inst->capability.frame_rate.min,
			inst->capability.frame_rate.max);
		rc = -EINVAL;
		goto exit;
	}

	if (inst->prop.fps != fps) {
		dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n",
				inst, inst->prop.fps, fps);
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type);
int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b);
int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b);
int msm_vidc_streamon(void *instance, enum v4l2_buf_type i);
int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl);
int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i);
int msm_vidc_comm_cmd(void *instance, union msm_v4l2_cmd *cmd);
int msm_vidc_poll(void *instance, struct file *filp,