diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/platform/msm/vidc/msm_v4l2_vidc.c | 10 | ||||
-rw-r--r-- | drivers/media/platform/msm/vidc/msm_vdec.c | 21 | ||||
-rw-r--r-- | drivers/media/platform/msm/vidc/msm_vdec.h | 17 | ||||
-rw-r--r-- | drivers/media/platform/msm/vidc/msm_vidc.c | 121 | ||||
-rw-r--r-- | drivers/media/platform/msm/vidc/msm_vidc_common.c | 5 | ||||
-rw-r--r-- | drivers/media/platform/msm/vidc/msm_vidc_common.h | 1 |
6 files changed, 155 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 |