1
2
3
4
5
6#include <linux/types.h>
7#include <media/v4l2-ctrls.h>
8
9#include "core.h"
10#include "helpers.h"
11#include "vdec.h"
12
13static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
14{
15 struct venus_inst *inst = ctrl_to_inst(ctrl);
16 struct vdec_controls *ctr = &inst->controls.dec;
17
18 switch (ctrl->id) {
19 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
20 ctr->post_loop_deb_mode = ctrl->val;
21 break;
22 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
23 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
24 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
25 case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
26 ctr->profile = ctrl->val;
27 break;
28 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
29 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
30 case V4L2_CID_MPEG_VIDEO_VP9_LEVEL:
31 ctr->level = ctrl->val;
32 break;
33 default:
34 return -EINVAL;
35 }
36
37 return 0;
38}
39
40static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
41{
42 struct venus_inst *inst = ctrl_to_inst(ctrl);
43 struct vdec_controls *ctr = &inst->controls.dec;
44 struct hfi_buffer_requirements bufreq;
45 enum hfi_version ver = inst->core->res->hfi_version;
46 u32 profile, level;
47 int ret;
48
49 switch (ctrl->id) {
50 case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
51 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
52 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
53 case V4L2_CID_MPEG_VIDEO_VP9_PROFILE:
54 ret = venus_helper_get_profile_level(inst, &profile, &level);
55 if (!ret)
56 ctr->profile = profile;
57 ctrl->val = ctr->profile;
58 break;
59 case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
60 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
61 case V4L2_CID_MPEG_VIDEO_VP9_LEVEL:
62 ret = venus_helper_get_profile_level(inst, &profile, &level);
63 if (!ret)
64 ctr->level = level;
65 ctrl->val = ctr->level;
66 break;
67 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
68 ctrl->val = ctr->post_loop_deb_mode;
69 break;
70 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
71 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq);
72 if (!ret)
73 ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver);
74 break;
75 default:
76 return -EINVAL;
77 }
78
79 return 0;
80}
81
82static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
83 .s_ctrl = vdec_op_s_ctrl,
84 .g_volatile_ctrl = vdec_op_g_volatile_ctrl,
85};
86
87int vdec_ctrl_init(struct venus_inst *inst)
88{
89 struct v4l2_ctrl *ctrl;
90 int ret;
91
92 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 9);
93 if (ret)
94 return ret;
95
96 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
97 V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
98 V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY,
99 ~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) |
100 (1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)),
101 V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE);
102 if (ctrl)
103 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
104
105 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
106 V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
107 V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
108 0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0);
109 if (ctrl)
110 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
111
112 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
113 V4L2_CID_MPEG_VIDEO_H264_PROFILE,
114 V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
115 ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
116 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
117 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
118 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
119 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) |
120 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)),
121 V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
122 if (ctrl)
123 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
124
125 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
126 V4L2_CID_MPEG_VIDEO_H264_LEVEL,
127 V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
128 0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0);
129 if (ctrl)
130 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
131
132 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
133 V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
134 V4L2_MPEG_VIDEO_VP8_PROFILE_3,
135 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
136 if (ctrl)
137 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
138
139 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
140 V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
141 V4L2_MPEG_VIDEO_VP9_PROFILE_3,
142 0, V4L2_MPEG_VIDEO_VP9_PROFILE_0);
143 if (ctrl)
144 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
145
146 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
147 V4L2_CID_MPEG_VIDEO_VP9_LEVEL,
148 V4L2_MPEG_VIDEO_VP9_LEVEL_6_2,
149 0, V4L2_MPEG_VIDEO_VP9_LEVEL_1_0);
150 if (ctrl)
151 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
152
153 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
154 V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 0, 1, 1, 0);
155
156 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
157 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 1);
158 if (ctrl)
159 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
160
161 ret = inst->ctrl_handler.error;
162 if (ret) {
163 v4l2_ctrl_handler_free(&inst->ctrl_handler);
164 return ret;
165 }
166
167 return 0;
168}
169
170void vdec_ctrl_deinit(struct venus_inst *inst)
171{
172 v4l2_ctrl_handler_free(&inst->ctrl_handler);
173}
174