summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Chandrashekhar Kalghatgi <akalghat@codeaurora.org>2017-06-12 21:34:16 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-06-19 11:36:42 -0700
commit395ead59b60b642ccabc7e3b4f89f0e2a93e36c6 (patch)
treee7ee1ca6efb4fa536608652e447bc60936f5922e
parentd4041b86d5e341c82a4e5b0cd09f4edc7ecb068a (diff)
msm: vidc: Addition of VIDIOC_QUERY_EXT_CTRL ioctl
Adding vidc support for VIDIOC_QUERY_EXT_CTRL ioctl. This ioctl will return the details for the V4L2 control identified by the ID provided by the user or the next supported control based upon the flags provided by the user. Change-Id: I68161ceb000a46a8e54333ab39c0229f8fbdbf72 Signed-off-by: Akshay Chandrashekhar Kalghatgi <akalghat@codeaurora.org>
-rw-r--r--drivers/media/platform/msm/vidc/msm_v4l2_vidc.c10
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c21
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.h17
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c121
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c5
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.h1
-rw-r--r--include/media/msm_vidc.h1
-rw-r--r--include/uapi/linux/videodev2.h1
8 files changed, 157 insertions, 20 deletions
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index c0271c757020..de5a2dececdf 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -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;
}
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 0764a18a7993..28a4006b480c 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -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);
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.h b/drivers/media/platform/msm/vidc/msm_vdec.h
index 47426c143c08..227cc99242d8 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.h
+++ b/drivers/media/platform/msm/vidc/msm_vdec.h
@@ -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
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 3e4be4418f80..f3d50c6a1e0c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -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;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index c9a871bae25b..f85fe6fd3867 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -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();
+}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index 01c1890bf5e1..7d28859c040c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -99,4 +99,5 @@ void msm_comm_cleanup_internal_buffers(struct msm_vidc_inst *inst);
int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a);
bool msm_comm_turbo_session(struct msm_vidc_inst *inst);
void msm_comm_print_inst_info(struct msm_vidc_inst *inst);
+void msm_comm_sort_ctrl(void);
#endif
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 8d13ca3cdd50..af5bce0054af 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -111,6 +111,7 @@ 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_query_ext_ctrl(void *instance, struct v4l2_query_ext_ctrl *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,
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index bb2c4ebf9ff4..fa930a91b4aa 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -1674,6 +1674,7 @@ struct v4l2_querymenu {
#define V4L2_CTRL_FLAG_VOLATILE 0x0080
#define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100
#define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200
+#define V4L2_CTRL_FLAG_MODIFY_LAYOUT 0X0400
/* Query flags, to be ORed with the control ID */
#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000