Commit | Line | Data |
---|---|---|
97fb5e8d | 1 | // SPDX-License-Identifier: GPL-2.0-only |
aaaa93ed SV |
2 | /* |
3 | * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. | |
4 | * Copyright (C) 2017 Linaro Ltd. | |
aaaa93ed SV |
5 | */ |
6 | #include <linux/types.h> | |
7 | #include <media/v4l2-ctrls.h> | |
8 | ||
9 | #include "core.h" | |
10 | #include "venc.h" | |
11 | ||
12 | #define BITRATE_MIN 32000 | |
13 | #define BITRATE_MAX 160000000 | |
14 | #define BITRATE_DEFAULT 1000000 | |
15 | #define BITRATE_DEFAULT_PEAK (BITRATE_DEFAULT * 2) | |
16 | #define BITRATE_STEP 100 | |
17 | #define SLICE_BYTE_SIZE_MAX 1024 | |
18 | #define SLICE_BYTE_SIZE_MIN 1024 | |
19 | #define SLICE_MB_SIZE_MAX 300 | |
20 | #define INTRA_REFRESH_MBS_MAX 300 | |
21 | #define AT_SLICE_BOUNDARY \ | |
22 | V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY | |
23 | ||
8fc58186 SV |
24 | static int venc_calc_bpframes(u32 gop_size, u32 conseq_b, u32 *bf, u32 *pf) |
25 | { | |
26 | u32 half = (gop_size - 1) >> 1; | |
27 | u32 b, p, ratio; | |
28 | bool found = false; | |
29 | ||
30 | if (!gop_size) | |
31 | return -EINVAL; | |
32 | ||
33 | *bf = *pf = 0; | |
34 | ||
35 | if (!conseq_b) { | |
36 | *pf = gop_size - 1; | |
37 | return 0; | |
38 | } | |
39 | ||
40 | b = p = half; | |
41 | ||
42 | for (; b <= gop_size - 1; b++, p--) { | |
43 | if (b % p) | |
44 | continue; | |
45 | ||
46 | ratio = b / p; | |
47 | ||
48 | if (ratio == conseq_b) { | |
49 | found = true; | |
50 | break; | |
51 | } | |
52 | ||
53 | if (ratio > conseq_b) | |
54 | break; | |
55 | } | |
56 | ||
57 | if (!found) | |
58 | return -EINVAL; | |
59 | ||
60 | if (b + p + 1 != gop_size) | |
61 | return -EINVAL; | |
62 | ||
63 | *bf = b; | |
64 | *pf = p; | |
65 | ||
66 | return 0; | |
67 | } | |
68 | ||
aaaa93ed SV |
69 | static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl) |
70 | { | |
71 | struct venus_inst *inst = ctrl_to_inst(ctrl); | |
72 | struct venc_controls *ctr = &inst->controls.enc; | |
c35f0b16 | 73 | struct hfi_enable en = { .enable = 1 }; |
61df5aa3 | 74 | struct hfi_bitrate brate; |
8fc58186 | 75 | u32 bframes; |
61df5aa3 | 76 | u32 ptype; |
8fc58186 | 77 | int ret; |
aaaa93ed SV |
78 | |
79 | switch (ctrl->id) { | |
80 | case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: | |
81 | ctr->bitrate_mode = ctrl->val; | |
82 | break; | |
83 | case V4L2_CID_MPEG_VIDEO_BITRATE: | |
84 | ctr->bitrate = ctrl->val; | |
61df5aa3 MG |
85 | mutex_lock(&inst->lock); |
86 | if (inst->streamon_out && inst->streamon_cap) { | |
87 | ptype = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE; | |
88 | brate.bitrate = ctr->bitrate; | |
89 | brate.layer_id = 0; | |
90 | ||
91 | ret = hfi_session_set_property(inst, ptype, &brate); | |
92 | if (ret) { | |
93 | mutex_unlock(&inst->lock); | |
94 | return ret; | |
95 | } | |
96 | } | |
97 | mutex_unlock(&inst->lock); | |
aaaa93ed SV |
98 | break; |
99 | case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: | |
100 | ctr->bitrate_peak = ctrl->val; | |
101 | break; | |
102 | case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: | |
103 | ctr->h264_entropy_mode = ctrl->val; | |
104 | break; | |
105 | case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: | |
106 | ctr->profile.mpeg4 = ctrl->val; | |
107 | break; | |
108 | case V4L2_CID_MPEG_VIDEO_H264_PROFILE: | |
109 | ctr->profile.h264 = ctrl->val; | |
110 | break; | |
5520b946 | 111 | case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: |
aaaa93ed SV |
112 | ctr->profile.vpx = ctrl->val; |
113 | break; | |
114 | case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: | |
115 | ctr->level.mpeg4 = ctrl->val; | |
116 | break; | |
117 | case V4L2_CID_MPEG_VIDEO_H264_LEVEL: | |
118 | ctr->level.h264 = ctrl->val; | |
119 | break; | |
120 | case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP: | |
121 | ctr->h264_i_qp = ctrl->val; | |
122 | break; | |
123 | case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP: | |
124 | ctr->h264_p_qp = ctrl->val; | |
125 | break; | |
126 | case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: | |
127 | ctr->h264_b_qp = ctrl->val; | |
128 | break; | |
129 | case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: | |
130 | ctr->h264_min_qp = ctrl->val; | |
131 | break; | |
132 | case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: | |
133 | ctr->h264_max_qp = ctrl->val; | |
134 | break; | |
135 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: | |
136 | ctr->multi_slice_mode = ctrl->val; | |
137 | break; | |
138 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: | |
139 | ctr->multi_slice_max_bytes = ctrl->val; | |
140 | break; | |
141 | case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: | |
142 | ctr->multi_slice_max_mb = ctrl->val; | |
143 | break; | |
144 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA: | |
145 | ctr->h264_loop_filter_alpha = ctrl->val; | |
146 | break; | |
147 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA: | |
148 | ctr->h264_loop_filter_beta = ctrl->val; | |
149 | break; | |
150 | case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE: | |
151 | ctr->h264_loop_filter_mode = ctrl->val; | |
152 | break; | |
153 | case V4L2_CID_MPEG_VIDEO_HEADER_MODE: | |
154 | ctr->header_mode = ctrl->val; | |
155 | break; | |
156 | case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB: | |
157 | break; | |
158 | case V4L2_CID_MPEG_VIDEO_GOP_SIZE: | |
8fc58186 SV |
159 | ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, &bframes, |
160 | &ctr->num_p_frames); | |
161 | if (ret) | |
162 | return ret; | |
163 | ||
aaaa93ed SV |
164 | ctr->gop_size = ctrl->val; |
165 | break; | |
166 | case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD: | |
167 | ctr->h264_i_period = ctrl->val; | |
168 | break; | |
169 | case V4L2_CID_MPEG_VIDEO_VPX_MIN_QP: | |
170 | ctr->vp8_min_qp = ctrl->val; | |
171 | break; | |
172 | case V4L2_CID_MPEG_VIDEO_VPX_MAX_QP: | |
173 | ctr->vp8_max_qp = ctrl->val; | |
174 | break; | |
175 | case V4L2_CID_MPEG_VIDEO_B_FRAMES: | |
8fc58186 SV |
176 | ret = venc_calc_bpframes(ctr->gop_size, ctrl->val, &bframes, |
177 | &ctr->num_p_frames); | |
178 | if (ret) | |
179 | return ret; | |
180 | ||
181 | ctr->num_b_frames = bframes; | |
aaaa93ed | 182 | break; |
c35f0b16 MG |
183 | case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: |
184 | mutex_lock(&inst->lock); | |
185 | if (inst->streamon_out && inst->streamon_cap) { | |
186 | ptype = HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME; | |
187 | ret = hfi_session_set_property(inst, ptype, &en); | |
188 | ||
189 | if (ret) { | |
190 | mutex_unlock(&inst->lock); | |
191 | return ret; | |
192 | } | |
193 | } | |
194 | mutex_unlock(&inst->lock); | |
195 | break; | |
aaaa93ed SV |
196 | default: |
197 | return -EINVAL; | |
198 | } | |
199 | ||
200 | return 0; | |
201 | } | |
202 | ||
203 | static const struct v4l2_ctrl_ops venc_ctrl_ops = { | |
204 | .s_ctrl = venc_op_s_ctrl, | |
205 | }; | |
206 | ||
207 | int venc_ctrl_init(struct venus_inst *inst) | |
208 | { | |
209 | int ret; | |
210 | ||
c35f0b16 | 211 | ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 28); |
aaaa93ed SV |
212 | if (ret) |
213 | return ret; | |
214 | ||
215 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
216 | V4L2_CID_MPEG_VIDEO_BITRATE_MODE, | |
217 | V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, | |
218 | ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) | | |
219 | (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)), | |
220 | V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); | |
221 | ||
222 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
223 | V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE, | |
224 | V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, | |
225 | 0, V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC); | |
226 | ||
227 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
228 | V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, | |
229 | V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY, | |
230 | ~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) | | |
231 | (1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)), | |
232 | V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE); | |
233 | ||
234 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
235 | V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, | |
236 | V4L2_MPEG_VIDEO_MPEG4_LEVEL_5, | |
237 | 0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0); | |
238 | ||
239 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
240 | V4L2_CID_MPEG_VIDEO_H264_PROFILE, | |
241 | V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH, | |
242 | ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | | |
243 | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | | |
244 | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | | |
245 | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | | |
246 | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) | | |
247 | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)), | |
248 | V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); | |
249 | ||
250 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
251 | V4L2_CID_MPEG_VIDEO_H264_LEVEL, | |
252 | V4L2_MPEG_VIDEO_H264_LEVEL_5_1, | |
253 | 0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0); | |
254 | ||
255 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
256 | V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE, | |
257 | AT_SLICE_BOUNDARY, | |
258 | 0, V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED); | |
259 | ||
260 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
261 | V4L2_CID_MPEG_VIDEO_HEADER_MODE, | |
262 | V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, | |
263 | 1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, | |
264 | V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE); | |
265 | ||
266 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, | |
267 | V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE, | |
268 | V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES, | |
269 | 0, V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE); | |
270 | ||
5520b946 KW |
271 | v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops, |
272 | V4L2_CID_MPEG_VIDEO_VP8_PROFILE, | |
273 | V4L2_MPEG_VIDEO_VP8_PROFILE_3, | |
274 | 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0); | |
275 | ||
aaaa93ed SV |
276 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, |
277 | V4L2_CID_MPEG_VIDEO_BITRATE, BITRATE_MIN, BITRATE_MAX, | |
278 | BITRATE_STEP, BITRATE_DEFAULT); | |
279 | ||
280 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
281 | V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, BITRATE_MIN, BITRATE_MAX, | |
282 | BITRATE_STEP, BITRATE_DEFAULT_PEAK); | |
283 | ||
284 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
aaaa93ed SV |
285 | V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26); |
286 | ||
287 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
288 | V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28); | |
289 | ||
290 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
291 | V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30); | |
292 | ||
293 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
294 | V4L2_CID_MPEG_VIDEO_H264_MIN_QP, 1, 51, 1, 1); | |
295 | ||
296 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
297 | V4L2_CID_MPEG_VIDEO_H264_MAX_QP, 1, 51, 1, 51); | |
298 | ||
299 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
300 | V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES, SLICE_BYTE_SIZE_MIN, | |
301 | SLICE_BYTE_SIZE_MAX, 1, SLICE_BYTE_SIZE_MIN); | |
302 | ||
303 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
304 | V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB, 1, | |
305 | SLICE_MB_SIZE_MAX, 1, 1); | |
306 | ||
307 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
308 | V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA, -6, 6, 1, 0); | |
309 | ||
310 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
311 | V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA, -6, 6, 1, 0); | |
312 | ||
313 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
314 | V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB, | |
315 | 0, INTRA_REFRESH_MBS_MAX, 1, 0); | |
316 | ||
317 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
f8e5b2f3 | 318 | V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30); |
aaaa93ed SV |
319 | |
320 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
321 | V4L2_CID_MPEG_VIDEO_VPX_MIN_QP, 1, 128, 1, 1); | |
322 | ||
323 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
324 | V4L2_CID_MPEG_VIDEO_VPX_MAX_QP, 1, 128, 1, 128); | |
325 | ||
326 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
327 | V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0); | |
328 | ||
329 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, | |
330 | V4L2_CID_MPEG_VIDEO_H264_I_PERIOD, 0, (1 << 16) - 1, 1, 0); | |
331 | ||
c35f0b16 MG |
332 | v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops, |
333 | V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0); | |
334 | ||
aaaa93ed SV |
335 | ret = inst->ctrl_handler.error; |
336 | if (ret) | |
337 | goto err; | |
338 | ||
339 | ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler); | |
340 | if (ret) | |
341 | goto err; | |
342 | ||
343 | return 0; | |
344 | err: | |
345 | v4l2_ctrl_handler_free(&inst->ctrl_handler); | |
346 | return ret; | |
347 | } | |
348 | ||
349 | void venc_ctrl_deinit(struct venus_inst *inst) | |
350 | { | |
351 | v4l2_ctrl_handler_free(&inst->ctrl_handler); | |
352 | } |