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

Commit 2305f01f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Addition of VIDIOC_QUERY_EXT_CTRL ioctl"

parents 3f302a66 395ead59
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -230,6 +230,14 @@ static int msm_v4l2_queryctrl(struct file *file, void *fh,
	return msm_vidc_query_ctrl((void *)vidc_inst, ctrl);
}

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

	return msm_vidc_query_ext_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,
@@ -247,6 +255,7 @@ static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
	.vidioc_s_ctrl = msm_v4l2_s_ctrl,
	.vidioc_g_ctrl = msm_v4l2_g_ctrl,
	.vidioc_queryctrl = msm_v4l2_queryctrl,
	.vidioc_query_ext_ctrl = msm_v4l2_query_ext_ctrl,
	.vidioc_s_ext_ctrls = msm_v4l2_s_ext_ctrl,
	.vidioc_subscribe_event = msm_v4l2_subscribe_event,
	.vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event,
@@ -321,6 +330,7 @@ static int msm_vidc_initialize_core(struct platform_device *pdev,
		init_completion(&core->completions[i]);
	}

	msm_comm_sort_ctrl();
	INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
	return rc;
}
+21 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
 *
 */

#include <linux/sort.h>
#include <linux/slab.h>
#include <soc/qcom/scm.h>
#include "msm_vidc_internal.h"
@@ -18,6 +19,7 @@
#include "vidc_hfi_api.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_dcvs.h"
#include "msm_vdec.h"

#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
#define MIN_NUM_OUTPUT_BUFFERS 4
@@ -553,6 +555,7 @@ static struct msm_vidc_ctrl msm_vdec_ctrls[] = {
			(1 << V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC)
			),
		.qmenu = mpeg_vidc_video_dpb_color_format,
		.flags = V4L2_CTRL_FLAG_MODIFY_LAYOUT,
	},
	{
		.id = V4L2_CID_VIDC_QBUF_MODE,
@@ -2814,3 +2817,21 @@ int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
	return msm_comm_ctrl_init(inst, msm_vdec_ctrls,
		ARRAY_SIZE(msm_vdec_ctrls), &msm_vdec_ctrl_ops);
}

void msm_vdec_g_ctrl(struct msm_vidc_ctrl **ctrls, int *num_ctrls)
{
	*ctrls = msm_vdec_ctrls;
	*num_ctrls = NUM_CTRLS;
}

static int msm_vdec_ctrl_cmp(const void *st1, const void *st2)
{
	return (int32_t)((struct msm_vidc_ctrl *)st1)->id -
		(int32_t)((struct msm_vidc_ctrl *)st2)->id;
}

void msm_vdec_ctrl_sort(void)
{
	sort(msm_vdec_ctrls, NUM_CTRLS, sizeof(struct msm_vidc_ctrl),
		msm_vdec_ctrl_cmp, NULL);
}
+10 −7
Original line number Diff line number Diff line
@@ -18,12 +18,13 @@

int msm_vdec_inst_init(struct msm_vidc_inst *inst);
int msm_vdec_ctrl_init(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_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
int msm_vdec_reqbufs(void *instance, struct v4l2_requestbuffers *b);
int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap);
int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f);
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_ext_ctrl(struct msm_vidc_inst *inst,
		struct v4l2_ext_controls *a);
int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b);
int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
int msm_vdec_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
int msm_vdec_qbuf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
@@ -32,6 +33,8 @@ int msm_vdec_streamon(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
int msm_vdec_streamoff(struct msm_vidc_inst *inst, enum v4l2_buf_type i);
int msm_vdec_cmd(struct msm_vidc_inst *inst, struct v4l2_decoder_cmd *dec);
int msm_vdec_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
struct vb2_ops *msm_vdec_get_vb2q_ops(void);
const struct vb2_ops *msm_vdec_get_vb2q_ops(void);
void msm_vdec_g_ctrl(struct msm_vidc_ctrl **ctrls, int *num_ctrls);
void msm_vdec_ctrl_sort(void);

#endif
+108 −13
Original line number Diff line number Diff line
@@ -14,13 +14,14 @@
#include <linux/dma-direction.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/bsearch.h>
#include <linux/delay.h>
#include <media/msm_vidc.h>
#include "msm_vidc_internal.h"
#include "msm_vidc_debug.h"
#include "msm_vdec.h"
#include "msm_venc.h"
#include "msm_vidc_common.h"
#include <linux/delay.h>
#include "vidc_hfi_api.h"
#include "msm_vidc_dcvs.h"

@@ -88,7 +89,7 @@ int msm_vidc_querycap(void *instance, struct v4l2_capability *cap)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_querycap(instance, cap);
		return msm_vdec_querycap(inst, cap);
	else if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_querycap(instance, cap);
	return -EINVAL;
@@ -103,7 +104,7 @@ int msm_vidc_enum_fmt(void *instance, struct v4l2_fmtdesc *f)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_enum_fmt(instance, f);
		return msm_vdec_enum_fmt(inst, f);
	else if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_enum_fmt(instance, f);
	return -EINVAL;
@@ -138,6 +139,101 @@ int msm_vidc_query_ctrl(void *instance, struct v4l2_queryctrl *ctrl)
}
EXPORT_SYMBOL(msm_vidc_query_ctrl);

static int msm_vidc_queryctrl_bsearch_cmp1(const void *key, const void *elt)
{
	return *(int32_t *)key - (int32_t)((struct msm_vidc_ctrl *)elt)->id;
}

static int msm_vidc_queryctrl_bsearch_cmp2(const void *key, const void *elt)
{
	uint32_t id = *(uint32_t *)key;
	struct msm_vidc_ctrl *ctrl = (struct msm_vidc_ctrl *)elt;

	if (id >= ctrl[0].id && id < ctrl[1].id)
		return 0;
	else if (id < ctrl[0].id)
		return -1;
	else
		return 1;
}

int msm_vidc_query_ext_ctrl(void *instance, struct v4l2_query_ext_ctrl *ctrl)
{
	struct msm_vidc_inst *inst = instance;
	bool get_next_ctrl = 0;
	int i, num_ctrls, rc = 0;
	struct msm_vidc_ctrl *key = NULL;
	struct msm_vidc_ctrl *msm_vdec_ctrls;

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

	i = ctrl->id;
	memset(ctrl, 0, sizeof(struct v4l2_query_ext_ctrl));
	ctrl->id = i;

	if (ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL)
		get_next_ctrl = 1;
	else if (ctrl->id & V4L2_CTRL_FLAG_NEXT_COMPOUND)
		goto query_ext_ctrl_err;

	ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
	ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_COMPOUND;

	if (ctrl->id > V4L2_CID_PRIVATE_BASE ||
		(ctrl->id >= V4L2_CID_BASE && ctrl->id <= V4L2_CID_LASTP1))
		goto query_ext_ctrl_err;
	else if (ctrl->id == V4L2_CID_PRIVATE_BASE && get_next_ctrl)
		ctrl->id = V4L2_CID_MPEG_MSM_VIDC_BASE;

	if (inst->session_type == MSM_VIDC_DECODER)
		msm_vdec_g_ctrl(&msm_vdec_ctrls, &num_ctrls);
	else
		return -EINVAL;

	if (!get_next_ctrl)
		key = bsearch(&ctrl->id, msm_vdec_ctrls, num_ctrls,
					sizeof(struct msm_vidc_ctrl),
					msm_vidc_queryctrl_bsearch_cmp1);
	else {
		key = bsearch(&ctrl->id, msm_vdec_ctrls, num_ctrls-1,
					sizeof(struct msm_vidc_ctrl),
					msm_vidc_queryctrl_bsearch_cmp2);

		if (key && ctrl->id > key->id)
			key++;
		if (key) {
			for (i = key-msm_vdec_ctrls, key = NULL;
				i < num_ctrls; i++)
				if (!(msm_vdec_ctrls[i].flags &
					V4L2_CTRL_FLAG_DISABLED)) {
					key = &msm_vdec_ctrls[i];
					break;
				}
		}
	}

	if (key) {
		ctrl->id = key->id;
		ctrl->type = key->type;
		strlcpy(ctrl->name, key->name, MAX_NAME_LENGTH);
		ctrl->minimum = key->minimum;
		ctrl->maximum = key->maximum;
		ctrl->step = key->step;
		ctrl->default_value = key->default_value;
		ctrl->flags = key->flags;
		ctrl->elems = 1;
		ctrl->nr_of_dims = 0;
		return rc;
	}

query_ext_ctrl_err:
	ctrl->name[0] = '\0';
	ctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
	return -EINVAL;
}
EXPORT_SYMBOL(msm_vidc_query_ext_ctrl);

int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
{
	struct msm_vidc_inst *inst = instance;
@@ -146,7 +242,7 @@ int msm_vidc_s_fmt(void *instance, struct v4l2_format *f)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_s_fmt(instance, f);
		return msm_vdec_s_fmt(inst, f);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_s_fmt(instance, f);
	return -EINVAL;
@@ -161,7 +257,7 @@ int msm_vidc_g_fmt(void *instance, struct v4l2_format *f)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_g_fmt(instance, f);
		return msm_vdec_g_fmt(inst, f);
	else if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_g_fmt(instance, f);
	return -EINVAL;
@@ -197,7 +293,7 @@ int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *control)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_s_ext_ctrl(instance, control);
		return msm_vdec_s_ext_ctrl(inst, control);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_s_ext_ctrl(instance, control);
	return -EINVAL;
@@ -212,7 +308,7 @@ int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_reqbufs(instance, b);
		return msm_vdec_reqbufs(inst, b);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_reqbufs(instance, b);
	return -EINVAL;
@@ -749,7 +845,7 @@ int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_prepare_buf(instance, b);
		return msm_vdec_prepare_buf(inst, b);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_prepare_buf(instance, b);
	return -EINVAL;
@@ -816,8 +912,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type)
		if (!release_buf)
			continue;
		if (inst->session_type == MSM_VIDC_DECODER)
			rc = msm_vdec_release_buf(instance,
				&buffer_info);
			rc = msm_vdec_release_buf(inst,	&buffer_info);
		if (inst->session_type == MSM_VIDC_ENCODER)
			rc = msm_venc_release_buf(instance,
				&buffer_info);
@@ -944,7 +1039,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
	}

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_qbuf(instance, b);
		return msm_vdec_qbuf(inst, b);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_qbuf(instance, b);

@@ -1030,7 +1125,7 @@ int msm_vidc_streamon(void *instance, enum v4l2_buf_type i)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_streamon(instance, i);
		return msm_vdec_streamon(inst, i);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_streamon(instance, i);
	return -EINVAL;
@@ -1045,7 +1140,7 @@ int msm_vidc_streamoff(void *instance, enum v4l2_buf_type i)
		return -EINVAL;

	if (inst->session_type == MSM_VIDC_DECODER)
		return msm_vdec_streamoff(instance, i);
		return msm_vdec_streamoff(inst, i);
	if (inst->session_type == MSM_VIDC_ENCODER)
		return msm_venc_streamoff(instance, i);
	return -EINVAL;
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include "vidc_hfi_api.h"
#include "msm_vidc_debug.h"
#include "msm_vidc_dcvs.h"
#include "msm_vdec.h"

#define IS_ALREADY_IN_STATE(__p, __d) ({\
	int __rc = (__p >= __d);\
@@ -5433,3 +5434,7 @@ static void msm_comm_print_debug_info(struct msm_vidc_inst *inst)
	}
	mutex_unlock(&core->lock);
}
void msm_comm_sort_ctrl(void)
{
	msm_vdec_ctrl_sort();
}
Loading