1 // SPDX-License-Identifier: GPL-2.0
3 * Contains the driver implementation for the V4L2 stateless interface.
6 #include <linux/debugfs.h>
7 #include <linux/font.h>
8 #include <media/v4l2-event.h>
9 #include <media/v4l2-ioctl.h>
10 #include <media/videobuf2-vmalloc.h>
11 #include <media/videobuf2-v4l2.h>
13 #include "visl-video.h"
16 #include "visl-debugfs.h"
18 #define MIN_CODED_SZ (1024U * 256U)
20 static void visl_set_current_codec(struct visl_ctx
*ctx
)
22 u32 fourcc
= ctx
->coded_fmt
.fmt
.pix_mp
.pixelformat
;
25 case V4L2_PIX_FMT_FWHT_STATELESS
:
26 ctx
->current_codec
= VISL_CODEC_FWHT
;
28 case V4L2_PIX_FMT_MPEG2_SLICE
:
29 ctx
->current_codec
= VISL_CODEC_MPEG2
;
31 case V4L2_PIX_FMT_VP8_FRAME
:
32 ctx
->current_codec
= VISL_CODEC_VP8
;
34 case V4L2_PIX_FMT_VP9_FRAME
:
35 ctx
->current_codec
= VISL_CODEC_VP9
;
37 case V4L2_PIX_FMT_H264_SLICE
:
38 ctx
->current_codec
= VISL_CODEC_H264
;
40 case V4L2_PIX_FMT_HEVC_SLICE
:
41 ctx
->current_codec
= VISL_CODEC_HEVC
;
43 case V4L2_PIX_FMT_AV1_FRAME
:
44 ctx
->current_codec
= VISL_CODEC_AV1
;
47 dprintk(ctx
->dev
, "Warning: unsupported fourcc: %d\n", fourcc
);
48 ctx
->current_codec
= VISL_CODEC_NONE
;
53 static void visl_print_fmt(struct visl_ctx
*ctx
, const struct v4l2_format
*f
)
55 const struct v4l2_pix_format_mplane
*pix_mp
= &f
->fmt
.pix_mp
;
58 dprintk(ctx
->dev
, "width: %d\n", pix_mp
->width
);
59 dprintk(ctx
->dev
, "height: %d\n", pix_mp
->height
);
60 dprintk(ctx
->dev
, "pixelformat: %c%c%c%c\n",
62 (pix_mp
->pixelformat
>> 8) & 0xff,
63 (pix_mp
->pixelformat
>> 16) & 0xff,
64 (pix_mp
->pixelformat
>> 24) & 0xff);
66 dprintk(ctx
->dev
, "field: %d\n", pix_mp
->field
);
67 dprintk(ctx
->dev
, "colorspace: %d\n", pix_mp
->colorspace
);
68 dprintk(ctx
->dev
, "num_planes: %d\n", pix_mp
->num_planes
);
69 dprintk(ctx
->dev
, "flags: %d\n", pix_mp
->flags
);
70 dprintk(ctx
->dev
, "quantization: %d\n", pix_mp
->quantization
);
71 dprintk(ctx
->dev
, "xfer_func: %d\n", pix_mp
->xfer_func
);
73 for (i
= 0; i
< pix_mp
->num_planes
; i
++) {
75 "plane[%d]: sizeimage: %d\n", i
, pix_mp
->plane_fmt
[i
].sizeimage
);
77 "plane[%d]: bytesperline: %d\n", i
, pix_mp
->plane_fmt
[i
].bytesperline
);
81 static int visl_tpg_init(struct visl_ctx
*ctx
)
83 const struct font_desc
*font
;
84 const char *font_name
= "VGA8x16";
86 u32 width
= ctx
->decoded_fmt
.fmt
.pix_mp
.width
;
87 u32 height
= ctx
->decoded_fmt
.fmt
.pix_mp
.height
;
88 struct v4l2_pix_format_mplane
*f
= &ctx
->decoded_fmt
.fmt
.pix_mp
;
92 font
= find_font(font_name
);
94 tpg_init(&ctx
->tpg
, width
, height
);
96 ret
= tpg_alloc(&ctx
->tpg
, width
);
100 tpg_set_font(font
->data
);
101 ret
= tpg_s_fourcc(&ctx
->tpg
,
107 tpg_reset_source(&ctx
->tpg
, width
, height
, f
->field
);
109 tpg_s_pattern(&ctx
->tpg
, TPG_PAT_75_COLORBAR
);
111 tpg_s_field(&ctx
->tpg
, f
->field
, false);
112 tpg_s_colorspace(&ctx
->tpg
, f
->colorspace
);
113 tpg_s_ycbcr_enc(&ctx
->tpg
, f
->ycbcr_enc
);
114 tpg_s_quantization(&ctx
->tpg
, f
->quantization
);
115 tpg_s_xfer_func(&ctx
->tpg
, f
->xfer_func
);
117 v4l2_err(&ctx
->dev
->v4l2_dev
,
118 "Font %s not found\n", font_name
);
123 dprintk(ctx
->dev
, "Initialized the V4L2 test pattern generator, w=%d, h=%d, max_w=%d\n",
124 width
, height
, width
);
134 static const u32 visl_decoded_fmts
[] = {
139 static const u32 visl_extended_decoded_fmts
[] = {
145 const struct visl_coded_format_desc visl_coded_fmts
[] = {
147 .pixelformat
= V4L2_PIX_FMT_FWHT_STATELESS
,
156 .ctrls
= &visl_fwht_ctrls
,
157 .num_decoded_fmts
= ARRAY_SIZE(visl_decoded_fmts
),
158 .decoded_fmts
= visl_decoded_fmts
,
161 .pixelformat
= V4L2_PIX_FMT_MPEG2_SLICE
,
170 .ctrls
= &visl_mpeg2_ctrls
,
171 .num_decoded_fmts
= ARRAY_SIZE(visl_decoded_fmts
),
172 .decoded_fmts
= visl_decoded_fmts
,
175 .pixelformat
= V4L2_PIX_FMT_VP8_FRAME
,
184 .ctrls
= &visl_vp8_ctrls
,
185 .num_decoded_fmts
= ARRAY_SIZE(visl_decoded_fmts
),
186 .decoded_fmts
= visl_decoded_fmts
,
189 .pixelformat
= V4L2_PIX_FMT_VP9_FRAME
,
198 .ctrls
= &visl_vp9_ctrls
,
199 .num_decoded_fmts
= ARRAY_SIZE(visl_decoded_fmts
),
200 .decoded_fmts
= visl_decoded_fmts
,
203 .pixelformat
= V4L2_PIX_FMT_H264_SLICE
,
212 .ctrls
= &visl_h264_ctrls
,
213 .num_decoded_fmts
= ARRAY_SIZE(visl_decoded_fmts
),
214 .decoded_fmts
= visl_decoded_fmts
,
217 .pixelformat
= V4L2_PIX_FMT_HEVC_SLICE
,
226 .ctrls
= &visl_hevc_ctrls
,
227 .num_decoded_fmts
= ARRAY_SIZE(visl_decoded_fmts
),
228 .decoded_fmts
= visl_decoded_fmts
,
231 .pixelformat
= V4L2_PIX_FMT_AV1_FRAME
,
240 .ctrls
= &visl_av1_ctrls
,
241 .num_decoded_fmts
= ARRAY_SIZE(visl_decoded_fmts
),
242 .decoded_fmts
= visl_decoded_fmts
,
247 const size_t num_coded_fmts
= ARRAY_SIZE(visl_coded_fmts
);
249 static const struct visl_coded_format_desc
*
250 visl_find_coded_fmt_desc(u32 fourcc
)
254 for (i
= 0; i
< ARRAY_SIZE(visl_coded_fmts
); i
++) {
255 if (visl_coded_fmts
[i
].pixelformat
== fourcc
)
256 return &visl_coded_fmts
[i
];
262 static void visl_init_fmt(struct v4l2_format
*f
, u32 fourcc
)
263 { memset(f
, 0, sizeof(*f
));
264 f
->fmt
.pix_mp
.pixelformat
= fourcc
;
265 f
->fmt
.pix_mp
.field
= V4L2_FIELD_NONE
;
266 f
->fmt
.pix_mp
.colorspace
= V4L2_COLORSPACE_REC709
;
267 f
->fmt
.pix_mp
.ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
268 f
->fmt
.pix_mp
.quantization
= V4L2_QUANTIZATION_DEFAULT
;
269 f
->fmt
.pix_mp
.xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
272 static void visl_reset_coded_fmt(struct visl_ctx
*ctx
)
274 struct v4l2_format
*f
= &ctx
->coded_fmt
;
275 struct v4l2_pix_format_mplane
*pix_mp
= &f
->fmt
.pix_mp
;
277 ctx
->coded_format_desc
= &visl_coded_fmts
[0];
278 visl_init_fmt(f
, ctx
->coded_format_desc
->pixelformat
);
280 f
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
281 f
->fmt
.pix_mp
.width
= ctx
->coded_format_desc
->frmsize
.min_width
;
282 f
->fmt
.pix_mp
.height
= ctx
->coded_format_desc
->frmsize
.min_height
;
284 pix_mp
->num_planes
= 1;
285 pix_mp
->plane_fmt
[0].sizeimage
= pix_mp
->width
* pix_mp
->height
* 8;
287 dprintk(ctx
->dev
, "OUTPUT format was set to:\n");
288 visl_print_fmt(ctx
, &ctx
->coded_fmt
);
290 visl_set_current_codec(ctx
);
293 static int visl_reset_decoded_fmt(struct visl_ctx
*ctx
)
295 struct v4l2_format
*f
= &ctx
->decoded_fmt
;
296 u32 decoded_fmt
= ctx
->coded_format_desc
[0].decoded_fmts
[0];
298 visl_init_fmt(f
, decoded_fmt
);
300 f
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
302 v4l2_fill_pixfmt_mp(&f
->fmt
.pix_mp
,
303 ctx
->coded_format_desc
->decoded_fmts
[0],
304 ctx
->coded_fmt
.fmt
.pix_mp
.width
,
305 ctx
->coded_fmt
.fmt
.pix_mp
.height
);
307 dprintk(ctx
->dev
, "CAPTURE format was set to:\n");
308 visl_print_fmt(ctx
, &ctx
->decoded_fmt
);
310 return visl_tpg_init(ctx
);
313 int visl_set_default_format(struct visl_ctx
*ctx
)
315 visl_reset_coded_fmt(ctx
);
316 return visl_reset_decoded_fmt(ctx
);
319 static struct visl_q_data
*get_q_data(struct visl_ctx
*ctx
,
320 enum v4l2_buf_type type
)
323 case V4L2_BUF_TYPE_VIDEO_OUTPUT
:
324 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
325 return &ctx
->q_data
[V4L2_M2M_SRC
];
326 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
327 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
:
328 return &ctx
->q_data
[V4L2_M2M_DST
];
335 static int visl_querycap(struct file
*file
, void *priv
,
336 struct v4l2_capability
*cap
)
338 strscpy(cap
->driver
, VISL_NAME
, sizeof(cap
->driver
));
339 strscpy(cap
->card
, VISL_NAME
, sizeof(cap
->card
));
340 snprintf(cap
->bus_info
, sizeof(cap
->bus_info
),
341 "platform:%s", VISL_NAME
);
346 static int visl_enum_fmt_vid_cap(struct file
*file
, void *priv
,
347 struct v4l2_fmtdesc
*f
)
349 struct visl_ctx
*ctx
= visl_file_to_ctx(file
);
350 u32 index
= f
->index
& ~V4L2_FMTDESC_FLAG_ENUM_ALL
;
351 int max_fmts
= ctx
->coded_format_desc
->num_decoded_fmts
;
352 const u32
*decoded_fmts
= ctx
->coded_format_desc
->decoded_fmts
;
354 if (f
->index
& V4L2_FMTDESC_FLAG_ENUM_ALL
) {
355 max_fmts
= ARRAY_SIZE(visl_extended_decoded_fmts
);
356 decoded_fmts
= visl_extended_decoded_fmts
;
361 if (index
>= max_fmts
)
364 f
->pixelformat
= decoded_fmts
[index
];
368 static int visl_enum_fmt_vid_out(struct file
*file
, void *priv
,
369 struct v4l2_fmtdesc
*f
)
371 if (f
->index
>= ARRAY_SIZE(visl_coded_fmts
))
374 f
->pixelformat
= visl_coded_fmts
[f
->index
].pixelformat
;
378 static int visl_g_fmt_vid_cap(struct file
*file
, void *priv
,
379 struct v4l2_format
*f
)
381 struct visl_ctx
*ctx
= visl_file_to_ctx(file
);
382 *f
= ctx
->decoded_fmt
;
387 static int visl_g_fmt_vid_out(struct file
*file
, void *priv
,
388 struct v4l2_format
*f
)
390 struct visl_ctx
*ctx
= visl_file_to_ctx(file
);
396 static int visl_try_fmt_vid_cap(struct file
*file
, void *priv
,
397 struct v4l2_format
*f
)
399 struct v4l2_pix_format_mplane
*pix_mp
= &f
->fmt
.pix_mp
;
400 struct visl_ctx
*ctx
= visl_file_to_ctx(file
);
401 const struct visl_coded_format_desc
*coded_desc
;
404 coded_desc
= ctx
->coded_format_desc
;
406 for (i
= 0; i
< coded_desc
->num_decoded_fmts
; i
++) {
407 if (coded_desc
->decoded_fmts
[i
] == pix_mp
->pixelformat
)
411 if (i
== coded_desc
->num_decoded_fmts
)
412 pix_mp
->pixelformat
= coded_desc
->decoded_fmts
[0];
414 v4l2_apply_frmsize_constraints(&pix_mp
->width
,
416 &coded_desc
->frmsize
);
418 v4l2_fill_pixfmt_mp(pix_mp
, pix_mp
->pixelformat
,
419 pix_mp
->width
, pix_mp
->height
);
421 pix_mp
->field
= V4L2_FIELD_NONE
;
426 static int visl_try_fmt_vid_out(struct file
*file
, void *priv
,
427 struct v4l2_format
*f
)
429 struct v4l2_pix_format_mplane
*pix_mp
= &f
->fmt
.pix_mp
;
430 const struct visl_coded_format_desc
*coded_desc
;
432 coded_desc
= visl_find_coded_fmt_desc(pix_mp
->pixelformat
);
434 pix_mp
->pixelformat
= visl_coded_fmts
[0].pixelformat
;
435 coded_desc
= &visl_coded_fmts
[0];
438 v4l2_apply_frmsize_constraints(&pix_mp
->width
,
440 &coded_desc
->frmsize
);
442 pix_mp
->field
= V4L2_FIELD_NONE
;
443 pix_mp
->num_planes
= 1;
445 if (pix_mp
->plane_fmt
[0].sizeimage
== 0)
446 pix_mp
->plane_fmt
[0].sizeimage
= max(MIN_CODED_SZ
,
447 pix_mp
->width
* pix_mp
->height
* 3);
452 static int visl_s_fmt_vid_out(struct file
*file
, void *priv
,
453 struct v4l2_format
*f
)
455 struct visl_ctx
*ctx
= visl_file_to_ctx(file
);
456 struct v4l2_m2m_ctx
*m2m_ctx
= ctx
->fh
.m2m_ctx
;
457 const struct visl_coded_format_desc
*desc
;
458 struct vb2_queue
*peer_vq
;
461 peer_vq
= v4l2_m2m_get_vq(m2m_ctx
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
);
462 if (vb2_is_busy(peer_vq
))
465 dprintk(ctx
->dev
, "Trying to set the OUTPUT format to:\n");
466 visl_print_fmt(ctx
, f
);
468 ret
= visl_try_fmt_vid_out(file
, priv
, f
);
472 desc
= visl_find_coded_fmt_desc(f
->fmt
.pix_mp
.pixelformat
);
473 ctx
->coded_format_desc
= desc
;
476 ret
= visl_reset_decoded_fmt(ctx
);
480 ctx
->decoded_fmt
.fmt
.pix_mp
.colorspace
= f
->fmt
.pix_mp
.colorspace
;
481 ctx
->decoded_fmt
.fmt
.pix_mp
.xfer_func
= f
->fmt
.pix_mp
.xfer_func
;
482 ctx
->decoded_fmt
.fmt
.pix_mp
.ycbcr_enc
= f
->fmt
.pix_mp
.ycbcr_enc
;
483 ctx
->decoded_fmt
.fmt
.pix_mp
.quantization
= f
->fmt
.pix_mp
.quantization
;
485 dprintk(ctx
->dev
, "OUTPUT format was set to:\n");
486 visl_print_fmt(ctx
, &ctx
->coded_fmt
);
488 visl_set_current_codec(ctx
);
492 static int visl_s_fmt_vid_cap(struct file
*file
, void *priv
,
493 struct v4l2_format
*f
)
495 struct visl_ctx
*ctx
= visl_file_to_ctx(file
);
498 dprintk(ctx
->dev
, "Trying to set the CAPTURE format to:\n");
499 visl_print_fmt(ctx
, f
);
501 ret
= visl_try_fmt_vid_cap(file
, priv
, f
);
505 ctx
->decoded_fmt
= *f
;
507 dprintk(ctx
->dev
, "CAPTURE format was set to:\n");
508 visl_print_fmt(ctx
, &ctx
->decoded_fmt
);
514 static int visl_enum_framesizes(struct file
*file
, void *priv
,
515 struct v4l2_frmsizeenum
*fsize
)
517 const struct visl_coded_format_desc
*fmt
;
518 struct visl_ctx
*ctx
= visl_file_to_ctx(file
);
520 if (fsize
->index
!= 0)
523 fmt
= visl_find_coded_fmt_desc(fsize
->pixel_format
);
526 "Unsupported format for the OUTPUT queue: %d\n",
527 fsize
->pixel_format
);
532 fsize
->type
= V4L2_FRMSIZE_TYPE_STEPWISE
;
533 fsize
->stepwise
= fmt
->frmsize
;
537 const struct v4l2_ioctl_ops visl_ioctl_ops
= {
538 .vidioc_querycap
= visl_querycap
,
539 .vidioc_enum_framesizes
= visl_enum_framesizes
,
541 .vidioc_enum_fmt_vid_cap
= visl_enum_fmt_vid_cap
,
542 .vidioc_g_fmt_vid_cap_mplane
= visl_g_fmt_vid_cap
,
543 .vidioc_try_fmt_vid_cap_mplane
= visl_try_fmt_vid_cap
,
544 .vidioc_s_fmt_vid_cap_mplane
= visl_s_fmt_vid_cap
,
546 .vidioc_enum_fmt_vid_out
= visl_enum_fmt_vid_out
,
547 .vidioc_g_fmt_vid_out_mplane
= visl_g_fmt_vid_out
,
548 .vidioc_try_fmt_vid_out_mplane
= visl_try_fmt_vid_out
,
549 .vidioc_s_fmt_vid_out_mplane
= visl_s_fmt_vid_out
,
551 .vidioc_reqbufs
= v4l2_m2m_ioctl_reqbufs
,
552 .vidioc_querybuf
= v4l2_m2m_ioctl_querybuf
,
553 .vidioc_qbuf
= v4l2_m2m_ioctl_qbuf
,
554 .vidioc_dqbuf
= v4l2_m2m_ioctl_dqbuf
,
555 .vidioc_prepare_buf
= v4l2_m2m_ioctl_prepare_buf
,
556 .vidioc_create_bufs
= v4l2_m2m_ioctl_create_bufs
,
557 .vidioc_expbuf
= v4l2_m2m_ioctl_expbuf
,
558 .vidioc_remove_bufs
= v4l2_m2m_ioctl_remove_bufs
,
560 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
561 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
563 .vidioc_decoder_cmd
= v4l2_m2m_ioctl_stateless_decoder_cmd
,
564 .vidioc_try_decoder_cmd
= v4l2_m2m_ioctl_stateless_try_decoder_cmd
,
566 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
567 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
570 static int visl_queue_setup(struct vb2_queue
*vq
,
571 unsigned int *nbuffers
,
572 unsigned int *num_planes
,
573 unsigned int sizes
[],
574 struct device
*alloc_devs
[])
576 struct visl_ctx
*ctx
= vb2_get_drv_priv(vq
);
577 struct v4l2_format
*f
;
581 if (V4L2_TYPE_IS_OUTPUT(vq
->type
)) {
585 f
= &ctx
->decoded_fmt
;
590 if (*num_planes
!= f
->fmt
.pix_mp
.num_planes
)
593 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++) {
594 if (sizes
[i
] < f
->fmt
.pix_mp
.plane_fmt
[i
].sizeimage
)
598 *num_planes
= f
->fmt
.pix_mp
.num_planes
;
599 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++)
600 sizes
[i
] = f
->fmt
.pix_mp
.plane_fmt
[i
].sizeimage
;
603 dprintk(ctx
->dev
, "%s: %d buffer(s) requested, num_planes=%d.\n",
604 qname
, *nbuffers
, *num_planes
);
606 for (i
= 0; i
< f
->fmt
.pix_mp
.num_planes
; i
++)
607 dprintk(ctx
->dev
, "plane[%d].sizeimage=%d\n",
608 i
, f
->fmt
.pix_mp
.plane_fmt
[i
].sizeimage
);
613 static void visl_queue_cleanup(struct vb2_queue
*vq
, u32 state
)
615 struct visl_ctx
*ctx
= vb2_get_drv_priv(vq
);
616 struct vb2_v4l2_buffer
*vbuf
;
618 dprintk(ctx
->dev
, "Cleaning up queues\n");
620 if (V4L2_TYPE_IS_OUTPUT(vq
->type
))
621 vbuf
= v4l2_m2m_src_buf_remove(ctx
->fh
.m2m_ctx
);
623 vbuf
= v4l2_m2m_dst_buf_remove(ctx
->fh
.m2m_ctx
);
628 v4l2_ctrl_request_complete(vbuf
->vb2_buf
.req_obj
.req
,
630 dprintk(ctx
->dev
, "Marked request %p as complete\n",
631 vbuf
->vb2_buf
.req_obj
.req
);
633 v4l2_m2m_buf_done(vbuf
, state
);
635 "Marked buffer %llu as done, state is %d\n",
636 vbuf
->vb2_buf
.timestamp
,
641 static int visl_buf_out_validate(struct vb2_buffer
*vb
)
643 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
645 vbuf
->field
= V4L2_FIELD_NONE
;
649 static int visl_buf_prepare(struct vb2_buffer
*vb
)
651 struct vb2_queue
*vq
= vb
->vb2_queue
;
652 struct visl_ctx
*ctx
= vb2_get_drv_priv(vq
);
653 u32 plane_sz
= vb2_plane_size(vb
, 0);
654 struct v4l2_pix_format
*pix_fmt
;
656 if (V4L2_TYPE_IS_OUTPUT(vq
->type
)) {
657 pix_fmt
= &ctx
->coded_fmt
.fmt
.pix
;
659 pix_fmt
= &ctx
->decoded_fmt
.fmt
.pix
;
660 vb2_set_plane_payload(vb
, 0, pix_fmt
->sizeimage
);
663 if (plane_sz
< pix_fmt
->sizeimage
) {
664 v4l2_err(&ctx
->dev
->v4l2_dev
, "plane[0] size is %d, sizeimage is %d\n",
665 plane_sz
, pix_fmt
->sizeimage
);
672 static int visl_start_streaming(struct vb2_queue
*vq
, unsigned int count
)
674 struct visl_ctx
*ctx
= vb2_get_drv_priv(vq
);
675 struct visl_q_data
*q_data
= get_q_data(ctx
, vq
->type
);
683 q_data
->sequence
= 0;
685 if (V4L2_TYPE_IS_CAPTURE(vq
->type
)) {
686 ctx
->capture_streamon_jiffies
= get_jiffies_64();
690 if (WARN_ON(!ctx
->coded_format_desc
)) {
698 visl_queue_cleanup(vq
, VB2_BUF_STATE_QUEUED
);
702 static void visl_stop_streaming(struct vb2_queue
*vq
)
704 struct visl_ctx
*ctx
= vb2_get_drv_priv(vq
);
706 dprintk(ctx
->dev
, "Stop streaming\n");
707 visl_queue_cleanup(vq
, VB2_BUF_STATE_ERROR
);
709 if (!keep_bitstream_buffers
)
710 visl_debugfs_clear_bitstream(ctx
->dev
);
713 static void visl_buf_queue(struct vb2_buffer
*vb
)
715 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
716 struct visl_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
718 v4l2_m2m_buf_queue(ctx
->fh
.m2m_ctx
, vbuf
);
721 static void visl_buf_request_complete(struct vb2_buffer
*vb
)
723 struct visl_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
725 v4l2_ctrl_request_complete(vb
->req_obj
.req
, &ctx
->hdl
);
728 static const struct vb2_ops visl_qops
= {
729 .queue_setup
= visl_queue_setup
,
730 .buf_out_validate
= visl_buf_out_validate
,
731 .buf_prepare
= visl_buf_prepare
,
732 .buf_queue
= visl_buf_queue
,
733 .start_streaming
= visl_start_streaming
,
734 .stop_streaming
= visl_stop_streaming
,
735 .buf_request_complete
= visl_buf_request_complete
,
738 int visl_queue_init(void *priv
, struct vb2_queue
*src_vq
,
739 struct vb2_queue
*dst_vq
)
741 struct visl_ctx
*ctx
= priv
;
744 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
745 src_vq
->io_modes
= VB2_MMAP
| VB2_DMABUF
;
746 src_vq
->drv_priv
= ctx
;
747 src_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
748 src_vq
->ops
= &visl_qops
;
749 src_vq
->mem_ops
= &vb2_vmalloc_memops
;
750 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
751 src_vq
->lock
= &ctx
->vb_mutex
;
752 src_vq
->supports_requests
= true;
753 src_vq
->subsystem_flags
|= VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF
;
755 ret
= vb2_queue_init(src_vq
);
759 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
760 dst_vq
->io_modes
= VB2_MMAP
| VB2_DMABUF
;
761 dst_vq
->drv_priv
= ctx
;
762 dst_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
763 dst_vq
->ops
= &visl_qops
;
764 dst_vq
->mem_ops
= &vb2_vmalloc_memops
;
765 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
766 dst_vq
->lock
= &ctx
->vb_mutex
;
768 return vb2_queue_init(dst_vq
);
771 int visl_request_validate(struct media_request
*req
)
773 struct media_request_object
*obj
;
774 struct visl_ctx
*ctx
= NULL
;
777 list_for_each_entry(obj
, &req
->objects
, list
) {
778 struct vb2_buffer
*vb
;
780 if (vb2_request_object_is_buffer(obj
)) {
781 vb
= container_of(obj
, struct vb2_buffer
, req_obj
);
782 ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
791 count
= vb2_request_buffer_cnt(req
);
793 v4l2_err(&ctx
->dev
->v4l2_dev
,
794 "No buffer was provided with the request\n");
796 } else if (count
> 1) {
797 v4l2_err(&ctx
->dev
->v4l2_dev
,
798 "More than one buffer was provided with the request\n");
802 return vb2_request_validate(req
);