1 // SPDX-License-Identifier: GPL-2.0-only
3 * vivid-vid-out.c - video output support functions.
5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
8 #include <linux/errno.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/videodev2.h>
12 #include <linux/v4l2-dv-timings.h>
13 #include <media/v4l2-common.h>
14 #include <media/v4l2-event.h>
15 #include <media/v4l2-dv-timings.h>
16 #include <media/v4l2-rect.h>
18 #include "vivid-core.h"
19 #include "vivid-vid-common.h"
20 #include "vivid-kthread-out.h"
21 #include "vivid-vid-out.h"
23 static int vid_out_queue_setup(struct vb2_queue
*vq
,
24 unsigned *nbuffers
, unsigned *nplanes
,
25 unsigned sizes
[], struct device
*alloc_devs
[])
27 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
28 const struct vivid_fmt
*vfmt
= dev
->fmt_out
;
29 unsigned planes
= vfmt
->buffers
;
30 unsigned h
= dev
->fmt_out_rect
.height
;
31 unsigned int size
= dev
->bytesperline_out
[0] * h
+ vfmt
->data_offset
[0];
34 for (p
= vfmt
->buffers
; p
< vfmt
->planes
; p
++)
35 size
+= dev
->bytesperline_out
[p
] * h
/ vfmt
->vdownsampling
[p
] +
38 if (dev
->field_out
== V4L2_FIELD_ALTERNATE
) {
40 * You cannot use write() with FIELD_ALTERNATE since the field
41 * information (TOP/BOTTOM) cannot be passed to the kernel.
43 if (vb2_fileio_is_active(vq
))
47 if (dev
->queue_setup_error
) {
49 * Error injection: test what happens if queue_setup() returns
52 dev
->queue_setup_error
= false;
58 * Check if the number of requested planes match
59 * the number of planes in the current format. You can't mix that.
61 if (*nplanes
!= planes
)
65 for (p
= 1; p
< planes
; p
++) {
66 if (sizes
[p
] < dev
->bytesperline_out
[p
] * h
+
71 for (p
= 0; p
< planes
; p
++)
72 sizes
[p
] = p
? dev
->bytesperline_out
[p
] * h
+
73 vfmt
->data_offset
[p
] : size
;
76 if (vq
->num_buffers
+ *nbuffers
< 2)
77 *nbuffers
= 2 - vq
->num_buffers
;
81 dprintk(dev
, 1, "%s: count=%d\n", __func__
, *nbuffers
);
82 for (p
= 0; p
< planes
; p
++)
83 dprintk(dev
, 1, "%s: size[%u]=%u\n", __func__
, p
, sizes
[p
]);
87 static int vid_out_buf_out_validate(struct vb2_buffer
*vb
)
89 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
90 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
92 dprintk(dev
, 1, "%s\n", __func__
);
94 if (dev
->field_out
!= V4L2_FIELD_ALTERNATE
)
95 vbuf
->field
= dev
->field_out
;
96 else if (vbuf
->field
!= V4L2_FIELD_TOP
&&
97 vbuf
->field
!= V4L2_FIELD_BOTTOM
)
102 static int vid_out_buf_prepare(struct vb2_buffer
*vb
)
104 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
105 const struct vivid_fmt
*vfmt
= dev
->fmt_out
;
106 unsigned int planes
= vfmt
->buffers
;
107 unsigned int h
= dev
->fmt_out_rect
.height
;
108 unsigned int size
= dev
->bytesperline_out
[0] * h
;
111 for (p
= vfmt
->buffers
; p
< vfmt
->planes
; p
++)
112 size
+= dev
->bytesperline_out
[p
] * h
/ vfmt
->vdownsampling
[p
];
114 dprintk(dev
, 1, "%s\n", __func__
);
116 if (WARN_ON(NULL
== dev
->fmt_out
))
119 if (dev
->buf_prepare_error
) {
121 * Error injection: test what happens if buf_prepare() returns
124 dev
->buf_prepare_error
= false;
128 for (p
= 0; p
< planes
; p
++) {
130 size
= dev
->bytesperline_out
[p
] * h
;
131 size
+= vb
->planes
[p
].data_offset
;
133 if (vb2_get_plane_payload(vb
, p
) < size
) {
134 dprintk(dev
, 1, "%s the payload is too small for plane %u (%lu < %u)\n",
135 __func__
, p
, vb2_get_plane_payload(vb
, p
), size
);
143 static void vid_out_buf_queue(struct vb2_buffer
*vb
)
145 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
146 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
147 struct vivid_buffer
*buf
= container_of(vbuf
, struct vivid_buffer
, vb
);
149 dprintk(dev
, 1, "%s\n", __func__
);
151 spin_lock(&dev
->slock
);
152 list_add_tail(&buf
->list
, &dev
->vid_out_active
);
153 spin_unlock(&dev
->slock
);
156 static int vid_out_start_streaming(struct vb2_queue
*vq
, unsigned count
)
158 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
161 if (vb2_is_streaming(&dev
->vb_vid_cap_q
))
162 dev
->can_loop_video
= vivid_vid_can_loop(dev
);
164 dev
->vid_out_seq_count
= 0;
165 dprintk(dev
, 1, "%s\n", __func__
);
166 if (dev
->start_streaming_error
) {
167 dev
->start_streaming_error
= false;
170 err
= vivid_start_generating_vid_out(dev
, &dev
->vid_out_streaming
);
173 struct vivid_buffer
*buf
, *tmp
;
175 list_for_each_entry_safe(buf
, tmp
, &dev
->vid_out_active
, list
) {
176 list_del(&buf
->list
);
177 vb2_buffer_done(&buf
->vb
.vb2_buf
,
178 VB2_BUF_STATE_QUEUED
);
184 /* abort streaming and wait for last buffer */
185 static void vid_out_stop_streaming(struct vb2_queue
*vq
)
187 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
189 dprintk(dev
, 1, "%s\n", __func__
);
190 vivid_stop_generating_vid_out(dev
, &dev
->vid_out_streaming
);
191 dev
->can_loop_video
= false;
194 static void vid_out_buf_request_complete(struct vb2_buffer
*vb
)
196 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
198 v4l2_ctrl_request_complete(vb
->req_obj
.req
, &dev
->ctrl_hdl_vid_out
);
201 const struct vb2_ops vivid_vid_out_qops
= {
202 .queue_setup
= vid_out_queue_setup
,
203 .buf_out_validate
= vid_out_buf_out_validate
,
204 .buf_prepare
= vid_out_buf_prepare
,
205 .buf_queue
= vid_out_buf_queue
,
206 .start_streaming
= vid_out_start_streaming
,
207 .stop_streaming
= vid_out_stop_streaming
,
208 .buf_request_complete
= vid_out_buf_request_complete
,
209 .wait_prepare
= vb2_ops_wait_prepare
,
210 .wait_finish
= vb2_ops_wait_finish
,
214 * Called whenever the format has to be reset which can occur when
215 * changing outputs, standard, timings, etc.
217 void vivid_update_format_out(struct vivid_dev
*dev
)
219 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
223 switch (dev
->output_type
[dev
->output
]) {
226 dev
->field_out
= dev
->tv_field_out
;
227 dev
->sink_rect
.width
= 720;
228 if (dev
->std_out
& V4L2_STD_525_60
) {
229 dev
->sink_rect
.height
= 480;
230 dev
->timeperframe_vid_out
= (struct v4l2_fract
) { 1001, 30000 };
231 dev
->service_set_out
= V4L2_SLICED_CAPTION_525
;
233 dev
->sink_rect
.height
= 576;
234 dev
->timeperframe_vid_out
= (struct v4l2_fract
) { 1000, 25000 };
235 dev
->service_set_out
= V4L2_SLICED_WSS_625
| V4L2_SLICED_TELETEXT_B
;
237 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
240 dev
->sink_rect
.width
= bt
->width
;
241 dev
->sink_rect
.height
= bt
->height
;
242 size
= V4L2_DV_BT_FRAME_WIDTH(bt
) * V4L2_DV_BT_FRAME_HEIGHT(bt
);
244 if (can_reduce_fps(bt
) && (bt
->flags
& V4L2_DV_FL_REDUCED_FPS
))
245 pixelclock
= div_u64(bt
->pixelclock
* 1000, 1001);
247 pixelclock
= bt
->pixelclock
;
249 dev
->timeperframe_vid_out
= (struct v4l2_fract
) {
250 size
/ 100, (u32
)pixelclock
/ 100
253 dev
->field_out
= V4L2_FIELD_ALTERNATE
;
255 dev
->field_out
= V4L2_FIELD_NONE
;
256 if (!dev
->dvi_d_out
&& (bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
)) {
257 if (bt
->width
== 720 && bt
->height
<= 576)
258 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
260 dev
->colorspace_out
= V4L2_COLORSPACE_REC709
;
262 dev
->colorspace_out
= V4L2_COLORSPACE_SRGB
;
266 dev
->xfer_func_out
= V4L2_XFER_FUNC_DEFAULT
;
267 dev
->ycbcr_enc_out
= V4L2_YCBCR_ENC_DEFAULT
;
268 dev
->hsv_enc_out
= V4L2_HSV_ENC_180
;
269 dev
->quantization_out
= V4L2_QUANTIZATION_DEFAULT
;
270 dev
->compose_out
= dev
->sink_rect
;
271 dev
->compose_bounds_out
= dev
->sink_rect
;
272 dev
->crop_out
= dev
->compose_out
;
273 if (V4L2_FIELD_HAS_T_OR_B(dev
->field_out
))
274 dev
->crop_out
.height
/= 2;
275 dev
->fmt_out_rect
= dev
->crop_out
;
276 for (p
= 0; p
< dev
->fmt_out
->planes
; p
++)
277 dev
->bytesperline_out
[p
] =
278 (dev
->sink_rect
.width
* dev
->fmt_out
->bit_depth
[p
]) / 8;
281 /* Map the field to something that is valid for the current output */
282 static enum v4l2_field
vivid_field_out(struct vivid_dev
*dev
, enum v4l2_field field
)
284 if (vivid_is_svid_out(dev
)) {
286 case V4L2_FIELD_INTERLACED_TB
:
287 case V4L2_FIELD_INTERLACED_BT
:
288 case V4L2_FIELD_SEQ_TB
:
289 case V4L2_FIELD_SEQ_BT
:
290 case V4L2_FIELD_ALTERNATE
:
292 case V4L2_FIELD_INTERLACED
:
294 return V4L2_FIELD_INTERLACED
;
297 if (vivid_is_hdmi_out(dev
))
298 return dev
->dv_timings_out
.bt
.interlaced
? V4L2_FIELD_ALTERNATE
:
300 return V4L2_FIELD_NONE
;
303 static enum tpg_pixel_aspect
vivid_get_pixel_aspect(const struct vivid_dev
*dev
)
305 if (vivid_is_svid_out(dev
))
306 return (dev
->std_out
& V4L2_STD_525_60
) ?
307 TPG_PIXEL_ASPECT_NTSC
: TPG_PIXEL_ASPECT_PAL
;
309 if (vivid_is_hdmi_out(dev
) &&
310 dev
->sink_rect
.width
== 720 && dev
->sink_rect
.height
<= 576)
311 return dev
->sink_rect
.height
== 480 ?
312 TPG_PIXEL_ASPECT_NTSC
: TPG_PIXEL_ASPECT_PAL
;
314 return TPG_PIXEL_ASPECT_SQUARE
;
317 int vivid_g_fmt_vid_out(struct file
*file
, void *priv
,
318 struct v4l2_format
*f
)
320 struct vivid_dev
*dev
= video_drvdata(file
);
321 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
322 const struct vivid_fmt
*fmt
= dev
->fmt_out
;
325 mp
->width
= dev
->fmt_out_rect
.width
;
326 mp
->height
= dev
->fmt_out_rect
.height
;
327 mp
->field
= dev
->field_out
;
328 mp
->pixelformat
= fmt
->fourcc
;
329 mp
->colorspace
= dev
->colorspace_out
;
330 mp
->xfer_func
= dev
->xfer_func_out
;
331 mp
->ycbcr_enc
= dev
->ycbcr_enc_out
;
332 mp
->quantization
= dev
->quantization_out
;
333 mp
->num_planes
= fmt
->buffers
;
334 for (p
= 0; p
< mp
->num_planes
; p
++) {
335 mp
->plane_fmt
[p
].bytesperline
= dev
->bytesperline_out
[p
];
336 mp
->plane_fmt
[p
].sizeimage
=
337 mp
->plane_fmt
[p
].bytesperline
* mp
->height
+
340 for (p
= fmt
->buffers
; p
< fmt
->planes
; p
++) {
341 unsigned stride
= dev
->bytesperline_out
[p
];
343 mp
->plane_fmt
[0].sizeimage
+=
344 (stride
* mp
->height
) / fmt
->vdownsampling
[p
];
349 int vivid_try_fmt_vid_out(struct file
*file
, void *priv
,
350 struct v4l2_format
*f
)
352 struct vivid_dev
*dev
= video_drvdata(file
);
353 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
354 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
355 struct v4l2_plane_pix_format
*pfmt
= mp
->plane_fmt
;
356 const struct vivid_fmt
*fmt
;
357 unsigned bytesperline
, max_bpl
;
362 fmt
= vivid_get_format(dev
, mp
->pixelformat
);
364 dprintk(dev
, 1, "Fourcc format (0x%08x) unknown.\n",
366 mp
->pixelformat
= V4L2_PIX_FMT_YUYV
;
367 fmt
= vivid_get_format(dev
, mp
->pixelformat
);
370 mp
->field
= vivid_field_out(dev
, mp
->field
);
371 if (vivid_is_svid_out(dev
)) {
373 h
= (dev
->std_out
& V4L2_STD_525_60
) ? 480 : 576;
375 w
= dev
->sink_rect
.width
;
376 h
= dev
->sink_rect
.height
;
378 if (V4L2_FIELD_HAS_T_OR_B(mp
->field
))
380 if (!dev
->has_scaler_out
&& !dev
->has_crop_out
&& !dev
->has_compose_out
) {
382 mp
->height
= h
/ factor
;
384 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
* factor
};
386 v4l2_rect_set_min_size(&r
, &vivid_min_rect
);
387 v4l2_rect_set_max_size(&r
, &vivid_max_rect
);
388 if (dev
->has_scaler_out
&& !dev
->has_crop_out
) {
389 struct v4l2_rect max_r
= { 0, 0, MAX_ZOOM
* w
, MAX_ZOOM
* h
};
391 v4l2_rect_set_max_size(&r
, &max_r
);
392 } else if (!dev
->has_scaler_out
&& dev
->has_compose_out
&& !dev
->has_crop_out
) {
393 v4l2_rect_set_max_size(&r
, &dev
->sink_rect
);
394 } else if (!dev
->has_scaler_out
&& !dev
->has_compose_out
) {
395 v4l2_rect_set_min_size(&r
, &dev
->sink_rect
);
398 mp
->height
= r
.height
/ factor
;
401 /* This driver supports custom bytesperline values */
403 mp
->num_planes
= fmt
->buffers
;
404 for (p
= 0; p
< fmt
->buffers
; p
++) {
405 /* Calculate the minimum supported bytesperline value */
406 bytesperline
= (mp
->width
* fmt
->bit_depth
[p
]) >> 3;
407 /* Calculate the maximum supported bytesperline value */
408 max_bpl
= (MAX_ZOOM
* MAX_WIDTH
* fmt
->bit_depth
[p
]) >> 3;
410 if (pfmt
[p
].bytesperline
> max_bpl
)
411 pfmt
[p
].bytesperline
= max_bpl
;
412 if (pfmt
[p
].bytesperline
< bytesperline
)
413 pfmt
[p
].bytesperline
= bytesperline
;
415 pfmt
[p
].sizeimage
= (pfmt
[p
].bytesperline
* mp
->height
) /
416 fmt
->vdownsampling
[p
] + fmt
->data_offset
[p
];
418 memset(pfmt
[p
].reserved
, 0, sizeof(pfmt
[p
].reserved
));
420 for (p
= fmt
->buffers
; p
< fmt
->planes
; p
++)
421 pfmt
[0].sizeimage
+= (pfmt
[0].bytesperline
* mp
->height
*
422 (fmt
->bit_depth
[p
] / fmt
->vdownsampling
[p
])) /
423 (fmt
->bit_depth
[0] / fmt
->vdownsampling
[0]);
425 mp
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
426 mp
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
427 mp
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
428 if (vivid_is_svid_out(dev
)) {
429 mp
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
430 } else if (dev
->dvi_d_out
|| !(bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
)) {
431 mp
->colorspace
= V4L2_COLORSPACE_SRGB
;
433 mp
->quantization
= V4L2_QUANTIZATION_LIM_RANGE
;
434 } else if (bt
->width
== 720 && bt
->height
<= 576) {
435 mp
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
436 } else if (mp
->colorspace
!= V4L2_COLORSPACE_SMPTE170M
&&
437 mp
->colorspace
!= V4L2_COLORSPACE_REC709
&&
438 mp
->colorspace
!= V4L2_COLORSPACE_OPRGB
&&
439 mp
->colorspace
!= V4L2_COLORSPACE_BT2020
&&
440 mp
->colorspace
!= V4L2_COLORSPACE_SRGB
) {
441 mp
->colorspace
= V4L2_COLORSPACE_REC709
;
443 memset(mp
->reserved
, 0, sizeof(mp
->reserved
));
447 int vivid_s_fmt_vid_out(struct file
*file
, void *priv
,
448 struct v4l2_format
*f
)
450 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
451 struct vivid_dev
*dev
= video_drvdata(file
);
452 struct v4l2_rect
*crop
= &dev
->crop_out
;
453 struct v4l2_rect
*compose
= &dev
->compose_out
;
454 struct vb2_queue
*q
= &dev
->vb_vid_out_q
;
455 int ret
= vivid_try_fmt_vid_out(file
, priv
, f
);
462 if (vb2_is_busy(q
) &&
463 (vivid_is_svid_out(dev
) ||
464 mp
->width
!= dev
->fmt_out_rect
.width
||
465 mp
->height
!= dev
->fmt_out_rect
.height
||
466 mp
->pixelformat
!= dev
->fmt_out
->fourcc
||
467 mp
->field
!= dev
->field_out
)) {
468 dprintk(dev
, 1, "%s device busy\n", __func__
);
473 * Allow for changing the colorspace on the fly. Useful for testing
474 * purposes, and it is something that HDMI transmitters are able
480 dev
->fmt_out
= vivid_get_format(dev
, mp
->pixelformat
);
481 if (V4L2_FIELD_HAS_T_OR_B(mp
->field
))
484 if (dev
->has_scaler_out
|| dev
->has_crop_out
|| dev
->has_compose_out
) {
485 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
};
487 if (dev
->has_scaler_out
) {
488 if (dev
->has_crop_out
)
489 v4l2_rect_map_inside(crop
, &r
);
492 if (dev
->has_compose_out
&& !dev
->has_crop_out
) {
493 struct v4l2_rect min_r
= {
496 factor
* r
.height
/ MAX_ZOOM
498 struct v4l2_rect max_r
= {
501 factor
* r
.height
* MAX_ZOOM
504 v4l2_rect_set_min_size(compose
, &min_r
);
505 v4l2_rect_set_max_size(compose
, &max_r
);
506 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
507 } else if (dev
->has_compose_out
) {
508 struct v4l2_rect min_r
= {
510 crop
->width
/ MAX_ZOOM
,
511 factor
* crop
->height
/ MAX_ZOOM
513 struct v4l2_rect max_r
= {
515 crop
->width
* MAX_ZOOM
,
516 factor
* crop
->height
* MAX_ZOOM
519 v4l2_rect_set_min_size(compose
, &min_r
);
520 v4l2_rect_set_max_size(compose
, &max_r
);
521 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
523 } else if (dev
->has_compose_out
&& !dev
->has_crop_out
) {
524 v4l2_rect_set_size_to(crop
, &r
);
526 v4l2_rect_set_size_to(compose
, &r
);
527 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
528 } else if (!dev
->has_compose_out
) {
529 v4l2_rect_map_inside(crop
, &r
);
531 v4l2_rect_set_size_to(compose
, &r
);
534 v4l2_rect_set_max_size(compose
, &r
);
535 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
537 crop
->height
*= factor
;
538 v4l2_rect_set_size_to(crop
, compose
);
539 v4l2_rect_map_inside(crop
, &r
);
541 crop
->height
/= factor
;
544 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
};
546 v4l2_rect_set_size_to(crop
, &r
);
548 v4l2_rect_set_size_to(compose
, &r
);
551 dev
->fmt_out_rect
.width
= mp
->width
;
552 dev
->fmt_out_rect
.height
= mp
->height
;
553 for (p
= 0; p
< mp
->num_planes
; p
++)
554 dev
->bytesperline_out
[p
] = mp
->plane_fmt
[p
].bytesperline
;
555 for (p
= dev
->fmt_out
->buffers
; p
< dev
->fmt_out
->planes
; p
++)
556 dev
->bytesperline_out
[p
] =
557 (dev
->bytesperline_out
[0] * dev
->fmt_out
->bit_depth
[p
]) /
558 dev
->fmt_out
->bit_depth
[0];
559 dev
->field_out
= mp
->field
;
560 if (vivid_is_svid_out(dev
))
561 dev
->tv_field_out
= mp
->field
;
564 dev
->colorspace_out
= mp
->colorspace
;
565 dev
->xfer_func_out
= mp
->xfer_func
;
566 dev
->ycbcr_enc_out
= mp
->ycbcr_enc
;
567 dev
->quantization_out
= mp
->quantization
;
568 if (dev
->loop_video
) {
569 vivid_send_source_change(dev
, SVID
);
570 vivid_send_source_change(dev
, HDMI
);
575 int vidioc_g_fmt_vid_out_mplane(struct file
*file
, void *priv
,
576 struct v4l2_format
*f
)
578 struct vivid_dev
*dev
= video_drvdata(file
);
580 if (!dev
->multiplanar
)
582 return vivid_g_fmt_vid_out(file
, priv
, f
);
585 int vidioc_try_fmt_vid_out_mplane(struct file
*file
, void *priv
,
586 struct v4l2_format
*f
)
588 struct vivid_dev
*dev
= video_drvdata(file
);
590 if (!dev
->multiplanar
)
592 return vivid_try_fmt_vid_out(file
, priv
, f
);
595 int vidioc_s_fmt_vid_out_mplane(struct file
*file
, void *priv
,
596 struct v4l2_format
*f
)
598 struct vivid_dev
*dev
= video_drvdata(file
);
600 if (!dev
->multiplanar
)
602 return vivid_s_fmt_vid_out(file
, priv
, f
);
605 int vidioc_g_fmt_vid_out(struct file
*file
, void *priv
,
606 struct v4l2_format
*f
)
608 struct vivid_dev
*dev
= video_drvdata(file
);
610 if (dev
->multiplanar
)
612 return fmt_sp2mp_func(file
, priv
, f
, vivid_g_fmt_vid_out
);
615 int vidioc_try_fmt_vid_out(struct file
*file
, void *priv
,
616 struct v4l2_format
*f
)
618 struct vivid_dev
*dev
= video_drvdata(file
);
620 if (dev
->multiplanar
)
622 return fmt_sp2mp_func(file
, priv
, f
, vivid_try_fmt_vid_out
);
625 int vidioc_s_fmt_vid_out(struct file
*file
, void *priv
,
626 struct v4l2_format
*f
)
628 struct vivid_dev
*dev
= video_drvdata(file
);
630 if (dev
->multiplanar
)
632 return fmt_sp2mp_func(file
, priv
, f
, vivid_s_fmt_vid_out
);
635 int vivid_vid_out_g_selection(struct file
*file
, void *priv
,
636 struct v4l2_selection
*sel
)
638 struct vivid_dev
*dev
= video_drvdata(file
);
640 if (!dev
->has_crop_out
&& !dev
->has_compose_out
)
642 if (sel
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
645 sel
->r
.left
= sel
->r
.top
= 0;
646 switch (sel
->target
) {
647 case V4L2_SEL_TGT_CROP
:
648 if (!dev
->has_crop_out
)
650 sel
->r
= dev
->crop_out
;
652 case V4L2_SEL_TGT_CROP_DEFAULT
:
653 if (!dev
->has_crop_out
)
655 sel
->r
= dev
->fmt_out_rect
;
657 case V4L2_SEL_TGT_CROP_BOUNDS
:
658 if (!dev
->has_crop_out
)
660 sel
->r
= vivid_max_rect
;
662 case V4L2_SEL_TGT_COMPOSE
:
663 if (!dev
->has_compose_out
)
665 sel
->r
= dev
->compose_out
;
667 case V4L2_SEL_TGT_COMPOSE_DEFAULT
:
668 case V4L2_SEL_TGT_COMPOSE_BOUNDS
:
669 if (!dev
->has_compose_out
)
671 sel
->r
= dev
->sink_rect
;
679 int vivid_vid_out_s_selection(struct file
*file
, void *fh
, struct v4l2_selection
*s
)
681 struct vivid_dev
*dev
= video_drvdata(file
);
682 struct v4l2_rect
*crop
= &dev
->crop_out
;
683 struct v4l2_rect
*compose
= &dev
->compose_out
;
684 unsigned factor
= V4L2_FIELD_HAS_T_OR_B(dev
->field_out
) ? 2 : 1;
687 if (!dev
->has_crop_out
&& !dev
->has_compose_out
)
689 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
693 case V4L2_SEL_TGT_CROP
:
694 if (!dev
->has_crop_out
)
696 ret
= vivid_vid_adjust_sel(s
->flags
, &s
->r
);
699 v4l2_rect_set_min_size(&s
->r
, &vivid_min_rect
);
700 v4l2_rect_set_max_size(&s
->r
, &dev
->fmt_out_rect
);
701 if (dev
->has_scaler_out
) {
702 struct v4l2_rect max_rect
= {
704 dev
->sink_rect
.width
* MAX_ZOOM
,
705 (dev
->sink_rect
.height
/ factor
) * MAX_ZOOM
708 v4l2_rect_set_max_size(&s
->r
, &max_rect
);
709 if (dev
->has_compose_out
) {
710 struct v4l2_rect min_rect
= {
712 s
->r
.width
/ MAX_ZOOM
,
713 (s
->r
.height
* factor
) / MAX_ZOOM
715 struct v4l2_rect max_rect
= {
717 s
->r
.width
* MAX_ZOOM
,
718 (s
->r
.height
* factor
) * MAX_ZOOM
721 v4l2_rect_set_min_size(compose
, &min_rect
);
722 v4l2_rect_set_max_size(compose
, &max_rect
);
723 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
725 } else if (dev
->has_compose_out
) {
727 s
->r
.height
*= factor
;
728 v4l2_rect_set_max_size(&s
->r
, &dev
->sink_rect
);
729 v4l2_rect_set_size_to(compose
, &s
->r
);
730 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
732 s
->r
.height
/= factor
;
734 v4l2_rect_set_size_to(&s
->r
, &dev
->sink_rect
);
735 s
->r
.height
/= factor
;
737 v4l2_rect_map_inside(&s
->r
, &dev
->fmt_out_rect
);
740 case V4L2_SEL_TGT_COMPOSE
:
741 if (!dev
->has_compose_out
)
743 ret
= vivid_vid_adjust_sel(s
->flags
, &s
->r
);
746 v4l2_rect_set_min_size(&s
->r
, &vivid_min_rect
);
747 v4l2_rect_set_max_size(&s
->r
, &dev
->sink_rect
);
748 v4l2_rect_map_inside(&s
->r
, &dev
->compose_bounds_out
);
750 s
->r
.height
/= factor
;
751 if (dev
->has_scaler_out
) {
752 struct v4l2_rect fmt
= dev
->fmt_out_rect
;
753 struct v4l2_rect max_rect
= {
755 s
->r
.width
* MAX_ZOOM
,
756 s
->r
.height
* MAX_ZOOM
758 struct v4l2_rect min_rect
= {
760 s
->r
.width
/ MAX_ZOOM
,
761 s
->r
.height
/ MAX_ZOOM
764 v4l2_rect_set_min_size(&fmt
, &min_rect
);
765 if (!dev
->has_crop_out
)
766 v4l2_rect_set_max_size(&fmt
, &max_rect
);
767 if (!v4l2_rect_same_size(&dev
->fmt_out_rect
, &fmt
) &&
768 vb2_is_busy(&dev
->vb_vid_out_q
))
770 if (dev
->has_crop_out
) {
771 v4l2_rect_set_min_size(crop
, &min_rect
);
772 v4l2_rect_set_max_size(crop
, &max_rect
);
774 dev
->fmt_out_rect
= fmt
;
775 } else if (dev
->has_crop_out
) {
776 struct v4l2_rect fmt
= dev
->fmt_out_rect
;
778 v4l2_rect_set_min_size(&fmt
, &s
->r
);
779 if (!v4l2_rect_same_size(&dev
->fmt_out_rect
, &fmt
) &&
780 vb2_is_busy(&dev
->vb_vid_out_q
))
782 dev
->fmt_out_rect
= fmt
;
783 v4l2_rect_set_size_to(crop
, &s
->r
);
784 v4l2_rect_map_inside(crop
, &dev
->fmt_out_rect
);
786 if (!v4l2_rect_same_size(&s
->r
, &dev
->fmt_out_rect
) &&
787 vb2_is_busy(&dev
->vb_vid_out_q
))
789 v4l2_rect_set_size_to(&dev
->fmt_out_rect
, &s
->r
);
790 v4l2_rect_set_size_to(crop
, &s
->r
);
791 crop
->height
/= factor
;
792 v4l2_rect_map_inside(crop
, &dev
->fmt_out_rect
);
795 s
->r
.height
*= factor
;
796 if (dev
->bitmap_out
&& (compose
->width
!= s
->r
.width
||
797 compose
->height
!= s
->r
.height
)) {
798 vfree(dev
->bitmap_out
);
799 dev
->bitmap_out
= NULL
;
810 int vivid_vid_out_g_pixelaspect(struct file
*file
, void *priv
,
811 int type
, struct v4l2_fract
*f
)
813 struct vivid_dev
*dev
= video_drvdata(file
);
815 if (type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
818 switch (vivid_get_pixel_aspect(dev
)) {
819 case TPG_PIXEL_ASPECT_NTSC
:
823 case TPG_PIXEL_ASPECT_PAL
:
833 int vidioc_g_fmt_vid_out_overlay(struct file
*file
, void *priv
,
834 struct v4l2_format
*f
)
836 struct vivid_dev
*dev
= video_drvdata(file
);
837 const struct v4l2_rect
*compose
= &dev
->compose_out
;
838 struct v4l2_window
*win
= &f
->fmt
.win
;
839 unsigned clipcount
= win
->clipcount
;
843 win
->w
.top
= dev
->overlay_out_top
;
844 win
->w
.left
= dev
->overlay_out_left
;
845 win
->w
.width
= compose
->width
;
846 win
->w
.height
= compose
->height
;
847 win
->clipcount
= dev
->clipcount_out
;
848 win
->field
= V4L2_FIELD_ANY
;
849 win
->chromakey
= dev
->chromakey_out
;
850 win
->global_alpha
= dev
->global_alpha_out
;
851 if (clipcount
> dev
->clipcount_out
)
852 clipcount
= dev
->clipcount_out
;
853 if (dev
->bitmap_out
== NULL
)
855 else if (win
->bitmap
) {
856 if (copy_to_user(win
->bitmap
, dev
->bitmap_out
,
857 ((dev
->compose_out
.width
+ 7) / 8) * dev
->compose_out
.height
))
860 if (clipcount
&& win
->clips
)
861 memcpy(win
->clips
, dev
->clips_out
,
862 clipcount
* sizeof(dev
->clips_out
[0]));
866 int vidioc_try_fmt_vid_out_overlay(struct file
*file
, void *priv
,
867 struct v4l2_format
*f
)
869 struct vivid_dev
*dev
= video_drvdata(file
);
870 const struct v4l2_rect
*compose
= &dev
->compose_out
;
871 struct v4l2_window
*win
= &f
->fmt
.win
;
876 win
->w
.left
= clamp_t(int, win
->w
.left
,
877 -dev
->display_width
, dev
->display_width
);
878 win
->w
.top
= clamp_t(int, win
->w
.top
,
879 -dev
->display_height
, dev
->display_height
);
880 win
->w
.width
= compose
->width
;
881 win
->w
.height
= compose
->height
;
883 * It makes no sense for an OSD to overlay only top or bottom fields,
884 * so always set this to ANY.
886 win
->field
= V4L2_FIELD_ANY
;
887 if (win
->clipcount
&& !win
->clips
)
889 if (win
->clipcount
> MAX_CLIPS
)
890 win
->clipcount
= MAX_CLIPS
;
891 if (win
->clipcount
) {
892 memcpy(dev
->try_clips_out
, win
->clips
,
893 win
->clipcount
* sizeof(dev
->clips_out
[0]));
894 for (i
= 0; i
< win
->clipcount
; i
++) {
895 struct v4l2_rect
*r
= &dev
->try_clips_out
[i
].c
;
897 r
->top
= clamp_t(s32
, r
->top
, 0, dev
->display_height
- 1);
898 r
->height
= clamp_t(s32
, r
->height
, 1, dev
->display_height
- r
->top
);
899 r
->left
= clamp_t(u32
, r
->left
, 0, dev
->display_width
- 1);
900 r
->width
= clamp_t(u32
, r
->width
, 1, dev
->display_width
- r
->left
);
903 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small
904 * number and it's typically a one-time deal.
906 for (i
= 0; i
< win
->clipcount
- 1; i
++) {
907 struct v4l2_rect
*r1
= &dev
->try_clips_out
[i
].c
;
909 for (j
= i
+ 1; j
< win
->clipcount
; j
++) {
910 struct v4l2_rect
*r2
= &dev
->try_clips_out
[j
].c
;
912 if (v4l2_rect_overlap(r1
, r2
))
916 memcpy(win
->clips
, dev
->try_clips_out
,
917 win
->clipcount
* sizeof(dev
->clips_out
[0]));
922 int vidioc_s_fmt_vid_out_overlay(struct file
*file
, void *priv
,
923 struct v4l2_format
*f
)
925 struct vivid_dev
*dev
= video_drvdata(file
);
926 const struct v4l2_rect
*compose
= &dev
->compose_out
;
927 struct v4l2_window
*win
= &f
->fmt
.win
;
928 int ret
= vidioc_try_fmt_vid_out_overlay(file
, priv
, f
);
929 unsigned bitmap_size
= ((compose
->width
+ 7) / 8) * compose
->height
;
930 unsigned clips_size
= win
->clipcount
* sizeof(dev
->clips_out
[0]);
931 void *new_bitmap
= NULL
;
937 new_bitmap
= vzalloc(bitmap_size
);
941 if (copy_from_user(new_bitmap
, win
->bitmap
, bitmap_size
)) {
947 dev
->overlay_out_top
= win
->w
.top
;
948 dev
->overlay_out_left
= win
->w
.left
;
949 vfree(dev
->bitmap_out
);
950 dev
->bitmap_out
= new_bitmap
;
951 dev
->clipcount_out
= win
->clipcount
;
952 if (dev
->clipcount_out
)
953 memcpy(dev
->clips_out
, dev
->try_clips_out
, clips_size
);
954 dev
->chromakey_out
= win
->chromakey
;
955 dev
->global_alpha_out
= win
->global_alpha
;
959 int vivid_vid_out_overlay(struct file
*file
, void *fh
, unsigned i
)
961 struct vivid_dev
*dev
= video_drvdata(file
);
963 if (i
&& !dev
->fmt_out
->can_do_overlay
) {
964 dprintk(dev
, 1, "unsupported output format for output overlay\n");
968 dev
->overlay_out_enabled
= i
;
972 int vivid_vid_out_g_fbuf(struct file
*file
, void *fh
,
973 struct v4l2_framebuffer
*a
)
975 struct vivid_dev
*dev
= video_drvdata(file
);
977 a
->capability
= V4L2_FBUF_CAP_EXTERNOVERLAY
|
978 V4L2_FBUF_CAP_BITMAP_CLIPPING
|
979 V4L2_FBUF_CAP_LIST_CLIPPING
|
980 V4L2_FBUF_CAP_CHROMAKEY
|
981 V4L2_FBUF_CAP_SRC_CHROMAKEY
|
982 V4L2_FBUF_CAP_GLOBAL_ALPHA
|
983 V4L2_FBUF_CAP_LOCAL_ALPHA
|
984 V4L2_FBUF_CAP_LOCAL_INV_ALPHA
;
985 a
->flags
= V4L2_FBUF_FLAG_OVERLAY
| dev
->fbuf_out_flags
;
986 a
->base
= (void *)dev
->video_pbase
;
987 a
->fmt
.width
= dev
->display_width
;
988 a
->fmt
.height
= dev
->display_height
;
989 if (dev
->fb_defined
.green
.length
== 5)
990 a
->fmt
.pixelformat
= V4L2_PIX_FMT_ARGB555
;
992 a
->fmt
.pixelformat
= V4L2_PIX_FMT_RGB565
;
993 a
->fmt
.bytesperline
= dev
->display_byte_stride
;
994 a
->fmt
.sizeimage
= a
->fmt
.height
* a
->fmt
.bytesperline
;
995 a
->fmt
.field
= V4L2_FIELD_NONE
;
996 a
->fmt
.colorspace
= V4L2_COLORSPACE_SRGB
;
1001 int vivid_vid_out_s_fbuf(struct file
*file
, void *fh
,
1002 const struct v4l2_framebuffer
*a
)
1004 struct vivid_dev
*dev
= video_drvdata(file
);
1005 const unsigned chroma_flags
= V4L2_FBUF_FLAG_CHROMAKEY
|
1006 V4L2_FBUF_FLAG_SRC_CHROMAKEY
;
1007 const unsigned alpha_flags
= V4L2_FBUF_FLAG_GLOBAL_ALPHA
|
1008 V4L2_FBUF_FLAG_LOCAL_ALPHA
|
1009 V4L2_FBUF_FLAG_LOCAL_INV_ALPHA
;
1012 if ((a
->flags
& chroma_flags
) == chroma_flags
)
1014 switch (a
->flags
& alpha_flags
) {
1016 case V4L2_FBUF_FLAG_GLOBAL_ALPHA
:
1017 case V4L2_FBUF_FLAG_LOCAL_ALPHA
:
1018 case V4L2_FBUF_FLAG_LOCAL_INV_ALPHA
:
1023 dev
->fbuf_out_flags
&= ~(chroma_flags
| alpha_flags
);
1024 dev
->fbuf_out_flags
= a
->flags
& (chroma_flags
| alpha_flags
);
1028 static const struct v4l2_audioout vivid_audio_outputs
[] = {
1029 { 0, "Line-Out 1" },
1030 { 1, "Line-Out 2" },
1033 int vidioc_enum_output(struct file
*file
, void *priv
,
1034 struct v4l2_output
*out
)
1036 struct vivid_dev
*dev
= video_drvdata(file
);
1038 if (out
->index
>= dev
->num_outputs
)
1041 out
->type
= V4L2_OUTPUT_TYPE_ANALOG
;
1042 switch (dev
->output_type
[out
->index
]) {
1044 snprintf(out
->name
, sizeof(out
->name
), "S-Video %u",
1045 dev
->output_name_counter
[out
->index
]);
1046 out
->std
= V4L2_STD_ALL
;
1047 if (dev
->has_audio_outputs
)
1048 out
->audioset
= (1 << ARRAY_SIZE(vivid_audio_outputs
)) - 1;
1049 out
->capabilities
= V4L2_OUT_CAP_STD
;
1052 snprintf(out
->name
, sizeof(out
->name
), "HDMI %u",
1053 dev
->output_name_counter
[out
->index
]);
1054 out
->capabilities
= V4L2_OUT_CAP_DV_TIMINGS
;
1060 int vidioc_g_output(struct file
*file
, void *priv
, unsigned *o
)
1062 struct vivid_dev
*dev
= video_drvdata(file
);
1068 int vidioc_s_output(struct file
*file
, void *priv
, unsigned o
)
1070 struct vivid_dev
*dev
= video_drvdata(file
);
1072 if (o
>= dev
->num_outputs
)
1075 if (o
== dev
->output
)
1078 if (vb2_is_busy(&dev
->vb_vid_out_q
) ||
1079 vb2_is_busy(&dev
->vb_vbi_out_q
) ||
1080 vb2_is_busy(&dev
->vb_meta_out_q
))
1084 dev
->tv_audio_output
= 0;
1085 if (dev
->output_type
[o
] == SVID
)
1086 dev
->vid_out_dev
.tvnorms
= V4L2_STD_ALL
;
1088 dev
->vid_out_dev
.tvnorms
= 0;
1090 dev
->vbi_out_dev
.tvnorms
= dev
->vid_out_dev
.tvnorms
;
1091 dev
->meta_out_dev
.tvnorms
= dev
->vid_out_dev
.tvnorms
;
1092 vivid_update_format_out(dev
);
1094 v4l2_ctrl_activate(dev
->ctrl_display_present
, vivid_is_hdmi_out(dev
));
1095 if (vivid_is_hdmi_out(dev
))
1096 v4l2_ctrl_s_ctrl(dev
->ctrl_display_present
,
1097 dev
->display_present
[dev
->output
]);
1102 int vidioc_enumaudout(struct file
*file
, void *fh
, struct v4l2_audioout
*vout
)
1104 if (vout
->index
>= ARRAY_SIZE(vivid_audio_outputs
))
1106 *vout
= vivid_audio_outputs
[vout
->index
];
1110 int vidioc_g_audout(struct file
*file
, void *fh
, struct v4l2_audioout
*vout
)
1112 struct vivid_dev
*dev
= video_drvdata(file
);
1114 if (!vivid_is_svid_out(dev
))
1116 *vout
= vivid_audio_outputs
[dev
->tv_audio_output
];
1120 int vidioc_s_audout(struct file
*file
, void *fh
, const struct v4l2_audioout
*vout
)
1122 struct vivid_dev
*dev
= video_drvdata(file
);
1124 if (!vivid_is_svid_out(dev
))
1126 if (vout
->index
>= ARRAY_SIZE(vivid_audio_outputs
))
1128 dev
->tv_audio_output
= vout
->index
;
1132 int vivid_vid_out_s_std(struct file
*file
, void *priv
, v4l2_std_id id
)
1134 struct vivid_dev
*dev
= video_drvdata(file
);
1136 if (!vivid_is_svid_out(dev
))
1138 if (dev
->std_out
== id
)
1140 if (vb2_is_busy(&dev
->vb_vid_out_q
) || vb2_is_busy(&dev
->vb_vbi_out_q
))
1143 vivid_update_format_out(dev
);
1147 static bool valid_cvt_gtf_timings(struct v4l2_dv_timings
*timings
)
1149 struct v4l2_bt_timings
*bt
= &timings
->bt
;
1151 if ((bt
->standards
& (V4L2_DV_BT_STD_CVT
| V4L2_DV_BT_STD_GTF
)) &&
1152 v4l2_valid_dv_timings(timings
, &vivid_dv_timings_cap
, NULL
, NULL
))
1158 int vivid_vid_out_s_dv_timings(struct file
*file
, void *_fh
,
1159 struct v4l2_dv_timings
*timings
)
1161 struct vivid_dev
*dev
= video_drvdata(file
);
1162 if (!vivid_is_hdmi_out(dev
))
1164 if (!v4l2_find_dv_timings_cap(timings
, &vivid_dv_timings_cap
,
1166 !valid_cvt_gtf_timings(timings
))
1168 if (v4l2_match_dv_timings(timings
, &dev
->dv_timings_out
, 0, true))
1170 if (vb2_is_busy(&dev
->vb_vid_out_q
))
1172 dev
->dv_timings_out
= *timings
;
1173 vivid_update_format_out(dev
);
1177 int vivid_vid_out_g_parm(struct file
*file
, void *priv
,
1178 struct v4l2_streamparm
*parm
)
1180 struct vivid_dev
*dev
= video_drvdata(file
);
1182 if (parm
->type
!= (dev
->multiplanar
?
1183 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
1184 V4L2_BUF_TYPE_VIDEO_OUTPUT
))
1187 parm
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
1188 parm
->parm
.output
.timeperframe
= dev
->timeperframe_vid_out
;
1189 parm
->parm
.output
.writebuffers
= 1;
1194 int vidioc_subscribe_event(struct v4l2_fh
*fh
,
1195 const struct v4l2_event_subscription
*sub
)
1197 switch (sub
->type
) {
1198 case V4L2_EVENT_SOURCE_CHANGE
:
1199 if (fh
->vdev
->vfl_dir
== VFL_DIR_RX
)
1200 return v4l2_src_change_event_subscribe(fh
, sub
);
1203 return v4l2_ctrl_subscribe_event(fh
, sub
);