xref: /linux/drivers/media/platform/qcom/iris/iris_venc.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
4  */
5 
6 #include <media/v4l2-event.h>
7 #include <media/v4l2-mem2mem.h>
8 
9 #include "iris_buffer.h"
10 #include "iris_common.h"
11 #include "iris_ctrls.h"
12 #include "iris_instance.h"
13 #include "iris_power.h"
14 #include "iris_venc.h"
15 #include "iris_vpu_buffer.h"
16 
iris_venc_inst_init(struct iris_inst * inst)17 int iris_venc_inst_init(struct iris_inst *inst)
18 {
19 	struct iris_core *core = inst->core;
20 	struct v4l2_format *f;
21 
22 	inst->fmt_src = kzalloc_obj(*inst->fmt_src);
23 	inst->fmt_dst = kzalloc_obj(*inst->fmt_dst);
24 	if (!inst->fmt_src || !inst->fmt_dst) {
25 		kfree(inst->fmt_src);
26 		kfree(inst->fmt_dst);
27 		return -ENOMEM;
28 	}
29 
30 	f = inst->fmt_dst;
31 	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
32 	f->fmt.pix_mp.width = DEFAULT_WIDTH;
33 	f->fmt.pix_mp.height = DEFAULT_HEIGHT;
34 	f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
35 	inst->codec = f->fmt.pix_mp.pixelformat;
36 	f->fmt.pix_mp.num_planes = 1;
37 	f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
38 	f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
39 	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
40 	f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
41 	f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
42 	f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
43 	f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
44 	inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
45 	inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
46 
47 	f = inst->fmt_src;
48 	f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
49 	f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
50 	f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128);
51 	f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32);
52 	f->fmt.pix_mp.num_planes = 1;
53 	f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128);
54 	f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
55 	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
56 	f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
57 	f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
58 	f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
59 	f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
60 	inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
61 	inst->buffers[BUF_INPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
62 
63 	inst->crop.left = 0;
64 	inst->crop.top = 0;
65 	inst->crop.width = DEFAULT_WIDTH;
66 	inst->crop.height = DEFAULT_HEIGHT;
67 
68 	inst->operating_rate = DEFAULT_FPS;
69 	inst->frame_rate = DEFAULT_FPS;
70 
71 	inst->enc_raw_width = DEFAULT_WIDTH;
72 	inst->enc_raw_height = DEFAULT_HEIGHT;
73 	inst->enc_scale_width = DEFAULT_WIDTH;
74 	inst->enc_scale_height = DEFAULT_HEIGHT;
75 
76 	memcpy(&inst->fw_caps[0], &core->inst_fw_caps_enc[0],
77 	       INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap));
78 
79 	return iris_ctrls_init(inst);
80 }
81 
iris_venc_inst_deinit(struct iris_inst * inst)82 void iris_venc_inst_deinit(struct iris_inst *inst)
83 {
84 	kfree(inst->fmt_dst);
85 	kfree(inst->fmt_src);
86 }
87 
88 static const struct iris_fmt iris_venc_formats_cap[] = {
89 	[IRIS_FMT_H264] = {
90 		.pixfmt = V4L2_PIX_FMT_H264,
91 		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
92 	},
93 	[IRIS_FMT_HEVC] = {
94 		.pixfmt = V4L2_PIX_FMT_HEVC,
95 		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
96 	},
97 };
98 
99 static const struct iris_fmt iris_venc_formats_out[] = {
100 	[IRIS_FMT_NV12] = {
101 		.pixfmt = V4L2_PIX_FMT_NV12,
102 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
103 	},
104 	[IRIS_FMT_QC08C] = {
105 		.pixfmt = V4L2_PIX_FMT_QC08C,
106 		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
107 	},
108 };
109 
110 static const struct iris_fmt *
find_format(struct iris_inst * inst,u32 pixfmt,u32 type)111 find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
112 {
113 	const struct iris_fmt *fmt = NULL;
114 	unsigned int size = 0;
115 	unsigned int i;
116 	switch (type) {
117 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
118 		fmt = iris_venc_formats_out;
119 		size = ARRAY_SIZE(iris_venc_formats_out);
120 		break;
121 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
122 		fmt = iris_venc_formats_cap;
123 		size = ARRAY_SIZE(iris_venc_formats_cap);
124 		break;
125 	default:
126 		return NULL;
127 	}
128 
129 	for (i = 0; i < size; i++) {
130 		if (fmt[i].pixfmt == pixfmt)
131 			break;
132 	}
133 
134 	if (i == size || fmt[i].type != type)
135 		return NULL;
136 
137 	return &fmt[i];
138 }
139 
140 static const struct iris_fmt *
find_format_by_index(struct iris_inst * inst,u32 index,u32 type)141 find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
142 {
143 	const struct iris_fmt *fmt = NULL;
144 	unsigned int size = 0;
145 
146 	switch (type) {
147 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
148 		fmt = iris_venc_formats_out;
149 		size = ARRAY_SIZE(iris_venc_formats_out);
150 		break;
151 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
152 		fmt = iris_venc_formats_cap;
153 		size = ARRAY_SIZE(iris_venc_formats_cap);
154 		break;
155 	default:
156 		return NULL;
157 	}
158 
159 	if (index >= size || fmt[index].type != type)
160 		return NULL;
161 
162 	return &fmt[index];
163 }
164 
iris_venc_enum_fmt(struct iris_inst * inst,struct v4l2_fmtdesc * f)165 int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
166 {
167 	const struct iris_fmt *fmt;
168 
169 	switch (f->type) {
170 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
171 		fmt = find_format_by_index(inst, f->index, f->type);
172 		if (!fmt)
173 			return -EINVAL;
174 
175 		f->pixelformat = fmt->pixfmt;
176 		break;
177 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
178 		fmt = find_format_by_index(inst, f->index, f->type);
179 		if (!fmt)
180 			return -EINVAL;
181 
182 		f->pixelformat = fmt->pixfmt;
183 		f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL;
184 		break;
185 	default:
186 		return -EINVAL;
187 	}
188 
189 	return 0;
190 }
191 
iris_venc_try_fmt(struct iris_inst * inst,struct v4l2_format * f)192 int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
193 {
194 	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
195 	const struct iris_fmt *fmt;
196 	struct v4l2_format *f_inst;
197 
198 	memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
199 	fmt = find_format(inst, pixmp->pixelformat, f->type);
200 	switch (f->type) {
201 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
202 		if (!fmt) {
203 			f_inst = inst->fmt_src;
204 			f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
205 			f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
206 			f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
207 		}
208 		break;
209 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
210 		if (!fmt) {
211 			f_inst = inst->fmt_dst;
212 			f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
213 			f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
214 			f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
215 		}
216 		break;
217 	default:
218 		return -EINVAL;
219 	}
220 
221 	if (pixmp->field == V4L2_FIELD_ANY)
222 		pixmp->field = V4L2_FIELD_NONE;
223 
224 	pixmp->num_planes = 1;
225 
226 	return 0;
227 }
228 
iris_venc_s_fmt_output(struct iris_inst * inst,struct v4l2_format * f)229 static int iris_venc_s_fmt_output(struct iris_inst *inst, struct v4l2_format *f)
230 {
231 	const struct iris_fmt *venc_fmt;
232 	struct v4l2_format *fmt;
233 	u32 codec_align;
234 
235 	iris_venc_try_fmt(inst, f);
236 
237 	venc_fmt = find_format(inst, f->fmt.pix_mp.pixelformat, f->type);
238 	if (!venc_fmt)
239 		return -EINVAL;
240 
241 	codec_align = venc_fmt->pixfmt == V4L2_PIX_FMT_HEVC ? 32 : 16;
242 
243 	fmt = inst->fmt_dst;
244 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
245 	/*
246 	 * If output format size != input format size,
247 	 * it is considered a scaling case,
248 	 * and the scaled size needs to be saved.
249 	 */
250 	if (f->fmt.pix_mp.width != inst->fmt_src->fmt.pix_mp.width ||
251 	    f->fmt.pix_mp.height != inst->fmt_src->fmt.pix_mp.height) {
252 		inst->enc_scale_width = f->fmt.pix_mp.width;
253 		inst->enc_scale_height = f->fmt.pix_mp.height;
254 		fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
255 		fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
256 	}
257 	fmt->fmt.pix_mp.num_planes = 1;
258 	fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
259 	fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
260 
261 	if (f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_DEFAULT &&
262 	    f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_REC709)
263 		f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
264 	fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
265 	fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
266 	fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
267 	fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
268 
269 	inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT);
270 	inst->buffers[BUF_OUTPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
271 	fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
272 	inst->codec = f->fmt.pix_mp.pixelformat;
273 	memcpy(f, fmt, sizeof(struct v4l2_format));
274 
275 	return 0;
276 }
277 
iris_venc_s_fmt_input(struct iris_inst * inst,struct v4l2_format * f)278 static int iris_venc_s_fmt_input(struct iris_inst *inst, struct v4l2_format *f)
279 {
280 	struct v4l2_format *fmt, *output_fmt;
281 
282 	iris_venc_try_fmt(inst, f);
283 
284 	if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type)))
285 		return -EINVAL;
286 
287 	fmt = inst->fmt_src;
288 	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
289 	fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
290 	fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
291 	fmt->fmt.pix_mp.num_planes = 1;
292 	fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
293 	fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128);
294 	fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
295 
296 	fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
297 	fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
298 	fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
299 	fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
300 
301 	output_fmt = inst->fmt_dst;
302 	output_fmt->fmt.pix_mp.width = fmt->fmt.pix_mp.width;
303 	output_fmt->fmt.pix_mp.height = fmt->fmt.pix_mp.height;
304 	output_fmt->fmt.pix_mp.colorspace = fmt->fmt.pix_mp.colorspace;
305 	output_fmt->fmt.pix_mp.xfer_func = fmt->fmt.pix_mp.xfer_func;
306 	output_fmt->fmt.pix_mp.ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc;
307 	output_fmt->fmt.pix_mp.quantization = fmt->fmt.pix_mp.quantization;
308 
309 	inst->buffers[BUF_INPUT].min_count = iris_vpu_buf_count(inst, BUF_INPUT);
310 	inst->buffers[BUF_INPUT].size = fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
311 
312 	inst->enc_raw_width = f->fmt.pix_mp.width;
313 	inst->enc_raw_height = f->fmt.pix_mp.height;
314 	inst->enc_scale_width = f->fmt.pix_mp.width;
315 	inst->enc_scale_height = f->fmt.pix_mp.height;
316 
317 	if (f->fmt.pix_mp.width != inst->crop.width ||
318 	    f->fmt.pix_mp.height != inst->crop.height) {
319 		inst->crop.top = 0;
320 		inst->crop.left = 0;
321 		inst->crop.width = fmt->fmt.pix_mp.width;
322 		inst->crop.height = fmt->fmt.pix_mp.height;
323 
324 		iris_venc_s_fmt_output(inst, output_fmt);
325 	}
326 
327 	memcpy(f, fmt, sizeof(struct v4l2_format));
328 
329 	return 0;
330 }
331 
iris_venc_s_fmt(struct iris_inst * inst,struct v4l2_format * f)332 int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
333 {
334 	struct vb2_queue *q;
335 
336 	q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type);
337 
338 	if (vb2_is_busy(q))
339 		return -EBUSY;
340 
341 	switch (f->type) {
342 	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
343 		return iris_venc_s_fmt_input(inst, f);
344 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
345 		return iris_venc_s_fmt_output(inst, f);
346 	default:
347 		return -EINVAL;
348 	}
349 }
350 
iris_venc_validate_format(struct iris_inst * inst,u32 pixelformat)351 int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat)
352 {
353 	const struct iris_fmt *fmt = NULL;
354 
355 	fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
356 	if (!fmt) {
357 		fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
358 		if (!fmt)
359 			return -EINVAL;
360 	}
361 
362 	return 0;
363 }
364 
iris_venc_subscribe_event(struct iris_inst * inst,const struct v4l2_event_subscription * sub)365 int iris_venc_subscribe_event(struct iris_inst *inst,
366 			      const struct v4l2_event_subscription *sub)
367 {
368 	switch (sub->type) {
369 	case V4L2_EVENT_EOS:
370 		return v4l2_event_subscribe(&inst->fh, sub, 0, NULL);
371 	case V4L2_EVENT_CTRL:
372 		return v4l2_ctrl_subscribe_event(&inst->fh, sub);
373 	default:
374 		return -EINVAL;
375 	}
376 }
377 
iris_venc_s_selection(struct iris_inst * inst,struct v4l2_selection * s)378 int iris_venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s)
379 {
380 	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
381 		return -EINVAL;
382 
383 	switch (s->target) {
384 	case V4L2_SEL_TGT_CROP:
385 		s->r.left = 0;
386 		s->r.top = 0;
387 
388 		if (s->r.width > inst->fmt_src->fmt.pix_mp.width ||
389 		    s->r.height > inst->fmt_src->fmt.pix_mp.height)
390 			return -EINVAL;
391 
392 		inst->crop.left = s->r.left;
393 		inst->crop.top = s->r.top;
394 		inst->crop.width = s->r.width;
395 		inst->crop.height = s->r.height;
396 		inst->fmt_dst->fmt.pix_mp.width = inst->crop.width;
397 		inst->fmt_dst->fmt.pix_mp.height = inst->crop.height;
398 		return iris_venc_s_fmt_output(inst, inst->fmt_dst);
399 	default:
400 		return -EINVAL;
401 	}
402 }
403 
iris_venc_s_param(struct iris_inst * inst,struct v4l2_streamparm * s_parm)404 int iris_venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
405 {
406 	struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
407 	struct vb2_queue *src_q = v4l2_m2m_get_src_vq(inst->m2m_ctx);
408 	struct vb2_queue *dst_q = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
409 	struct v4l2_fract *timeperframe = NULL;
410 	u32 default_rate = DEFAULT_FPS;
411 	bool is_frame_rate = false;
412 	u32 fps, max_rate;
413 
414 	int ret = 0;
415 
416 	if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
417 		timeperframe = &s_parm->parm.output.timeperframe;
418 		max_rate = caps->max_operating_rate;
419 		s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
420 	} else {
421 		timeperframe = &s_parm->parm.capture.timeperframe;
422 		is_frame_rate = true;
423 		max_rate = caps->max_frame_rate;
424 		s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
425 	}
426 
427 	if (!timeperframe->denominator || !timeperframe->numerator) {
428 		if (!timeperframe->numerator)
429 			timeperframe->numerator = 1;
430 		if (!timeperframe->denominator)
431 			timeperframe->denominator = default_rate;
432 	}
433 
434 	fps = timeperframe->denominator / timeperframe->numerator;
435 	if (!fps)
436 		return -EINVAL;
437 
438 	if (fps > max_rate) {
439 		ret = -ENOMEM;
440 		goto reset_rate;
441 	}
442 
443 	if (is_frame_rate)
444 		inst->frame_rate = fps;
445 	else
446 		inst->operating_rate = fps;
447 
448 	if ((s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && vb2_is_streaming(src_q)) ||
449 	    (s_parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && vb2_is_streaming(dst_q))) {
450 		ret = iris_check_core_mbpf(inst);
451 		if (ret)
452 			goto reset_rate;
453 		ret = iris_check_core_mbps(inst);
454 		if (ret)
455 			goto reset_rate;
456 	}
457 
458 	return 0;
459 
460 reset_rate:
461 	if (ret) {
462 		if (is_frame_rate)
463 			inst->frame_rate = default_rate;
464 		else
465 			inst->operating_rate = default_rate;
466 	}
467 
468 	return ret;
469 }
470 
iris_venc_g_param(struct iris_inst * inst,struct v4l2_streamparm * s_parm)471 int iris_venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
472 {
473 	struct v4l2_fract *timeperframe = NULL;
474 
475 	if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
476 		timeperframe = &s_parm->parm.output.timeperframe;
477 		timeperframe->numerator = 1;
478 		timeperframe->denominator = inst->operating_rate;
479 		s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
480 	} else {
481 		timeperframe = &s_parm->parm.capture.timeperframe;
482 		timeperframe->numerator = 1;
483 		timeperframe->denominator = inst->frame_rate;
484 		s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
485 	}
486 
487 	return 0;
488 }
489 
iris_venc_streamon_input(struct iris_inst * inst)490 int iris_venc_streamon_input(struct iris_inst *inst)
491 {
492 	int ret;
493 
494 	ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
495 	if (ret)
496 		return ret;
497 
498 	ret = iris_alloc_and_queue_persist_bufs(inst, BUF_ARP);
499 	if (ret)
500 		return ret;
501 
502 	iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
503 
504 	ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
505 	if (ret)
506 		return ret;
507 
508 	ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
509 	if (ret)
510 		return ret;
511 
512 	ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
513 	if (ret)
514 		return ret;
515 
516 	return iris_process_streamon_input(inst);
517 }
518 
iris_venc_streamon_output(struct iris_inst * inst)519 int iris_venc_streamon_output(struct iris_inst *inst)
520 {
521 	int ret;
522 
523 	ret = iris_set_properties(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
524 	if (ret)
525 		goto error;
526 
527 	ret = iris_alloc_and_queue_persist_bufs(inst, BUF_ARP);
528 	if (ret)
529 		return ret;
530 
531 	iris_get_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
532 
533 	ret = iris_destroy_dequeued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
534 	if (ret)
535 		goto error;
536 
537 	ret = iris_create_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
538 	if (ret)
539 		goto error;
540 
541 	ret = iris_queue_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
542 	if (ret)
543 		goto error;
544 
545 	ret = iris_process_streamon_output(inst);
546 	if (ret)
547 		goto error;
548 
549 	return ret;
550 
551 error:
552 	iris_session_streamoff(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
553 
554 	return ret;
555 }
556 
iris_venc_qbuf(struct iris_inst * inst,struct vb2_v4l2_buffer * vbuf)557 int iris_venc_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf)
558 {
559 	struct iris_buffer *buf = to_iris_buffer(vbuf);
560 	struct vb2_buffer *vb2 = &vbuf->vb2_buf;
561 	struct vb2_queue *q;
562 	int ret;
563 
564 	ret = iris_vb2_buffer_to_driver(vb2, buf);
565 	if (ret)
566 		return ret;
567 
568 	if (buf->type == BUF_INPUT)
569 		iris_set_ts_metadata(inst, vbuf);
570 
571 	q = v4l2_m2m_get_vq(inst->m2m_ctx, vb2->type);
572 	if (!vb2_is_streaming(q)) {
573 		buf->attr |= BUF_ATTR_DEFERRED;
574 		return 0;
575 	}
576 
577 	iris_scale_power(inst);
578 
579 	return iris_queue_buffer(inst, buf);
580 }
581 
iris_venc_start_cmd(struct iris_inst * inst)582 int iris_venc_start_cmd(struct iris_inst *inst)
583 {
584 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
585 	enum iris_inst_sub_state clear_sub_state = 0;
586 	struct vb2_queue *dst_vq;
587 	int ret;
588 
589 	dst_vq = v4l2_m2m_get_dst_vq(inst->m2m_ctx);
590 
591 	if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
592 	    inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) {
593 		vb2_clear_last_buffer_dequeued(dst_vq);
594 		clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
595 		if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
596 			if (hfi_ops->session_resume_drain) {
597 				ret = hfi_ops->session_resume_drain(inst,
598 					V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
599 				if (ret)
600 					return ret;
601 			}
602 			clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
603 		}
604 		if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
605 			if (hfi_ops->session_resume_drain) {
606 				ret = hfi_ops->session_resume_drain(inst,
607 					V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
608 				if (ret)
609 					return ret;
610 			}
611 			clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
612 		}
613 	} else {
614 		dev_err(inst->core->dev, "start called before receiving last_flag\n");
615 		iris_inst_change_state(inst, IRIS_INST_ERROR);
616 		return -EBUSY;
617 	}
618 
619 	inst->last_buffer_dequeued = false;
620 
621 	return iris_inst_change_sub_state(inst, clear_sub_state, 0);
622 }
623 
iris_venc_stop_cmd(struct iris_inst * inst)624 int iris_venc_stop_cmd(struct iris_inst *inst)
625 {
626 	const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops;
627 	int ret;
628 
629 	ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
630 	if (ret)
631 		return ret;
632 
633 	ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN);
634 
635 	iris_scale_power(inst);
636 
637 	return ret;
638 }
639