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

Commit 73da4a37 authored by Arun Menon's avatar Arun Menon
Browse files

msm: vidc: Consolidate v4l2 control logic in driver



There was code duplication for v4l2 control setup in
decoder and encoder. This change tries to cut down on
the code duplication and makes common functionality
available for both decoder and encoder.

Change-Id: I8cb54297e82ca8161bea5248dce5289f7eda03c5
Signed-off-by: default avatarArun Menon <avmenon@codeaurora.org>
parent b06f2ad5
Loading
Loading
Loading
Loading
+8 −141
Original line number Diff line number Diff line
@@ -1120,7 +1120,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
	f->fmt.pix_mp.pixelformat = fmt->fourcc;
	f->fmt.pix_mp.num_planes = fmt->num_planes;
	if (inst->in_reconfig) {
		bool ds_enabled = msm_comm_g_ctrl(inst,
		bool ds_enabled = msm_comm_g_ctrl_for_id(inst,
			V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO);

		/*
@@ -1379,7 +1379,7 @@ static int set_default_properties(struct msm_vidc_inst *inst)
		dprintk(VIDC_DBG, "Enable dynamic buffer mode\n");
		ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
		ctrl.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
		rc = v4l2_s_ctrl(NULL, &inst->ctrl_handler, &ctrl);
		rc = msm_comm_s_ctrl(inst, &ctrl);
		if (rc)
			dprintk(VIDC_ERR,
				"Failed to enable dynamic buffer mode by default: %d\n",
@@ -2602,7 +2602,8 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
		switch (ext_control[i].id) {
		case V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE:
			control.value = ext_control[i].value;
			rc = v4l2_s_ctrl(NULL, &inst->ctrl_handler, &control);

			rc = msm_comm_s_ctrl(inst, &control);
			if (rc)
				dprintk(VIDC_ERR,
					"%s Failed setting stream output mode : %d\n",
@@ -2611,7 +2612,7 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
		case V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT:
			switch (ext_control[i].value) {
			case V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE:
				if (!msm_comm_g_ctrl(inst, control.id)) {
				if (!msm_comm_g_ctrl_for_id(inst, control.id)) {
					rc = msm_comm_release_output_buffers(
						inst);
					if (rc)
@@ -2627,7 +2628,7 @@ static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
					fourcc = V4L2_PIX_FMT_NV12_UBWC;
				else
					fourcc = V4L2_PIX_FMT_NV12_TP10_UBWC;
				if (msm_comm_g_ctrl(inst, control.id)) {
				if (msm_comm_g_ctrl_for_id(inst, control.id)) {
					rc = msm_comm_set_color_format(inst,
						HAL_BUFFER_OUTPUT, fourcc);
					if (rc) {
@@ -2742,15 +2743,6 @@ const struct v4l2_ctrl_ops *msm_vdec_get_ctrl_ops(void)
	return &msm_vdec_ctrl_ops;
}

int msm_vdec_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
{
	return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl);
}
int msm_vdec_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
{
	return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
}

int msm_vdec_s_ext_ctrl(struct msm_vidc_inst *inst,
	struct v4l2_ext_controls *ctrl)
{
@@ -2768,134 +2760,9 @@ int msm_vdec_s_ext_ctrl(struct msm_vidc_inst *inst,
	return rc;
}

static struct v4l2_ctrl **get_super_cluster(struct msm_vidc_inst *inst,
				int *size)
{
	int c = 0, sz = 0;
	struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
			NUM_CTRLS, GFP_KERNEL);

	if (!size || !cluster || !inst)
		return NULL;

	for (c = 0; c < NUM_CTRLS; c++)
		cluster[sz++] = inst->ctrls[c];

	*size = sz;
	return cluster;
}

int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
{
	int idx = 0;
	struct v4l2_ctrl_config ctrl_cfg = {0};
	int ret_val = 0;
	int cluster_size = 0;

	if (!inst) {
		dprintk(VIDC_ERR, "%s - invalid input\n", __func__);
		return -EINVAL;
	return msm_comm_ctrl_init(inst, msm_vdec_ctrls,
		ARRAY_SIZE(msm_vdec_ctrls), &msm_vdec_ctrl_ops);
}
	inst->ctrls = kzalloc(sizeof(struct v4l2_ctrl *) * NUM_CTRLS,
				GFP_KERNEL);
	if (!inst->ctrls) {
		dprintk(VIDC_ERR, "%s - failed to allocate ctrl\n", __func__);
		return -ENOMEM;
	}

	ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);

	if (ret_val) {
		dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n",
				inst->ctrl_handler.error);
		return ret_val;
	}

	for (; idx < NUM_CTRLS; idx++) {
		struct v4l2_ctrl *ctrl = NULL;
		if (IS_PRIV_CTRL(msm_vdec_ctrls[idx].id)) {
			/*add private control*/
			ctrl_cfg.def = msm_vdec_ctrls[idx].default_value;
			ctrl_cfg.flags = 0;
			ctrl_cfg.id = msm_vdec_ctrls[idx].id;
			/* ctrl_cfg.is_private =
			 * msm_vdec_ctrls[idx].is_private;
			 * ctrl_cfg.is_volatile =
			 * msm_vdec_ctrls[idx].is_volatile;*/
			ctrl_cfg.max = msm_vdec_ctrls[idx].maximum;
			ctrl_cfg.min = msm_vdec_ctrls[idx].minimum;
			ctrl_cfg.menu_skip_mask =
				msm_vdec_ctrls[idx].menu_skip_mask;
			ctrl_cfg.name = msm_vdec_ctrls[idx].name;
			ctrl_cfg.ops = &msm_vdec_ctrl_ops;
			ctrl_cfg.step = msm_vdec_ctrls[idx].step;
			ctrl_cfg.type = msm_vdec_ctrls[idx].type;
			ctrl_cfg.qmenu = msm_vdec_ctrls[idx].qmenu;

			ctrl = v4l2_ctrl_new_custom(&inst->ctrl_handler,
					&ctrl_cfg, NULL);
		} else {
			if (msm_vdec_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
				ctrl = v4l2_ctrl_new_std_menu(
					&inst->ctrl_handler,
					&msm_vdec_ctrl_ops,
					msm_vdec_ctrls[idx].id,
					msm_vdec_ctrls[idx].maximum,
					msm_vdec_ctrls[idx].menu_skip_mask,
					msm_vdec_ctrls[idx].default_value);
			} else {
				ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
					&msm_vdec_ctrl_ops,
					msm_vdec_ctrls[idx].id,
					msm_vdec_ctrls[idx].minimum,
					msm_vdec_ctrls[idx].maximum,
					msm_vdec_ctrls[idx].step,
					msm_vdec_ctrls[idx].default_value);
			}
		}

		if (!ctrl) {
			dprintk(VIDC_ERR, "%s - invalid ctrl\n", __func__);
			return -EINVAL;
		}

		ret_val = inst->ctrl_handler.error;
		if (ret_val) {
			dprintk(VIDC_ERR,
					"Error adding ctrl (%s) to ctrl handle, %d\n",
					msm_vdec_ctrls[idx].name,
					inst->ctrl_handler.error);
			return ret_val;
		}

		ctrl->flags |= msm_vdec_ctrls[idx].flags;
		inst->ctrls[idx] = ctrl;
	}

	/* Construct a super cluster of all controls */
	inst->cluster = get_super_cluster(inst, &cluster_size);
	if (!inst->cluster || !cluster_size) {
		dprintk(VIDC_WARN,
				"Failed to setup super cluster\n");
		return -EINVAL;
	}

	v4l2_ctrl_cluster(cluster_size, inst->cluster);

	return ret_val;
}

int msm_vdec_ctrl_deinit(struct msm_vidc_inst *inst)
{
	if (!inst) {
		dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
		return -EINVAL;
	}

	kfree(inst->ctrls);
	kfree(inst->cluster);
	v4l2_ctrl_handler_free(&inst->ctrl_handler);

	return 0;
}
+0 −3
Original line number Diff line number Diff line
@@ -18,13 +18,10 @@

int msm_vdec_inst_init(struct msm_vidc_inst *inst);
int msm_vdec_ctrl_init(struct msm_vidc_inst *inst);
int msm_vdec_ctrl_deinit(struct msm_vidc_inst *inst);
int msm_vdec_querycap(void *instance, struct v4l2_capability *cap);
int msm_vdec_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
int msm_vdec_s_fmt(void *instance, struct v4l2_format *f);
int msm_vdec_g_fmt(void *instance, struct v4l2_format *f);
int msm_vdec_s_ctrl(void *instance, struct v4l2_control *a);
int msm_vdec_g_ctrl(void *instance, struct v4l2_control *a);
int msm_vdec_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
int msm_vdec_reqbufs(void *instance, struct v4l2_requestbuffers *b);
int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+2 −130
Original line number Diff line number Diff line
@@ -3207,15 +3207,6 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
	return rc;
}

int msm_venc_s_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
{
	return v4l2_s_ctrl(NULL, &inst->ctrl_handler, ctrl);
}
int msm_venc_g_ctrl(struct msm_vidc_inst *inst, struct v4l2_control *ctrl)
{
	return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
}

int msm_venc_s_ext_ctrl(struct msm_vidc_inst *inst,
	struct v4l2_ext_controls *ctrl)
{
@@ -3761,128 +3752,9 @@ int msm_venc_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i)
	return rc;
}

static struct v4l2_ctrl **get_super_cluster(struct msm_vidc_inst *inst,
				int *size)
{
	int c = 0, sz = 0;
	struct v4l2_ctrl **cluster = kmalloc(sizeof(struct v4l2_ctrl *) *
			NUM_CTRLS, GFP_KERNEL);

	if (!size || !cluster || !inst)
		return NULL;

	for (c = 0; c < NUM_CTRLS; c++)
		cluster[sz++] =  inst->ctrls[c];

	*size = sz;
	return cluster;
}

int msm_venc_ctrl_init(struct msm_vidc_inst *inst)
{
	int idx = 0;
	struct v4l2_ctrl_config ctrl_cfg = {0};
	int ret_val = 0;
	int cluster_size = 0;

	if (!inst) {
		dprintk(VIDC_ERR, "%s - invalid input\n", __func__);
		return -EINVAL;
	}

	inst->ctrls = kzalloc(sizeof(struct v4l2_ctrl *) * NUM_CTRLS,
				GFP_KERNEL);
	if (!inst->ctrls) {
		dprintk(VIDC_ERR, "%s - failed to allocate ctrl\n", __func__);
		return -ENOMEM;
	}

	ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);
	if (ret_val) {
		dprintk(VIDC_ERR, "CTRL ERR: Control handler init failed, %d\n",
			inst->ctrl_handler.error);
		return ret_val;
	}

	for (; idx < NUM_CTRLS; idx++) {
		struct v4l2_ctrl *ctrl = NULL;
		if (IS_PRIV_CTRL(msm_venc_ctrls[idx].id)) {
			ctrl_cfg.def = msm_venc_ctrls[idx].default_value;
			ctrl_cfg.flags = 0;
			ctrl_cfg.id = msm_venc_ctrls[idx].id;
			ctrl_cfg.max = msm_venc_ctrls[idx].maximum;
			ctrl_cfg.min = msm_venc_ctrls[idx].minimum;
			ctrl_cfg.menu_skip_mask =
				msm_venc_ctrls[idx].menu_skip_mask;
			ctrl_cfg.name = msm_venc_ctrls[idx].name;
			ctrl_cfg.ops = &msm_venc_ctrl_ops;
			ctrl_cfg.step = msm_venc_ctrls[idx].step;
			ctrl_cfg.type = msm_venc_ctrls[idx].type;
			ctrl_cfg.qmenu = msm_venc_ctrls[idx].qmenu;
			ctrl = v4l2_ctrl_new_custom(
					&inst->ctrl_handler,
					&ctrl_cfg, NULL);
		} else {
			if (msm_venc_ctrls[idx].type == V4L2_CTRL_TYPE_MENU) {
				ctrl = v4l2_ctrl_new_std_menu(
					&inst->ctrl_handler,
					&msm_venc_ctrl_ops,
					msm_venc_ctrls[idx].id,
					msm_venc_ctrls[idx].maximum,
					msm_venc_ctrls[idx].menu_skip_mask,
					msm_venc_ctrls[idx].default_value);
			} else {
				ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
					&msm_venc_ctrl_ops,
					msm_venc_ctrls[idx].id,
					msm_venc_ctrls[idx].minimum,
					msm_venc_ctrls[idx].maximum,
					msm_venc_ctrls[idx].step,
					msm_venc_ctrls[idx].default_value);
			}
		}

		if (!ctrl) {
			dprintk(VIDC_ERR, "%s - invalid ctrl : %s\n",
				ctrl_cfg.name, __func__);
			return -EINVAL;
		}

		ret_val = inst->ctrl_handler.error;
		if (ret_val) {
			dprintk(VIDC_ERR,
					"Error adding ctrl (%s) to ctrl handle, %d\n",
					msm_venc_ctrls[idx].name,
					inst->ctrl_handler.error);
			return ret_val;
		}

		inst->ctrls[idx] = ctrl;
	}

	/* Construct a super cluster of all controls */
	inst->cluster = get_super_cluster(inst, &cluster_size);
	if (!inst->cluster || !cluster_size) {
		dprintk(VIDC_WARN,
				"Failed to setup super cluster\n");
		return -EINVAL;
	}

	v4l2_ctrl_cluster(cluster_size, inst->cluster);

	return ret_val;
}

int msm_venc_ctrl_deinit(struct msm_vidc_inst *inst)
{
	if (!inst) {
		dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
		return -EINVAL;
	return msm_comm_ctrl_init(inst, msm_venc_ctrls,
			ARRAY_SIZE(msm_venc_ctrls), &msm_venc_ctrl_ops);
}
	kfree(inst->ctrls);
	kfree(inst->cluster);
	v4l2_ctrl_handler_free(&inst->ctrl_handler);

	return 0;
}
+0 −3
Original line number Diff line number Diff line
@@ -18,13 +18,10 @@

int msm_venc_inst_init(struct msm_vidc_inst *inst);
int msm_venc_ctrl_init(struct msm_vidc_inst *inst);
int msm_venc_ctrl_deinit(struct msm_vidc_inst *inst);
int msm_venc_querycap(void *instance, struct v4l2_capability *cap);
int msm_venc_enum_fmt(void *instance, struct v4l2_fmtdesc *f);
int msm_venc_s_fmt(void *instance, struct v4l2_format *f);
int msm_venc_g_fmt(void *instance, struct v4l2_format *f);
int msm_venc_s_ctrl(void *instance, struct v4l2_control *a);
int msm_venc_g_ctrl(void *instance, struct v4l2_control *a);
int msm_venc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
int msm_venc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
int msm_venc_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
+4 −18
Original line number Diff line number Diff line
@@ -146,11 +146,7 @@ int msm_vidc_s_ctrl(void *instance, struct v4l2_control *control)
	if (!inst || !control)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_s_ctrl(instance, control);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_s_ctrl(instance, control);
	return -EINVAL;
	return msm_comm_s_ctrl(instance, control);
}
EXPORT_SYMBOL(msm_vidc_s_ctrl);

@@ -161,11 +157,7 @@ int msm_vidc_g_ctrl(void *instance, struct v4l2_control *control)
	if (!inst || !control)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_g_ctrl(instance, control);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_g_ctrl(instance, control);
	return -EINVAL;
	return msm_comm_g_ctrl(instance, control);
}
EXPORT_SYMBOL(msm_vidc_g_ctrl);

@@ -1224,10 +1216,7 @@ fail_init:
fail_bufq_output:
	vb2_queue_release(&inst->bufq[CAPTURE_PORT].vb2_bufq);
fail_bufq_capture:
	if (session_type == MSM_VIDC_DECODER)
		msm_vdec_ctrl_deinit(inst);
	else if (session_type == MSM_VIDC_ENCODER)
		msm_venc_ctrl_deinit(inst);
	msm_comm_ctrl_deinit(inst);
	msm_smem_delete_client(inst->mem_client);
fail_mem_client:
	kfree(inst);
@@ -1339,10 +1328,7 @@ int msm_vidc_close(void *instance)
	}
	mutex_unlock(&inst->registeredbufs.lock);

	if (inst->session_type == MSM_VIDC_DECODER)
		msm_vdec_ctrl_deinit(inst);
	else if (inst->session_type == MSM_VIDC_ENCODER)
		msm_venc_ctrl_deinit(inst);
	msm_comm_ctrl_deinit(inst);

	cleanup_instance(inst);
	if (inst->state != MSM_VIDC_CORE_INVALID &&
Loading