This source file includes following definitions.
- hantro_get_formats
- hantro_find_format
- hantro_get_default_fmt
- vidioc_querycap
- vidioc_enum_framesizes
- vidioc_enum_fmt
- vidioc_enum_fmt_vid_cap
- vidioc_enum_fmt_vid_out
- vidioc_g_fmt_out_mplane
- vidioc_g_fmt_cap_mplane
- vidioc_try_fmt
- vidioc_try_fmt_cap_mplane
- vidioc_try_fmt_out_mplane
- hantro_reset_fmt
- hantro_reset_encoded_fmt
- hantro_reset_raw_fmt
- hantro_reset_fmts
- hantro_update_requires_request
- vidioc_s_fmt_out_mplane
- vidioc_s_fmt_cap_mplane
- hantro_queue_setup
- hantro_buf_plane_check
- hantro_buf_prepare
- hantro_buf_queue
- hantro_vq_is_coded
- hantro_start_streaming
- hantro_return_bufs
- hantro_stop_streaming
- hantro_buf_request_complete
- hantro_buf_out_validate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <linux/interrupt.h>
18 #include <linux/io.h>
19 #include <linux/module.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/videodev2.h>
22 #include <linux/workqueue.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-event.h>
25 #include <media/v4l2-mem2mem.h>
26 #include <media/videobuf2-core.h>
27 #include <media/videobuf2-dma-sg.h>
28
29 #include "hantro.h"
30 #include "hantro_hw.h"
31 #include "hantro_v4l2.h"
32
33 static const struct hantro_fmt *
34 hantro_get_formats(const struct hantro_ctx *ctx, unsigned int *num_fmts)
35 {
36 const struct hantro_fmt *formats;
37
38 if (hantro_is_encoder_ctx(ctx)) {
39 formats = ctx->dev->variant->enc_fmts;
40 *num_fmts = ctx->dev->variant->num_enc_fmts;
41 } else {
42 formats = ctx->dev->variant->dec_fmts;
43 *num_fmts = ctx->dev->variant->num_dec_fmts;
44 }
45
46 return formats;
47 }
48
49 static const struct hantro_fmt *
50 hantro_find_format(const struct hantro_fmt *formats, unsigned int num_fmts,
51 u32 fourcc)
52 {
53 unsigned int i;
54
55 for (i = 0; i < num_fmts; i++)
56 if (formats[i].fourcc == fourcc)
57 return &formats[i];
58 return NULL;
59 }
60
61 static const struct hantro_fmt *
62 hantro_get_default_fmt(const struct hantro_fmt *formats, unsigned int num_fmts,
63 bool bitstream)
64 {
65 unsigned int i;
66
67 for (i = 0; i < num_fmts; i++) {
68 if (bitstream == (formats[i].codec_mode !=
69 HANTRO_MODE_NONE))
70 return &formats[i];
71 }
72 return NULL;
73 }
74
75 static int vidioc_querycap(struct file *file, void *priv,
76 struct v4l2_capability *cap)
77 {
78 struct hantro_dev *vpu = video_drvdata(file);
79 struct video_device *vdev = video_devdata(file);
80
81 strscpy(cap->driver, vpu->dev->driver->name, sizeof(cap->driver));
82 strscpy(cap->card, vdev->name, sizeof(cap->card));
83 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform: %s",
84 vpu->dev->driver->name);
85 return 0;
86 }
87
88 static int vidioc_enum_framesizes(struct file *file, void *priv,
89 struct v4l2_frmsizeenum *fsize)
90 {
91 struct hantro_ctx *ctx = fh_to_ctx(priv);
92 const struct hantro_fmt *formats, *fmt;
93 unsigned int num_fmts;
94
95 if (fsize->index != 0) {
96 vpu_debug(0, "invalid frame size index (expected 0, got %d)\n",
97 fsize->index);
98 return -EINVAL;
99 }
100
101 formats = hantro_get_formats(ctx, &num_fmts);
102 fmt = hantro_find_format(formats, num_fmts, fsize->pixel_format);
103 if (!fmt) {
104 vpu_debug(0, "unsupported bitstream format (%08x)\n",
105 fsize->pixel_format);
106 return -EINVAL;
107 }
108
109
110 if (fmt->codec_mode == HANTRO_MODE_NONE)
111 return -EINVAL;
112
113 fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
114 fsize->stepwise = fmt->frmsize;
115
116 return 0;
117 }
118
119 static int vidioc_enum_fmt(struct file *file, void *priv,
120 struct v4l2_fmtdesc *f, bool capture)
121
122 {
123 struct hantro_ctx *ctx = fh_to_ctx(priv);
124 const struct hantro_fmt *fmt, *formats;
125 unsigned int num_fmts, i, j = 0;
126 bool skip_mode_none;
127
128
129
130
131
132
133
134
135
136
137
138 skip_mode_none = capture == hantro_is_encoder_ctx(ctx);
139
140 formats = hantro_get_formats(ctx, &num_fmts);
141 for (i = 0; i < num_fmts; i++) {
142 bool mode_none = formats[i].codec_mode == HANTRO_MODE_NONE;
143
144 if (skip_mode_none == mode_none)
145 continue;
146 if (j == f->index) {
147 fmt = &formats[i];
148 f->pixelformat = fmt->fourcc;
149 return 0;
150 }
151 ++j;
152 }
153 return -EINVAL;
154 }
155
156 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
157 struct v4l2_fmtdesc *f)
158 {
159 return vidioc_enum_fmt(file, priv, f, true);
160 }
161
162 static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
163 struct v4l2_fmtdesc *f)
164 {
165 return vidioc_enum_fmt(file, priv, f, false);
166 }
167
168 static int vidioc_g_fmt_out_mplane(struct file *file, void *priv,
169 struct v4l2_format *f)
170 {
171 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
172 struct hantro_ctx *ctx = fh_to_ctx(priv);
173
174 vpu_debug(4, "f->type = %d\n", f->type);
175
176 *pix_mp = ctx->src_fmt;
177
178 return 0;
179 }
180
181 static int vidioc_g_fmt_cap_mplane(struct file *file, void *priv,
182 struct v4l2_format *f)
183 {
184 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
185 struct hantro_ctx *ctx = fh_to_ctx(priv);
186
187 vpu_debug(4, "f->type = %d\n", f->type);
188
189 *pix_mp = ctx->dst_fmt;
190
191 return 0;
192 }
193
194 static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f,
195 bool capture)
196 {
197 struct hantro_ctx *ctx = fh_to_ctx(priv);
198 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
199 const struct hantro_fmt *formats, *fmt, *vpu_fmt;
200 unsigned int num_fmts;
201 bool coded;
202
203 coded = capture == hantro_is_encoder_ctx(ctx);
204
205 vpu_debug(4, "trying format %c%c%c%c\n",
206 (pix_mp->pixelformat & 0x7f),
207 (pix_mp->pixelformat >> 8) & 0x7f,
208 (pix_mp->pixelformat >> 16) & 0x7f,
209 (pix_mp->pixelformat >> 24) & 0x7f);
210
211 formats = hantro_get_formats(ctx, &num_fmts);
212 fmt = hantro_find_format(formats, num_fmts, pix_mp->pixelformat);
213 if (!fmt) {
214 fmt = hantro_get_default_fmt(formats, num_fmts, coded);
215 f->fmt.pix_mp.pixelformat = fmt->fourcc;
216 }
217
218 if (coded) {
219 pix_mp->num_planes = 1;
220 vpu_fmt = fmt;
221 } else if (hantro_is_encoder_ctx(ctx)) {
222 vpu_fmt = ctx->vpu_dst_fmt;
223 } else {
224 vpu_fmt = ctx->vpu_src_fmt;
225
226
227
228
229 pix_mp->width = ctx->src_fmt.width;
230 pix_mp->height = ctx->src_fmt.height;
231 }
232
233 pix_mp->field = V4L2_FIELD_NONE;
234
235 v4l2_apply_frmsize_constraints(&pix_mp->width, &pix_mp->height,
236 &vpu_fmt->frmsize);
237
238 if (!coded) {
239
240 v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width,
241 pix_mp->height);
242
243
244
245
246
247 if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
248 pix_mp->plane_fmt[0].sizeimage +=
249 128 * DIV_ROUND_UP(pix_mp->width, 16) *
250 DIV_ROUND_UP(pix_mp->height, 16);
251 } else if (!pix_mp->plane_fmt[0].sizeimage) {
252
253
254
255
256
257 pix_mp->plane_fmt[0].sizeimage = fmt->header_size +
258 pix_mp->width * pix_mp->height * fmt->max_depth;
259 }
260
261 return 0;
262 }
263
264 static int vidioc_try_fmt_cap_mplane(struct file *file, void *priv,
265 struct v4l2_format *f)
266 {
267 return vidioc_try_fmt(file, priv, f, true);
268 }
269
270 static int vidioc_try_fmt_out_mplane(struct file *file, void *priv,
271 struct v4l2_format *f)
272 {
273 return vidioc_try_fmt(file, priv, f, false);
274 }
275
276 static void
277 hantro_reset_fmt(struct v4l2_pix_format_mplane *fmt,
278 const struct hantro_fmt *vpu_fmt)
279 {
280 memset(fmt, 0, sizeof(*fmt));
281
282 fmt->pixelformat = vpu_fmt->fourcc;
283 fmt->field = V4L2_FIELD_NONE;
284 fmt->colorspace = V4L2_COLORSPACE_JPEG,
285 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
286 fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
287 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
288 }
289
290 static void
291 hantro_reset_encoded_fmt(struct hantro_ctx *ctx)
292 {
293 const struct hantro_fmt *vpu_fmt, *formats;
294 struct v4l2_pix_format_mplane *fmt;
295 unsigned int num_fmts;
296
297 formats = hantro_get_formats(ctx, &num_fmts);
298 vpu_fmt = hantro_get_default_fmt(formats, num_fmts, true);
299
300 if (hantro_is_encoder_ctx(ctx)) {
301 ctx->vpu_dst_fmt = vpu_fmt;
302 fmt = &ctx->dst_fmt;
303 } else {
304 ctx->vpu_src_fmt = vpu_fmt;
305 fmt = &ctx->src_fmt;
306 }
307
308 hantro_reset_fmt(fmt, vpu_fmt);
309 fmt->num_planes = 1;
310 fmt->width = vpu_fmt->frmsize.min_width;
311 fmt->height = vpu_fmt->frmsize.min_height;
312 fmt->plane_fmt[0].sizeimage = vpu_fmt->header_size +
313 fmt->width * fmt->height * vpu_fmt->max_depth;
314 }
315
316 static void
317 hantro_reset_raw_fmt(struct hantro_ctx *ctx)
318 {
319 const struct hantro_fmt *raw_vpu_fmt, *formats;
320 struct v4l2_pix_format_mplane *raw_fmt, *encoded_fmt;
321 unsigned int num_fmts;
322
323 formats = hantro_get_formats(ctx, &num_fmts);
324 raw_vpu_fmt = hantro_get_default_fmt(formats, num_fmts, false);
325
326 if (hantro_is_encoder_ctx(ctx)) {
327 ctx->vpu_src_fmt = raw_vpu_fmt;
328 raw_fmt = &ctx->src_fmt;
329 encoded_fmt = &ctx->dst_fmt;
330 } else {
331 ctx->vpu_dst_fmt = raw_vpu_fmt;
332 raw_fmt = &ctx->dst_fmt;
333 encoded_fmt = &ctx->src_fmt;
334 }
335
336 hantro_reset_fmt(raw_fmt, raw_vpu_fmt);
337 v4l2_fill_pixfmt_mp(raw_fmt, raw_vpu_fmt->fourcc,
338 encoded_fmt->width,
339 encoded_fmt->height);
340 }
341
342 void hantro_reset_fmts(struct hantro_ctx *ctx)
343 {
344 hantro_reset_encoded_fmt(ctx);
345 hantro_reset_raw_fmt(ctx);
346 }
347
348 static void
349 hantro_update_requires_request(struct hantro_ctx *ctx, u32 fourcc)
350 {
351 switch (fourcc) {
352 case V4L2_PIX_FMT_JPEG:
353 ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = false;
354 break;
355 case V4L2_PIX_FMT_MPEG2_SLICE:
356 case V4L2_PIX_FMT_VP8_FRAME:
357 case V4L2_PIX_FMT_H264_SLICE:
358 ctx->fh.m2m_ctx->out_q_ctx.q.requires_requests = true;
359 break;
360 default:
361 break;
362 }
363 }
364
365 static int
366 vidioc_s_fmt_out_mplane(struct file *file, void *priv, struct v4l2_format *f)
367 {
368 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
369 struct hantro_ctx *ctx = fh_to_ctx(priv);
370 struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
371 const struct hantro_fmt *formats;
372 unsigned int num_fmts;
373 int ret;
374
375 ret = vidioc_try_fmt_out_mplane(file, priv, f);
376 if (ret)
377 return ret;
378
379 if (!hantro_is_encoder_ctx(ctx)) {
380 struct vb2_queue *peer_vq;
381
382
383
384
385
386
387 if (vb2_is_streaming(vq) || (vb2_is_busy(vq) &&
388 pix_mp->pixelformat != ctx->src_fmt.pixelformat))
389 return -EBUSY;
390
391
392
393
394
395 peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
396 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
397 if (vb2_is_busy(peer_vq))
398 return -EBUSY;
399 } else {
400
401
402
403
404 if (vb2_is_busy(vq))
405 return -EBUSY;
406 }
407
408 formats = hantro_get_formats(ctx, &num_fmts);
409 ctx->vpu_src_fmt = hantro_find_format(formats, num_fmts,
410 pix_mp->pixelformat);
411 ctx->src_fmt = *pix_mp;
412
413
414
415
416
417
418
419
420
421
422 if (!hantro_is_encoder_ctx(ctx))
423 hantro_reset_raw_fmt(ctx);
424
425
426 ctx->dst_fmt.colorspace = pix_mp->colorspace;
427 ctx->dst_fmt.ycbcr_enc = pix_mp->ycbcr_enc;
428 ctx->dst_fmt.xfer_func = pix_mp->xfer_func;
429 ctx->dst_fmt.quantization = pix_mp->quantization;
430
431 hantro_update_requires_request(ctx, pix_mp->pixelformat);
432
433 vpu_debug(0, "OUTPUT codec mode: %d\n", ctx->vpu_src_fmt->codec_mode);
434 vpu_debug(0, "fmt - w: %d, h: %d\n",
435 pix_mp->width, pix_mp->height);
436 return 0;
437 }
438
439 static int vidioc_s_fmt_cap_mplane(struct file *file, void *priv,
440 struct v4l2_format *f)
441 {
442 struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
443 struct hantro_ctx *ctx = fh_to_ctx(priv);
444 const struct hantro_fmt *formats;
445 struct vb2_queue *vq;
446 unsigned int num_fmts;
447 int ret;
448
449
450 vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
451 if (vb2_is_busy(vq))
452 return -EBUSY;
453
454 if (hantro_is_encoder_ctx(ctx)) {
455 struct vb2_queue *peer_vq;
456
457
458
459
460
461
462 peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
463 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
464 if (vb2_is_busy(peer_vq) &&
465 (pix_mp->pixelformat != ctx->dst_fmt.pixelformat ||
466 pix_mp->height != ctx->dst_fmt.height ||
467 pix_mp->width != ctx->dst_fmt.width))
468 return -EBUSY;
469 }
470
471 ret = vidioc_try_fmt_cap_mplane(file, priv, f);
472 if (ret)
473 return ret;
474
475 formats = hantro_get_formats(ctx, &num_fmts);
476 ctx->vpu_dst_fmt = hantro_find_format(formats, num_fmts,
477 pix_mp->pixelformat);
478 ctx->dst_fmt = *pix_mp;
479
480
481
482
483
484
485
486
487
488
489 if (hantro_is_encoder_ctx(ctx))
490 hantro_reset_raw_fmt(ctx);
491
492
493 ctx->src_fmt.colorspace = pix_mp->colorspace;
494 ctx->src_fmt.ycbcr_enc = pix_mp->ycbcr_enc;
495 ctx->src_fmt.xfer_func = pix_mp->xfer_func;
496 ctx->src_fmt.quantization = pix_mp->quantization;
497
498 vpu_debug(0, "CAPTURE codec mode: %d\n", ctx->vpu_dst_fmt->codec_mode);
499 vpu_debug(0, "fmt - w: %d, h: %d\n",
500 pix_mp->width, pix_mp->height);
501
502 hantro_update_requires_request(ctx, pix_mp->pixelformat);
503
504 return 0;
505 }
506
507 const struct v4l2_ioctl_ops hantro_ioctl_ops = {
508 .vidioc_querycap = vidioc_querycap,
509 .vidioc_enum_framesizes = vidioc_enum_framesizes,
510
511 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_cap_mplane,
512 .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt_out_mplane,
513 .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt_out_mplane,
514 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_cap_mplane,
515 .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt_out_mplane,
516 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_cap_mplane,
517 .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
518 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
519
520 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
521 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
522 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
523 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
524 .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
525 .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
526 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
527
528 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
529 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
530
531 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
532 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
533 };
534
535 static int
536 hantro_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
537 unsigned int *num_planes, unsigned int sizes[],
538 struct device *alloc_devs[])
539 {
540 struct hantro_ctx *ctx = vb2_get_drv_priv(vq);
541 struct v4l2_pix_format_mplane *pixfmt;
542 int i;
543
544 switch (vq->type) {
545 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
546 pixfmt = &ctx->dst_fmt;
547 break;
548 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
549 pixfmt = &ctx->src_fmt;
550 break;
551 default:
552 vpu_err("invalid queue type: %d\n", vq->type);
553 return -EINVAL;
554 }
555
556 if (*num_planes) {
557 if (*num_planes != pixfmt->num_planes)
558 return -EINVAL;
559 for (i = 0; i < pixfmt->num_planes; ++i)
560 if (sizes[i] < pixfmt->plane_fmt[i].sizeimage)
561 return -EINVAL;
562 return 0;
563 }
564
565 *num_planes = pixfmt->num_planes;
566 for (i = 0; i < pixfmt->num_planes; ++i)
567 sizes[i] = pixfmt->plane_fmt[i].sizeimage;
568 return 0;
569 }
570
571 static int
572 hantro_buf_plane_check(struct vb2_buffer *vb, const struct hantro_fmt *vpu_fmt,
573 struct v4l2_pix_format_mplane *pixfmt)
574 {
575 unsigned int sz;
576 int i;
577
578 for (i = 0; i < pixfmt->num_planes; ++i) {
579 sz = pixfmt->plane_fmt[i].sizeimage;
580 vpu_debug(4, "plane %d size: %ld, sizeimage: %u\n",
581 i, vb2_plane_size(vb, i), sz);
582 if (vb2_plane_size(vb, i) < sz) {
583 vpu_err("plane %d is too small for output\n", i);
584 return -EINVAL;
585 }
586 }
587 return 0;
588 }
589
590 static int hantro_buf_prepare(struct vb2_buffer *vb)
591 {
592 struct vb2_queue *vq = vb->vb2_queue;
593 struct hantro_ctx *ctx = vb2_get_drv_priv(vq);
594
595 if (V4L2_TYPE_IS_OUTPUT(vq->type))
596 return hantro_buf_plane_check(vb, ctx->vpu_src_fmt,
597 &ctx->src_fmt);
598
599 return hantro_buf_plane_check(vb, ctx->vpu_dst_fmt, &ctx->dst_fmt);
600 }
601
602 static void hantro_buf_queue(struct vb2_buffer *vb)
603 {
604 struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
605 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
606
607 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
608 }
609
610 static bool hantro_vq_is_coded(struct vb2_queue *q)
611 {
612 struct hantro_ctx *ctx = vb2_get_drv_priv(q);
613
614 return hantro_is_encoder_ctx(ctx) != V4L2_TYPE_IS_OUTPUT(q->type);
615 }
616
617 static int hantro_start_streaming(struct vb2_queue *q, unsigned int count)
618 {
619 struct hantro_ctx *ctx = vb2_get_drv_priv(q);
620 int ret = 0;
621
622 if (V4L2_TYPE_IS_OUTPUT(q->type))
623 ctx->sequence_out = 0;
624 else
625 ctx->sequence_cap = 0;
626
627 if (hantro_vq_is_coded(q)) {
628 enum hantro_codec_mode codec_mode;
629
630 if (V4L2_TYPE_IS_OUTPUT(q->type))
631 codec_mode = ctx->vpu_src_fmt->codec_mode;
632 else
633 codec_mode = ctx->vpu_dst_fmt->codec_mode;
634
635 vpu_debug(4, "Codec mode = %d\n", codec_mode);
636 ctx->codec_ops = &ctx->dev->variant->codec_ops[codec_mode];
637 if (ctx->codec_ops->init)
638 ret = ctx->codec_ops->init(ctx);
639 }
640
641 return ret;
642 }
643
644 static void
645 hantro_return_bufs(struct vb2_queue *q,
646 struct vb2_v4l2_buffer *(*buf_remove)(struct v4l2_m2m_ctx *))
647 {
648 struct hantro_ctx *ctx = vb2_get_drv_priv(q);
649
650 for (;;) {
651 struct vb2_v4l2_buffer *vbuf;
652
653 vbuf = buf_remove(ctx->fh.m2m_ctx);
654 if (!vbuf)
655 break;
656 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
657 &ctx->ctrl_handler);
658 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
659 }
660 }
661
662 static void hantro_stop_streaming(struct vb2_queue *q)
663 {
664 struct hantro_ctx *ctx = vb2_get_drv_priv(q);
665
666 if (hantro_vq_is_coded(q)) {
667 if (ctx->codec_ops && ctx->codec_ops->exit)
668 ctx->codec_ops->exit(ctx);
669 }
670
671
672
673
674
675
676 if (V4L2_TYPE_IS_OUTPUT(q->type))
677 hantro_return_bufs(q, v4l2_m2m_src_buf_remove);
678 else
679 hantro_return_bufs(q, v4l2_m2m_dst_buf_remove);
680 }
681
682 static void hantro_buf_request_complete(struct vb2_buffer *vb)
683 {
684 struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
685
686 v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->ctrl_handler);
687 }
688
689 static int hantro_buf_out_validate(struct vb2_buffer *vb)
690 {
691 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
692
693 vbuf->field = V4L2_FIELD_NONE;
694 return 0;
695 }
696
697 const struct vb2_ops hantro_queue_ops = {
698 .queue_setup = hantro_queue_setup,
699 .buf_prepare = hantro_buf_prepare,
700 .buf_queue = hantro_buf_queue,
701 .buf_out_validate = hantro_buf_out_validate,
702 .buf_request_complete = hantro_buf_request_complete,
703 .start_streaming = hantro_start_streaming,
704 .stop_streaming = hantro_stop_streaming,
705 .wait_prepare = vb2_ops_wait_prepare,
706 .wait_finish = vb2_ops_wait_finish,
707 };